mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-13 15:09:39 +00:00
8321515: ARM32: Move method resolution information out of the cpCache properly
Reviewed-by: shade
This commit is contained in:
parent
8a0a6f8c25
commit
f573f6d233
@ -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<ResolvedMethodEntry>::base_offset_in_bytes());
|
||||
add(cache, cache, index);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user