8202713: Create a MacroAssembler::access_load/store_at wrapper for S390 and PPC
Reviewed-by: eosterlund, goetz
--- a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.cpp Thu May 17 14:19:54 2018 +0200
@@ -304,15 +304,15 @@
void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register base, RegisterOrConstant ind_or_offs, Register dst,
- Register tmp1, Register tmp2, bool needs_frame, Label *is_null) {
+ Register tmp1, Register tmp2, bool needs_frame, Label *L_handle_null) {
bool on_oop = type == T_OBJECT || type == T_ARRAY;
bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
bool on_reference = on_weak || on_phantom;
Label done;
- if (on_oop && on_reference && is_null == NULL) { is_null = &done; }
+ if (on_oop && on_reference && L_handle_null == NULL) { L_handle_null = &done; }
// Load the value of the referent field.
- ModRefBarrierSetAssembler::load_at(masm, decorators, type, base, ind_or_offs, dst, tmp1, tmp2, needs_frame, is_null);
+ ModRefBarrierSetAssembler::load_at(masm, decorators, type, base, ind_or_offs, dst, tmp1, tmp2, needs_frame, L_handle_null);
if (on_oop && on_reference) {
// Generate the G1 pre-barrier code to log the value of
// the referent field in an SATB buffer. Note with
--- a/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.hpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/gc/g1/g1BarrierSetAssembler_ppc.hpp Thu May 17 14:19:54 2018 +0200
@@ -61,7 +61,7 @@
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register base, RegisterOrConstant ind_or_offs, Register dst,
- Register tmp1, Register tmp2, bool needs_frame, Label *is_null = NULL);
+ Register tmp1, Register tmp2, bool needs_frame, Label *L_handle_null = NULL);
virtual void resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2, bool needs_frame);
};
--- a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.cpp Thu May 17 14:19:54 2018 +0200
@@ -65,9 +65,10 @@
void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register base, RegisterOrConstant ind_or_offs, Register dst,
- Register tmp1, Register tmp2, bool needs_frame, Label *is_null) {
- bool on_heap = (decorators & IN_HEAP) != 0;
- bool on_root = (decorators & IN_ROOT) != 0;
+ Register tmp1, Register tmp2, bool needs_frame, Label *L_handle_null) {
+ bool on_heap = (decorators & IN_HEAP) != 0;
+ bool on_root = (decorators & IN_ROOT) != 0;
+ bool not_null = (decorators & OOP_NOT_NULL) != 0;
assert(on_heap || on_root, "where?");
assert_different_registers(ind_or_offs.register_or_noreg(), dst, R0);
@@ -75,19 +76,24 @@
case T_ARRAY:
case T_OBJECT: {
if (UseCompressedOops && on_heap) {
- __ lwz(dst, ind_or_offs, base);
- if (is_null) {
+ if (L_handle_null != NULL) { // Label provided.
+ __ lwz(dst, ind_or_offs, base);
__ cmpwi(CCR0, dst, 0);
- __ beq(CCR0, *is_null);
+ __ beq(CCR0, *L_handle_null);
__ decode_heap_oop_not_null(dst);
- } else {
+ } else if (not_null) { // Guaranteed to be not null.
+ Register narrowOop = (tmp1 != noreg && Universe::narrow_oop_base_disjoint()) ? tmp1 : dst;
+ __ lwz(narrowOop, ind_or_offs, base);
+ __ decode_heap_oop_not_null(dst, narrowOop);
+ } else { // Any oop.
+ __ lwz(dst, ind_or_offs, base);
__ decode_heap_oop(dst);
}
} else {
__ ld(dst, ind_or_offs, base);
- if (is_null) {
+ if (L_handle_null != NULL) {
__ cmpdi(CCR0, dst, 0);
- __ beq(CCR0, *is_null);
+ __ beq(CCR0, *L_handle_null);
}
}
break;
--- a/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.hpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/gc/shared/barrierSetAssembler_ppc.hpp Thu May 17 14:19:54 2018 +0200
@@ -45,7 +45,7 @@
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register base, RegisterOrConstant ind_or_offs, Register dst,
- Register tmp1, Register tmp2, bool needs_frame, Label *is_null = NULL);
+ Register tmp1, Register tmp2, bool needs_frame, Label *L_handle_null = NULL);
virtual void resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2, bool needs_frame);
--- a/src/hotspot/cpu/ppc/interp_masm_ppc.hpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/interp_masm_ppc.hpp Thu May 17 14:19:54 2018 +0200
@@ -77,7 +77,7 @@
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, Label *is_null = NULL);
+ void load_resolved_reference_at_index(Register result, Register index, Label *L_handle_null = NULL);
// load cpool->resolved_klass_at(index)
void load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass);
--- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp Thu May 17 14:19:54 2018 +0200
@@ -471,7 +471,7 @@
}
// Load object from cpool->resolved_references(index).
-void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index, Label *is_null) {
+void InterpreterMacroAssembler::load_resolved_reference_at_index(Register result, Register index, Label *L_handle_null) {
assert_different_registers(result, index);
get_constant_pool(result);
@@ -494,8 +494,7 @@
#endif
// Add in the index.
add(result, tmp, result);
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->load_at(this, IN_HEAP, T_OBJECT, result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, tmp, R0, false, is_null);
+ load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, tmp, R0, false, 0, L_handle_null);
}
// load cpool->resolved_klass_at(index)
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu May 17 14:19:54 2018 +0200
@@ -2045,7 +2045,8 @@
Label& wrong_method_type) {
assert_different_registers(mtype_reg, mh_reg, temp_reg);
// Compare method type against that of the receiver.
- load_heap_oop_not_null(temp_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg), mh_reg);
+ load_heap_oop(temp_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg), mh_reg,
+ noreg, noreg, false, OOP_NOT_NULL);
cmpd(CCR0, temp_reg, mtype_reg);
bne(CCR0, wrong_method_type);
}
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.hpp Thu May 17 14:19:54 2018 +0200
@@ -27,6 +27,7 @@
#define CPU_PPC_VM_MACROASSEMBLER_PPC_HPP
#include "asm/assembler.hpp"
+#include "oops/accessDecorators.hpp"
#include "runtime/rtmLocking.hpp"
#include "utilities/macros.hpp"
@@ -691,17 +692,26 @@
inline void null_check_throw(Register a, int offset, Register temp_reg, address exception_entry);
inline void null_check(Register a, int offset, Label *Lis_null); // implicit only if Lis_null not provided
- // Load heap oop and decompress. Loaded oop may not be null.
- // Specify tmp to save one cycle.
- inline void load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1 = noreg,
- Register tmp = noreg);
- // Store heap oop and decompress. Decompressed oop may not be null.
- // Specify tmp register if d should not be changed.
- inline void store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1,
- Register tmp = noreg);
+ // Access heap oop, handle encoding and GC barriers.
+ // Some GC barriers call C so use needs_frame = true if an extra frame is needed at the current call site.
+ private:
+ inline void access_store_at(BasicType type, DecoratorSet decorators,
+ Register base, RegisterOrConstant ind_or_offs, Register val,
+ Register tmp1, Register tmp2, Register tmp3, bool needs_frame);
+ inline void access_load_at(BasicType type, DecoratorSet decorators,
+ Register base, RegisterOrConstant ind_or_offs, Register dst,
+ Register tmp1, Register tmp2, bool needs_frame, Label *L_handle_null = NULL);
- // Null allowed.
- inline void load_heap_oop(Register d, RegisterOrConstant offs, Register s1 = noreg, Label *is_null = NULL);
+ public:
+ // Specify tmp1 for better code in certain compressed oops cases. Specify Label to bail out on null oop.
+ // tmp1, tmp2 and needs_frame are used with decorators ON_PHANTOM_OOP_REF or ON_WEAK_OOP_REF.
+ inline void load_heap_oop(Register d, RegisterOrConstant offs, Register s1,
+ Register tmp1, Register tmp2, bool needs_frame,
+ DecoratorSet decorators = 0, Label *L_handle_null = NULL);
+
+ inline void store_heap_oop(Register d, RegisterOrConstant offs, Register s1,
+ Register tmp1, Register tmp2, Register tmp3, bool needs_frame,
+ DecoratorSet decorators = 0);
// Encode/decode heap oop. Oop may not be null, else en/decoding goes wrong.
// src == d allowed.
--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp Thu May 17 14:19:54 2018 +0200
@@ -30,6 +30,8 @@
#include "asm/macroAssembler.hpp"
#include "asm/codeBuffer.hpp"
#include "code/codeCache.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
#include "runtime/safepointMechanism.hpp"
inline bool MacroAssembler::is_ld_largeoffset(address a) {
@@ -323,45 +325,52 @@
}
}
-inline void MacroAssembler::load_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, Register tmp) {
- if (UseCompressedOops) {
- // In disjoint mode decoding can save a cycle if src != dst.
- Register narrowOop = (tmp != noreg && Universe::narrow_oop_base_disjoint()) ? tmp : d;
- lwz(narrowOop, offs, s1);
- // Attention: no null check here!
- Register res = decode_heap_oop_not_null(d, narrowOop);
- assert(res == d, "caller will not consume loaded value");
+inline void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators,
+ Register base, RegisterOrConstant ind_or_offs, Register val,
+ Register tmp1, Register tmp2, Register tmp3, bool needs_frame) {
+ assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
+ ON_UNKNOWN_OOP_REF)) == 0, "unsupported decorator");
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bool as_raw = (decorators & AS_RAW) != 0;
+ if (as_raw) {
+ bs->BarrierSetAssembler::store_at(this, decorators, type,
+ base, ind_or_offs, val,
+ tmp1, tmp2, tmp3, needs_frame);
} else {
- ld(d, offs, s1);
+ bs->store_at(this, decorators, type,
+ base, ind_or_offs, val,
+ tmp1, tmp2, tmp3, needs_frame);
}
}
-inline void MacroAssembler::store_heap_oop_not_null(Register d, RegisterOrConstant offs, Register s1, Register tmp) {
- if (UseCompressedOops) {
- Register compressedOop = encode_heap_oop_not_null((tmp != noreg) ? tmp : d, d);
- stw(compressedOop, offs, s1);
+inline void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators,
+ Register base, RegisterOrConstant ind_or_offs, Register dst,
+ Register tmp1, Register tmp2, bool needs_frame, Label *L_handle_null) {
+ assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
+ ON_PHANTOM_OOP_REF | ON_WEAK_OOP_REF)) == 0, "unsupported decorator");
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bool as_raw = (decorators & AS_RAW) != 0;
+ if (as_raw) {
+ bs->BarrierSetAssembler::load_at(this, decorators, type,
+ base, ind_or_offs, dst,
+ tmp1, tmp2, needs_frame, L_handle_null);
} else {
- std(d, offs, s1);
+ bs->load_at(this, decorators, type,
+ base, ind_or_offs, dst,
+ tmp1, tmp2, needs_frame, L_handle_null);
}
}
-inline void MacroAssembler::load_heap_oop(Register d, RegisterOrConstant offs, Register s1, Label *is_null) {
- if (UseCompressedOops) {
- lwz(d, offs, s1);
- if (is_null != NULL) {
- cmpwi(CCR0, d, 0);
- beq(CCR0, *is_null);
- decode_heap_oop_not_null(d);
- } else {
- decode_heap_oop(d);
- }
- } else {
- ld(d, offs, s1);
- if (is_null != NULL) {
- cmpdi(CCR0, d, 0);
- beq(CCR0, *is_null);
- }
- }
+inline void MacroAssembler::load_heap_oop(Register d, RegisterOrConstant offs, Register s1,
+ Register tmp1, Register tmp2,
+ bool needs_frame, DecoratorSet decorators, Label *L_handle_null) {
+ access_load_at(T_OBJECT, IN_HEAP | decorators, s1, offs, d, tmp1, tmp2, needs_frame, L_handle_null);
+}
+
+inline void MacroAssembler::store_heap_oop(Register d, RegisterOrConstant offs, Register s1,
+ Register tmp1, Register tmp2, Register tmp3,
+ bool needs_frame, DecoratorSet decorators) {
+ access_store_at(T_OBJECT, IN_HEAP | decorators, s1, offs, d, tmp1, tmp2, tmp3, needs_frame);
}
inline Register MacroAssembler::encode_heap_oop_not_null(Register d, Register src) {
--- a/src/hotspot/cpu/ppc/methodHandles_ppc.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/methodHandles_ppc.cpp Thu May 17 14:19:54 2018 +0200
@@ -173,11 +173,14 @@
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ verify_oop(recv);
- __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv, temp2);
+ __ load_heap_oop(method_temp, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes()), recv,
+ temp2, noreg, false, OOP_NOT_NULL);
__ verify_oop(method_temp);
- __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp, temp2);
+ __ load_heap_oop(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes()), method_temp,
+ temp2, noreg, false, OOP_NOT_NULL);
__ verify_oop(method_temp);
- __ load_heap_oop_not_null(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), method_temp);
+ __ load_heap_oop(method_temp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), method_temp,
+ temp2, noreg, false, OOP_NOT_NULL);
__ verify_oop(method_temp);
__ ld(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), method_temp);
@@ -338,7 +341,8 @@
if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
Label L_ok;
Register temp2_defc = temp2;
- __ load_heap_oop_not_null(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg, temp3);
+ __ load_heap_oop(temp2_defc, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg,
+ temp3, noreg, false, OOP_NOT_NULL);
load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
__ verify_klass_ptr(temp2_defc);
__ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, L_ok);
@@ -365,7 +369,8 @@
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp2);
}
- __ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), member_reg);
+ __ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), member_reg,
+ temp3, noreg, false, OOP_NOT_NULL);
__ ld(R19_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), R19_method);
break;
@@ -373,7 +378,8 @@
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp2);
}
- __ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), member_reg);
+ __ load_heap_oop(R19_method, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()), member_reg,
+ temp3, noreg, false, OOP_NOT_NULL);
__ ld(R19_method, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()), R19_method);
break;
@@ -415,7 +421,8 @@
}
Register temp2_intf = temp2;
- __ load_heap_oop_not_null(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg, temp3);
+ __ load_heap_oop(temp2_intf, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()), member_reg,
+ temp3, noreg, false, OOP_NOT_NULL);
load_klass_from_Class(_masm, temp2_intf, temp3, temp4);
__ verify_klass_ptr(temp2_intf);
--- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp Thu May 17 14:19:54 2018 +0200
@@ -2198,7 +2198,7 @@
// ======== loop entry is here ========
__ bind(load_element);
- __ load_heap_oop(R10_oop, R8_offset, R3_from, &store_null); // Load the oop.
+ __ load_heap_oop(R10_oop, R8_offset, R3_from, R12_tmp, noreg, false, AS_RAW, &store_null);
__ load_klass(R11_klass, R10_oop); // Query the object klass.
--- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp Thu May 17 14:19:54 2018 +0200
@@ -524,11 +524,8 @@
__ cmpdi(CCR0, R3_RET, 0);
__ beq(CCR0, slow_path);
- // Load the value of the referent field.
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->load_at(_masm, IN_HEAP | ON_WEAK_OOP_REF, T_OBJECT,
- R3_RET, referent_offset, R3_RET,
- /* non-volatile temp */ R31, R11_scratch1, true);
+ __ load_heap_oop(R3_RET, referent_offset, R3_RET,
+ /* non-volatile temp */ R31, R11_scratch1, true, ON_WEAK_OOP_REF);
// Generate the G1 pre-barrier code to log the value of
// the referent field in an SATB buffer. Note with
--- a/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/ppc/templateTable_ppc_64.cpp Thu May 17 14:19:54 2018 +0200
@@ -62,8 +62,7 @@
Register tmp3,
DecoratorSet decorators) {
assert_different_registers(tmp1, tmp2, tmp3, val, base);
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->store_at(_masm, decorators, T_OBJECT, base, offset, val, tmp1, tmp2, tmp3, false);
+ __ store_heap_oop(val, offset, base, tmp1, tmp2, tmp3, false, decorators);
}
static void do_oop_load(InterpreterMacroAssembler* _masm,
@@ -75,8 +74,7 @@
DecoratorSet decorators) {
assert_different_registers(base, tmp1, tmp2);
assert_different_registers(dst, tmp1, tmp2);
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->load_at(_masm, decorators, T_OBJECT, base, offset, dst, tmp1, tmp2, false);
+ __ load_heap_oop(dst, offset, base, tmp1, tmp2, false, decorators);
}
// ============================================================================
--- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.cpp Thu May 17 14:19:54 2018 +0200
@@ -96,14 +96,14 @@
}
void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
- const Address& src, Register dst, Register tmp1, Register tmp2, Label *is_null) {
+ const Address& src, Register dst, Register tmp1, Register tmp2, Label *L_handle_null) {
bool on_oop = type == T_OBJECT || type == T_ARRAY;
bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
bool on_reference = on_weak || on_phantom;
Label done;
- if (on_oop && on_reference && is_null == NULL) { is_null = &done; }
- ModRefBarrierSetAssembler::load_at(masm, decorators, type, src, dst, tmp1, tmp2, is_null);
+ if (on_oop && on_reference && L_handle_null == NULL) { L_handle_null = &done; }
+ ModRefBarrierSetAssembler::load_at(masm, decorators, type, src, dst, tmp1, tmp2, L_handle_null);
if (on_oop && on_reference) {
// Generate the G1 pre-barrier code to log the value of
// the referent field in an SATB buffer.
--- a/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/gc/g1/g1BarrierSetAssembler_s390.hpp Thu May 17 14:19:54 2018 +0200
@@ -65,7 +65,7 @@
#endif
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
- const Address& src, Register dst, Register tmp1, Register tmp2, Label *is_null = NULL);
+ const Address& src, Register dst, Register tmp1, Register tmp2, Label *L_handle_null = NULL);
virtual void resolve_jobject(MacroAssembler* masm, Register value, Register tmp1, Register tmp2);
};
--- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp Thu May 17 14:19:54 2018 +0200
@@ -36,9 +36,10 @@
}
void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
- const Address& addr, Register dst, Register tmp1, Register tmp2, Label *is_null) {
- bool on_heap = (decorators & IN_HEAP) != 0;
- bool on_root = (decorators & IN_ROOT) != 0;
+ const Address& addr, Register dst, Register tmp1, Register tmp2, Label *L_handle_null) {
+ bool on_heap = (decorators & IN_HEAP) != 0;
+ bool on_root = (decorators & IN_ROOT) != 0;
+ bool not_null = (decorators & OOP_NOT_NULL) != 0;
assert(on_heap || on_root, "where?");
switch (type) {
@@ -46,16 +47,16 @@
case T_OBJECT: {
if (UseCompressedOops && on_heap) {
__ z_llgf(dst, addr);
- if (is_null) {
- __ compareU32_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *is_null);
+ if (L_handle_null != NULL) { // Label provided.
+ __ compareU32_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *L_handle_null);
__ oop_decoder(dst, dst, false);
} else {
- __ oop_decoder(dst, dst, true);
+ __ oop_decoder(dst, dst, !not_null);
}
} else {
__ z_lg(dst, addr);
- if (is_null) {
- __ compareU64_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *is_null);
+ if (L_handle_null != NULL) {
+ __ compareU64_and_branch(dst, (intptr_t)0, Assembler::bcondEqual, *L_handle_null);
}
}
break;
--- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.hpp Thu May 17 14:19:54 2018 +0200
@@ -40,7 +40,7 @@
Register dst, Register count, bool do_return = false);
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
- const Address& addr, Register dst, Register tmp1, Register tmp2, Label *is_null = NULL);
+ const Address& addr, Register dst, Register tmp1, Register tmp2, Label *L_handle_null = NULL);
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
const Address& addr, Register val, Register tmp1, Register tmp2, Register tmp3);
--- a/src/hotspot/cpu/s390/interp_masm_s390.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp Thu May 17 14:19:54 2018 +0200
@@ -391,8 +391,7 @@
bind(index_ok);
#endif
z_agr(result, index); // Address of indexed array element.
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->load_at(this, IN_HEAP, T_OBJECT, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), result, tmp, noreg);
+ load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp, noreg);
}
// load cpool->resolved_klass_at(index)
--- a/src/hotspot/cpu/s390/macroAssembler_s390.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.cpp Thu May 17 14:19:54 2018 +0200
@@ -4047,68 +4047,52 @@
BLOCK_COMMENT("} compare heap oop");
}
-// Load heap oop and decompress, if necessary.
-void MacroAssembler::load_heap_oop(Register dest, const Address &a) {
- if (UseCompressedOops) {
- z_llgf(dest, a.disp(), a.indexOrR0(), a.baseOrR0());
- oop_decoder(dest, dest, true);
- } else {
- z_lg(dest, a.disp(), a.indexOrR0(), a.baseOrR0());
- }
-}
-
-// Load heap oop and decompress, if necessary.
-void MacroAssembler::load_heap_oop(Register dest, int64_t disp, Register base) {
- if (UseCompressedOops) {
- z_llgf(dest, disp, base);
- oop_decoder(dest, dest, true);
- } else {
- z_lg(dest, disp, base);
- }
-}
-
-// Load heap oop and decompress, if necessary.
-void MacroAssembler::load_heap_oop_not_null(Register dest, int64_t disp, Register base) {
- if (UseCompressedOops) {
- z_llgf(dest, disp, base);
- oop_decoder(dest, dest, false);
+void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators,
+ const Address& addr, Register val,
+ Register tmp1, Register tmp2, Register tmp3) {
+ assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
+ ON_UNKNOWN_OOP_REF)) == 0, "unsupported decorator");
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bool as_raw = (decorators & AS_RAW) != 0;
+ if (as_raw) {
+ bs->BarrierSetAssembler::store_at(this, decorators, type,
+ addr, val,
+ tmp1, tmp2, tmp3);
} else {
- z_lg(dest, disp, base);
- }
-}
-
-// Compress, if necessary, and store oop to heap.
-void MacroAssembler::store_heap_oop(Register Roop, RegisterOrConstant offset, Register base) {
- Register Ridx = offset.is_register() ? offset.register_or_noreg() : Z_R0;
- if (UseCompressedOops) {
- assert_different_registers(Roop, offset.register_or_noreg(), base);
- encode_heap_oop(Roop);
- z_st(Roop, offset.constant_or_zero(), Ridx, base);
+ bs->store_at(this, decorators, type,
+ addr, val,
+ tmp1, tmp2, tmp3);
+ }
+}
+
+void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators,
+ const Address& addr, Register dst,
+ Register tmp1, Register tmp2, Label *is_null) {
+ assert((decorators & ~(AS_RAW | IN_HEAP | IN_HEAP_ARRAY | IN_ROOT | OOP_NOT_NULL |
+ ON_PHANTOM_OOP_REF | ON_WEAK_OOP_REF)) == 0, "unsupported decorator");
+ BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+ bool as_raw = (decorators & AS_RAW) != 0;
+ if (as_raw) {
+ bs->BarrierSetAssembler::load_at(this, decorators, type,
+ addr, dst,
+ tmp1, tmp2, is_null);
} else {
- z_stg(Roop, offset.constant_or_zero(), Ridx, base);
- }
-}
-
-// Compress, if necessary, and store oop to heap. Oop is guaranteed to be not NULL.
-void MacroAssembler::store_heap_oop_not_null(Register Roop, RegisterOrConstant offset, Register base) {
- Register Ridx = offset.is_register() ? offset.register_or_noreg() : Z_R0;
- if (UseCompressedOops) {
- assert_different_registers(Roop, offset.register_or_noreg(), base);
- encode_heap_oop_not_null(Roop);
- z_st(Roop, offset.constant_or_zero(), Ridx, base);
- } else {
- z_stg(Roop, offset.constant_or_zero(), Ridx, base);
- }
-}
-
-// Store NULL oop to heap.
-void MacroAssembler::store_heap_oop_null(Register zero, RegisterOrConstant offset, Register base) {
- Register Ridx = offset.is_register() ? offset.register_or_noreg() : Z_R0;
- if (UseCompressedOops) {
- z_st(zero, offset.constant_or_zero(), Ridx, base);
- } else {
- z_stg(zero, offset.constant_or_zero(), Ridx, base);
- }
+ bs->load_at(this, decorators, type,
+ addr, dst,
+ tmp1, tmp2, is_null);
+ }
+}
+
+void MacroAssembler::load_heap_oop(Register dest, const Address &a,
+ Register tmp1, Register tmp2,
+ DecoratorSet decorators, Label *is_null) {
+ access_load_at(T_OBJECT, IN_HEAP | decorators, a, dest, tmp1, tmp2, is_null);
+}
+
+void MacroAssembler::store_heap_oop(Register Roop, const Address &a,
+ Register tmp1, Register tmp2, Register tmp3,
+ DecoratorSet decorators) {
+ access_store_at(T_OBJECT, IN_HEAP | decorators, a, Roop, tmp1, tmp2, tmp3);
}
//-------------------------------------------------
--- a/src/hotspot/cpu/s390/macroAssembler_s390.hpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/macroAssembler_s390.hpp Thu May 17 14:19:54 2018 +0200
@@ -27,6 +27,7 @@
#define CPU_S390_VM_MACROASSEMBLER_S390_HPP
#include "asm/assembler.hpp"
+#include "oops/accessDecorators.hpp"
#define MODERN_IFUN(name) ((void (MacroAssembler::*)(Register, int64_t, Register, Register))&MacroAssembler::name)
#define CLASSIC_IFUN(name) ((void (MacroAssembler::*)(Register, int64_t, Register, Register))&MacroAssembler::name)
@@ -804,12 +805,25 @@
int get_oop_base_complement(Register Rbase, uint64_t oop_base);
void compare_heap_oop(Register Rop1, Address mem, bool maybeNULL);
void compare_klass_ptr(Register Rop1, int64_t disp, Register Rbase, bool maybeNULL);
- void load_heap_oop(Register dest, const Address &a);
- void load_heap_oop(Register d, int64_t si16, Register s1);
- void load_heap_oop_not_null(Register d, int64_t si16, Register s1);
- void store_heap_oop(Register Roop, RegisterOrConstant offset, Register base);
- void store_heap_oop_not_null(Register Roop, RegisterOrConstant offset, Register base);
- void store_heap_oop_null(Register zero, RegisterOrConstant offset, Register base);
+
+ // Access heap oop, handle encoding and GC barriers.
+ private:
+ void access_store_at(BasicType type, DecoratorSet decorators,
+ const Address& addr, Register val,
+ Register tmp1, Register tmp2, Register tmp3);
+ void access_load_at(BasicType type, DecoratorSet decorators,
+ const Address& addr, Register dst,
+ Register tmp1, Register tmp2, Label *is_null = NULL);
+
+ public:
+ // tmp1 and tmp2 are used with decorators ON_PHANTOM_OOP_REF or ON_WEAK_OOP_REF.
+ void load_heap_oop(Register dest, const Address &a,
+ Register tmp1, Register tmp2,
+ DecoratorSet decorators = 0, Label *is_null = NULL);
+ void store_heap_oop(Register Roop, const Address &a,
+ Register tmp1, Register tmp2, Register tmp3,
+ DecoratorSet decorators = 0);
+
void oop_encoder(Register Rdst, Register Rsrc, bool maybeNULL,
Register Rbase = Z_R1, int pow2_offset = -1, bool only32bitValid = false);
void oop_decoder(Register Rdst, Register Rsrc, bool maybeNULL,
--- a/src/hotspot/cpu/s390/methodHandles_s390.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp Thu May 17 14:19:54 2018 +0200
@@ -196,16 +196,19 @@
// Load the invoker, as MH -> MH.form -> LF.vmentry
__ verify_oop(recv);
__ load_heap_oop(method_temp,
- Address(recv,
- NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));
+ Address(recv,
+ NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())),
+ noreg, noreg, OOP_NOT_NULL);
__ verify_oop(method_temp);
__ load_heap_oop(method_temp,
- Address(method_temp,
- NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
+ Address(method_temp,
+ NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())),
+ noreg, noreg, OOP_NOT_NULL);
__ verify_oop(method_temp);
__ load_heap_oop(method_temp,
- Address(method_temp,
- NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())));
+ Address(method_temp,
+ NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes())),
+ noreg, noreg, OOP_NOT_NULL);
__ verify_oop(method_temp);
__ z_lg(method_temp,
Address(method_temp,
@@ -405,7 +408,8 @@
NearLabel L_ok;
Register temp2_defc = temp2;
- __ load_heap_oop(temp2_defc, member_clazz);
+ __ load_heap_oop(temp2_defc, member_clazz,
+ noreg, noreg, OOP_NOT_NULL);
load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
__ verify_klass_ptr(temp2_defc);
__ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, L_ok);
@@ -431,7 +435,8 @@
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
}
- __ load_heap_oop(Z_method, member_vmtarget);
+ __ load_heap_oop(Z_method, member_vmtarget,
+ noreg, noreg, OOP_NOT_NULL);
__ z_lg(Z_method, vmtarget_method);
method_is_live = true;
break;
@@ -440,7 +445,8 @@
if (VerifyMethodHandles) {
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
}
- __ load_heap_oop(Z_method, member_vmtarget);
+ __ load_heap_oop(Z_method, member_vmtarget,
+ noreg, noreg, OOP_NOT_NULL);
__ z_lg(Z_method, vmtarget_method);
method_is_live = true;
break;
@@ -481,7 +487,8 @@
Register temp3_intf = temp3;
- __ load_heap_oop(temp3_intf, member_clazz);
+ __ load_heap_oop(temp3_intf, member_clazz,
+ noreg, noreg, OOP_NOT_NULL);
load_klass_from_Class(_masm, temp3_intf, temp2, temp4);
Register Z_index = Z_method;
--- a/src/hotspot/cpu/s390/s390.ad Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/s390.ad Thu May 17 14:19:54 2018 +0200
@@ -2239,8 +2239,8 @@
// Go through the vtable. Get receiver klass. Receiver already
// checked for non-null. If we'll go thru a C2I adapter, the
// interpreter expects method in Z_method.
- // Use Z_method to temporarily hold the klass oop. Z_R1_scratch is destroyed
- // by load_heap_oop_not_null.
+ // Use Z_method to temporarily hold the klass oop.
+ // Z_R1_scratch is destroyed.
__ load_klass(Z_method, Z_R2);
int entry_offset = in_bytes(Klass::vtable_start_offset()) + vtable_index * vtableEntry::size_in_bytes();
--- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Thu May 17 14:19:54 2018 +0200
@@ -512,9 +512,7 @@
__ z_bre(slow_path);
// Load the value of the referent field.
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->load_at(_masm, IN_HEAP | ON_WEAK_OOP_REF, T_OBJECT,
- Address(pre_val, referent_offset), pre_val, scratch1, scratch2);
+ __ load_heap_oop(pre_val, Address(pre_val, referent_offset), scratch1, scratch2, ON_WEAK_OOP_REF);
// Restore caller sp for c2i case.
__ resize_frame_absolute(Z_R10, Z_R0, true); // Cut the stack back to where the caller started.
--- a/src/hotspot/cpu/s390/templateTable_s390.cpp Wed May 16 11:11:03 2018 -0400
+++ b/src/hotspot/cpu/s390/templateTable_s390.cpp Thu May 17 14:19:54 2018 +0200
@@ -200,8 +200,7 @@
Register tmp3,
DecoratorSet decorators) {
assert_different_registers(tmp1, tmp2, tmp3, val, addr.base());
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->store_at(_masm, decorators, T_OBJECT, addr, val, tmp1, tmp2, tmp3);
+ __ store_heap_oop(val, addr, tmp1, tmp2, tmp3, decorators);
}
static void do_oop_load(InterpreterMacroAssembler* _masm,
@@ -212,8 +211,7 @@
DecoratorSet decorators) {
assert_different_registers(addr.base(), tmp1, tmp2);
assert_different_registers(dst, tmp1, tmp2);
- BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
- bs->load_at(_masm, decorators, T_OBJECT, addr, dst, tmp1, tmp2);
+ __ load_heap_oop(dst, addr, tmp1, tmp2, decorators);
}
Address TemplateTable::at_bcp(int offset) {