jit_common.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 2,132 行 · 第 1/5 页
C
2,132 行
/* * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include "javavm/include/interpreter.h"#include "javavm/include/directmem.h"#include "javavm/include/indirectmem.h"#include "javavm/include/utils.h"#include "javavm/include/bcattr.h"#include "javavm/include/porting/int.h"#include "javavm/include/common_exceptions.h"#include "javavm/include/preloader.h"#include "javavm/include/jit_common.h"#include "javavm/include/porting/jit/jit.h"#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitasmconstants.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitintrinsic.h"#include "javavm/include/jit/jitstats.h"#include "javavm/include/opcodes.h"#ifdef CVM_JIT_ESTIMATE_COMPILATION_SPEED#include "javavm/include/preloader_impl.h"#include "javavm/include/porting/time.h"#endifstatic CVMUint16*lookupStackMap( CVMCompiledStackMaps* maps, CVMUint32 off, CVMInt32* msize, CVMInt32* psize){ int nentries; int i; CVMUint16* largeMaps; CVMCompiledStackMapEntry* e; CVMCompiledStackMapLargeEntry* l; /* do straight search for now. When maps get sorted properly, can do better */ if (maps == NULL) return NULL; nentries = maps->noGCPoints; for (i = 0; i < nentries; i++){ if (maps->smEntries[i].pc == off) break; } if (i >= nentries) return NULL; /* iterated off the end! */ e = & maps->smEntries[i]; if (e->totalSize < (unsigned)0xff){ *msize = e->totalSize; *psize = e->paramSize; return &(e->state); }else{ largeMaps = (CVMUint16*)((char*)maps + sizeof (maps->noGCPoints) + nentries * sizeof (CVMCompiledStackMapEntry)); l = (CVMCompiledStackMapLargeEntry*) &largeMaps[e->state]; *msize = l->totalSize; *psize = l->paramSize; return &(l->state[0]); }}static CVMUint16*findStackMap( CVMExecEnv * targetEE, CVMCompiledMethodDescriptor* cmd, CVMUint32* offPtr, CVMInt32* msize, CVMInt32* psize, CVMFrame* frame){ CVMCompiledStackMaps* maps = CVMcmdStackMaps(cmd); CVMUint16* mapData; CVMUint8* compiledPc; CVMUint8* javaPc; CVMUint32 off = *offPtr; CVMMethodBlock* mb = frame->mb; mapData = lookupStackMap(maps, off, msize, psize); if (mapData != NULL){ /* If we are throwing an exception, we can prune the locals to scan, as we do below when a stackmap isn't found. But it's probably cheaper to scan a few extra locals than to perform another lookup. */ return mapData; } /* * There is no map here. We'd better be throwing an exception. * In this case, only the locals matter since the stack and * temps get discarded, and those locals are described at any * convenient handler to which we could transfer. */ if (!CVMexceptionIsBeingThrownInFrame(targetEE, frame)) {#ifdef CVM_DEBUG extern void CVMbcList(CVMMethodBlock* mb); CVMconsolePrintf("Unable to find stackmap for method:\n" " %C.%M\n" " at PC 0x%x, offset 0x%x\n" " method startPC is 0x%x\n", CVMmbClassBlock(mb), mb, off + CVMcmdStartPC(cmd), off, CVMcmdStartPC(cmd)); CVMconsolePrintf("\nThe method's bytecode:\n"); CVMbcList(mb); CVMconsolePrintf("\n");#endif#ifdef CVM_DEBUG_DUMPSTACK CVMconsolePrintf("\nThe thread's backtrace:\n"); CVMdumpStack(&targetEE->interpreterStack,0,0,0); CVMconsolePrintf("\n");#endif#ifdef CVM_DEBUG CVMpanic("Unable to find stackmap");#endif CVMassert(CVM_FALSE); } /* Check for the handler here: */ compiledPc = off + CVMcmdStartPC(cmd); javaPc = CVMpcmapCompiledPcToJavaPc(mb, compiledPc); javaPc = CVMfindInnermostHandlerFor(CVMmbJmd(mb), javaPc); if (javaPc == 0){ /* this stack frame is getting blown away anyway. */ *msize = 0; *psize = 0; return NULL; } compiledPc = CVMpcmapJavaPcToCompiledPc(mb, javaPc); *offPtr = off = compiledPc - CVMcmdStartPC(cmd); mapData = lookupStackMap(maps, off, msize, psize); CVMassert(mapData != NULL); return mapData;}/* * Given a compiled frame and PC, this function sets up an iterator for all * matching mb's. Due to inlining, a PC can correspond to multiple mb's. * * The return value is the number of mb's in the trace... * * The ordering is reverse from what you would expect. So to get the * real call order, you should traverse the backtrace items * "backwards". */voidCVMJITframeIterate(CVMFrame* frame, CVMJITFrameIterator *iter){ 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 = CVMcmdInliningInfo(cmd); CVMassert(CVMframeIsCompiled(frame)); iter->frame = frame; iter->mb = mb; iter->pcOffset = pcOffset; iter->index = -1; iter->invokePC = -1; /* No inlining in this method. So we can trust the frame */ if (inliningInfo == NULL) { iter->numEntries = 0; iter->inliningEntries = NULL; /* avoid compiler warning */ return; } iter->inliningEntries = inliningInfo->entries; iter->numEntries = inliningInfo->numEntries; /* CVMconsolePrintf("FRAME 0x%x (pc=0x%x, offset=%d), %C.%M\n", frame, pc, pcOffset, CVMmbClassBlock(mb), mb); */}/* * Given a compiled frame and PC, this iterates over all matching mb's. * Due to inlining, a PC can correspond to multiple mb's. * * The ordering is reverse from what you would expect. So to get the * real call order, you should traverse the backtrace items * "backwards". */CVMBoolCVMJITframeIterateSkip(CVMJITFrameIterator *iter, CVMBool skipArtificial, CVMBool popFrame){ CVMInt32 pcOffset = iter->pcOffset; CVMInt32 lastIndex = iter->index; ++iter->index; while (iter->index < iter->numEntries) { CVMCompiledInliningInfoEntry* iEntry = &iter->inliningEntries[iter->index]; if (iEntry->pcOffset1 <= pcOffset && pcOffset < iEntry->pcOffset2) { if (skipArtificial && (iEntry->flags & CVM_FRAMEFLAG_ARTIFICIAL) != 0) { lastIndex = iter->index; } else { break; } } ++iter->index; } if (iter->index == iter->numEntries && skipArtificial && (iter->frame->flags & CVM_FRAMEFLAG_ARTIFICIAL) != 0) { ++iter->index; } if (popFrame) { /* perhaps when we support inlined exception handlers... */ } if (iter->index <= iter->numEntries) { CVMassert(lastIndex != iter->index); if (lastIndex != -1) { iter->invokePC = iter->inliningEntries[lastIndex].invokePC; } else { iter->invokePC = -1; } return CVM_TRUE; } return CVM_FALSE;}CVMUint32CVMJITframeIterateCount(CVMJITFrameIterator *iter, CVMBool skipArtificial){ CVMUint32 count = 0; while (CVMJITframeIterateSkip(iter, skipArtificial, CVM_FALSE)) { ++count; } return count;}CVMFrame *CVMJITframeIterateGetFrame(CVMJITFrameIterator *iter){ CVMassert(iter->index == iter->numEntries); return iter->frame;}static CVMBoolCVMJITframeIterateContainsPc(CVMJITFrameIterator *iter, CVMUint32 off){ if (iter->index == iter->numEntries) {#ifdef CVM_DEBUG_ASSERTS CVMFrame *frame = iter->frame; CVMCompiledMethodDescriptor *cmd = CVMmbCmd(frame->mb); CVMUint32 codeSize = CVMcmdCodeBufSize(cmd) - sizeof(CVMUint32); CVMassert(off < codeSize);#endif return CVM_TRUE; } else { CVMCompiledInliningInfoEntry* iEntry = &iter->inliningEntries[iter->index]; return (iEntry->pcOffset1 <= off && off < iEntry->pcOffset2); }}CVMUint8 *CVMJITframeIterateGetJavaPc(CVMJITFrameIterator *iter){ /* * Get the java pc of the frame. This is a bit tricky for compiled * frames since we need to map from the compiled pc to the java pc. */ if (iter->invokePC != -1) { /* The invokePC will be set if we have iterated through an inlined frame already. */ CVMUint16 invokePC = iter->invokePC; CVMMethodBlock *mb = CVMJITframeIterateGetMb(iter); CVMUint8 *pc = CVMmbJavaCode(mb) + invokePC; CVMassert(CVMbcAttr(*pc, INVOCATION)); return pc; } else if (iter->index == iter->numEntries) { /* We have reached the initial Java frame, without seeing an inlined frame. Rely on the pc map table. */ CVMFrame *frame = iter->frame; return CVMpcmapCompiledPcToJavaPc(frame->mb, CVMcompiledFramePC(frame)); } else { /* We must be in the top-most inlined method, so we have no PC information. */ return NULL; }}voidCVMJITframeIterateSetJavaPc(CVMJITFrameIterator *iter, CVMUint8 *pc){ /* * Set the pc of the frame. */ CVMFrame *frame; /* No support for inlined frames yet */ CVMassert(iter->index == iter->numEntries); frame = iter->frame; /* need to convert java pc to compiled pc */ CVMcompiledFramePC(frame) = CVMpcmapJavaPcToCompiledPc(frame->mb, pc);}CVMStackVal32 *CVMJITframeIterateGetLocals(CVMJITFrameIterator *iter){ CVMUint16 firstLocal = 0; if (iter->index < iter->numEntries) { firstLocal = iter->inliningEntries[iter->index].firstLocal; } { CVMFrame *frame = iter->frame; CVMCompiledMethodDescriptor *cmd = CVMmbCmd(frame->mb); CVMStackVal32* locals = (CVMStackVal32 *)frame - CVMcmdMaxLocals(cmd); return &locals[firstLocal]; }}CVMObjectICell *CVMJITframeIterateSyncObject(CVMJITFrameIterator *iter){ if (iter->index == iter->numEntries) { return &CVMframeReceiverObj(iter->frame, Compiled); } else { CVMCompiledInliningInfoEntry *entry = &iter->inliningEntries[iter->index]; CVMUint16 localNo = entry->firstLocal + entry->syncObject; CVMFrame *frame = iter->frame; CVMCompiledMethodDescriptor *cmd = CVMmbCmd(frame->mb); CVMStackVal32* locals = (CVMStackVal32 *)frame - CVMcmdMaxLocals(cmd); return &locals[localNo].ref; }}CVMMethodBlock *CVMJITframeIterateGetMb(CVMJITFrameIterator *iter){ if (iter->index == iter->numEntries) { return iter->mb; } else { CVMCompiledInliningInfoEntry* iEntry = &iter->inliningEntries[iter->index]; CVMassert(iEntry->pcOffset1 <= iter->pcOffset && iter->pcOffset < iEntry->pcOffset2); return iEntry->mb; }}CVMFrameFlagsCVMJITframeIterateGetFlags(CVMJITFrameIterator *iter){ if (iter->index == iter->numEntries) { return iter->frame->flags; } else { CVMCompiledInliningInfoEntry* iEntry = &iter->inliningEntries[iter->index]; CVMassert(iEntry->pcOffset1 <= iter->pcOffset && iter->pcOffset < iEntry->pcOffset2); return iEntry->flags; }}voidCVMJITframeIterateSetFlags(CVMJITFrameIterator *iter, CVMFrameFlags flags){ if (iter->index == iter->numEntries) { iter->frame->flags = flags; } else { CVMCompiledInliningInfoEntry* iEntry = &iter->inliningEntries[iter->index]; CVMassert(iEntry->pcOffset1 <= iter->pcOffset && iter->pcOffset < iEntry->pcOffset2); iEntry->flags = flags; }}CVMBoolCVMJITframeIterateIsInlined(CVMJITFrameIterator *iter){ return (iter->index < iter->numEntries);}CVMBoolCVMJITframeIterateHandlesExceptions(CVMJITFrameIterator *iter){ return (iter->index == iter->numEntries);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?