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