src/cpu/x86/vm/templateTable_x86_64.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6829192 Cdiff src/cpu/x86/vm/templateTable_x86_64.cpp

src/cpu/x86/vm/templateTable_x86_64.cpp

Print this page
rev 1022 : 6829192: JSR 292 needs to support 64-bit x86
Summary: changes for method handles and invokedynamic
Reviewed-by: ?, ?

*** 201,222 **** __ movzbl(scratch, at_bcp(0)); __ cmpl(scratch, Bytecodes::_breakpoint); __ jcc(Assembler::notEqual, fast_patch); __ get_method(scratch); // Let breakpoint table handling rewrite to quicker bytecode ! __ call_VM(noreg, ! CAST_FROM_FN_PTR(address, ! InterpreterRuntime::set_original_bytecode_at), ! scratch, r13, bc); #ifndef ASSERT __ jmpb(patch_done); - __ bind(fast_patch); - } #else __ jmp(patch_done); __ bind(fast_patch); } Label okay; __ load_unsigned_byte(scratch, at_bcp(0)); __ cmpl(scratch, (int) Bytecodes::java_code(bytecode)); __ jcc(Assembler::equal, okay); __ cmpl(scratch, bc); --- 201,219 ---- __ movzbl(scratch, at_bcp(0)); __ cmpl(scratch, Bytecodes::_breakpoint); __ jcc(Assembler::notEqual, fast_patch); __ get_method(scratch); // Let breakpoint table handling rewrite to quicker bytecode ! __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, r13, bc); #ifndef ASSERT __ jmpb(patch_done); #else __ jmp(patch_done); + #endif __ bind(fast_patch); } + #ifdef ASSERT Label okay; __ load_unsigned_byte(scratch, at_bcp(0)); __ cmpl(scratch, (int) Bytecodes::java_code(bytecode)); __ jcc(Assembler::equal, okay); __ cmpl(scratch, bc);
*** 2052,2081 **** if (os::is_MP()) { // Not needed on single CPU __ membar(order_constraint); } } ! void TemplateTable::resolve_cache_and_index(int byte_no, ! Register Rcache, ! Register index) { assert(byte_no == 1 || byte_no == 2, "byte_no out of range"); const Register temp = rbx; assert_different_registers(Rcache, index, temp); const int shift_count = (1 + byte_no) * BitsPerByte; Label resolved; ! __ get_cache_and_index_at_bcp(Rcache, index, 1); ! __ movl(temp, Address(Rcache, ! index, Address::times_8, ! constantPoolCacheOopDesc::base_offset() + ! ConstantPoolCacheEntry::indices_offset())); __ shrl(temp, shift_count); // have we resolved this bytecode? __ andl(temp, 0xFF); __ cmpl(temp, (int) bytecode()); __ jcc(Assembler::equal, resolved); // resolve first time through address entry; switch (bytecode()) { case Bytecodes::_getstatic: --- 2049,2080 ---- if (os::is_MP()) { // Not needed on single CPU __ membar(order_constraint); } } ! void TemplateTable::resolve_cache_and_index(int byte_no, Register Rcache, Register index) { assert(byte_no == 1 || byte_no == 2, "byte_no out of range"); + bool is_invokedynamic = (bytecode() == Bytecodes::_invokedynamic); const Register temp = rbx; assert_different_registers(Rcache, index, temp); const int shift_count = (1 + byte_no) * BitsPerByte; Label resolved; ! __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic); ! if (is_invokedynamic) { ! // we are resolved if the f1 field contains a non-null CallSite object ! __ cmpptr(Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()), (int32_t) NULL_WORD); ! __ jcc(Assembler::notEqual, resolved); ! } else { ! __ movl(temp, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); __ shrl(temp, shift_count); // have we resolved this bytecode? __ andl(temp, 0xFF); __ cmpl(temp, (int) bytecode()); __ jcc(Assembler::equal, resolved); + } // resolve first time through address entry; switch (bytecode()) { case Bytecodes::_getstatic:
*** 2088,2106 **** case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break; default: ShouldNotReachHere(); break; } __ movl(temp, (int) bytecode()); __ call_VM(noreg, entry, temp); // Update registers with resolved info ! __ get_cache_and_index_at_bcp(Rcache, index, 1); __ bind(resolved); } // The Rcache and index registers must be set before call void TemplateTable::load_field_cp_cache_entry(Register obj, --- 2087,2108 ---- case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke); break; + case Bytecodes::_invokedynamic: + entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); + break; default: ShouldNotReachHere(); break; } __ movl(temp, (int) bytecode()); __ call_VM(noreg, entry, temp); // Update registers with resolved info ! __ get_cache_and_index_at_bcp(Rcache, index, 1, is_invokedynamic); __ bind(resolved); } // The Rcache and index registers must be set before call void TemplateTable::load_field_cp_cache_entry(Register obj,
*** 2830,2848 **** void TemplateTable::count_calls(Register method, Register temp) { // implemented elsewhere ShouldNotReachHere(); } ! void TemplateTable::prepare_invoke(Register method, ! Register index, ! int byte_no, ! Bytecodes::Code code) { // determine flags const bool is_invokeinterface = code == Bytecodes::_invokeinterface; const bool is_invokevirtual = code == Bytecodes::_invokevirtual; const bool is_invokespecial = code == Bytecodes::_invokespecial; ! const bool load_receiver = code != Bytecodes::_invokestatic; const bool receiver_null_check = is_invokespecial; const bool save_flags = is_invokeinterface || is_invokevirtual; // setup registers & access constant pool cache const Register recv = rcx; const Register flags = rdx; --- 2832,2849 ---- void TemplateTable::count_calls(Register method, Register temp) { // implemented elsewhere ShouldNotReachHere(); } ! void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) { // determine flags + Bytecodes::Code code = bytecode(); const bool is_invokeinterface = code == Bytecodes::_invokeinterface; + const bool is_invokedynamic = code == Bytecodes::_invokedynamic; const bool is_invokevirtual = code == Bytecodes::_invokevirtual; const bool is_invokespecial = code == Bytecodes::_invokespecial; ! const bool load_receiver = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic); const bool receiver_null_check = is_invokespecial; const bool save_flags = is_invokeinterface || is_invokevirtual; // setup registers & access constant pool cache const Register recv = rcx; const Register flags = rdx;
*** 2856,2869 **** // load receiver if needed (note: no return address pushed yet) if (load_receiver) { __ movl(recv, flags); __ andl(recv, 0xFF); if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 ! __ movptr(recv, Address(rsp, recv, Address::times_8, ! -Interpreter::expr_offset_in_bytes(1))); __ verify_oop(recv); } // do null check if needed if (receiver_null_check) { __ null_check(recv); } --- 2857,2874 ---- // load receiver if needed (note: no return address pushed yet) if (load_receiver) { __ movl(recv, flags); __ andl(recv, 0xFF); if (TaggedStackInterpreter) __ shll(recv, 1); // index*2 ! Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1)); ! if (is_invokedynamic) { ! __ lea(recv, recv_addr); ! } else { ! __ movptr(recv, recv_addr); __ verify_oop(recv); } + } // do null check if needed if (receiver_null_check) { __ null_check(recv); }
*** 2876,2889 **** __ shrl(flags, ConstantPoolCacheEntry::tosBits); // Make sure we don't need to mask flags for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); // load return address { ! ExternalAddress return_5((address)Interpreter::return_5_addrs_by_index_table()); ! ExternalAddress return_3((address)Interpreter::return_3_addrs_by_index_table()); ! __ lea(rscratch1, (is_invokeinterface ? return_5 : return_3)); ! __ movptr(flags, Address(rscratch1, flags, Address::times_8)); } // push return address __ push(flags); --- 2881,2898 ---- __ shrl(flags, ConstantPoolCacheEntry::tosBits); // Make sure we don't need to mask flags for tosBits after the above shift ConstantPoolCacheEntry::verify_tosBits(); // load return address { ! address table_addr; ! if (is_invokeinterface || is_invokedynamic) ! table_addr = (address)Interpreter::return_5_addrs_by_index_table(); ! else ! table_addr = (address)Interpreter::return_3_addrs_by_index_table(); ! ExternalAddress table(table_addr); ! __ lea(rscratch1, table); ! __ movptr(flags, Address(rscratch1, flags, Address::times_ptr)); } // push return address __ push(flags);
*** 2945,2955 **** } void TemplateTable::invokevirtual(int byte_no) { transition(vtos, vtos); ! prepare_invoke(rbx, noreg, byte_no, bytecode()); // rbx: index // rcx: receiver // rdx: flags --- 2954,2964 ---- } void TemplateTable::invokevirtual(int byte_no) { transition(vtos, vtos); ! prepare_invoke(rbx, noreg, byte_no); // rbx: index // rcx: receiver // rdx: flags
*** 2957,2977 **** } void TemplateTable::invokespecial(int byte_no) { transition(vtos, vtos); ! prepare_invoke(rbx, noreg, byte_no, bytecode()); // do the call __ verify_oop(rbx); __ profile_call(rax); __ jump_from_interpreted(rbx, rax); } void TemplateTable::invokestatic(int byte_no) { transition(vtos, vtos); ! prepare_invoke(rbx, noreg, byte_no, bytecode()); // do the call __ verify_oop(rbx); __ profile_call(rax); __ jump_from_interpreted(rbx, rax); } --- 2966,2986 ---- } void TemplateTable::invokespecial(int byte_no) { transition(vtos, vtos); ! prepare_invoke(rbx, noreg, byte_no); // do the call __ verify_oop(rbx); __ profile_call(rax); __ jump_from_interpreted(rbx, rax); } void TemplateTable::invokestatic(int byte_no) { transition(vtos, vtos); ! prepare_invoke(rbx, noreg, byte_no); // do the call __ verify_oop(rbx); __ profile_call(rax); __ jump_from_interpreted(rbx, rax); }
*** 2981,2991 **** __ stop("fast_invokevfinal not used on amd64"); } void TemplateTable::invokeinterface(int byte_no) { transition(vtos, vtos); ! prepare_invoke(rax, rbx, byte_no, bytecode()); // rax: Interface // rbx: index // rcx: receiver // rdx: flags --- 2990,3000 ---- __ stop("fast_invokevfinal not used on amd64"); } void TemplateTable::invokeinterface(int byte_no) { transition(vtos, vtos); ! prepare_invoke(rax, rbx, byte_no); // rax: Interface // rbx: index // rcx: receiver // rdx: flags
*** 3070,3080 **** // the call_VM checks for exception, so we should never return here. __ should_not_reach_here(); return; } ! __ stop("invokedynamic NYI");//6815692// } //----------------------------------------------------------------------------- // Allocation --- 3079,3106 ---- // the call_VM checks for exception, so we should never return here. __ should_not_reach_here(); return; } ! prepare_invoke(rax, rbx, byte_no); ! ! // rax: CallSite object (f1) ! // rbx: unused (f2) ! // rcx: receiver address ! // rdx: flags (unused) ! ! if (ProfileInterpreter) { ! Label L; ! // %%% should make a type profile for any invokedynamic that takes a ref argument ! // profile this call ! __ profile_call(r13); ! } ! ! __ movptr(rcx, Address(rax, __ delayed_value(java_dyn_CallSite::target_offset_in_bytes, rcx))); ! __ null_check(rcx); ! __ prepare_to_jump_from_interpreted(); ! __ jump_to_method_handle_entry(rcx, rdx); } //----------------------------------------------------------------------------- // Allocation
src/cpu/x86/vm/templateTable_x86_64.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File