diff --git a/src/hotspot/cpu/arm/interp_masm_arm.cpp b/src/hotspot/cpu/arm/interp_masm_arm.cpp index 481c3d09e58..635acd781f9 100644 --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp @@ -303,15 +303,19 @@ void InterpreterMacroAssembler::load_field_entry(Register cache, Register index, } void InterpreterMacroAssembler::load_method_entry(Register cache, Register index, int bcp_offset) { + assert_different_registers(cache, index); + // Get index out of bytecode pointer get_index_at_bcp(index, bcp_offset, cache /* as tmp */, sizeof(u2)); + + // sizeof(ResolvedMethodEntry) is not a power of 2 on Arm, so can't use shift mov(cache, sizeof(ResolvedMethodEntry)); mul(index, index, cache); // Scale the index to be the entry index * sizeof(ResolvedMethodEntry) // load constant pool cache pointer ldr(cache, Address(FP, frame::interpreter_frame_cache_offset * wordSize)); // Get address of method entries array - ldr(cache, Address(cache, ConstantPoolCache::method_entries_offset())); + ldr(cache, Address(cache, in_bytes(ConstantPoolCache::method_entries_offset()))); add(cache, cache, Array::base_offset_in_bytes()); add(cache, cache, index); } diff --git a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp index ba9a3fd7a9b..efaf78ee568 100644 --- a/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp @@ -370,17 +370,16 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, if (index_size == sizeof(u4)) { __ load_resolved_indy_entry(Rcache, Rindex); __ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedIndyEntry::num_parameters_offset()))); - __ check_stack_top(); - __ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize)); } else { // Pop N words from the stack assert(index_size == sizeof(u2), "Can only be u2"); __ load_method_entry(Rcache, Rindex); - __ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedIndyEntry::num_parameters_offset()))); - __ check_stack_top(); - __ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize)); + __ ldrh(Rcache, Address(Rcache, in_bytes(ResolvedMethodEntry::num_parameters_offset()))); } + __ check_stack_top(); + __ add(Rstack_top, Rstack_top, AsmOperand(Rcache, lsl, Interpreter::logStackElementSize)); + __ convert_retval_to_tos(state); __ check_and_handle_popframe(); diff --git a/src/hotspot/cpu/arm/templateTable_arm.cpp b/src/hotspot/cpu/arm/templateTable_arm.cpp index e478f08c977..55a0120e7c7 100644 --- a/src/hotspot/cpu/arm/templateTable_arm.cpp +++ b/src/hotspot/cpu/arm/templateTable_arm.cpp @@ -3666,15 +3666,15 @@ void TemplateTable::prepare_invoke(Register Rcache, Register recv) { // load receiver if needed (after extra argument is pushed so parameter size is correct) if (load_receiver) { __ ldrh(recv, Address(Rcache, in_bytes(ResolvedMethodEntry::num_parameters_offset()))); - Address recv_addr = __ receiver_argument_address(Rstack_top, Rtemp, recv); - __ ldr(recv, recv_addr); + __ add(recv, Rstack_top, AsmOperand(recv, lsl, Interpreter::logStackElementSize)); + __ ldr(recv, Address(recv, -Interpreter::stackElementSize)); __ verify_oop(recv); } // load return address { const address table = (address) Interpreter::invoke_return_entry_table_for(code); - __ mov_slow(Rtemp, table); - __ ldr(LR, Address::indexed_ptr(Rtemp, ret_type)); + __ mov_slow(LR, table); + __ ldr(LR, Address::indexed_ptr(LR, ret_type)); } } @@ -3744,10 +3744,13 @@ void TemplateTable::invokevirtual(int byte_no) { void TemplateTable::invokespecial(int byte_no) { transition(vtos, vtos); assert(byte_no == f1_byte, "use this argument"); + const Register Rrecv = R2_tmp; - load_resolved_method_entry_special_or_static(R2_tmp, // ResolvedMethodEntry* + const Register Rflags = R3_tmp; + + load_resolved_method_entry_special_or_static(Rrecv, // ResolvedMethodEntry* Rmethod, // Method* - R3_tmp); // Flags + Rflags); // Flags prepare_invoke(Rrecv, Rrecv); __ verify_oop(Rrecv); __ null_check(Rrecv, Rtemp); @@ -3760,12 +3763,16 @@ void TemplateTable::invokespecial(int byte_no) { void TemplateTable::invokestatic(int byte_no) { transition(vtos, vtos); assert(byte_no == f1_byte, "use this argument"); - load_resolved_method_entry_special_or_static(R2_tmp, // ResolvedMethodEntry* + + const Register Rrecv = R2_tmp; + const Register Rflags = R3_tmp; + + load_resolved_method_entry_special_or_static(Rrecv, // ResolvedMethodEntry* Rmethod, // Method* - R3_tmp); // Flags - prepare_invoke(R2_tmp, R2_tmp); + Rflags); // Flags + prepare_invoke(Rrecv, Rrecv); // do the call - __ profile_call(R2_tmp); + __ profile_call(Rrecv); __ jump_from_interpreted(Rmethod); } @@ -3788,10 +3795,10 @@ void TemplateTable::invokeinterface(int byte_no) { const Register Rflags = R3_tmp; const Register Rklass = R2_tmp; // Note! Same register with Rrecv - load_resolved_method_entry_interface(R2_tmp, // ResolvedMethodEntry* - R1_tmp, // Klass* + load_resolved_method_entry_interface(Rrecv, // ResolvedMethodEntry* + Rinterf, // Klass* Rmethod, // Method* or itable/vtable index - R3_tmp); // Flags + Rflags); // Flags prepare_invoke(Rrecv, Rrecv); // First check for Object case, then private interface method,