interpreter.c

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

C
2,289
字号
/* * @(#)interpreter.c	1.409 06/10/25 * * 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/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/sync.h"#include "javavm/include/globals.h"#include "javavm/include/stacks.h"#include "javavm/include/stackwalk.h"#include "javavm/include/interpreter.h"#include "javavm/include/jni_impl.h"#include "javavm/include/localroots.h"#include "javavm/include/globalroots.h"#include "javavm/include/indirectmem.h"#include "javavm/include/gc_common.h"#include "javavm/include/signature.h"#include "javavm/include/preloader.h"#include "javavm/include/basictypes.h"#include "javavm/include/stackmaps.h"#include "javavm/include/bcattr.h"#include "javavm/include/common_exceptions.h"#include "javavm/include/opcodes.h"#include "generated/offsets/java_lang_Throwable.h"#ifdef CVM_CLASSLOADING#include "generated/offsets/java_lang_ClassLoader.h"#endif#include "javavm/include/clib.h"#include "javavm/include/porting/threads.h"#include "javavm/include/porting/int.h"#include "javavm/include/porting/system.h"#ifdef CVM_CLASSLOADING#include "javavm/include/porting/linker.h"#endif#ifdef CVM_REFLECT#include "javavm/include/reflect.h"#endif#ifdef CVM_JVMTI#include "javavm/include/jvmtiExport.h"#endif#ifdef CVM_JVMPI#include "javavm/include/jvmpi_impl.h"#endif#ifdef CVM_JIT#include "javavm/include/jit/jitpcmap.h"#include "javavm/include/porting/jit/ccm.h"#include "javavm/include/ccee.h"#endif#ifdef CVM_HW#include "include/hw.h"#endif#ifdef CVM_TRACE#define MAX_TRACE_INDENT_DEPTH  15static void printIndent(int traceDepth){    /* We're assuming the number of decimal digits in the trace depth is less       than 3.  If it reaches 3 or above (which highly unlikely), we'll just       allow the indentation to be little off by the extra digits: */    const char *digitPad = (traceDepth < 10) ? " " : "";    int depth, i;    CVMconsolePrintf("%d%s", traceDepth, digitPad);    depth = (traceDepth < MAX_TRACE_INDENT_DEPTH) ?	     traceDepth : MAX_TRACE_INDENT_DEPTH;    for (i = 0; i < depth; i++) {	CVMconsolePrintf("  ");    }}#define CVMtraceMethod(ee, x) \    CVMtraceExec(CVM_DEBUGFLAG(TRACE_METHOD), {		       \	CVMconsolePrintf("<%d>", ee->threadID);		       \	printIndent(ee->traceDepth);			       \	CVMconsolePrintf x;				       \    })#endif /* CVM_TRACE */static CVMFrame *CVMframeIterateGetBaseFrame(CVMFrameIterator *iter);/* Capacities for the thread's local roots stack. */#define CVM_MIN_LOCALROOTS_STACKCHUNK_SIZE 20#define CVM_MAX_LOCALROOTS_STACK_SIZE      \    3 * CVM_MIN_LOCALROOTS_STACKCHUNK_SIZE#define CVM_INITIAL_LOCALROOTS_STACK_SIZE   \    CVM_MIN_LOCALROOTS_STACKCHUNK_SIZEstatic CVMBoolCVMarrayIsAssignable(CVMExecEnv* ee, 		     CVMClassBlock* srcArrayCb,		     CVMClassBlock* dstArrayCb);#if defined(CVM_DEBUG) || defined(CVM_DEBUG_DUMPSTACK) || defined(CVM_DEBUG_STACKTRACES)static char*CVMaddstr(const char *s, char* buf, char* limit, char term){    char c;    while ((c = *s) && c != term && buf < limit) {	*buf++ = c;	s++;    }    return buf;}#endif /* CVM_DEBUG */#if (defined(CVM_DEBUG) || defined(CVM_DEBUG_DUMPSTACK) || \     defined(CVM_DEBUG_STACKTRACES)) && defined(CVM_DEBUG_CLASSINFO)static char*CVMadddec(CVMInt32 n, char* buf, char* limit){     char dec[11];    int i = sizeof(dec) - 1;    dec[i] = 0;    if (n < 0) {        n = -n;        if (buf < limit)            *buf++ = '-';    }    while (n != 0) {        i--;        dec[i] = (char)((n % 10) + '0');        n = n / 10;    }    return CVMaddstr(&dec[i], buf, limit, 0);}#endif /* CVM_DEBUG */#if defined(CVM_DEBUG_CLASSINFO) || defined(CVM_JVMPI)CVMInt32CVMpc2lineno(CVMMethodBlock *mb, CVMUint16 pc_offset){    CVMUint32 length;    CVMassert(!CVMmbIs(mb, NATIVE));    length = CVMmbLineNumberTableLength(mb);    if (length > 0) {	CVMLineNumberEntry *ln = CVMmbLineNumberTable(mb);	CVMUint16 l = 0;	CVMUint16 u = length;	if (pc_offset < ln[l].startpc) { 	    return -1;	}	if (pc_offset >= ln[u - 1].startpc) {	    return ln[u - 1].lineNumber;	}	while (l < u) {	    int m = (l + u) >> 1;	    if (pc_offset < ln[m].startpc) {	        u = m;	    } else if (pc_offset >= ln[m + 1].startpc) {	        l = m;	    } else {	        /* ln[m].startpc <= pc_offset < ln[m + 1].startpc */ 	        return ln[m].lineNumber;	    }	}	CVMassert(CVM_FALSE);    }    return -1;}#endif /* defined(CVM_DEBUG_CLASSINFO) || defined(CVM_JVMPI) *//* * Convert either a pc or a frame to a string in the format: *    <classname>.<methodname>(Native Method) *        or *    <classname>.<methodname>(<sourcefilename>:<linenumber>) * * If a pc is specified, it is always a javapc and never a compiled pc, * even if isCompiled is true. */#if defined(CVM_TRACE) || defined(CVM_DEBUG) || defined(CVM_DEBUG_DUMPSTACK) || defined(CVM_DEBUG_STACKTRACES)voidCVMframe2string(CVMFrame* frame, char *buf, char* limit) {    CVMUint8* pc;    CVMBool   isCompiled;    if (CVMframeIsTransition(frame) | CVMframeIsJava(frame)) {	pc = CVMframePc(frame);    } else {	pc = NULL;    }#ifdef CVM_JIT    isCompiled = CVMframeIsCompiled(frame);    if (isCompiled) {	pc = CVMpcmapCompiledPcToJavaPc(frame->mb, CVMcompiledFramePC(frame));    }#else    isCompiled = CVM_FALSE;#endif    CVMpc2string(pc, frame->mb, CVMframeIsTransition(frame), isCompiled, 		 buf, limit);}voidCVMframeIterate2string(CVMFrameIterator *iter, char *buf, char *limit) {    CVMUint8* pc;    CVMMethodBlock *mb;    CVMBool   isCompiled;    CVMBool   isTransition = CVM_FALSE;    pc = CVMframeIterateGetJavaPc(iter);    mb = CVMframeIterateGetMb(iter);#ifdef CVM_JIT    isCompiled = iter->jitFrame;#else    isCompiled = CVM_FALSE;#endif    if (!isCompiled) {	isTransition = CVMframeIsTransition(iter->frame);    }    CVMpc2string(pc, mb, isTransition, isCompiled, buf, limit);}voidCVMlineno2string(CVMInt32 lineno, CVMMethodBlock* mb, 	         CVMBool isTransition, CVMBool isCompiled,                 char *buf, char* limit){    CVMClassBlock*  cb;    CVMassert(buf < limit);    CVMassert(mb != NULL);    cb = CVMmbClassBlock(mb);    --limit;	/* Save room for terminating '\0' */    buf += CVMformatString(buf, limit - buf, "%C.%M", cb, mb);    if (CVMmbIs(mb, NATIVE)) {	buf = CVMaddstr("(Native Method)", buf, limit, 0);    } else if (isTransition) {	buf = CVMaddstr("(Transition Method)", buf, limit, 0);    } else {#ifdef CVM_DEBUG_CLASSINFO	const char* fn = CVMcbSourceFileName(cb);#endif#ifdef CVM_JIT	if (isCompiled) {	    buf = CVMaddstr("(Compiled Method)", buf, limit, 0);	}#endif /* CVM_JIT */	#ifndef CVM_DEBUG_CLASSINFO	buf = CVMaddstr("(Unknown Source)", buf, limit, 0);#else	if (fn == NULL) {	    buf = CVMaddstr("(Unknown Source)", buf, limit, 0);	} else {	    /* Just want the short name */	    fn = strrchr(fn, '/');	    if (fn != NULL) {		/* skip past last separator */		fn += 1;	    } else {		fn = CVMcbSourceFileName(cb);	    }			    buf = CVMaddstr("(", buf, limit, 0);	    buf = CVMaddstr(fn, buf, limit, 0);	    if (lineno >= 0) {		buf = CVMaddstr(":", buf, limit, 0);		buf = CVMadddec(lineno, buf, limit);	    }	    buf = CVMaddstr(")", buf, limit, 0);	}#endif /* CVM_DEBUG_CLASSINFO */    }    *buf = 0;    return;}voidCVMpc2string(CVMUint8* pc, CVMMethodBlock* mb,	     CVMBool isTransition, CVMBool isCompiled,	     char *buf, char* limit){    CVMInt32    lineno;    CVMassert(buf < limit);    CVMassert(mb != NULL);		        /*     * Get the pc offset from the start of the code so we can     * use it to lookup linenumber info.      */    /*      * This expression is obviously a rather small pointer     * difference. So just cast it to the type of 'pc_offset'.     */#ifdef CVM_DEBUG_CLASSINFO    if (CVMmbIs(mb, NATIVE) || isTransition) {        lineno = -1;    } else {        CVMUint16    pc_offset;        pc_offset = pc - CVMmbJavaCode(mb);		        lineno = CVMpc2lineno(mb, pc_offset);    }#else    lineno = -1;#endif    CVMlineno2string(lineno, mb, isTransition, isCompiled,                     buf, limit);}#endif /* CVM_DEBUG *//* * Initialize a CVMExecEnv. * The threadInfo argument can be NULL if invoked from  * CVMinitVMGlobalState() or CVMjniAttachCurrentThread(). * The argument is typically used to pass on info from a parent thread  * to a child. */CVMBool CVMinitExecEnv(CVMExecEnv* ee, CVMExecEnv* targetEE,	       CVMThreadStartInfo* threadInfo){    CVMBool result;    /*     * Unless we are prepared to zero out every field by hand, then     * we have to do this...     */    memset(targetEE, 0, sizeof *targetEE);    CVMCstackBufferInit(targetEE);	/* Unset EE-buffer flag */    /* threadInfo == NULL if invoked from CVMinitVMGlobalState() or      * CVMjniAttachCurrentThread(). Set CVM_TRUE to ee->userThread     * in those cases. */    targetEE->userThread =	(threadInfo == NULL)?(CVM_TRUE):(!threadInfo->isDaemon);    /* Need to initialize consistent states before anything else     * or some debugging asserts may get upset.     */    {	int i;	for (i = 0; i < CVM_NUM_CONSISTENT_STATES; ++i) {	    CVMtcsInit(CVM_TCSTATE(targetEE, i));	}    }#ifdef CVM_DEBUG    /* Also make sure this EE doesn't think we hold any locks. */    targetEE->sysLocks = NULL;#endif    /* The first frame has to be a JNI frame so we can allocate     * jni local refs from it.     */    result = CVMinitStack(ee, &targetEE->interpreterStack, 			  CVMglobals.config.javaStackMinSize,#ifdef CVM_JVMTI                          /* Leave some space to post events */			  CVMglobals.config.javaStackMaxSize -                          CVMglobals.config.javaStackChunkSize, #else 			  CVMglobals.config.javaStackMaxSize, #endif			  CVMglobals.config.javaStackChunkSize,			  CVMJNIFrameCapacity,			  CVM_FRAMETYPE_JNI);    if (!result) {	goto failed; /* exception NOT thrown */    }    CVMjniFrameInit(CVMgetJNIFrame(targetEE->interpreterStack.currentFrame),                    CVM_FALSE);    result = CVMinitStack(ee, &targetEE->localRootsStack, 			  CVM_INITIAL_LOCALROOTS_STACK_SIZE,			  CVM_MAX_LOCALROOTS_STACK_SIZE, 			  CVM_MIN_LOCALROOTS_STACKCHUNK_SIZE,			  CVMbaseFrameCapacity,			  CVM_FRAMETYPE_LOCALROOT);    if (!result) {	goto failed; /* exception NOT thrown */    }    if (!CVMeeSyncInit(targetEE)) {	goto failed; /* exception NOT thrown */    }    CVMinitJNIEnv(&targetEE->jniEnv);    /* Allocate JNI local refs for targetEE     */    CVMcurrentThreadICell(targetEE)	= CVMjniCreateLocalRef0(ee, targetEE);    CVMmiscICell(targetEE)              = CVMjniCreateLocalRef0(ee, targetEE);    CVMsyncICell(targetEE)              = CVMjniCreateLocalRef0(ee, targetEE);    CVMfinalizerRegisterICell(targetEE) = CVMjniCreateLocalRef0(ee, targetEE);    CVMallocationRetryICell(targetEE)   = CVMjniCreateLocalRef0(ee, targetEE);    CVMlocalExceptionICell(targetEE)    = CVMjniCreateLocalRef0(ee, targetEE);#ifdef CVM_REMOTE_EXCEPTIONS_SUPPORTED    CVMremoteExceptionICell(targetEE)   = CVMjniCreateLocalRef0(ee, targetEE);#endif    CVMcurrentExceptionICell(targetEE)  = CVMjniCreateLocalRef0(ee, targetEE);    /*     * Clear flags and objects (which should already be null)     */    CVMclearLocalException(targetEE);    CVMclearRemoteException(targetEE);#ifdef CVM_LVM /* %begin lvm */    {

⌨️ 快捷键说明

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