Skip to content
Permalink
Browse files
8260369: [PPC64] Add support for JDK-8200555
Reviewed-by: lucy
  • Loading branch information
TheRealMDoerr committed Feb 5, 2021
1 parent 224c166 commit 48f5220c8018f9c166df8d49ce1eb2070695d961
@@ -77,7 +77,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
Register tmp1, Register tmp2, Register tmp3, Label &ok_is_subtype);

// Load object from cpool->resolved_references(index).
void load_resolved_reference_at_index(Register result, Register index, Register tmp1, Label *L_handle_null = NULL);
void load_resolved_reference_at_index(Register result, Register index, Register tmp1, Register tmp2,
Label *L_handle_null = NULL);

// load cpool->resolved_klass_at(index)
void load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass);
@@ -477,33 +477,34 @@ void InterpreterMacroAssembler::get_u4(Register Rdst, Register Rsrc, int offset,
// Load object from cpool->resolved_references(index).
// Kills:
// - index
void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index, Register tmp1,
void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index,
Register tmp1, Register tmp2,
Label *L_handle_null) {
assert_different_registers(result, index);
assert_different_registers(result, index, tmp1, tmp2);
assert(index->is_nonvolatile(), "needs to survive C-call in resolve_oop_handle");
get_constant_pool(result);

// Convert from field index to resolved_references() index and from
// word index to byte offset. Since this is a java object, it can be compressed.
Register tmp2 = index; // reuse
sldi(tmp1, index, LogBytesPerHeapOop);
sldi(index, index, LogBytesPerHeapOop);
// Load pointer for resolved_references[] objArray.
ld(result, ConstantPool::cache_offset_in_bytes(), result);
ld(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
resolve_oop_handle(result);
resolve_oop_handle(result, tmp1, tmp2, MacroAssembler::PRESERVATION_NONE);
#ifdef ASSERT
Label index_ok;
lwa(R0, arrayOopDesc::length_offset_in_bytes(), result);
sldi(R0, R0, LogBytesPerHeapOop);
cmpd(CCR0, tmp1, R0);
cmpd(CCR0, index, R0);
blt(CCR0, index_ok);
stop("resolved reference index out of bounds");
bind(index_ok);
#endif
// Add in the index.
add(result, tmp1, result);
add(result, index, result);
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result,
tmp1, tmp2,
MacroAssembler::PRESERVATION_FRAME_LR,
MacroAssembler::PRESERVATION_NONE,
0, L_handle_null);
}

@@ -3233,16 +3233,22 @@ void MacroAssembler::load_klass(Register dst, Register src) {
}

// ((OopHandle)result).resolve();
void MacroAssembler::resolve_oop_handle(Register result) {
// OopHandle::resolve is an indirection.
ld(result, 0, result);
void MacroAssembler::resolve_oop_handle(Register result, Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level) {
access_load_at(T_OBJECT, IN_NATIVE, result, noreg, result, tmp1, tmp2, preservation_level);
}

void MacroAssembler::load_mirror_from_const_method(Register mirror, Register const_method) {
ld(mirror, in_bytes(ConstMethod::constants_offset()), const_method);
ld(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
ld(mirror, in_bytes(Klass::java_mirror_offset()), mirror);
resolve_oop_handle(mirror);
void MacroAssembler::resolve_weak_handle(Register result, Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level) {
Label resolved;

// A null weak handle resolves to null.
cmpdi(CCR0, result, 0);
beq(CCR0, resolved);

access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF, result, noreg, result, tmp1, tmp2,
preservation_level);
bind(resolved);
}

void MacroAssembler::load_method_holder(Register holder, Register method) {
@@ -743,8 +743,10 @@ class MacroAssembler: public Assembler {
void store_klass(Register dst_oop, Register klass, Register tmp = R0);
void store_klass_gap(Register dst_oop, Register val = noreg); // Will store 0 if val not specified.

void resolve_oop_handle(Register result);
void load_mirror_from_const_method(Register mirror, Register const_method);
void resolve_oop_handle(Register result, Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level);
void resolve_weak_handle(Register result, Register tmp1, Register tmp2,
MacroAssembler::PreservationLevel preservation_level);
void load_method_holder(Register holder, Register method);

static int instr_size_for_decode_klass_not_null();
@@ -933,11 +933,14 @@ void TemplateInterpreterGenerator::lock_method(Register Rflags, Register Rscratc
// state_size: We save the current state of the interpreter to this area.
//
void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Register Rsize_of_parameters, Register Rsize_of_locals) {
Register parent_frame_resize = R6_ARG4, // Frame will grow by this number of bytes.
top_frame_size = R7_ARG5,
Rconst_method = R8_ARG6;
Register Rparent_frame_resize = R6_ARG4, // Frame will grow by this number of bytes.
Rtop_frame_size = R7_ARG5,
Rconst_method = R8_ARG6,
Rconst_pool = R9_ARG7,
Rmirror = R10_ARG8;

assert_different_registers(Rsize_of_parameters, Rsize_of_locals, parent_frame_resize, top_frame_size);
assert_different_registers(Rsize_of_parameters, Rsize_of_locals, Rparent_frame_resize, Rtop_frame_size,
Rconst_method, Rconst_pool);

__ ld(Rconst_method, method_(const));
__ lhz(Rsize_of_parameters /* number of params */,
@@ -948,51 +951,51 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
// We add two slots to the parameter_count, one for the jni
// environment and one for a possible native mirror.
Label skip_native_calculate_max_stack;
__ addi(top_frame_size, Rsize_of_parameters, 2);
__ cmpwi(CCR0, top_frame_size, Argument::n_register_parameters);
__ addi(Rtop_frame_size, Rsize_of_parameters, 2);
__ cmpwi(CCR0, Rtop_frame_size, Argument::n_register_parameters);
__ bge(CCR0, skip_native_calculate_max_stack);
__ li(top_frame_size, Argument::n_register_parameters);
__ li(Rtop_frame_size, Argument::n_register_parameters);
__ bind(skip_native_calculate_max_stack);
__ sldi(Rsize_of_parameters, Rsize_of_parameters, Interpreter::logStackElementSize);
__ sldi(top_frame_size, top_frame_size, Interpreter::logStackElementSize);
__ sub(parent_frame_resize, R1_SP, R15_esp); // <0, off by Interpreter::stackElementSize!
__ sldi(Rtop_frame_size, Rtop_frame_size, Interpreter::logStackElementSize);
__ sub(Rparent_frame_resize, R1_SP, R15_esp); // <0, off by Interpreter::stackElementSize!
assert(Rsize_of_locals == noreg, "Rsize_of_locals not initialized"); // Only relevant value is Rsize_of_parameters.
} else {
__ lhz(Rsize_of_locals /* number of params */, in_bytes(ConstMethod::size_of_locals_offset()), Rconst_method);
__ sldi(Rsize_of_parameters, Rsize_of_parameters, Interpreter::logStackElementSize);
__ sldi(Rsize_of_locals, Rsize_of_locals, Interpreter::logStackElementSize);
__ lhz(top_frame_size, in_bytes(ConstMethod::max_stack_offset()), Rconst_method);
__ lhz(Rtop_frame_size, in_bytes(ConstMethod::max_stack_offset()), Rconst_method);
__ sub(R11_scratch1, Rsize_of_locals, Rsize_of_parameters); // >=0
__ sub(parent_frame_resize, R1_SP, R15_esp); // <0, off by Interpreter::stackElementSize!
__ sldi(top_frame_size, top_frame_size, Interpreter::logStackElementSize);
__ add(parent_frame_resize, parent_frame_resize, R11_scratch1);
__ sub(Rparent_frame_resize, R1_SP, R15_esp); // <0, off by Interpreter::stackElementSize!
__ sldi(Rtop_frame_size, Rtop_frame_size, Interpreter::logStackElementSize);
__ add(Rparent_frame_resize, Rparent_frame_resize, R11_scratch1);
}

// Compute top frame size.
__ addi(top_frame_size, top_frame_size, frame::abi_reg_args_size + frame::ijava_state_size);
__ addi(Rtop_frame_size, Rtop_frame_size, frame::abi_reg_args_size + frame::ijava_state_size);

// Cut back area between esp and max_stack.
__ addi(parent_frame_resize, parent_frame_resize, frame::abi_minframe_size - Interpreter::stackElementSize);
__ addi(Rparent_frame_resize, Rparent_frame_resize, frame::abi_minframe_size - Interpreter::stackElementSize);

__ round_to(top_frame_size, frame::alignment_in_bytes);
__ round_to(parent_frame_resize, frame::alignment_in_bytes);
// parent_frame_resize = (locals-parameters) - (ESP-SP-ABI48) Rounded to frame alignment size.
__ round_to(Rtop_frame_size, frame::alignment_in_bytes);
__ round_to(Rparent_frame_resize, frame::alignment_in_bytes);
// Rparent_frame_resize = (locals-parameters) - (ESP-SP-ABI48) Rounded to frame alignment size.
// Enlarge by locals-parameters (not in case of native_call), shrink by ESP-SP-ABI48.

if (!native_call) {
// Stack overflow check.
// Native calls don't need the stack size check since they have no
// expression stack and the arguments are already on the stack and
// we only add a handful of words to the stack.
__ add(R11_scratch1, parent_frame_resize, top_frame_size);
__ add(R11_scratch1, Rparent_frame_resize, Rtop_frame_size);
generate_stack_overflow_check(R11_scratch1, R12_scratch2);
}

// Set up interpreter state registers.

__ add(R18_locals, R15_esp, Rsize_of_parameters);
__ ld(R27_constPoolCache, in_bytes(ConstMethod::constants_offset()), Rconst_method);
__ ld(R27_constPoolCache, ConstantPool::cache_offset_in_bytes(), R27_constPoolCache);
__ ld(Rconst_pool, in_bytes(ConstMethod::constants_offset()), Rconst_method);
__ ld(R27_constPoolCache, ConstantPool::cache_offset_in_bytes(), Rconst_pool);

// Set method data pointer.
if (ProfileInterpreter) {
@@ -1012,19 +1015,21 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist

// Resize parent frame.
__ mflr(R12_scratch2);
__ neg(parent_frame_resize, parent_frame_resize);
__ resize_frame(parent_frame_resize, R11_scratch1);
__ neg(Rparent_frame_resize, Rparent_frame_resize);
__ resize_frame(Rparent_frame_resize, R11_scratch1);
__ std(R12_scratch2, _abi0(lr), R1_SP);

// Get mirror and store it in the frame as GC root for this Method*.
__ load_mirror_from_const_method(R12_scratch2, Rconst_method);
__ ld(Rmirror, ConstantPool::pool_holder_offset_in_bytes(), Rconst_pool);
__ ld(Rmirror, in_bytes(Klass::java_mirror_offset()), Rmirror);
__ resolve_oop_handle(Rmirror, R11_scratch1, R12_scratch2, MacroAssembler::PRESERVATION_FRAME_LR_GP_REGS);

__ addi(R26_monitor, R1_SP, -frame::ijava_state_size);
__ addi(R15_esp, R26_monitor, -Interpreter::stackElementSize);

// Store values.
__ std(R19_method, _ijava_state_neg(method), R1_SP);
__ std(R12_scratch2, _ijava_state_neg(mirror), R1_SP);
__ std(Rmirror, _ijava_state_neg(mirror), R1_SP);
__ std(R18_locals, _ijava_state_neg(locals), R1_SP);
__ std(R27_constPoolCache, _ijava_state_neg(cpoolCache), R1_SP);

@@ -1046,12 +1051,12 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
__ std(R0, _ijava_state_neg(oop_tmp), R1_SP); // only used for native_call

// Store sender's SP and this frame's top SP.
__ subf(R12_scratch2, top_frame_size, R1_SP);
__ subf(R12_scratch2, Rtop_frame_size, R1_SP);
__ std(R21_sender_SP, _ijava_state_neg(sender_sp), R1_SP);
__ std(R12_scratch2, _ijava_state_neg(top_frame_sp), R1_SP);

// Push top frame.
__ push_frame(top_frame_size, R11_scratch1);
__ push_frame(Rtop_frame_size, R11_scratch1);
}

// End of helpers
@@ -26,7 +26,8 @@
#ifndef CPU_PPC_TEMPLATETABLE_PPC_HPP
#define CPU_PPC_TEMPLATETABLE_PPC_HPP

static void prepare_invoke(int byte_no, Register Rmethod, Register Rret_addr, Register Rindex, Register Rrecv, Register Rflags, Register Rscratch);
static void prepare_invoke(int byte_no, Register Rmethod, Register Rret_addr, Register Rindex, Register Rrecv, Register Rflags,
Register Rscratch1, Register Rscratch2);
static void invokevfinal_helper(Register Rmethod, Register Rflags, Register Rscratch1, Register Rscratch2);
static void generate_vtable_call(Register Rrecv_klass, Register Rindex, Register Rret, Register Rtemp);
static void invokeinterface_object_method(Register Rrecv_klass, Register Rret, Register Rflags, Register Rindex, Register Rtemp, Register Rtemp2);
Loading

0 comments on commit 48f5220

Please sign in to comment.