📄 execute.c
字号:
#define TOKEN (*ip)#endif/*========================================================================= * FUNCTION: Interpret() * TYPE: Instrumentation version of Interpret() * OVERVIEW: Calls the real Interpret() and prints out the * instrumentation results * INTERFACE: * parameters: <none> * returns: <nothing> *=======================================================================*/void Interpret() { CurrentNativeMethod = NULL; START_TEMPORARY_ROOTS IS_TEMPORARY_ROOT(thisObjectGCSafe, NULL); FastInterpret(); END_TEMPORARY_ROOTS#if INSTRUMENT fprintf(stdout,"bytecodes =\t%d\n", bytecodes); fprintf(stdout,"slowcodes =\t%d\t(%d)%%\n", slowcodes, slowcodes/(bytecodes/100)); fprintf(stdout,"calls =\t%d\t(%d)%%\n", calls, calls/(bytecodes/100)); fprintf(stdout,"branches taken =\t%d\t(%d)%%\n", branches, branches/(bytecodes/100)); fprintf(stdout,"rescheduled =\t%d\t(%d)%%\n", reshed, reshed/(bytecodes/100)); fprintf(stdout,"bytecodes =\t%d\n", bytecodes); fprintf(stdout,"slowcodes =\t%d\t(%d)%%\n", slowcodes, slowcodes/(bytecodes/100)); fprintf(stdout,"calls =\t%d\t(%d)%%\n", calls, calls/(bytecodes/100)); fprintf(stdout,"branches taken =\t%d\t(%d)%%\n", branches, branches/(bytecodes/100)); fprintf(stdout,"rescheduled =\t%d\t(%d)%%\n", reshed, reshed/(bytecodes/100));#endif /* INSTRUMENT */}/*========================================================================= * FUNCTION: Interpret() * TYPE: public global operation * OVERVIEW: Execute bytecode. * INTERFACE: * parameters: <none> * returns: <nothing> * * NOTES: Remember to initialize all virtual machine registers * and the call stack before entering the interpreter. *=======================================================================*/#if !ALTERNATIVE_FAST_INTERPRETERvoid FastInterpret() { /* * Define as locals those machine registers that are appropriate. * Typically you get a lot of bang for the buck simply by making * ip and sp local, but if you can make all the VM registers * (ip, sp, lp, fp and cp) local, that's even better. */#if IPISLOCAL#undef ip register BYTE* ip; /* Instruction pointer (program counter) */#endif#if SPISLOCAL#undef sp register cell* sp; /* Execution stack pointer */#endif#if LPISLOCAL#undef lp register cell* lp; /* Local variable pointer */#endif#if FPISLOCAL#undef fp register FRAME fp; /* Current frame pointer */#endif#if CPISLOCAL#undef cp register CONSTANTPOOL cp; /* Constant pool pointer */#endif#if ENABLE_JAVA_DEBUGGER register BYTE token;#endif /* * Define other local variables */#if NEED_LONG_ALIGNMENT || NEED_DOUBLE_ALIGNMENT Java8 tdub;#endif METHOD thisMethod; OBJECT thisObject; int invokerSize; const char *exception; VMRESTORE /** Restore virtual machine registers to local variables **/#if ENABLE_JAVA_DEBUGGERgoto reschedulePoint;#else goto next0;#endif/************************************************************************* * Top of the actual interpreter loop * *************************************************************************/ /* * If RESCHEDULEATBRANCH is not defined then we always test for thread * scheduling before every bytecode. This is like in KVM 1.0 version. */#if !RESCHEDULEATBRANCHnext3: ip++;next2: ip++;next1: ip++;next0:reschedulePoint: RESCHEDULE#endif /* * If RESCHEDULEATBRANCH is defined then we only test for thread * scheduling when reschedulePoint is called. */#if RESCHEDULEATBRANCHreschedulePoint: RESCHEDULE#if ENABLE_JAVA_DEBUGGER goto next0a;#else goto next0;#endifnext3: ip++;next2: ip++;next1: ip++;next0:#if ENABLE_JAVA_DEBUGGER token = *ip; /* * Be careful, there is a goto in this following macro that jumps back * up to a label in the RESCHEDULE macro; ugly, I know */ __doSingleStep()next0a:#endif#endif /* RESCHEDULEATBRANCH */ /* * Profile the instruction */ INSTRUCTIONPROFILE /* * Trace the instruction here if the option is enabled */ INSTRUCTIONTRACE /* * Increment the bytecode counter */ INC_BYTECODES /* * Extreme debug option to call the garbage collector before every bytecode */ DO_VERY_EXCESSIVE_GARBAGE_COLLECTION /* * Dispatch the bytecode */#if ENABLE_JAVA_DEBUGGER switch (token) {#else switch (((unsigned char)*ip)) {#endif/*=======================================================================*//* Include the bytecode definitions we need for this function *//*=======================================================================*/#define STANDARDBYTECODES 1#define FLOATBYTECODES IMPLEMENTS_FLOAT#define FASTBYTECODES ENABLEFASTBYTECODES#if SPLITINFREQUENTBYTECODES#define INFREQUENTSTANDARDBYTECODES 0#else#define INFREQUENTSTANDARDBYTECODES 1#endif#include "bytecodes.c"#undef STANDARDBYTECODES#undef FLOATBYTECODES#undef FASTBYTECODES#undef INFREQUENTSTANDARDBYTECODES/*=======================================================================*/ /* * If COMMONBRANCHING is defined then include the code to load ip * See the BRANCHIF macro */#if COMMONBRANCHING branchPoint: { INC_BRANCHES ip += getShort(ip + 1); goto reschedulePoint; }#endif callMethod_interface: invokerSize = 5; /* Size of the bytecode */ goto callMethod_general; callMethod_virtual: callMethod_static: callMethod_special: invokerSize = 3; /* Size of the bytecode */ callMethod_general: { int res; INC_CALLS /* Check if the method is a native method */ if (thisMethod->accessFlags & ACC_NATIVE) { ip += invokerSize; VMSAVE invokeNativeFunction(thisMethod); VMRESTORE TRACE_METHOD_EXIT(thisMethod); goto reschedulePoint; } if (thisMethod->accessFlags & ACC_ABSTRACT) { fatalError(KVM_MSG_ABSTRACT_METHOD_INVOKED); } thisObjectGCSafe = thisObject; VMSAVE res = pushFrame(thisMethod); VMRESTORE if (res) { /* Advance to next inst on return */ fp->previousIp += invokerSize; } if (res) { if (thisMethod->accessFlags & ACC_SYNCHRONIZED) { VMSAVE monitorEnter(thisObjectGCSafe); VMRESTORE fp->syncObject = thisObjectGCSafe; } } thisObjectGCSafe = NULL; goto reschedulePoint; }#if SPLITINFREQUENTBYTECODES callSlowInterpret: { int __token = TOKEN; VMSAVE SlowInterpret(__token); VMRESTORE goto reschedulePoint; /* test for rescheduling */ }#endif handleNullPointerException: { exception = NullPointerException; goto handleException; } handleArrayIndexOutOfBoundsException: { exception = ArrayIndexOutOfBoundsException; goto handleException; } handleArithmeticException: { exception = ArithmeticException; goto handleException; } handleArrayStoreException: { exception = ArrayStoreException; goto handleException; } handleClassCastException: { exception = ClassCastException; goto handleException; } handleJavaLangError: { exception = JavaLangError_name; goto handleException; } handleException: { VMSAVE raiseException(exception); VMRESTORE goto reschedulePoint; }#if PADTABLE notImplemented:#endif default: { sprintf(str_buffer, KVM_MSG_ILLEGAL_BYTECODE_1LONGPARAM, (long)TOKEN); fatalError(str_buffer); break; } } fatalError(KVM_MSG_INTERPRETER_STOPPED);}#endif /* ALTERNATIVE_FAST_INTERPRETER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -