Index: vm/vmcore/src/jit/compile.cpp =================================================================== --- vm/vmcore/src/jit/compile.cpp (revision 569233) +++ vm/vmcore/src/jit/compile.cpp (working copy) @@ -41,6 +41,11 @@ #include "jvmti_break_intf.h" #include "cci.h" #include "open/gc.h" +#include "encoder.h" +#include "nogc.h" +#include "open/thread_helpers.h" +#include "m2n.h" +#include "../port/src/lil/ia32/pim/m2n_ia32_internal.h" #include "vm_stats.h" #include "dump.h" @@ -228,6 +233,193 @@ for(i=0; iget_name()->bytes, "nlog") == 0) + if (is_static && !is_synchronised && num_ref_args == 0 && (strcmp(method->get_name()->bytes, "nlog") == 0) ) { + int stub_size = 1000; + char *ss = (char*)(clss->get_class_loader()->GetCodePool()->alloc(stub_size, DEFAULT_CODE_ALIGNMENT, CAA_Allocate)); + char* start = ss; + + memset(ss, 0xcc /*int 3*/, stub_size); + + void *jlc = clss->get_class_handle(); + + printf("%s %s\n", clss->get_java_name()->bytes, method->get_name()->bytes); + //printf(" class handle: %x\n\n", jlc); + + int32 disable_count_offset = (unsigned) &(((HyThread_public *) (0))->disable_count); + int32 request_offset = (unsigned) &(((HyThread_public *) (0))->request); + + if (strcmp(method->get_name()->bytes, "oneTimeInitialization") == 0) { + ss = int3(ss); + } + + // **** push callee-save registers + ss = push(ss, ebp_opnd); + ss = push(ss, ebx_opnd); + ss = push(ss, esi_opnd); + ss = push(ss, edi_opnd); + + // **** get TLS to ebx + ss = gen_hythread_self_helper(ss); + ss = mov(ss, ecx_opnd, eax_opnd); // hythread + ss = mov(ss, ebx_opnd, M_Base_Opnd(eax_reg, 0x10)); // vm_thread + + // **** generate m2n frame + // original: + // ss = m2n_gen_push_m2n(ss, method, (POINTER_SIZE_INT)FRAME_JNI, true, 10); + // inlined: + + ss = mov(ss, eax_opnd, ebx_opnd); + ss = push(ss, Imm_Opnd(size_32, 0)); + ss = push(ss, Imm_Opnd(0x01 | FRAME_NON_UNWINDABLE)); + + int last_m2n_frame_offset = (int)&((VM_thread*)0)->last_m2n_frame; + ss = alu(ss, add_opc, eax_opnd, Imm_Opnd(last_m2n_frame_offset)); + + ss = push(ss, Imm_Opnd((unsigned)method)); + ss = push(ss, Imm_Opnd(0)); + ss = push(ss, eax_opnd); + ss = push(ss, M_Base_Opnd(eax_reg, +0)); + ss = mov(ss, M_Base_Opnd(eax_reg, +0), esp_opnd ); + + // **** allocate handles and get the stack working + // TODO: allocate handles and get the stack working + ss = alu(ss, sub_opc, esp_opnd, Imm_Opnd(0x2C)); + ss = mov(ss, ebp_opnd, esp_opnd); + ss = mov(ss, M_Base_Opnd(ebp_reg, 0x00), 0x10009); + ss = mov(ss, M_Base_Opnd(ebp_reg, 0x04), 0x00); + ss = mov(ss, M_Base_Opnd(esp_reg, 0x34), ebp_opnd); + + // prepare class handle + ss = mov(ss, eax_opnd, M_Opnd( (int32)jlc ) ); + ss = mov(ss, M_Base_Opnd(ebp_reg, 0x08), eax_opnd ); + + // **** call hythread_suspend_enable + // original: + // ss = call(ss, (char *)hythread_suspend_enable); + // inlined: + ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, disable_count_offset)); + ss = alu(ss, sub_opc, eax_opnd, Imm_Opnd(1)); + ss = mov(ss, M_Base_Opnd(ecx_reg, disable_count_offset), eax_opnd); + + + ss = push(ss, ebx_opnd); + ss = push(ss, ecx_opnd); + + // **** prepare native args + + // TODO: prepare non-static methods' arguments + + // jclass + ss = lea(ss, eax_opnd, M_Base_Opnd(ebp_reg, 0x08)); +// ss = mov(ss, eax_opnd, Imm_Opnd( (int32)jlc )); + ss = push(ss, eax_opnd); + + // JNIEnv + ss = mov(ss, eax_opnd, M_Base_Opnd(ebx_reg, 0x14)); + ss = push(ss, eax_opnd); + + // **** native call + ss = call(ss, (char *)func); + ss = mov(ss, esi_opnd, eax_opnd); + ss = mov(ss, edi_opnd, edx_opnd); + + ss = pop(ss, ecx_opnd); + ss = pop(ss, ebx_opnd); + + // **** hythread_suspend_disable + // original: + // ss = push(ss, eax_opnd); + // ss = push(ss, edx_opnd); + // ss = call(ss, (char *)hythread_suspend_disable); + // ss = pop(ss, eax_opnd); + // ss = pop(ss, edx_opnd); + // inlined: + ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, disable_count_offset)); + ss = alu(ss, add_opc, eax_opnd, Imm_Opnd(1)); + ss = mov(ss, M_Base_Opnd(ecx_reg, disable_count_offset), eax_opnd); + + // if ((HyThread_public *)thread)->disable_count == 1) && + ss = alu(ss, cmp_opc, eax_opnd, Imm_Opnd(1)); + ss = branch8(ss, Condition_NE, Imm_Opnd(0x0D + 7)); + // (((HyThread_public *)thread)->request) + ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, request_offset)); + ss = test(ss, eax_opnd, eax_opnd); + ss = branch8(ss, Condition_E, Imm_Opnd(0x06 + 7)); + // hythread_safe_point_other(thread); + + // TODO: optimize push-pop before hythread_safe_point_other + ss = push(ss, eax_opnd); + ss = push(ss, ebx_opnd); + ss = push(ss, ecx_opnd); + ss = push(ss, edx_opnd); + ss = call(ss, (char*)hythread_safe_point_other); + ss = pop(ss, edx_opnd); + ss = pop(ss, ebx_opnd); + ss = pop(ss, ecx_opnd); + ss = pop(ss, eax_opnd); + + // **** check for the exception + ss = mov(ss, eax_opnd, M_Base_Opnd(ebx_reg, 0x20)); + ss = test(ss, eax_opnd, eax_opnd); + ss = branch8(ss, Condition_NE, Imm_Opnd(0x0D + 7)); + ss = mov(ss, eax_opnd, M_Base_Opnd(ebx_reg, 0x24)); + ss = test(ss, eax_opnd, eax_opnd); + ss = branch8(ss, Condition_E, Imm_Opnd(0x06 + 7)); + + // TODO: optimize push-pop before exn_rethrow + ss = push(ss, eax_opnd); + ss = push(ss, ebx_opnd); + ss = push(ss, ecx_opnd); + ss = push(ss, edx_opnd); + ss = call(ss, (char*)exn_rethrow); + ss = pop(ss, edx_opnd); + ss = pop(ss, ebx_opnd); + ss = pop(ss, ecx_opnd); + ss = pop(ss, eax_opnd); + + // **** move the result + ss = mov(ss, eax_opnd, esi_opnd); + ss = mov(ss, edx_opnd, edi_opnd); + + // **** generate m2n frame + // TODO: generate common-case optimized m2n_gen_pop_m2n + // original: + // ss = m2n_gen_pop_m2n(ss, true, 10, 0x2C, 0); + // inlined: + + //buf = call(buf, (char*)m2n_free_local_handles); + + // pop "garbage" from the stack + //if (extra_on_stack) { + //Imm_Opnd imm(extra_on_stack); + //buf = alu(buf, add_opc, esp_opnd, imm); + //} + ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(0x2C)); + + // Unlink the M2nFrame from the list of the current thread + ss = pop(ss, esi_opnd); + ss = pop(ss, ebx_opnd); + ss = mov(ss, M_Base_Opnd(ebx_reg, +0), esi_opnd); + ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(+16)); + + + // **** pop callee-save registers + ss = pop(ss, edi_opnd); + ss = pop(ss, esi_opnd); + ss = pop(ss, ebx_opnd); + ss = pop(ss, ebp_opnd); + + + + ss = ret(ss); + + printf("%d\n", (int)(start-ss)); + + return start; + + } else { + //***** Part 1: Entry, Stats, Override, push m2n, allocate space for handles LilCodeStub* cs = lil_parse_code_stub("entry 0:managed:%0m;", method); @@ -267,6 +459,7 @@ if (is_static) { void *jlc = clss->get_class_handle(); + printf("jlc: %x\n", jlc); cs = lil_parse_onto_end(cs, //"ld l1,[%0i:pint];" "ld l1,[%0i:ref];", @@ -529,6 +722,7 @@ lil_free_code_stub(cs); return addr; +} } // compile_create_lil_jni_stub