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