jit_cisc.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 690 行 · 第 1/2 页
C
690 行
con->currentExpr = root->expr;#endif compilationResult = CVMJITCompileExpression_match( root->expr, con);#ifdef CVM_JIT_ENABLE_IR_CFG con->currentExpr = NULL;#endif if (compilationResult < 0 ){ CVMtraceJITCodegenExec({ CVMconsolePrintf( "******Indigestable expression in node " "%d\n", CVMJITirnodeGetID(con->errNode)); CVMJITirdumpIRNodeAlways(con, root->expr, 0, " "); CVMconsolePrintf("\n > \n********\n"); }); success = CVM_FALSE; if (compilationResult == JIT_IR_SYNTAX_ERROR){ /* There was an IR syntax error */#ifdef CVM_DEBUG CVMpanic("CVMJIT: IR syntax error");#endif CVMassert(CVM_FALSE); CVMJITerror(con, CANNOT_COMPILE, "CVMJIT: IR syntax error"); } } CVMJITCompileExpression_synthesis( root->expr, con); root = CVMJITirnodeGetRootNext(root); } root = CVMJITirlistGetHead(CVMJITirblockGetRootList(bk)); while (root != NULL){ con->cgsp = con->cgstackInit; CVMJITCompileExpression_action( root->expr, con); root = CVMJITirnodeGetRootNext(root); } /* * If there is another block and we fall through to it, then * make sure we load any expected incoming locals, and branch * around any code that involves gc (like load/spill of phis). */ if (CVMJITirblockGetNext(bk) != NULL && CVMJITirblockFallsThru(bk)) { CVMJITIRBlock* target = CVMJITirblockGetNext(bk); CVMRMpinAllIncomingLocals(con, target, CVM_FALSE); /* * Backward branch targets load their own locals so OSR will * work, so we don't want to end up loading the locals twice. * Also, we don't want to execute any PHI or GC related code. * Instead, branch around all this code. */ if (CVMJITirblockIsBackwardBranchTarget(target) && (target->phiCount > 0#ifdef CVM_JIT_REGISTER_LOCALS || target->incomingLocalsCount > 0#endif )) { /* There's no way the fallthrough block has an addr yet. */ CVMassert(!(target->flags & CVMJITIRBLOCK_ADDRESS_FIXED)); CVMJITaddCodegenComment((con, "fallthrough to block L%d, which is " "backward branch target", CVMJITirblockGetBlockID(target))); CVMCPUemitBranchNeedFixup(con, target->logicalAddress, CVMCPU_COND_AL, &(target->branchFixupList)); } CVMRMunpinAllIncomingLocals(con, target); } CVMRMendBlock(con); } bk = CVMJITirblockGetNext(bk); } /* Sanity check inlining information */ CVMassert(con->inliningDepth == 0); /* More sanity checks of inlining information after all blocks are done */ CVMassert(con->inliningInfoIdx == con->numInliningInfoEntries);#ifdef CVMCPU_HAS_CP_REG con->target.cpLogicalPC = CVMJITcbufGetLogicalPC(con);#endif /* The following should come after the last instruction generated. */ CVMJITdumpRuntimeConstantPool(con, CVM_TRUE); /* * Handle patchable instructions in the prologue */ CVMCPUemitMethodProloguePatch(con, &prec); /* * Remember this for when we initialize the cmd */ con->intToCompOffset = prec.intToCompOffset;#ifdef CVMJIT_PATCH_BASED_GC_CHECKS /* Check for the consistency of the gc check count */ CVMassert(con->gcCheckPcsIndex == con->gcCheckPcsSize);#endif if (!success) { CVMJITerror(con, CANNOT_COMPILE, "Indigestible Expression encountered"); } CVMJITflushCache(con->codeEntry, con->curPhysicalPC);}#define CVMJIT_STARTPC_MIN_ALIGNMENT 8#define CVMJIT_STARTPC_MAX_PAD 16#ifdef CVMJIT_ALIGN_STARTPC#define CVMJIT_STARTPC_ALIGNMENT 32#else#define CVMJIT_STARTPC_ALIGNMENT CVMJIT_STARTPC_MIN_ALIGNMENT#endifstatic voidallocateCodeBuffer(CVMJITCompilationContext* con){ CVMSize inliningInfoSize; CVMSize pcMapTableSize; CVMSize extraSpace = 0; int space;#ifdef CVMJIT_PATCH_BASED_GC_CHECKS int gcCheckPcsSize;#endif /* reserve memory for the compiledPC <-> javaPC mapping table */ if (con->mapPcNodeCount != 0) { pcMapTableSize = CVMoffsetof(CVMCompiledPcMapTable, maps) + sizeof(CVMCompiledPcMap) * con->mapPcNodeCount; pcMapTableSize = CVMalignWordUp(pcMapTableSize); extraSpace += pcMapTableSize; } else { pcMapTableSize = 0; } /* Reserve space for inlining information */ if (con->numInliningInfoEntries > 0) { CVMassert(con->maxInliningDepth > 0); inliningInfoSize = sizeof(CVMCompiledInliningInfo) + (con->numInliningInfoEntries - 1) * sizeof(CVMCompiledInliningInfoEntry); inliningInfoSize = CVMalignWordUp(inliningInfoSize); extraSpace += inliningInfoSize; } else { inliningInfoSize = 0; }#ifdef CVMJIT_PATCH_BASED_GC_CHECKS /* Reserve space for patch lists */ if (con->gcCheckPcsSize > 0) { CVMUint32 memSize; /* room for everything but the pcEntries list */ memSize = CVMoffsetof(CVMCompiledGCCheckPCs, pcEntries); /* room for the pcEntries list */ memSize += con->gcCheckPcsSize * sizeof(CVMUint16); /* room for the patchedInstructions list */ memSize += sizeof(CVMCPUInstruction); memSize &= ~(sizeof(CVMCPUInstruction)-1); memSize += con->gcCheckPcsSize * sizeof(CVMCPUInstruction); gcCheckPcsSize = memSize; gcCheckPcsSize = CVMalignWordUp(gcCheckPcsSize); extraSpace += gcCheckPcsSize; } else { gcCheckPcsSize = 0; }#endif space = extraSpace; /* padding for startPC alignment */ extraSpace += CVMJIT_STARTPC_ALIGNMENT - 4; CVMJITcbufAllocate(con, extraSpace); CVMJITcbufGetLogicalPC(con) = 0; memset(CVMJITcbufGetPhysicalPC(con), 0, extraSpace); /* memory layout: cbuf size extra size extra cmd code stackmaps */ if (con->mapPcNodeCount != 0) { CVMtraceJITCodegenExec({ CVMconsolePrintf("PC MAP TABLE ADDRESS = 0x%x\n", CVMJITcbufGetPhysicalPC(con)); }); con->pcMapTable = (void *)CVMJITcbufGetPhysicalPC(con); con->pcMapTable->numEntries = con->mapPcNodeCount; con->mapPcNodeCount = 0; /* reset for use by backend */ space -= pcMapTableSize; CVMJITcbufGetPhysicalPC(con) += pcMapTableSize; CVMassert(CVMJITcbufGetPhysicalPC(con) < con->codeBufEnd); } /* Reserve space for inlining information */ if (con->numInliningInfoEntries > 0) { CVMtraceJITCodegenExec({ CVMconsolePrintf("INLINING INFO ADDRESS = 0x%x\n", CVMJITcbufGetPhysicalPC(con)); }); con->inliningInfo = (void *)CVMJITcbufGetPhysicalPC(con); con->inliningInfo->numEntries = con->numInliningInfoEntries; con->inliningInfo->maxDepth = con->maxInliningDepth; space -= inliningInfoSize; CVMJITcbufGetPhysicalPC(con) += inliningInfoSize; CVMassert(CVMJITcbufGetPhysicalPC(con) < con->codeBufEnd); } else { con->inliningInfo = NULL; } con->inliningDepth = 0; con->inliningInfoIdx = 0;#ifdef CVMJIT_PATCH_BASED_GC_CHECKS /* Reserve space for patch lists */ if (con->gcCheckPcsSize > 0) { /* allocate... */ CVMtraceJITCodegenExec({ CVMconsolePrintf("GC CHECK PCS ADDRESS = 0x%x\n", CVMJITcbufGetPhysicalPC(con)); }); con->gcCheckPcs = (void *)CVMJITcbufGetPhysicalPC(con); con->gcCheckPcs->noEntries = con->gcCheckPcsSize; space -= gcCheckPcsSize; CVMJITcbufGetPhysicalPC(con) += gcCheckPcsSize; CVMassert(CVMJITcbufGetPhysicalPC(con) < con->codeBufEnd); } else { con->gcCheckPcs = NULL; }#endif CVMassert(space == 0); /* extra, cmd, code */ CVMJITcbufGetPhysicalPC(con) += sizeof (CVMCompiledMethodDescriptor); /* align to CVMJIT_STARTPC_ALIGNMENT boundary */ { CVMSize pc = (CVMSize)CVMJITcbufGetPhysicalPC(con); CVMSize pc1 = CVMpackSizeBy(pc, CVMJIT_STARTPC_ALIGNMENT); if (pc1 - pc <= CVMJIT_STARTPC_MAX_PAD) { pc = pc1; } else if (CVMJIT_STARTPC_MIN_ALIGNMENT < CVMJIT_STARTPC_MAX_PAD) { pc = CVMpackSizeBy(pc, CVMJIT_STARTPC_MIN_ALIGNMENT); } CVMJITcbufGetPhysicalPC(con) = (CVMUint8 *)pc; } con->codeEntry = CVMJITcbufGetPhysicalPC(con); CVMtraceJITCodegenExec({ CVMconsolePrintf("CODE ENTRY ADDRESS = 0x%x\n", con->codeEntry); });}/* SVMC_JIT d022609 (ML) 2004-01-12. get the address of a frame variable. extracted from `CVMCPUemitFrameReference'. */void CVMCPUgetFrameReference(CVMJITCompilationContext* con, enum CVMCPUFrameReferenceType addressing, int cellNumber, int* frameReg, int* frameOffset){ if (addressing == CVMCPU_FRAME_LOCAL) { /* Locals are located just before the frame ptr */ /* This is a negative offset */ *frameOffset = -(int)((con->numberLocalWords - cellNumber) * sizeof(CVMJavaVal32)); *frameReg = CVMCPU_JFP_REG; } else if (addressing == CVMCPU_FRAME_TEMP) { CVMassert(addressing == CVMCPU_FRAME_TEMP); /* Temps are located just after the frame ptr */ /* This is a positive offset */ *frameOffset = CVM_COMPILEDFRAME_SIZE + cellNumber * sizeof(CVMJavaVal32); *frameReg = CVMCPU_JFP_REG; } else { CVMassert(addressing == CVMCPU_FRAME_CSTACK); /* the reference is to the start of the C frame */ /* This is a positive offset */ *frameOffset = cellNumber * sizeof(CVMJavaVal32); *frameReg = CVMCPU_SP_REG; } /* Make sure we're within the addressing range: */ if ((*frameOffset > CVMCPU_MAX_LOADSTORE_OFFSET) || (*frameOffset < -(CVMCPU_MAX_LOADSTORE_OFFSET))) { CVMJITerror(con, CANNOT_COMPILE, "method has locals out of reach"); }}voidCVMCPUemitFrameReference(CVMJITCompilationContext* con, int opcode, int reg_or_const, enum CVMCPUFrameReferenceType addressing, int cellNumber, int is_const){#ifdef CVM_TRACE_JIT const char *addressType = NULL;#endif CVMtraceJITCodegenExec({ switch (addressing){ case CVMCPU_FRAME_LOCAL: addressType = "Java local cell #"; break; case CVMCPU_FRAME_TEMP: addressType = "Java temp cell #"; break; case CVMCPU_FRAME_CSTACK: addressType = "C frame cell #"; break; default: addressType = "Bad address form X "; break; } }); { int frameReg; int frameOffset; CVMCPUgetFrameReference(con, addressing, cellNumber, &frameReg, &frameOffset); CVMJITaddCodegenComment((con, "%s %d", addressType, cellNumber++)); if (is_const) CVMCPUemitMemoryReferenceImmediateConst(con, opcode, reg_or_const, frameReg, frameOffset); else CVMCPUemitMemoryReferenceImmediate(con, opcode, reg_or_const, frameReg, frameOffset); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?