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