jitgrammarrules.jcs
来自「This is a resource based on j2me embedde」· JCS 代码 · 共 1,919 行 · 第 1/5 页
JCS
1,919 行
CVMJITInliningInfoStackEntry* topEntry; CVMCompiledInliningInfoEntry* recordedEntry; CVMUint16 pcEnd = CVMJITcbufGetLogicalPC(con); CVMJITMethodContext *mc; CVMUint16 count = CVMJITirnodeGetNull(thisNode)->data; CVMassert(count > 0); while (count-- > 0) { CVMassert(con->inliningDepth > 0); topEntry = &con->inliningStack[--con->inliningDepth]; mc = topEntry->mc; CVMassert(topEntry->pcOffset1 > 0); CVMassert(topEntry->mc != NULL); CVMassert(con->inliningInfoIdx < con->numInliningInfoEntries); /* Now commit another "permanent" entry */ recordedEntry = &con->inliningInfo->entries[con->inliningInfoIdx++]; recordedEntry->pcOffset1 = topEntry->pcOffset1; recordedEntry->mb = mc->mb; recordedEntry->pcOffset2 = pcEnd; recordedEntry->invokePC = mc->invokePC; recordedEntry->flags = 0; { recordedEntry->firstLocal = mc->firstLocal; if (CVMmbIs(mc->mb, SYNCHRONIZED)) { CVMassert(!CVMmbIs(mc->mb, STATIC)); recordedEntry->syncObject = mc->syncObject; } else { recordedEntry->syncObject = 0; } } CVMJITprintCodegenComment(("End inlining of %C.%M (end pc=%d):", CVMmbClassBlock(recordedEntry->mb), recordedEntry->mb, pcEnd)); }}#ifdef CVM_DEBUGstatic voidprintInliningInfo(CVMJITCompilationContext *con, CVMJITIRNode* thisNode, const char* what){ CVMJITUnaryOp* unop = CVMJITirnodeGetUnaryOp(thisNode); if (CVMJITirnodeIsConstMB(unop->operand)) { CVMMethodBlock* mb; CVMJITConstantAddr* constAddr; constAddr = CVMJITirnodeGetConstantAddr(unop->operand); mb = constAddr->mb; CVMJITprintCodegenComment(("%s of %C.%M:", what, CVMmbClassBlock(mb), mb)); } else { CVMJITprintCodegenComment(("%s (node id %d):", what, CVMJITirnodeGetID(unop->operand))); }}#else#define printInliningInfo(con, thisNode, what)#endif/* * For nodes of the form: * NODE .... reg<width> * * Pass the reg<width> value onto NODE */static voidpassLastEvaluated(CVMJITCompilationContext* con, CVMJITRMContext* rc, CVMJITIRNodePtr thisNode){ /* Associate the last evaluated sub-node on to its parent */ CVMRMResource* arg = popResource(con); CVMRMoccupyAndUnpinResource(rc, arg, thisNode); pushResource(con, arg);}/* Purpose: Converts a constant into reg32 value. */static voidconst2Reg32(CVMJITCompilationContext *con, CVMJITRMContext *rc, CVMJITIRNodePtr thisNode){ CVMInt32 constant = CVMJITirnodeGetConstant32(thisNode)->j.i; CVMRMResource *dest = CVMRMbindResourceForConstant32(rc, constant); /* Need this in case this constant is a CSE */ CVMRMoccupyAndUnpinResource(rc, dest, thisNode); pushResource(con, dest);}/* Purpose: Converts a constant into reg32 value. */static voidconst2RegAddr(CVMJITCompilationContext *con, CVMJITRMContext *rc, CVMJITIRNodePtr thisNode){ CVMAddr constant = CVMJITirnodeGetConstantAddr(thisNode)->vAddr; CVMRMResource *dest = CVMRMbindResourceForConstantAddr(rc, constant); /* Need this in case this constant is a CSE */ CVMRMoccupyAndUnpinResource(rc, dest, thisNode); pushResource(con, dest);}#ifdef CVMJIT_INTRINSICS/* Get absolute value of srcReg and set condition codes: adds rDest, rSrc, #0 neglt rDest, rSrc*/static void emitAbsolute(CVMJITCompilationContext* con, int destReg, int srcReg){ CVMCPUemitBinaryALU(con, CVMCPU_ADD_OPCODE, destReg, srcReg, CVMCPUALURhsTokenConstZero, CVMJIT_SETCC);#ifndef CVMCPU_HAS_ALU_SETCC CVMCPUemitCompare(con, CVMCPU_CMP_OPCODE, CVMCPU_COND_LT, srcReg, CVMCPUALURhsTokenConstZero);#endif CVMCPUemitUnaryALUConditional(con, CVMCPU_NEG_OPCODE, destReg, srcReg, CVMJIT_NOSETCC, CVMCPU_COND_LT);}CVMJITRegsRequiredTypeCVMJITRISCintrinsicDefaultGetRequired(CVMJITCompilationContext *con, CVMJITIRNode *intrinsicNode, CVMJITRegsRequiredType argsRequiredSet){ return argsRequiredSet;}CVMRMregsetCVMJITRISCintrinsicDefaultGetArgTarget(CVMJITCompilationContext *con, int typeTag, CVMUint16 argNumber, CVMUint16 argWordIndex){ return CVMRM_ANY_SET;}#ifdef CVMJIT_SIMPLE_SYNC_METHODSCVMJITRegsRequiredTypeCVMJITRISCintrinsicSimpleLockReleaseGetRequired( CVMJITCompilationContext *con, CVMJITIRNode *intrinsicNode, CVMJITRegsRequiredType argsRequiredSet){#if CVM_FASTLOCK_TYPE == CVM_FASTLOCK_ATOMICOPS /* During the release, we may call CVMCCMruntimeSimpleSyncUnlock, * which requires ARG1 and ARG2 */ return argsRequiredSet | ARG1 | ARG2 | CVMCPU_AVOID_C_CALL;#else return argsRequiredSet;#endif}CVMRMregsetCVMJITRISCintrinsicSimpleLockReleaseGetArgTarget( CVMJITCompilationContext *con, int typeTag, CVMUint16 argNumber, CVMUint16 argWordIndex){ CVMassert(argNumber == 0);#if CVM_FASTLOCK_TYPE == CVM_FASTLOCK_ATOMICOPS /* During the release, we may call CVMCCMruntimeSimpleSyncUnlock, * which requires "this" to be in ARG2 */ return ARG2;#else return CVMRM_ANY_SET;#endif}#endif /* CVMJIT_SIMPLE_SYNC_METHODS *//* intrinsic emitter for Thread.currentThread(). */static voidjava_lang_Thread_currentThread_EmitOperator(CVMJITCompilationContext *con, CVMJITIRNode *intrinsicNode){ struct CVMJITCompileExpression_rule_computation_state *goal_top = (struct CVMJITCompileExpression_rule_computation_state *) (con->goal_top); CVMRMResource* dest = CVMRMgetResource(CVMRM_INT_REGS(con), GET_REGISTER_GOALS, 1); int destReg = CVMRMgetRegisterNumber(dest); int eeReg; /* ldr eeReg, [sp, #OFFSET_CVMCCExecEnv_ee] @ Get ee. ldr rDest, [eeReg, #OFFSET_CVMExecEnv_threadICell] @ Get threadICell. ldr rDest, [rDest] @ Get thread obj. */#ifdef CVMCPU_EE_REG eeReg = CVMCPU_EE_REG;#else eeReg = destReg; /* Get the ee from the ccee: */ CVMJITaddCodegenComment((con, "eeReg = ccee->ee")); CVMCPUemitCCEEReferenceImmediate(con, CVMCPU_LDRADDR_OPCODE, eeReg, offsetof(CVMCCExecEnv, eeX));#endif /* Get the thread icell from the ee: */ CVMJITaddCodegenComment((con, "destReg = ee->threadICell")); CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_LDRADDR_OPCODE, destReg, eeReg, offsetof(CVMExecEnv, threadICell)); /* Get the thread object from the thread icell: */ CVMJITaddCodegenComment((con, "destReg = *ee->threadICell")); CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_LDRADDR_OPCODE, destReg, destReg, 0); CVMRMoccupyAndUnpinResource(CVMRM_INT_REGS(con), dest, intrinsicNode); pushResource(con, dest);}static voidiabsEmitOperator(CVMJITCompilationContext *con, CVMJITIRNode *intrinsicNode){ struct CVMJITCompileExpression_rule_computation_state *goal_top = (struct CVMJITCompileExpression_rule_computation_state *) (con->goal_top); CVMRMResource* src = popResource(con); CVMRMResource* dest = CVMRMgetResource(CVMRM_INT_REGS(con), GET_REGISTER_GOALS, 1); CVMRMpinResource(CVMRM_INT_REGS(con), src, CVMRM_ANY_SET, CVMRM_EMPTY_SET); emitAbsolute(con, CVMRMgetRegisterNumber(dest), CVMRMgetRegisterNumber(src)); CVMRMrelinquishResource(CVMRM_INT_REGS(con), src); CVMRMoccupyAndUnpinResource(CVMRM_INT_REGS(con), dest, intrinsicNode); pushResource(con, dest);}#ifdef CVMJIT_SIMPLE_SYNC_METHODS#if CVM_FASTLOCK_TYPE == CVM_FASTLOCK_MICROLOCK && \ CVM_MICROLOCK_TYPE == CVM_MICROLOCK_SWAP_SPINLOCK/* * Intrinsic emitter for spinlock microlock version of CVM.simpleLockGrab(). * * Grabs CVMglobals.objGlobalMicroLock using atomic swap. If it fails, * returns FALSE. If successful, checks if the object is already locked. * If locked, releases CVMglobals.objGlobalMicroLock and returns FALSE. * Otherwise returns TRUE. */static voidsimpleLockGrabEmitter( CVMJITCompilationContext * con, CVMJITIRNode *intrinsicNode){ CVMRMResource* obj = popResource(con); CVMRMResource* objHdr; CVMRMResource* dest; CVMRMResource* microLock; int objRegID, objHdrRegID, destRegID, microLockRegID; int fixupPC1, fixupPC2; /* To patch the conditional branches */ struct CVMJITCompileExpression_rule_computation_state *goal_top = (struct CVMJITCompileExpression_rule_computation_state *) (con->goal_top); dest = CVMRMgetResource(CVMRM_INT_REGS(con), GET_REGISTER_GOALS, 1); objHdr = CVMRMgetResource(CVMRM_INT_REGS(con), CVMRM_ANY_SET, CVMRM_SAFE_SET, 1); CVMRMpinResource(CVMRM_INT_REGS(con), obj, CVMRM_ANY_SET, CVMRM_SAFE_SET); objRegID = CVMRMgetRegisterNumber(obj); objHdrRegID = CVMRMgetRegisterNumber(objHdr); destRegID = CVMRMgetRegisterNumber(dest); /* load microlock address into microLockRegID */ CVMJITsetSymbolName((con, "&CVMglobals.objGlobalMicroLock")); microLock = CVMRMgetResourceForConstant32( CVMRM_INT_REGS(con), CVMRM_ANY_SET, CVMRM_SAFE_SET, (CVMUint32)&CVMglobals.objGlobalMicroLock); microLockRegID = CVMRMgetRegisterNumber(microLock); /* preload the address to help caching */ CVMJITaddCodegenComment((con, "tmp = CVMglobals.objGlobalMicroLock")); CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_LDR32_OPCODE, destRegID, microLockRegID, 0); /* Get microlock LOCKED flag */ CVMJITaddCodegenComment((con, "CVM_MICROLOCK_LOCKED")); CVMCPUemitLoadConstant(con, destRegID, CVM_MICROLOCK_LOCKED); /* atomic swap LOCKED into the microlock */ CVMJITaddCodegenComment((con, "swp(CVMglobals.objGlobalMicroLock, CVM_MICROLOCK_LOCKED)")); CVMCPUemitAtomicSwap(con, destRegID, microLockRegID); /* check if microlock is already locked */ CVMJITaddCodegenComment((con, "check if microlock is locked")); CVMCPUemitCompareConstant(con, CVMCPU_CMP_OPCODE, CVMCPU_COND_EQ, destRegID, CVM_MICROLOCK_LOCKED); /* branch if microlock already locked */ CVMJITaddCodegenComment((con, "br failed if microlock is locked")); fixupPC1 = CVMCPUemitBranch(con, 0, CVMCPU_COND_EQ);#ifdef IAI_CODE_SCHEDULER_SCORE_BOARD fixupPC1 = CVMJITcbufGetLogicalInstructionPC(con);#endif /* load the object header */ CVMJITaddCodegenComment((con, "get obj.hdr.various32")); CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_LDR32_OPCODE, objHdrRegID, objRegID, CVMoffsetof(CVMObjectHeader,various32)); /* assume not locked and set intrinsic result */ CVMJITaddCodegenComment((con, "assume not locked: result = true")); CVMCPUemitLoadConstant(con, destRegID, CVM_TRUE); /* get sync bits from object header */ CVMJITaddCodegenComment((con, "get obj sync bits")); CVMCPUemitBinaryALUConstant(con, CVMCPU_AND_OPCODE, objHdrRegID, objHdrRegID, CVM_SYNC_MASK, CVMJIT_NOSETCC); /* check if object is unlocked */ CVMJITaddCodegenComment((con, "check if obj unlocked")); CVMCPUemitCompareConstant(con, CVMCPU_CMP_OPCODE, CVMCPU_COND_EQ, objHdrRegID, CVM_LOCKSTATE_UNLOCKED); /* branch if object not locked */ CVMJITaddCodegenComment((con, "br done if object is not locked")); fixupPC2 = CVMCPUemitBranch(con, 0, CVMCPU_COND_EQ);#ifdef IAI_CODE_SCHEDULER_SCORE_BOARD fixupPC2 = CVMJITcbufGetLogicalInstructionPC(con);#endif /* Object is locked. Release microlock */ CVMJITaddCodegenComment((con, "CVM_MICROLOCK_UNLOCKED")); CVMCPUemitLoadConstant(con, destRegID, CVM_MICROLOCK_UNLOCKED); CVMJITaddCodegenComment((con, "CVMglobals.objGlobalMicroLock = CVM_MICROLOCK_UNLOCKED")); CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_STR32_OPCODE, destRegID, microLockRegID, 0); /* Failure target. Make instrinsic return false. */ CVMtraceJITCodegen(("\t\tfailed:\n")); CVMJITfixupAddress(con, fixupPC1, CVMJITcbufGetLogicalPC(con), CVMJIT_COND_BRANCH_ADDRESS_MODE); CVMCPUemitLoadConstant(con, destRegID, CVM_FALSE); /* "done" target. No change is made instrinc result. */ CVMtraceJITCodegen(("\t\tdone:\n")); CVMJITfixupAddress(con, fixupPC2, CVMJITcbufGetLogicalPC(con), CVMJIT_COND_BRANCH_ADDRESS_MODE);#ifdef CVM_DEBUG /* For Debug builds, we do the following: * * 1. Set the ee's microlock depth to 0 or 1 based on success. * 2. Set CVMglobals.jit.currentSimpleSyncMB to the Simple Sync * mb we are currently generating code for. * * (1) is done so C code will assert if the micrlock gets out * of balance. Note we don't assert in here in the generated code * because it is too ugly. * * (2) is done in case there is ever a problem, we can find out * the last Simple Sync method called by looking in CVMglobals. * It is disabled with #if 0 by default. */ { /* 1. Set the ee's microlock depth to 0 or 1 based on success. */ int eeReg;#ifndef CVMCPU_EE_REG CVMRMResource *eeRes = CVMRMgetResource(CVMRM_INT_REGS(con), CVMRM_ANY_SET, CVMRM_EMPTY_SET, 1); eeReg = CVMRMgetRegisterNumber(eeRes); /* Get the ee: */ CVMJITaddCodegenComment((con, "eeReg = ccee->ee")); CVMCPUemitCCEEReferenceImmediate(con, CVMCPU_LDR32_OPCODE, eeReg, CVMoffsetof(CVMCCExecEnv, eeX));#else eeReg = CVMCPU_EE_REG;#endif /* Set the ee's microlock depth. We just set it to the result * of this intrinsic, which will be 0 or 1. */ CVMJITaddCodegenComment((con, "ee->microLock = <result>")); CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_STR32_OPCODE, destRegID, eeReg, offsetof(CVMExecEnv, microLock));#ifndef CVMCPU_EE_REG CVMRMrelinquishResource(CVMRM_INT_REGS(con), eeRes);#endif } /* * The following debugging code is disabled for now, but can be enabled * if Simple Sync methods are suspected of causing problems, like a * deadlock or assert. */#if 0
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?