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 + -
显示快捷键?