jit_common.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 2,132 行 · 第 1/5 页

C
2,132
字号
}CVMMethodBlock *CVMJITframeGetMb(CVMFrame *frame){    CVMassert(CVMframeMaskBitsAreCorrect(frame));    if (CVMframeIsCompiled(frame)) {	CVMMethodBlock*		      mb = frame->mb;	CVMCompiledMethodDescriptor*  cmd = CVMmbCmd(mb);	CVMUint8*		      pc0 = CVMcompiledFramePC(frame);	CVMUint8*		      startPC = CVMcmdStartPC(cmd);	CVMUint8*		      pc1 = CVMJITmassageCompiledPC(pc0,						startPC);	CVMInt32		      pcOffset = pc1 - startPC;	CVMCompiledInliningInfo*      inliningInfo;	CVMCompiledInliningInfoEntry* iEntry;	int i;	inliningInfo = CVMcmdInliningInfo(cmd);		if (inliningInfo != NULL) {	    for (i = 0; i < inliningInfo->numEntries; i++) {		iEntry = &inliningInfo->entries[i];		if (iEntry->pcOffset1 <= pcOffset &&		    pcOffset < iEntry->pcOffset2)		{		    return iEntry->mb;		}	    }	}	return mb;    } else {	return frame->mb;    }}CVMMethodBlock *CVMJITeeGetCurrentFrameMb(CVMExecEnv *ee){    CVMFrame *frame = CVMeeGetCurrentFrame(ee);    if (!CVMframeMaskBitsAreCorrect(frame)) {	CVMJITfixupFrames(frame);    }    return CVMJITframeGetMb(frame);}voidCVMcompiledFrameScanner(CVMExecEnv* ee,			CVMFrame* frame, CVMStackChunk* chunk,			CVMRefCallbackFunc callback, void* scannerData,			CVMGCOptions* opts){    CVMMethodBlock*		  mb = frame->mb;    CVMCompiledMethodDescriptor*  cmd = CVMmbCmd(mb);    CVMUint8*			  pc = CVMcompiledFramePC(frame);    CVMInt32			  pcOffset = pc - CVMcmdStartPC(cmd);    CVMBool			  isAtReturn = CVM_FALSE;    CVMUint16*			  mapData;    CVMInt32			  mapSize = 0;    CVMInt32			  paramSize = 0;    CVMUint16			  bitmap;    int				  bitNo;    int				  noSlotsToScan;    int				  i;    CVMStackVal32*		  scanPtr;    CVMObject**			  slot;    CVMInterpreterStackData*	  interpreterStackData =	(CVMInterpreterStackData *)scannerData;    void*			  data = interpreterStackData->callbackData;    CVMExecEnv*			  targetEE = interpreterStackData->targetEE;    if (pc == (CVMUint8*)CONSTANT_HANDLE_GC_FOR_RETURN) {        CVMassert(frame == targetEE->interpreterStack.currentFrame);        isAtReturn = CVM_TRUE;                pcOffset = -1;    } else {	CVMassert((CVMUint32)pcOffset <= 0xffff);    }    /* CVMassert(pcOffset < CVMjmdCodeLength(jmd)); would be nice... */    CVMtraceGcScan(("Scanning compiled frame for %C.%M (frame =0x%x maxLocals=%d, stack=0x%x, pc=%d[0x%x] full pc = 0x%x )\n",		    CVMmbClassBlock(mb), mb,		    frame,		    CVMcmdMaxLocals(cmd),		    CVMframeOpstack(frame, Compiled),		    pcOffset,		    CVMcmdStartPC(cmd),		    pc));    if (isAtReturn) {        goto returnValueScanAndSync;    }    {	CVMInt32 off = pcOffset;	/* NOTE: The range of PC offsets set by findStackMap() can only be	   between 0 and 0xffff. */	mapData = findStackMap(targetEE, cmd, (CVMUint32 *)&off,			       &mapSize, &paramSize, frame);	if (mapData == NULL) {	    /*	     * nothing to do here, as the stack frame is getting blown away	     * by an exception.	     */	    CVMassert(CVMexceptionIsBeingThrownInFrame(targetEE, frame));	    /* CR6287566: blow away the locals so we don't run into any	       scanning bugs with the caller's args. */#if 1		noSlotsToScan = CVMcmdMaxLocals(cmd);		scanPtr = (CVMStackVal32*)frame - noSlotsToScan;		for (i = 0; i < noSlotsToScan; i++, scanPtr++) {		    CVMID_icellSetNull(&scanPtr->j.r);		}#endif	    goto check_inlined_sync;	}	/* Did findStackMap() skip to an exception handler? */	if (off != pcOffset) {	    CVMJITFrameIterator iter;	    CVMBool foundHandler = CVM_FALSE;	    CVMJITframeIterate(frame, &iter);	    /* Scan sync objects until we get to the handler frame */	    while (CVMJITframeIterateSkip(&iter, CVM_FALSE, CVM_FALSE)) {		if (CVMJITframeIterateContainsPc(&iter, off)) {		    foundHandler = CVM_TRUE;		    break;		} else {		    CVMMethodBlock *mb  = CVMJITframeIterateGetMb(&iter);		    if (CVMmbIs(mb, SYNCHRONIZED)) {			CVMObjectICell* objICell =			    CVMJITframeIterateSyncObject(&iter);			if (objICell != NULL) {			    slot = (CVMObject**)objICell;			    callback(slot, data);			}		    }		}	    }	    CVMassert(foundHandler);	}    }    bitmap = *mapData++;    bitNo  = 0;    /*     * Scan locals     */    noSlotsToScan = CVMcmdMaxLocals(cmd);    scanPtr = (CVMStackVal32*)frame - noSlotsToScan;    for (i = 0; i < noSlotsToScan; i++) {	if ((bitmap & 1) != 0) {	    slot = (CVMObject**)scanPtr;	    if (*slot != 0) {		callback(slot, data);	    }	}	scanPtr++;	bitmap >>= 1;	bitNo++;	if (bitNo == 16) {	    bitNo = 0;	    bitmap = *mapData++;	}    }#if 0    /*      This is currently disabled because it does not deal      correctly with a CNI method (no frame of its own)      throwing an exception.    */    /*      This frame is throwing an exception, so don't bother      scanning any further.    */    if (CVMexceptionIsBeingThrownInFrame(targetEE, frame)) {	/*	   If we aren't the top frame, then the callee frame	   had better be due to classloading during exception	   handling.	*/	CVMassert(interpreterStackData->prevFrame == NULL ||	    (CVMframeIsFreelist(interpreterStackData->prevFrame) &&		interpreterStackData->prevFrame->mb == NULL));	goto skip_opstack;    }#endif    scanPtr = (CVMStackVal32*)CVMframeOpstack(frame, Compiled);    mapSize -= noSlotsToScan;    CVMassert((frame == targetEE->interpreterStack.currentFrame)               == (interpreterStackData->prevFrame == NULL));    /*     * if we are the top frame, or calling through a JNI or     * transition frame, then we scan the outgoing parameters, too.     * Else not.     */    if (interpreterStackData->prevFrame == NULL	|| CVMframeIsFreelist(interpreterStackData->prevFrame)        || CVMframeIsTransition(interpreterStackData->prevFrame)) {        /* count the parameters */        noSlotsToScan = mapSize;    } else {	/* don't count the parameters */	noSlotsToScan = mapSize - paramSize;    }    /*     * The stackmaps for the variables and the operand stack are     * consecutive. Keep bitmap, bitNo, mapData as is.     */    for (i = 0; i < noSlotsToScan; i++) {	if ((bitmap & 1) != 0) {	    slot = (CVMObject**)scanPtr;	    if (*slot != 0) {		callback(slot, data);	    }	}	scanPtr++;	bitmap >>= 1;	bitNo++;	if (bitNo == 16) {	    bitNo = 0;	    bitmap = *mapData++;	}    }#if 0skip_opstack:#endif    /*     * The classes of the methods executing. Do this only if not all classes     * are roots.     */    {	CVMJITFrameIterator iter;	CVMJITframeIterate(frame, &iter);	while (CVMJITframeIterateSkip(&iter, CVM_FALSE, CVM_FALSE)) {	    CVMMethodBlock *mb  = CVMJITframeIterateGetMb(&iter);	    CVMClassBlock* cb = CVMmbClassBlock(mb);	    CVMscanClassIfNeeded(ee, cb, callback, data);	}    }    check_outer_sync:    /*     * And last but not least, javaframe->receiverObj     */    if (CVMmbIs(mb, SYNCHRONIZED)){	slot = (CVMObject**)&CVMframeReceiverObj(frame, Compiled);	callback(slot, data);    }    return;check_inlined_sync:    /* Scan sync objects of all inlined methods, plus outer method */    {	CVMJITFrameIterator iter;	CVMJITframeIterate(frame, &iter);	while (CVMJITframeIterateSkip(&iter, CVM_FALSE, CVM_FALSE)) {	    CVMMethodBlock *mb  = CVMJITframeIterateGetMb(&iter);	    if (CVMmbIs(mb, SYNCHRONIZED)) {		CVMObjectICell* objICell = CVMJITframeIterateSyncObject(&iter);		if (objICell != NULL) {		    slot = (CVMObject**)objICell;		    callback(slot, data);		}	    }	}    }    return;returnValueScanAndSync:    /* Scan return value */    /* Check ref-based return value */    if (CVMtypeidGetReturnType(CVMmbNameAndTypeID(mb)) == CVM_TYPEID_OBJ) {        slot = (CVMObject**)((CVMStackVal32*)frame - CVMcmdMaxLocals(cmd));        if (*slot != 0) {            callback(slot, data);        }    }    goto check_outer_sync;}#undef TRACE#define TRACE(a) CVMtraceOpcode(a)#define DECACHE_TOS()	 frame->topOfStack = topOfStack;#define CACHE_TOS()	 topOfStack = frame->topOfStack;#define CACHE_PREV_TOS() topOfStack = CVMframePrev(frame)->topOfStack;#define CACHE_FRAME()	 ee->interpreterStack.currentFrame#define DECACHE_FRAME()	 ee->interpreterStack.currentFrame = frame;#ifdef CVM_DEBUG_ASSERTSstatic CVMBoolinFrame(CVMFrame* frame, CVMStackVal32* tos){    if (CVMframeIsCompiled(frame)) {	CVMCompiledMethodDescriptor *cmd = CVMmbCmd(frame->mb);	CVMStackVal32* base = (CVMStackVal32 *)frame - CVMcmdMaxLocals(cmd);	CVMStackVal32* top  = base + CVMcmdCapacity(cmd);	return ((tos >= base) && (tos <= top));    } else if (CVMframeIsJava(frame)) {	CVMJavaMethodDescriptor* jmd = CVMmbJmd(frame->mb);	CVMStackVal32* base = CVMframeOpstack(frame, Java);	CVMStackVal32* top  = base + CVMjmdMaxStack(jmd);	return ((tos >= base) && (tos <= top));    } else {	return CVM_TRUE;    }}#endif#define frameSanity(f, tos)	inFrame((f), (tos))CVMCompiledResultCodeCVMinvokeCompiledHelper(CVMExecEnv *ee, CVMFrame *frame,			CVMMethodBlock **mb_p){    CVMMethodBlock *mb = *mb_p;    CVMStackVal32 *topOfStack;    CACHE_TOS();check_mb:    if (mb == NULL) {        /* Make sure there isn't an exception thrown first: */        if (CVMexceptionOccurred(ee)) {            return CVM_COMPILED_EXCEPTION;        }	/*	 * Do this check after we check the exception, because	 * topOfStack might be stale if an exception was	 * thrown.	 */	CVMassert(frameSanity(frame,topOfStack));	/* Support for CNI calls */	if (CVMframeIsTransition(frame)) {	    *mb_p = frame->mb;	    return CVM_COMPILED_NEW_TRANSITION;	}        /* If we're not invoking a transition method, then we must be returning           from this compiled method: */        TRACE_METHOD_RETURN(frame);	CVMassert(CVMframeIsCompiled(frame));#if 0	CVMD_gcSafeCheckPoint(ee, {}, {});#endif	mb = frame->mb;	if (CVMmbIs(mb, SYNCHRONIZED)) {	    CVMCompiledMethodDescriptor *cmd = CVMmbCmd(mb);	    CVMStackVal32* locals = (CVMStackVal32 *)frame -		CVMcmdMaxLocals(cmd);	    CVMObjectICell* retObjICell = &locals[0].j.r;	    CVMObjectICell* receiverObjICell =		&CVMframeReceiverObj(frame, Compiled);	    if (!CVMfastTryUnlock(ee,		CVMID_icellDirect(ee, receiverObjICell)))	    {		CVMBool areturn =		    CVMtypeidGetReturnType(CVMmbNameAndTypeID(mb)) ==			CVM_TYPEID_OBJ;		CVMBool success;		CVMcompiledFramePC(frame) =		    (CVMUint8*)CONSTANT_HANDLE_GC_FOR_RETURN;		success = CVMsyncReturnHelper(ee, frame, retObjICell, areturn);		if (!success) {		    CVMassert(frameSanity(frame,topOfStack));		    return CVM_COMPILED_EXCEPTION;		}	    }	}	CVMpopFrameSpecial(&ee->interpreterStack, frame, {	    /* changing stack chunk */	    CVMFrame *prev = prev_;	    int	retType = CVMtypeidGetReturnType(CVMmbNameAndTypeID(mb));	    if (retType == CVM_TYPEID_VOID) {		topOfStack = prev->topOfStack;	    } else if (retType == CVM_TYPEID_LONG ||		retType == CVM_TYPEID_DOUBLE)	    {		CVMmemCopy64(&prev->topOfStack[0].j.raw,		    &topOfStack[-2].j.raw);		topOfStack = prev->topOfStack + 2;	    } else {		prev->topOfStack[0] = topOfStack[-1];		topOfStack = prev->topOfStack + 1;;	    }	});	CVMassert(frameSanity(frame,topOfStack));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?