📄 executejava_split2.c
字号:
* * As long as java code is being executed, the interpreter is iterative, * not recursive. However, if native code is invoked, then it may re-enter * executeJavaMethod. In this case there will already be frames on * the stack. * * Upon entry: * -ee->interpreterStack.currentFrame must be a transition * frame that holds the method arguments. * -currentFrame->topOfStack must point after the arguments. * * Returns the current PC. */CVMUint8*CVMgcUnsafeExecuteJavaMethodQuick(CVMExecEnv* ee, CVMUint8* pc, CVMStackVal32* topOfStack, CVMSlotVal32* locals, CVMConstantPool* cp, CVMClassBlock** retCb){#ifdef CVM_TRACE char trBuf[30]; /* needed by GET_LONGCSTRING */#endif#ifndef CVM_USELABELS CVMUint32 opcode;#endif#ifdef CVM_USELABELS#include "generated/javavm/include/opcodeLabels.h" const static void* const opclabels_data[256] = { &&opc_0, &&opc_1, &&opc_2, &&opc_3, &&opc_4, &&opc_5, &&opc_6, &&opc_7, &&opc_8, &&opc_9, &&opc_10, &&opc_11, &&opc_12, &&opc_13, &&opc_14, &&opc_15, &&opc_16, &&opc_17, &&opc_18, &&opc_19, &&opc_20, &&opc_21, &&opc_22, &&opc_23, &&opc_24, &&opc_25, &&opc_26, &&opc_27, &&opc_28, &&opc_29, &&opc_30, &&opc_31, &&opc_32, &&opc_33, &&opc_34, &&opc_35, &&opc_36, &&opc_37, &&opc_38, &&opc_39, &&opc_40, &&opc_41, &&opc_42, &&opc_43, &&opc_44, &&opc_45, &&opc_46, &&opc_47, &&opc_48, &&opc_49, &&opc_50, &&opc_51, &&opc_52, &&opc_53, &&opc_54, &&opc_55, &&opc_56, &&opc_57, &&opc_58, &&opc_59, &&opc_60, &&opc_61, &&opc_62, &&opc_63, &&opc_64, &&opc_65, &&opc_66, &&opc_67, &&opc_68, &&opc_69, &&opc_70, &&opc_71, &&opc_72, &&opc_73, &&opc_74, &&opc_75, &&opc_76, &&opc_77, &&opc_78, &&opc_79, &&opc_80, &&opc_81, &&opc_82, &&opc_83, &&opc_84, &&opc_85, &&opc_86, &&opc_87, &&opc_88, &&opc_89, &&opc_90, &&opc_91, &&opc_92, &&opc_93, &&opc_94, &&opc_95, &&opc_96, &&opc_97, &&opc_98, &&opc_99, &&opc_100, &&opc_101, &&opc_102, &&opc_103, &&opc_104, &&opc_105, &&opc_106, &&opc_107, &&opc_108, &&opc_109, &&opc_110, &&opc_111, &&opc_112, &&opc_113, &&opc_114, &&opc_115, &&opc_116, &&opc_117, &&opc_118, &&opc_119, &&opc_120, &&opc_121, &&opc_122, &&opc_123, &&opc_124, &&opc_125, &&opc_126, &&opc_127, &&opc_128, &&opc_129, &&opc_130, &&opc_131, &&opc_132, &&opc_133, &&opc_134, &&opc_135, &&opc_136, &&opc_137, &&opc_138, &&opc_139, &&opc_140, &&opc_141, &&opc_142, &&opc_143, &&opc_144, &&opc_145, &&opc_146, &&opc_147, &&opc_148, &&opc_149, &&opc_150, &&opc_151, &&opc_152, &&opc_153, &&opc_154, &&opc_155, &&opc_156, &&opc_157, &&opc_158, &&opc_159, &&opc_160, &&opc_161, &&opc_162, &&opc_163, &&opc_164, &&opc_165, &&opc_166, &&opc_167, &&opc_168, &&opc_169, &&opc_170, &&opc_171, &&opc_172, &&opc_173, &&opc_174, &&opc_175, &&opc_176, &&opc_177, &&opc_178, &&opc_179, &&opc_180, &&opc_181, &&opc_182, &&opc_183, &&opc_184, &&opc_185, &&opc_186, &&opc_187, &&opc_188, &&opc_189, &&opc_190, &&opc_191, &&opc_192, &&opc_193, &&opc_194, &&opc_195, &&opc_196, &&opc_197, &&opc_198, &&opc_199, &&opc_200, &&opc_201, &&opc_202, &&opc_203, &&opc_204, &&opc_205, &&opc_206, &&opc_207, &&opc_208, &&opc_209, &&opc_210, &&opc_211, &&opc_212, &&opc_213, &&opc_214, &&opc_215, &&opc_216, &&opc_217, &&opc_218, &&opc_219, &&opc_220, &&opc_221, &&opc_222, &&opc_223, &&opc_224, &&opc_225, &&opc_226, &&opc_227, &&opc_228, &&opc_229, &&opc_230, &&opc_231, &&opc_232, &&opc_233, &&opc_234, &&opc_235, &&opc_236, &&opc_237, &&opc_238, &&opc_239, &&opc_240, &&opc_241, &&opc_242, &&opc_243, &&opc_244, &&opc_245, &&opc_246, &&opc_247, &&opc_248, &&opc_249, &&opc_250, &&opc_251, &&opc_252, &&opc_253, &&opc_254, &&opc_255 }; const void* const *opclabels = &opclabels_data[0];#endif /* CVM_USELABELS */ CVMMethodBlock* mb; CVMFrame* frame; frame = ee->interpreterStack.currentFrame; CVMassert(CVMD_isgcUnsafe(ee));#ifdef CVM_PREFETCH_OPCODE#ifndef CVM_USELABELS opcode = *pc; /* prefetch first opcode */#endif#endif#ifdef CVM_JVMTI if (*pc == opc_breakpoint) { CVMUint32 opcode0; CVMD_gcSafeExec(ee, { opcode0 = CVMjvmtiGetBreakpointOpcode(ee, pc, CVM_FALSE); }); REEXECUTE_BYTECODE(opcode0); }#endif#ifndef CVM_USELABELS while (1) {#endif#ifndef CVM_PREFETCH_OPCODE opcode = *pc;#endif /* Using this label avoids double breakpoints when quickening and * when returing from transition frames. */#ifndef CVM_USELABELSskip_prefetch:#endif /* * Concentrate all byte-code definition macros here, so we can * freely re-order their locations in the handler list */#undef OPC_CONST_n#define OPC_CONST_n(opcname, const_type, value) \ CASE(opcname) { \ OPCODE_INTRO_DECL \ \ TRACE(("\t%s\n", CVMopnames[*pc])); \ OPCODE_UPDATE_NEW(pc[1]); \ topOfStack += 1; \ OPCODE_UPDATE_NEXT(opcode); \ pc += 1; \ STACK_INFO(-1).const_type = value; \ CONTINUE_NEXT(opcode); \ }#undef OPC_CONST2_n#define OPC_CONST2_n(opcname, value, key) \ CASE(opc_##opcname) \ { \ CVM##key##2Jvm(&STACK_INFO(0).raw, \ CVM##key##Const##value()); \ TRACE(("\t%s\n", CVMopnames[*pc])); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); \ }/* Load 1 word values from a local variable */#define OPC_LOAD1_n(type, num) \ CASE(opc_##type##load_##num) { \ OPCODE_INTRO_DECL \ CVMSlotVal32 l; \ \ OPCODE_UPDATE_NEW(pc[1]); \ pc += 1; \ l = locals[num]; \ OPCODE_UPDATE_NEXT(opcode); \ topOfStack += 1; \ TRACEIF(opc_##type##load_##num, \ ("\t%s locals[%d](0x%x) =>\n", \ CVMopnames[pc[-1]], num, STACK_OBJECT(0))); \ STACK_SLOT(-1) = l; \ CONTINUE_NEXT(opcode); \ }/* Store a 1 word local variable */#undef OPC_STORE1_n#define OPC_STORE1_n(type, num) \ CASE(opc_##type##store_##num) { \ OPCODE_INTRO_DECL \ CVMSlotVal32 l; \ \ OPCODE_UPDATE_NEW(pc[1]); \ pc += 1; \ topOfStack -= 1; \ l = STACK_SLOT(0); \ OPCODE_UPDATE_NEXT(opcode); \ TRACEIF(opc_##type##load_##num, \ ("\t%s locals[%d](0x%x) =>\n", \ CVMopnames[pc[0]], num, STACK_OBJECT(0))); \ locals[num] = l; \ CONTINUE_NEXT(opcode); \ }/* Load 2 word values from a local variable */#define OPC_LOAD2_n(type, num) \ CASE(opc_##type##load_##num) \ CVMmemCopy64(&STACK_INFO(0).raw, &locals[num].j.raw); \ TRACEIF(opc_dload_##num, ("\t%s locals[%d](%f) =>\n", \ CVMopnames[*pc], num, \ STACK_DOUBLE(0))); \ TRACEIF(opc_lload_##num, ("\t%s locals[%d](%s) =>\n", \ CVMopnames[*pc], num, \ GET_LONGCSTRING(STACK_LONG(0)))); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2);/* Store a 2 word local variable */#undef OPC_STORE2_n#define OPC_STORE2_n(type, num) \ CASE(opc_##type##store_##num) \ CVMmemCopy64(&locals[num].j.raw, &STACK_INFO(-2).raw); \ TRACEIF(opc_dstore_##num, ("\t%s %f => locals[%d]\n", \ CVMopnames[*pc], STACK_DOUBLE(-2), num)); \ TRACEIF(opc_lstore_##num, ("\t%s %s => locals[%d]\n", \ CVMopnames[*pc], \ GET_LONGCSTRING(STACK_LONG(-2)), num)); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);/* Perform various binary integer operations */#undef OPC_INT1_BINARY #define OPC_INT1_BINARY(opcname, opname, test) \ CASE(opc_i##opcname) { \ OPCODE_INTRO_DECL \ CVMJavaInt lhs, rhs, result; \ \ OPCODE_UPDATE_NEW(pc[1]); \ rhs = STACK_INT(-1); \ lhs = STACK_INT(-2); \ OPCODE_UPDATE_NEXT(opcode); \ if (test && (rhs == 0)) { \ goto throwArithmethicException; \ } \ pc += 1; \ result = CVMint##opname(lhs, rhs); \ topOfStack -= 1; \ \ STACK_INT(-1) = result; \ \ TRACE(("\t%s => %d\n", CVMopnames[*pc], STACK_INT(-1))); \ \ CONTINUE_NEXT(opcode); \ } #undef OPC_INT2_BINARY #define OPC_INT2_BINARY(opcname, opname, test) \ CASE(opc_l##opcname) \ { \ CVMJavaLong l1, l2, r1; \ l2 = CVMjvm2Long(&STACK_INFO(-2).raw); \ if (test && CVMlongEqz(l2)) { \ goto throwArithmethicException; \ } \ l1 = CVMjvm2Long(&STACK_INFO(-4).raw); \ r1 = CVMlong##opname(l1, l2); \ CVMlong2Jvm(&STACK_INFO(-4).raw, r1); \ TRACE(("\t%s => %s\n", CVMopnames[*pc], \ GET_LONGCSTRING(STACK_LONG(-4)))); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ }/* Perform various binary floating number operations */#undef OPC_FLOAT1_BINARY #define OPC_FLOAT1_BINARY(opcname, opname) \ CASE(opc_f##opcname) \ STACK_FLOAT(-2) = \ CVMfloat##opname(STACK_FLOAT(-2), STACK_FLOAT(-1)); \ TRACE(("\t%s => %f\n", CVMopnames[*pc], STACK_FLOAT (-2))); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);#undef OPC_FLOAT2_BINARY #define OPC_FLOAT2_BINARY(opcname, opname) \ CASE(opc_d##opcname) { \ CVMJavaDouble l1, l2, r; \ l1 = CVMjvm2Double(&STACK_INFO(-4).raw); \ l2 = CVMjvm2Double(&STACK_INFO(-2).raw); \ r = CVMdouble##opname(l1, l2); \ CVMdouble2Jvm(&STACK_INFO(-4).raw, r); \ TRACE(("\t%s => %f\n", CVMopnames[*pc], STACK_DOUBLE(-4))); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ } \ /* Shift operations * Shift left int and long: ishl, lshl * Logical shift right int and long w/zero extension: iushr, lushr * Arithmetic shift right int and long w/sign extension: ishr, lshr */#undef OPC_SHIFT1_BINARY#define OPC_SHIFT1_BINARY(opcname, opname) \ CASE(opc_i##opcname) \ STACK_INT(-2) = CVMint##opname(STACK_INT(-2), STACK_INT(-1));\ TRACE(("\t%s => %d\n", CVMopnames[*pc], STACK_INT(-2))); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ #undef OPC_SHIFT2_BINARY#define OPC_SHIFT2_BINARY(opcname, opname) \ CASE(opc_l##opcname) \ { \ CVMJavaLong v, r; \ v = CVMjvm2Long(&STACK_INFO(-3).raw); \ r = CVMlong##opname(v, STACK_INT(-1)); \ CVMlong2Jvm(&STACK_INFO(-3).raw, r); \ TRACE(("\t%s => %s\n", CVMopnames[*pc], \ GET_LONGCSTRING(STACK_LONG(-3)))); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ } /* comparison operators */#define COMPARISON_OP_WITHZERO(name, comparison) \ CASE_NT(opc_if##name) { \ int skip = (STACK_INT(-1) comparison 0) \ ? CVMgetInt16(pc + 1) : 3; \ JVMPI_TRACE_IF((STACK_INT(-1) comparison 0)); \ TRACE(("\t%s goto +%d (%staken)\n", \ CVMopnames[*pc], \ CVMgetInt16(pc + 1), \ (STACK_INT(-1) comparison 0) ? "" : "not ")); \ UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_GC_CHECK(skip, -1); \ }#define COMPARISON_OP_INTS(name, comparison) \ CASE_NT(opc_if_icmp##name) { \ int skip = (STACK_INT(-2) comparison STACK_INT(-1)) \ ? CVMgetInt16(pc + 1) : 3; \ JVMPI_TRACE_IF((STACK_INT(-2) comparison STACK_INT(-1))); \ TRACE(("\t%s goto +%d (%staken)\n", \ CVMopnames[*pc], \ CVMgetInt16(pc + 1), \ (STACK_INT(-2) comparison STACK_INT(-1)) ? "" : "not ")); \ UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_GC_CHECK(skip, -2); \ } \#define COMPARISON_OP_REFS(name, comparison) \ CASE_NT(opc_if_acmp##name) { \ int skip = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)) \ ? CVMgetInt16(pc + 1) : 3; \ JVMPI_TRACE_IF((STACK_OBJECT(-2) comparison STACK_OBJECT(-1))); \ TRACE(("\t%s goto +%d (%staken)\n", \ CVMopnames[*pc], \ CVMgetInt16(pc + 1), \ (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)) \ ? "" : "not ")); \ UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_GC_CHECK(skip, -2); \ }#define NULL_COMPARISON_OP(name, not) \ CASE_NT(opc_if##name) { \ int skip = (not(STACK_OBJECT(-1) == 0)) \ ? CVMgetInt16(pc + 1) : 3; \ JVMPI_TRACE_IF((not(STACK_OBJECT(-1) == 0))); \ TRACE(("\t%s goto +%d (%staken)\n", \ CVMopnames[*pc], \ CVMgetInt16(pc + 1), \ (not(STACK_OBJECT(-1) == 0)) \ ? "" : "not ")); \ UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_GC_CHECK(skip, -1); \ } /* Array access byte-codes */ /* Every array access byte-code starts out like this */#define ARRAY_INTRO(T, arrayOff) \ CVMArrayOf##T* arrObj = (CVMArrayOf##T*)STACK_OBJECT(arrayOff); \ CVMJavaInt index = STACK_INT(arrayOff + 1); \ CHECK_NULL(arrObj); \ /* This clever idea is from ExactVM. No need to test index >= 0. \ Instead, do an unsigned comparison. Negative indices will appear \ as positive numbers >= 2^31, which is just out of the range \ of legal Java array indices */ \ if ((CVMUint32)index >= CVMD_arrayGetLength(arrObj)) { \ goto throwArrayIndexOutOfBoundsException; \ } /* 32-bit loads. These handle conversion from < 32-bit types */#define ARRAY_LOADTO32(T, format, stackRes) \ { \ ARRAY_INTRO(T, -2); \ CVMD_arrayRead##T(arrObj, index, stackRes(-2)); \ TRACE(("\t%s %O[%d](" format ") ==>\n", CVMopnames[*pc], \ arrObj, index, stackRes(-1))); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ } /* 64-bit loads */#define ARRAY_LOADTO64(T,T2) \ { \ CVMJava##T temp64; \ ARRAY_INTRO(T, -2); \ CVMD_arrayRead##T(arrObj, index, temp64); \ CVM##T2##2Jvm(&STACK_INFO(-2).raw, temp64); \ TRACE(("\t%s %O[%d](0x%X, 0x%X) ==>\n", CVMopnames[*pc], \ arrObj, index, STACK_INT(-2), STACK_INT(-1))); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 0); \ } /* 32-bit stores. These handle conversion to < 32-bit types */#define ARRAY_STOREFROM32(T, format, stackSrc) \ { \ ARRAY_INTRO(T, -3); \ CVMD_arrayWrite##T(arrObj, index, stackSrc(-1)); \ TRACE(("\t%s " format " ==> %O[%d] ==>\n", CVMopnames[*pc], \ stackSrc(-1), arrObj, index)); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); \ } /* 64-bit stores */#define ARRAY_STOREFROM64(T) \ { \ CVMJava##T temp64; \ ARRAY_INTRO(T, -4); \ temp64 = CVMjvm2##T(&STACK_INFO(-2).raw); \ CVMD_arrayWrite##T(arrObj, index, temp64); \ TRACE(("\t%s (0x%X, 0x%X) ==> %O[%d]\n", CVMopnames[*pc], \ STACK_INT(-2), STACK_INT(-1), arrObj, index)); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -4); \ }#ifdef CVM_USELABELS goto *opclabels[*pc];#else switch (opcode) {#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -