< prev index next >

src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp

Print this page

        

*** 44,53 **** --- 44,54 ---- #include "runtime/synchronizer.hpp" #include "runtime/timer.hpp" #include "runtime/vframeArray.hpp" #include "utilities/debug.hpp" #include "utilities/macros.hpp" + #include "classfile/systemDictionary.hpp" #define __ _masm-> // Size of interpreter code. Increase if too small. Interpreter will // fail with a guarantee ("not enough space for interpreter generation");
*** 196,207 **** --- 197,212 ---- } else if (state == dtos) { __ MacroAssembler::verify_FPU(UseSSE >= 2 ? 0 : 1, "generate_return_entry_for in interpreter"); } #endif // _LP64 + // __ stop("12121212"); + // Restore stack bottom in case i2c adjusted stack __ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); + // __ addq(rsp, rbp); // XXXXXXXX see generate_fixed_frame + // and NULL it as marker that esp is now tos until next java call __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals();
*** 652,669 **** // rdx: cp cache void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // initialize fixed part of activation frame __ push(rax); // save return address __ enter(); // save old & set new rbp __ push(rbcp); // set sender sp __ push((int)NULL_WORD); // leave last_sp as null __ movptr(rbcp, Address(rbx, Method::const_offset())); // get ConstMethod* __ lea(rbcp, Address(rbcp, ConstMethod::codes_offset())); // get codebase __ push(rbx); // save Method* // Get mirror and store it in the frame as GC root for this Method* __ load_mirror(rdx, rbx); ! __ push(rdx); if (ProfileInterpreter) { Label method_data_continue; __ movptr(rdx, Address(rbx, in_bytes(Method::method_data_offset()))); __ testptr(rdx, rdx); __ jcc(Assembler::zero, method_data_continue); --- 657,676 ---- // rdx: cp cache void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { // initialize fixed part of activation frame __ push(rax); // save return address __ enter(); // save old & set new rbp + __ subq(rbcp, rbp); // must be added to rbp to get the old one. __ push(rbcp); // set sender sp + __ push((int)NULL_WORD); // leave last_sp as null __ movptr(rbcp, Address(rbx, Method::const_offset())); // get ConstMethod* __ lea(rbcp, Address(rbcp, ConstMethod::codes_offset())); // get codebase __ push(rbx); // save Method* // Get mirror and store it in the frame as GC root for this Method* __ load_mirror(rdx, rbx); ! __ push(rdx); // oop if (ProfileInterpreter) { Label method_data_continue; __ movptr(rdx, Address(rbx, in_bytes(Method::method_data_offset()))); __ testptr(rdx, rdx); __ jcc(Assembler::zero, method_data_continue);
*** 676,697 **** __ movptr(rdx, Address(rbx, Method::const_offset())); __ movptr(rdx, Address(rdx, ConstMethod::constants_offset())); __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes())); __ push(rdx); // set constant pool cache ! __ push(rlocals); // set locals pointer if (native_call) { __ push(0); // no bcp } else { __ push(rbcp); // set bcp } __ push(0); // reserve word for pointer to expression stack bottom __ movptr(Address(rsp, 0), rsp); // set expression stack bottom } // End of helpers // Method entry for java.lang.ref.Reference.get. address TemplateInterpreterGenerator::generate_Reference_get_entry(void) { #if INCLUDE_ALL_GCS // Code: _aload_0, _getfield, _areturn // parameter size = 1 --- 683,900 ---- __ movptr(rdx, Address(rbx, Method::const_offset())); __ movptr(rdx, Address(rdx, ConstMethod::constants_offset())); __ movptr(rdx, Address(rdx, ConstantPool::cache_offset_in_bytes())); __ push(rdx); // set constant pool cache ! // __ push(rlocals); // set locals pointer ! __ mov(rdx, rlocals); ! __ subq(rdx, rbp); ! __ push(rdx); // set locals pointer if (native_call) { __ push(0); // no bcp } else { __ push(rbcp); // set bcp } __ push(0); // reserve word for pointer to expression stack bottom __ movptr(Address(rsp, 0), rsp); // set expression stack bottom } + void TemplateInterpreterGenerator::generate_continuation_frame(bool native_call, AbstractInterpreter::MethodKind kind) { + // rdx = no. of additional locals + // rcx = size of parameters + // rbx = Method* + // free registers: rax, + + if (kind == AbstractInterpreter::java_lang_continuation_getStack) { + // return; + } + + // total overhead size: entry_size + (saved rbp through expr stack + // bottom). be sure to change this if you add/subtract anything + // to/from the overhead area + const int entry_size = frame::interpreter_frame_monitor_size() * wordSize; + const int overhead = -(frame::interpreter_frame_initial_sp_offset * wordSize) + entry_size; + assert(overhead > 0, "overhead is 0 or negative"); + // test if we're in a continuation + Label done, done0; + Register cont = r10; + const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread); + NOT_LP64(__ get_thread(thread)); + + __ movptr(cont, Address(thread, in_bytes(JavaThread::continuation_offset()))); + __ testl(cont, cont); + __ jcc(Assembler::zero, done); + + Register array = r11, index_rsp = r13; // index_rbp = r10; (r12 is taken) + __ continuation_save_registers(cont, array, index_rsp); + + __ load_heap_oop(array, Address(cont, java_lang_Continuation::stack_offset)); + __ lea(array, Address(array, arrayOopDesc::base_offset_in_bytes(T_INT))); + + __ movptr(index_rsp, rsp); + __ subq(index_rsp, array); // now index is the offset _in bytes_ into the array + + __ cmpl(index_rsp, overhead); + __ jcc(Assembler::above, done0); // fast path + + // slow path -- call getStack to allocate a new stack for us + + // Done by continuation_exit: + __ shrq(index_rsp, 2); // now index is the (int) index into the array + + // __ movq(index_rbp, rbp); + // __ subq(index_rbp, array); + // __ shrq(index_rbp, 2); // now index is the (int) index into the array + + __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); + __ call_VM(cont, CAST_FROM_FN_PTR(address, InterpreterRuntime::get_continuation_stack), cont, index_rsp, rdx); + + __ stop("generate_continuation_frame slow 1111"); + // Done by continuation_enter: + // __ load_heap_oop(array, Address(cont, java_lang_Continuation::stack_offset)); // now array is the new array + // __ lea(rsp, Address(array, index_rsp, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_INT))); + // __ lea(rbp, Address(array, index_rbp, Address::times_4, arrayOopDesc::base_offset_in_bytes(T_INT))); + + __ bind(done0); + __ continuation_restore_registers(cont, array, index_rsp); + + __ bind(done); + } + // End of helpers + /*address TemplateInterpreterGenerator::generate_Continuation_run_entry(void) { + address entry = __ pc(); + + // CallInfo callinfo; + // Klass* recvrKlass = SystemDictionary::resolve_or_null(vmSymbols::java_lang_Continuation(), NULL); // SystemDictionary::Continuation_klass(); + // LinkInfo link_info(recvrKlass, vmSymbols::enter_name(), vmSymbols::continuationEnter_signature()); + // LinkResolver::resolve_special_call(callinfo, Handle(), link_info, NULL); + // methodHandle method = callinfo.selected_method(); + // assert(method.not_null(), "should have thrown exception"); + + const Address constMethod(rbx, Method::const_offset()); + // const Address access_flags(rbx, Method::access_flags_offset()); + + __ movptr(rdx, constMethod); + + const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset()); + // const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); + + __ load_unsigned_short(rcx, size_of_parameters); + __ subl(rdx, rdx);// rdx = 0 = no. of additional locals + + // rbx: Method* + // rcx: size of parameters + // rbcp: sender_sp (could differ from sp+wordSize if we were called via c2i ) + + // see if we've got enough room on the stack for locals plus overhead. + // generate_stack_overflow_check(); + + __ pop(rax); // get return address + + // compute beginning of parameters + __ lea(rlocals, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); + __ movptr(rax, Address(rlocals, 0)); // Address(rsp, wordSize) + + // rax: local 0 + Register recv = rax; + __ push(recv); + + Register rmethod = rbx; // Method* must be rbx for interpreter calling convention + __ movptr(rmethod, AddressLiteral((address)&java_lang_Continuation::stack_method, RelocationHolder::none), NULL); + + // load return address + //const address table_addr = (address) Interpreter::invoke_return_entry_table_for(code); + ExternalAddress table(entry); + __ movptr(rdx, table); + // push return address + __ push(rdx); // ???? AddressLiteral(__ pc(), RelocationHolder::none) + + // initialize fixed part of activation frame + // __ enter(); // remove if generate_fixed_frame + // generate_fixed_frame(false); + + // __ stop("zzzz"); + + __ jump_from_interpreted(rmethod, rax); + + + return entry; + }*/ + + + // Method entry for java.lang.Continuation.run. + address TemplateInterpreterGenerator::generate_Continuation_run_entry(void) { + address entry = __ pc(); + + const Address constMethod(rbx, Method::const_offset()); + // const Address access_flags(rbx, Method::access_flags_offset()); + + __ movptr(rdx, constMethod); + + const Address size_of_parameters(rdx, + ConstMethod::size_of_parameters_offset()); + // const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); + + __ load_unsigned_short(rcx, size_of_parameters); + __ subl(rdx, rdx);// rdx = 0 = no. of additional locals + + // rbx: Method* + // rcx: size of parameters + // rbcp: sender_sp (could differ from sp+wordSize if we were called via c2i ) + + // see if we've got enough room on the stack for locals plus overhead. + generate_stack_overflow_check(); + + // rbx: Method* + // rcx: size of parameters + // rbcp: sender sp + + __ pop(rax); // get return address + + // compute beginning of parameters + __ lea(rlocals, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); + + // add 2 zero-initialized slots for native calls + // initialize result_handler slot + __ push((int) NULL_WORD); + // slot for oop temp + // (static native method holder mirror/jni oop result) + __ push((int) NULL_WORD); + + // initialize fixed part of activation frame + generate_fixed_frame(false); + + __ movptr(rax, Address(rlocals, 0)); // Address(rsp, wordSize) + + // rax: local 0 + + // const int target_offset = java_lang_Continuation::target_offset; + // guarantee(target_offset > 0, "target offset not initialized"); + + // Load the value of the referent field. + // const Address field_address(rax, target_offset); + // __ load_heap_oop(rcx, field_address); + + // const Register thread = rcx; + // __ get_thread(thread); + // __ set_last_Java_frame(thread, noreg, noreg, NULL); + // __ reset_last_Java_frame(thread, false); + + Register rarg1 = rax; + __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::enter_continuation), rarg1); + + // __ get_thread(thread); + // __ reset_last_Java_frame(thread, false); + + __ remove_activation(vtos, rbcp); + __ jmp(rbcp); + + return entry; + } + // Method entry for java.lang.ref.Reference.get. address TemplateInterpreterGenerator::generate_Reference_get_entry(void) { #if INCLUDE_ALL_GCS // Code: _aload_0, _getfield, _areturn // parameter size = 1
*** 1036,1045 **** --- 1239,1249 ---- #ifndef _LP64 __ get_thread(thread); __ lea(t, Address(thread, JavaThread::jni_environment_offset())); __ movptr(Address(rsp, 0), t); + __ stop("LOOM XXX"); // assert not called // set_last_Java_frame_before_call // It is enough that the pc() // points into the right code segment. It does not have to be the correct return pc. __ set_last_Java_frame(thread, noreg, rbp, __ pc()); #else
*** 1317,1327 **** --- 1521,1533 ---- // remove activation __ movptr(t, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp + // __ addq(t, rbp); __ leave(); // remove frame anchor + // __ stop("k9k9k9k9"); __ pop(rdi); // get return address __ mov(rsp, t); // set sp to sender sp __ jmp(rdi); if (inc_counter) {
*** 1352,1379 **** __ should_not_reach_here(); return entry_point; } // // Generic interpreted method entry to (asm) interpreter // ! address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { // determine code generation flags bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; // ebx: Method* ! // rbcp: sender sp address entry_point = __ pc(); const Address constMethod(rbx, Method::const_offset()); const Address access_flags(rbx, Method::access_flags_offset()); const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset()); const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); - // get parameter size (always needed) __ movptr(rdx, constMethod); __ load_unsigned_short(rcx, size_of_parameters); // rbx: Method* --- 1558,1588 ---- __ should_not_reach_here(); return entry_point; } + address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) { + return generate_normal_entry(synchronized, AbstractInterpreter::zerolocals); + } + // // Generic interpreted method entry to (asm) interpreter // ! address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized, AbstractInterpreter::MethodKind kind) { // determine code generation flags bool inc_counter = UseCompiler || CountCompiledCalls || LogTouchedMethods; // ebx: Method* ! // rbcp: sender sp (set in InterpreterMacroAssembler::prepare_to_jump_from_interpreted / generate_call_stub) address entry_point = __ pc(); const Address constMethod(rbx, Method::const_offset()); const Address access_flags(rbx, Method::access_flags_offset()); const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset()); const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); // get parameter size (always needed) __ movptr(rdx, constMethod); __ load_unsigned_short(rcx, size_of_parameters); // rbx: Method*
*** 1385,1399 **** // YYY // __ incrementl(rdx); // __ andl(rdx, -2); // see if we've got enough room on the stack for locals plus overhead. generate_stack_overflow_check(); // get return address ! __ pop(rax); // compute beginning of parameters __ lea(rlocals, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); // rdx - # of additional locals --- 1594,1618 ---- // YYY // __ incrementl(rdx); // __ andl(rdx, -2); + generate_continuation_frame(false, kind); + // see if we've got enough room on the stack for locals plus overhead. generate_stack_overflow_check(); // get return address ! __ pop(rax); // saved from rax in generate_fixed_frame ! ! if (kind == AbstractInterpreter::java_lang_continuation_enter) { ! Register cont = r10; ! const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread); ! NOT_LP64(__ get_thread(thread)); ! __ movptr(cont, Address(thread, in_bytes(JavaThread::continuation_offset()))); ! __ push(cont); // ensure that the first parameter (this) is on the stack ! } // compute beginning of parameters __ lea(rlocals, Address(rsp, rcx, Interpreter::stackElementScale(), -wordSize)); // rdx - # of additional locals
*** 1411,1420 **** --- 1630,1643 ---- } // initialize fixed part of activation frame generate_fixed_frame(false); + // if (kind == AbstractInterpreter::java_lang_continuation_getStack) { + // __ stop("23232323"); + // } + // make sure method is not native & not abstract #ifdef ASSERT __ movl(rax, access_flags); { Label L;
*** 1459,1471 **** --- 1682,1701 ---- } Label continue_after_compile; __ bind(continue_after_compile); + Label no_cont; + __ movptr(r11, Address(r15_thread, in_bytes(JavaThread::continuation_offset()))); + __ testl(r11, r11); + __ jcc(Assembler::zero, no_cont); + // check for synchronized interpreted methods bang_stack_shadow_pages(false); + __ bind(no_cont); + // reset the _do_not_unlock_if_synchronized flag NOT_LP64(__ get_thread(thread)); __ movbool(do_not_unlock_if_synchronized, false); // check for synchronized methods
*** 1503,1514 **** --- 1733,1752 ---- #endif // jvmti support __ notify_method_entry(); + // if (kind == AbstractInterpreter::java_lang_continuation_getStack) { + // __ stop("78787878787"); + // } + __ dispatch_next(vtos); + if (kind == AbstractInterpreter::java_lang_continuation_getStack) { + __ stop("9090909090909"); + } + // invocation counter overflow if (inc_counter) { if (ProfileInterpreter) { // We have decided to profile this method in the interpreter __ bind(profile_method);
< prev index next >