mirror of
https://github.com/openjdk/jdk.git
synced 2026-08-03 06:35:31 +00:00
8388170: [s390x] compiler/inlining/LateInlineQueueDrainTest.java#id0 fail due to invalid ret_addr_offset
Reviewed-by: amitkumar, aph
This commit is contained in:
parent
ead9921903
commit
bb05fd9f72
@ -1662,19 +1662,19 @@ bool needs_acquiring_load_exclusive(const Node *n)
|
||||
// from the start of the call to the point where the return address
|
||||
// will point.
|
||||
|
||||
int MachCallStaticJavaNode::ret_addr_offset()
|
||||
int MachCallStaticJavaNode::ret_addr_offset() const
|
||||
{
|
||||
// call should be a simple bl
|
||||
int off = 4;
|
||||
return off;
|
||||
}
|
||||
|
||||
int MachCallDynamicJavaNode::ret_addr_offset()
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() const
|
||||
{
|
||||
return 16; // movz, movk, movk, bl
|
||||
}
|
||||
|
||||
int MachCallRuntimeNode::ret_addr_offset() {
|
||||
int MachCallRuntimeNode::ret_addr_offset() const {
|
||||
// for generated stubs the call will be
|
||||
// bl(addr)
|
||||
// or with far branches
|
||||
|
||||
@ -430,18 +430,18 @@ OptoRegPair c2::return_value(int ideal_reg) {
|
||||
// from the start of the call to the point where the return address
|
||||
// will point.
|
||||
|
||||
int MachCallStaticJavaNode::ret_addr_offset() {
|
||||
int MachCallStaticJavaNode::ret_addr_offset() const {
|
||||
bool far = (_method == nullptr) ? maybe_far_call(this) : !cache_reachable();
|
||||
return (far ? 3 : 1) * NativeInstruction::instruction_size;
|
||||
}
|
||||
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() {
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() const {
|
||||
bool far = !cache_reachable();
|
||||
// mov_oop is always 2 words
|
||||
return (2 + (far ? 3 : 1)) * NativeInstruction::instruction_size;
|
||||
}
|
||||
|
||||
int MachCallRuntimeNode::ret_addr_offset() {
|
||||
int MachCallRuntimeNode::ret_addr_offset() const {
|
||||
// bl or movw; movt; blx
|
||||
bool far = maybe_far_call(this);
|
||||
return (far ? 3 : 1) * NativeInstruction::instruction_size;
|
||||
|
||||
@ -1171,16 +1171,16 @@ bool followed_by_acquire(const Node *load) {
|
||||
|
||||
// PPC port: Removed use of lazy constant construct.
|
||||
|
||||
int MachCallStaticJavaNode::ret_addr_offset() {
|
||||
int MachCallStaticJavaNode::ret_addr_offset() const {
|
||||
// It's only a single branch-and-link instruction.
|
||||
return 4;
|
||||
}
|
||||
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() {
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() const {
|
||||
return 12;
|
||||
}
|
||||
|
||||
int MachCallRuntimeNode::ret_addr_offset() {
|
||||
int MachCallRuntimeNode::ret_addr_offset() const {
|
||||
if (rule() == CallRuntimeDirect_rule) {
|
||||
// CallRuntimeDirectNode uses call_c.
|
||||
#if defined(ABI_ELFv2)
|
||||
|
||||
@ -1208,17 +1208,17 @@ bool needs_acquiring_load_reserved(const Node *n)
|
||||
// from the start of the call to the point where the return address
|
||||
// will point.
|
||||
|
||||
int MachCallStaticJavaNode::ret_addr_offset()
|
||||
int MachCallStaticJavaNode::ret_addr_offset() const
|
||||
{
|
||||
return 3 * NativeInstruction::instruction_size; // auipc + ld + jalr
|
||||
}
|
||||
|
||||
int MachCallDynamicJavaNode::ret_addr_offset()
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() const
|
||||
{
|
||||
return NativeMovConstReg::movptr2_instruction_size + (3 * NativeInstruction::instruction_size); // movptr2, auipc + ld + jal
|
||||
}
|
||||
|
||||
int MachCallRuntimeNode::ret_addr_offset() {
|
||||
int MachCallRuntimeNode::ret_addr_offset() const {
|
||||
// For address inside the code cache the call will be:
|
||||
// auipc + jalr
|
||||
// For real runtime callouts it will be 8 instructions
|
||||
|
||||
@ -886,29 +886,59 @@ int MachNode::compute_padding(int current_offset) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MachCallStaticJavaNode::ret_addr_offset() {
|
||||
int MachCallStaticJavaNode::ret_addr_offset() const {
|
||||
if (_method) {
|
||||
return 8;
|
||||
return MacroAssembler::call_far_pcrelative_size();
|
||||
} else {
|
||||
return MacroAssembler::call_far_patchable_ret_addr_offset();
|
||||
}
|
||||
}
|
||||
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() {
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() const {
|
||||
// Consider size of receiver type profiling (C2 tiers).
|
||||
int profile_receiver_type_size = 0;
|
||||
|
||||
int vtable_index = this->_vtable_index;
|
||||
if (vtable_index == -4) {
|
||||
return 14 + profile_receiver_type_size;
|
||||
return MacroAssembler::load_const_from_toc_size()
|
||||
+ MacroAssembler::call_far_pcrelative_size();
|
||||
} else {
|
||||
assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
|
||||
return 36 + profile_receiver_type_size;
|
||||
// This should return the size of instructions in vtable dispatch
|
||||
// branch of z_enc_java_dynamic_call
|
||||
int offset = 0;
|
||||
|
||||
// __ load_klass(Z_method, Z_R2);
|
||||
if (UseCompactObjectHeaders) {
|
||||
// load_narrow_klass_compact (z_lg z_srlg)
|
||||
offset += 6 // z_lg
|
||||
+ 6; // z_srlg;
|
||||
} else {
|
||||
offset += 6; // z_llgf
|
||||
}
|
||||
offset += MacroAssembler::instr_size_for_decode_klass_not_null();
|
||||
|
||||
// check if displacement is valid, as it will generate different
|
||||
// instructions:
|
||||
int entry_offset = in_bytes(Klass::vtable_start_offset()) +
|
||||
vtable_index * vtableEntry::size_in_bytes();
|
||||
int v_off = entry_offset + in_bytes(vtableEntry::method_offset());
|
||||
if (!Displacement::is_validDisp(v_off)) {
|
||||
offset += MacroAssembler::load_const_size(); // emits iihf + iilf
|
||||
}
|
||||
// both generate z_lg
|
||||
offset += 6; // z_lg (z_method, v_off | Address(Z_method, Z_R1_scratch))
|
||||
// common footer
|
||||
offset += 6; // z_lg(Z_R1_scratch, Method::from_compiled_offset())
|
||||
offset += 2; // z_basr
|
||||
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
int MachCallRuntimeNode::ret_addr_offset() {
|
||||
return 12 + MacroAssembler::call_far_patchable_ret_addr_offset();
|
||||
int MachCallRuntimeNode::ret_addr_offset() const {
|
||||
return 6 // get_PC() (LARL)
|
||||
+ 6 // save_return_pc() (STG)
|
||||
+ MacroAssembler::call_far_patchable_ret_addr_offset();
|
||||
}
|
||||
|
||||
// Compute padding required for nodes which need alignment
|
||||
@ -994,7 +1024,6 @@ static inline void z_assert_aligned(C2_MacroAssembler *masm, int disp, Register
|
||||
int emit_call_reloc(C2_MacroAssembler *masm, intptr_t entry_point, relocInfo::relocType rtype,
|
||||
PhaseRegAlloc* ra_, bool is_native_call = false) {
|
||||
__ set_inst_mark(); // Used in z_enc_java_static_call() and emit_java_to_interp().
|
||||
address old_mark = __ inst_mark();
|
||||
unsigned int start_off = __ offset();
|
||||
|
||||
if (is_native_call) {
|
||||
@ -1024,7 +1053,6 @@ int emit_call_reloc(C2_MacroAssembler *masm, intptr_t entry_point, relocInfo::re
|
||||
|
||||
static int emit_call_reloc(C2_MacroAssembler *masm, intptr_t entry_point, RelocationHolder const& rspec) {
|
||||
__ set_inst_mark(); // Used in z_enc_java_static_call() and emit_java_to_interp().
|
||||
address old_mark = __ inst_mark();
|
||||
unsigned int start_off = __ offset();
|
||||
|
||||
relocInfo::relocType rtype = rspec.type();
|
||||
@ -2344,8 +2372,7 @@ encode %{
|
||||
// callee doesn't.
|
||||
unsigned int start_off = __ offset();
|
||||
// Compute size of "larl + stg + call_c_opt".
|
||||
const int size_of_code = 6 + 6 + MacroAssembler::call_far_patchable_size();
|
||||
__ get_PC(Z_R14, size_of_code);
|
||||
__ get_PC(Z_R14, ret_addr_offset());
|
||||
__ save_return_pc();
|
||||
assert(__ offset() - start_off == 12, "bad prelude len: %d", __ offset() - start_off);
|
||||
|
||||
@ -2356,30 +2383,28 @@ encode %{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
// Plausibility check for size_of_code assumptions.
|
||||
unsigned int actual_ret_off = __ offset();
|
||||
assert(start_off + size_of_code == actual_ret_off, "wrong return_pc");
|
||||
#endif
|
||||
assert(__ offset() - start_off == (uint)ret_addr_offset(),
|
||||
"z_enc_java_to_runtime_call return offset mismatch: emitted %d bytes, ret_addr_offset()=%d",
|
||||
__ offset() - start_off, ret_addr_offset());
|
||||
__ post_call_nop();
|
||||
%}
|
||||
|
||||
enc_class z_enc_java_static_call(method meth) %{
|
||||
unsigned int start_off = __ offset();
|
||||
// Call to fixup routine. Fixup routine uses ScopeDesc info to determine
|
||||
// whom we intended to call.
|
||||
int ret_offset = 0;
|
||||
|
||||
if (!_method) {
|
||||
ret_offset = emit_call_reloc(masm, $meth$$method,
|
||||
relocInfo::runtime_call_w_cp_type, ra_);
|
||||
emit_call_reloc(masm, $meth$$method,
|
||||
relocInfo::runtime_call_w_cp_type, ra_);
|
||||
} else {
|
||||
int method_index = resolved_method_index(masm);
|
||||
if (_optimized_virtual) {
|
||||
ret_offset = emit_call_reloc(masm, $meth$$method,
|
||||
opt_virtual_call_Relocation::spec(method_index));
|
||||
emit_call_reloc(masm, $meth$$method,
|
||||
opt_virtual_call_Relocation::spec(method_index));
|
||||
} else {
|
||||
ret_offset = emit_call_reloc(masm, $meth$$method,
|
||||
static_call_Relocation::spec(method_index));
|
||||
emit_call_reloc(masm, $meth$$method,
|
||||
static_call_Relocation::spec(method_index));
|
||||
}
|
||||
}
|
||||
assert(__ inst_mark() != nullptr, "emit_call_reloc must set_inst_mark()");
|
||||
@ -2394,6 +2419,9 @@ encode %{
|
||||
}
|
||||
|
||||
__ clear_inst_mark();
|
||||
assert(__ offset() - start_off == (uint)ret_addr_offset(),
|
||||
"z_enc_java_static_call return offset mismatch: emitted %d bytes, ret_addr_offset()=%d",
|
||||
__ offset() - start_off, ret_addr_offset());
|
||||
__ post_call_nop();
|
||||
%}
|
||||
|
||||
@ -2418,9 +2446,8 @@ encode %{
|
||||
// to determine who we intended to call.
|
||||
int method_index = resolved_method_index(masm);
|
||||
__ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr, method_index));
|
||||
unsigned int ret_off = __ offset();
|
||||
assert(__ offset() - start_off == 6, "bad prelude len: %d", __ offset() - start_off);
|
||||
ret_off += emit_call_reloc(masm, $meth$$method, relocInfo::none, ra_);
|
||||
emit_call_reloc(masm, $meth$$method, relocInfo::none, ra_);
|
||||
__ clear_inst_mark();
|
||||
assert(_method, "lazy_constant may be wrong when _method==null");
|
||||
} else {
|
||||
@ -2449,8 +2476,11 @@ encode %{
|
||||
__ z_lg(Z_R1_scratch, Address(Z_method, Method::from_compiled_offset()));
|
||||
// Call target. Either compiled code or C2I adapter.
|
||||
__ z_basr(Z_R14, Z_R1_scratch);
|
||||
unsigned int ret_off = __ offset();
|
||||
}
|
||||
assert(__ offset() - start_off == (uint)ret_addr_offset(),
|
||||
"z_enc_java_dynamic_call return offset mismatch: emitted %d bytes, ret_addr_offset()=%d",
|
||||
__ offset() - start_off, ret_addr_offset());
|
||||
|
||||
__ post_call_nop();
|
||||
%}
|
||||
|
||||
|
||||
@ -1634,21 +1634,21 @@ static int clear_avx_size() {
|
||||
// !!!!! Special hack to get all types of calls to specify the byte offset
|
||||
// from the start of the call to the point where the return address
|
||||
// will point.
|
||||
int MachCallStaticJavaNode::ret_addr_offset()
|
||||
int MachCallStaticJavaNode::ret_addr_offset() const
|
||||
{
|
||||
int offset = 5; // 5 bytes from start of call to where return address points
|
||||
offset += clear_avx_size();
|
||||
return offset;
|
||||
}
|
||||
|
||||
int MachCallDynamicJavaNode::ret_addr_offset()
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() const
|
||||
{
|
||||
int offset = 15; // 15 bytes from start of call to where return address points
|
||||
offset += clear_avx_size();
|
||||
return offset;
|
||||
}
|
||||
|
||||
int MachCallRuntimeNode::ret_addr_offset() {
|
||||
int MachCallRuntimeNode::ret_addr_offset() const {
|
||||
int offset = 13; // movq r10,#addr; callq (r10)
|
||||
if (this->ideal_Opcode() != Op_CallLeafVector) {
|
||||
offset += clear_avx_size();
|
||||
|
||||
@ -937,7 +937,7 @@ public:
|
||||
virtual bool pinned() const { return false; }
|
||||
virtual const Type* Value(PhaseGVN* phase) const;
|
||||
virtual const RegMask &in_RegMask(uint) const;
|
||||
virtual int ret_addr_offset() { return 0; }
|
||||
virtual int ret_addr_offset() const { return 0; }
|
||||
|
||||
NOT_LP64(bool return_value_is_used() const;)
|
||||
|
||||
@ -998,7 +998,7 @@ public:
|
||||
// If this is an uncommon trap, return the request code, else zero.
|
||||
int uncommon_trap_request() const;
|
||||
|
||||
virtual int ret_addr_offset();
|
||||
virtual int ret_addr_offset() const;
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
void dump_trap_args(outputStream *st) const;
|
||||
@ -1014,7 +1014,7 @@ public:
|
||||
init_class_id(Class_MachCallDynamicJava);
|
||||
DEBUG_ONLY(_vtable_index = -99); // throw an assert if uninitialized
|
||||
}
|
||||
virtual int ret_addr_offset();
|
||||
virtual int ret_addr_offset() const;
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
#endif
|
||||
@ -1032,7 +1032,7 @@ public:
|
||||
MachCallRuntimeNode() : MachCallNode() {
|
||||
init_class_id(Class_MachCallRuntime);
|
||||
}
|
||||
virtual int ret_addr_offset();
|
||||
virtual int ret_addr_offset() const;
|
||||
#ifndef PRODUCT
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user