executejava_aligned.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,990 行 · 第 1/5 页
C
1,990 行
goto handle_pending_request; \ } \ JVMPI_CHECK_FOR_DATA_DUMP_REQUEST(ee); \ UPDATE_PC_AND_TOS_AND_CONTINUE((skip), stack); \}/* * UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_BACKWARDS_CHECK2 - Same as * above but the dispatching code does a goto dispatch_opcode. * This saves us a few bytes in the opcode implementation when * doing alignment based dispatching, which helps some opcodes * fit into the required size. */#undef UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_BACKWARDS_CHECK2#ifdef CVM_ALIGNMENT_BASED_DISPATCHING#define UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_BACKWARDS_CHECK2(skip, stack) { \ FETCH_NEXT_OPCODE(skip) \ if ((skip) <= 0 && CHECK_PENDING_REQUESTS(ee)) { \ goto handle_pending_request; \ } \ JVMPI_CHECK_FOR_DATA_DUMP_REQUEST(ee); \ UPDATE_PC_AND_TOS(skip, stack); \ goto dispatch_opcode; \}#else#define UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_BACKWARDS_CHECK2(skip, stack) \ UPDATE_PC_AND_TOS_AND_CONTINUE_WITH_BACKWARDS_CHECK(skip, stack)#endif/* * A bunch of macros for optionally handling dispatching out of line. * Rather than inlining the dispatching code with the opcode, you can * optionally choose to goto a label that will handle dispatching * for the opcode's specific opcode size and stack adjustment. This * allows us to get a number of opcodes below the 64 bytes limit when * using alignment based dispatching. Otherwise these macros just default * to inlining the dispatching code with the opcode. Note that only * opcodes that need to be shrunk a little to fit in 64 bytes should * use these macros. */#undef UPDATE_PC_AND_TOS_AND_CONTINUE_1_0#undef UPDATE_PC_AND_TOS_AND_CONTINUE_1_m1#undef UPDATE_PC_AND_TOS_AND_CONTINUE_1_m2#undef UPDATE_PC_AND_TOS_AND_CONTINUE_1_m4#undef UPDATE_PC_AND_TOS_AND_CONTINUE_2_0#undef UPDATE_PC_AND_TOS_AND_CONTINUE_3_0#undef UPDATE_PC_AND_TOS_AND_CONTINUE_3_1#undef UPDATE_PC_AND_TOS_AND_CONTINUE_3_2#undef UPDATE_PC_AND_TOS_AND_CONTINUE_3_m2#ifdef CVM_ALIGNMENT_BASED_DISPATCHING#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_0 \ goto update_pc_and_tos_and_continue_1_0;#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_m1 \ goto update_pc_and_tos_and_continue_1_m1;#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_m2 \ goto update_pc_and_tos_and_continue_1_m2;#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_m3 \ goto update_pc_and_tos_and_continue_1_m3;#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_m4 \ goto update_pc_and_tos_and_continue_1_m4;#define UPDATE_PC_AND_TOS_AND_CONTINUE_2_0 \ goto update_pc_and_tos_and_continue_2_0;#define UPDATE_PC_AND_TOS_AND_CONTINUE_3_0 \ goto update_pc_and_tos_and_continue_3_0;#define UPDATE_PC_AND_TOS_AND_CONTINUE_3_1 \ goto update_pc_and_tos_and_continue_3_1;#define UPDATE_PC_AND_TOS_AND_CONTINUE_3_2 \ goto update_pc_and_tos_and_continue_3_2;#define UPDATE_PC_AND_TOS_AND_CONTINUE_3_m2 \ goto update_pc_and_tos_and_continue_3_m2;#else#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_0 \ FETCH_NEXT_OPCODE(1); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 0);#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_m1 \ FETCH_NEXT_OPCODE(1); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1);#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_m2 \ FETCH_NEXT_OPCODE(1); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2);#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_m3 \ FETCH_NEXT_OPCODE(1); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3);#define UPDATE_PC_AND_TOS_AND_CONTINUE_1_m4 \ FETCH_NEXT_OPCODE(1); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -4);#define UPDATE_PC_AND_TOS_AND_CONTINUE_2_0 \ FETCH_NEXT_OPCODE(2); \ UPDATE_PC_AND_TOS_AND_CONTINUE(2, 0);#define UPDATE_PC_AND_TOS_AND_CONTINUE_3_0 \ FETCH_NEXT_OPCODE(3); \ UPDATE_PC_AND_TOS_AND_CONTINUE(3, 0);#define UPDATE_PC_AND_TOS_AND_CONTINUE_3_1 \ FETCH_NEXT_OPCODE(3); \ UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);#define UPDATE_PC_AND_TOS_AND_CONTINUE_3_2 \ FETCH_NEXT_OPCODE(3); \ UPDATE_PC_AND_TOS_AND_CONTINUE(3, 2);#define UPDATE_PC_AND_TOS_AND_CONTINUE_3_m2 \ FETCH_NEXT_OPCODE(3); \ UPDATE_PC_AND_TOS_AND_CONTINUE(3, -2);#endif/* * Macros for accessing the stack. */#undef STACK_INFO#undef STACK_INT#undef STACK_FLOAT#undef STACK_ICELL#undef STACK_ADDR#undef STACK_OBJECT#undef STACK_DOUBLE#undef STACK_LONG#define STACK_SLOT(offset) (topOfStack[offset].s)#define STACK_INFO(offset) (STACK_SLOT(offset).j)#define STACK_ADDR(offset) (STACK_SLOT(offset).a)#define STACK_INT(offset) (STACK_INFO(offset).i)#define STACK_FLOAT(offset) (STACK_INFO(offset).f)#define STACK_ICELL(offset) (STACK_INFO(offset).r)#define STACK_OBJECT(offset) (CVMID_icellDirect(ee, &STACK_ICELL(offset)))#define STACK_DOUBLE(offset) \ CVMjvm2Double(&STACK_INFO(offset).raw)#define STACK_LONG(offset) \ CVMjvm2Long(&STACK_INFO(offset).raw)#ifdef CVM_TRACE#undef GET_LONGCSTRING#define GET_LONGCSTRING(number) \ (CVMlong2String(number, trBuf, trBuf+sizeof(trBuf)), trBuf)#endif/* * Macros for caching and flushing the interpreter state. Some local * variables need to be flushed out to the frame before we do certain * things (like pushing frames or becomming gc safe) and some need to * be recached later (like after popping a frame). We could use one * macro to cache or decache everything, but this would be less then * optimal because we don't always need to cache or decache everything * because some things we know are already cached or decached. */#undef DECACHE_TOS#undef CACHE_TOS#undef CACHE_PREV_TOS#define DECACHE_TOS() frame->topOfStack = topOfStack;#define CACHE_TOS() topOfStack = frame->topOfStack;#define CACHE_PREV_TOS() topOfStack = CVMframePrev(frame)->topOfStack;#undef DECACHE_PC#undef CACHE_PC#define DECACHE_PC() CVMframePc(frame) = pc;#define CACHE_PC() pc = CVMframePc(frame);#undef CACHE_FRAME#define CACHE_FRAME() frame = stack->currentFrame; /* * CHECK_NULL - Macro for throwing a NullPointerException if the object * passed is a null ref. */#undef CHECK_NULL#define CHECK_NULL(obj_) \ if ((obj_) == 0) { \ goto null_pointer_exception; \ }/* * Function to verify that all opcodes are less than CVM_OPCODE_ALIGN_SIZE * in bytes. It can also be modified to print out the size of each * opcode implementation. We don't do this inline or static, because * this can disrupt gcc register allocation. */#ifdef CVM_CHECK_OPCODE_SIZESextern voidCVMcheckOpcodeSizes(const void* firstOpcodeImplPtr, const void* const *opclabels){ int i; const void* opcodePtr = firstOpcodeImplPtr; for (i = 0; i < 255; i++) { int opcodeSize = (int)opclabels[i+1] - (int)opcodePtr; if (opcodeSize > CVM_OPCODE_ALIGN_SIZE) {#if 1 opcodePtr += CVM_OPCODE_ALIGN_SIZE; printf("interpreter loop opcode too big!\n");#else CVMpanic("interpreter loop opcode too big!");#endif } /*printf("0x%5x: %d %-20s\n", opcodeSize, i, CVMopnames[i]);*/ printf("0x%5x: %d\n", opcodeSize, i); opcodePtr += CVM_OPCODE_ALIGN_SIZE; }}#endif /* CVM_CHECK_OPCODE_SIZES *//* * The following 4 structures are static java bytecodes * that contain the transition code for various types of method * invocations. They are used to handle the invocation of * the mb passed into executeJavaMethod. */static const CVMUint8 CVMinvokeStaticTransitionCode[] = { opc_invokestatic_quick, 0, 1, opc_exittransition};static const CVMUint8 CVMinvokeVirtualTransitionCode[] = { opc_invokevirtual_quick_w, 0, 1, opc_exittransition};static const CVMUint8 CVMinvokeNonVirtualTransitionCode[] = { opc_invokenonvirtual_quick, 0, 1, opc_exittransition};static const CVMUint8 CVMinvokeInterfaceTransitionCode[] = { opc_invokeinterface_quick, 0, 1, 0, 0, opc_exittransition};/* * CVMgcUnsafeExecuteJavaMethod * * The real deal. This is where byte codes actually get interpreted. * Basically it's a big while loop that iterates until we return from * the method passed in. * * 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. */voidCVMgcUnsafeExecuteJavaMethod(CVMExecEnv* ee, CVMMethodBlock* mb, CVMBool isStatic, CVMBool isVirtual){ CVMFrame* frame; /* actually it's a CVMJavaFrame */ CVMFrame* initialframe; /* the initial transition frame that holds the arguments */ CVMStack* stack = &ee->interpreterStack; CVMStackVal32* topOfStack; /* access with STACK_ and _TOS macros */ CVMSlotVal32* locals = 0; /* area in the frame for local variables */ CVMUint8* pc;#ifdef CVM_ALIGNMENT_BASED_DISPATCHING const void* nextOpcodeImpl;#else CVMUint32 opcode;#endif CVMConstantPool* cp; CVMTransitionConstantPool transitioncp; CVMClassBlock* initCb; CVMClassBlock* newCb; CVMObjectICell* receiverObjICell; /* the object we are dispatching on or the Class object for static calls */ CVMArrayOfAnyType* directArr; /* for opc_newarray */#ifdef CVM_CLASSLOADING CVMBool clobbersCpIndex; /* true if quickening clobbers the cp index */#endif#ifdef CVM_TRACE char trBuf[30]; /* needed by GET_LONGCSTRING */#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];#ifdef CVM_ALIGNMENT_BASED_DISPATCHING typedef struct { CVMUint8 bytecodes[CVM_OPCODE_ALIGN_SIZE]; } CVMopcodeImplementation; /* Don't included the "const" below or bad code will be generated. */ const CVMopcodeImplementation* /* const */ firstOpcodeImplPtr = &&opc_first_opcode;#endif /* CVM_ALIGNMENT_BASED_DISPATCHING */#endif /* CVM_USELABELS */ goto executejava_setup;dispatch_opcode: ASMLABEL(label_dispatch_opcode); FETCH_NEXT_OPCODE(0);#ifdef CVM_USELABELS DISPATCH_OPCODE();#endif #ifndef CVM_USELABELS while (1)#endif {#ifndef CVM_PREFETCH_OPCODE opcode = *pc;#endif#ifndef CVM_USELABELS opcode_switch: switch (opcode)#endif { CASE(opc_nop, 1)#ifdef CVM_ALIGNMENT_BASED_DISPATCHING opc_first_opcode:#endif TRACE(("\t%s\n", CVMopnames[pc[0]])); FETCH_NEXT_OPCODE(1); UPDATE_PC_AND_TOS_AND_CONTINUE(1, 0); /* Push miscellaneous constants onto the stack. */ CASE(opc_aconst_null, 1) CVMID_icellSetNull(&STACK_ICELL(0)); TRACE(("\t%s\n", CVMopnames[pc[0]])); UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1);#undef OPC_CONST_n#define OPC_CONST_n(opcode, const_type, value) \ CASE(opcode, 1) \ STACK_INFO(0).const_type = value; \ TRACE(("\t%s\n", CVMopnames[pc[0]])); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); /* TODO - outline to make pc-relative table smaller on sarm */#undef OPC_CONST2_n#define OPC_CONST2_n(opcname, value, key) \ CASE(opc_##opcname, 1) \ CVM##key##2Jvm(&STACK_INFO(0).raw, CVM##key##Const##value()); \ TRACE(("\t%s\n", CVMopnames[pc[0]])); \ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); OPC_CONST_n(opc_iconst_m1, i, -1); OPC_CONST_n(opc_iconst_0, i, 0); OPC_CONST_n(opc_iconst_1, i, 1); OPC_CONST_n(opc_iconst_2, i, 2); OPC_CONST_n(opc_iconst_3, i, 3); OPC_CONST_n(opc_iconst_4, i, 4); OPC_CONST_n(opc_iconst_5, i, 5); OPC_CONST2_n(lconst_0, Zero, long); OPC_CONST2_n(lconst_1, One, long); OPC_CONST_n(opc_fconst_0, f, 0.0); OPC_CONST_n(opc_fconst_1, f, 1.0); OPC_CONST_n(opc_fconst_2, f, 2.0); OPC_CONST2_n(dconst_0, Zero, double); OPC_CONST2_n(dconst_1, One, double); /* Push a 1-byte signed integer value onto the stack. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?