--- a/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Oct 17 20:27:44 2019 +0100
+++ b/src/hotspot/cpu/ppc/macroAssembler_ppc.cpp Thu Oct 17 20:53:35 2019 +0100
@@ -32,6 +32,7 @@
#include "interpreter/interpreter.hpp"
#include "memory/resourceArea.hpp"
#include "nativeInst_ppc.hpp"
+#include "oops/klass.inline.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/icache.hpp"
@@ -2011,15 +2012,33 @@
bind(L_failure); // Fallthru if not successful.
}
-void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
- Register temp_reg,
- Label& wrong_method_type) {
- assert_different_registers(mtype_reg, mh_reg, temp_reg);
- // Compare method type against that of the receiver.
- load_heap_oop(temp_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg), mh_reg,
- noreg, noreg, false, IS_NOT_NULL);
- cmpd(CCR0, temp_reg, mtype_reg);
- bne(CCR0, wrong_method_type);
+void MacroAssembler::clinit_barrier(Register klass, Register thread, Label* L_fast_path, Label* L_slow_path) {
+ assert(L_fast_path != NULL || L_slow_path != NULL, "at least one is required");
+
+ Label L_fallthrough;
+ if (L_fast_path == NULL) {
+ L_fast_path = &L_fallthrough;
+ } else if (L_slow_path == NULL) {
+ L_slow_path = &L_fallthrough;
+ }
+
+ // Fast path check: class is fully initialized
+ lbz(R0, in_bytes(InstanceKlass::init_state_offset()), klass);
+ cmpwi(CCR0, R0, InstanceKlass::fully_initialized);
+ beq(CCR0, *L_fast_path);
+
+ // Fast path check: current thread is initializer thread
+ ld(R0, in_bytes(InstanceKlass::init_thread_offset()), klass);
+ cmpd(CCR0, thread, R0);
+ if (L_slow_path == &L_fallthrough) {
+ beq(CCR0, *L_fast_path);
+ } else if (L_fast_path == &L_fallthrough) {
+ bne(CCR0, *L_slow_path);
+ } else {
+ Unimplemented();
+ }
+
+ bind(L_fallthrough);
}
RegisterOrConstant MacroAssembler::argument_offset(RegisterOrConstant arg_slot,
@@ -2060,7 +2079,7 @@
// whether the epoch is still valid
// Note that the runtime guarantees sufficient alignment of JavaThread
// pointers to allow age to be placed into low bits
- assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits,
+ assert(markWord::age_shift == markWord::lock_bits + markWord::biased_lock_bits,
"biased locking makes assumptions about bit layout");
if (PrintBiasedLockingStatistics) {
@@ -2070,13 +2089,13 @@
stwx(temp_reg, temp2_reg);
}
- andi(temp_reg, mark_reg, markOopDesc::biased_lock_mask_in_place);
- cmpwi(cr_reg, temp_reg, markOopDesc::biased_lock_pattern);
+ andi(temp_reg, mark_reg, markWord::biased_lock_mask_in_place);
+ cmpwi(cr_reg, temp_reg, markWord::biased_lock_pattern);
bne(cr_reg, cas_label);
load_klass(temp_reg, obj_reg);
- load_const_optimized(temp2_reg, ~((int) markOopDesc::age_mask_in_place));
+ load_const_optimized(temp2_reg, ~((int) markWord::age_mask_in_place));
ld(temp_reg, in_bytes(Klass::prototype_header_offset()), temp_reg);
orr(temp_reg, R16_thread, temp_reg);
xorr(temp_reg, mark_reg, temp_reg);
@@ -2107,7 +2126,7 @@
// If the low three bits in the xor result aren't clear, that means
// the prototype header is no longer biased and we have to revoke
// the bias on this object.
- andi(temp2_reg, temp_reg, markOopDesc::biased_lock_mask_in_place);
+ andi(temp2_reg, temp_reg, markWord::biased_lock_mask_in_place);
cmpwi(cr_reg, temp2_reg, 0);
bne(cr_reg, try_revoke_bias);
@@ -2121,10 +2140,10 @@
// otherwise the manipulations it performs on the mark word are
// illegal.
- int shift_amount = 64 - markOopDesc::epoch_shift;
+ int shift_amount = 64 - markWord::epoch_shift;
// rotate epoch bits to right (little) end and set other bits to 0
// [ big part | epoch | little part ] -> [ 0..0 | epoch ]
- rldicl_(temp2_reg, temp_reg, shift_amount, 64 - markOopDesc::epoch_bits);
+ rldicl_(temp2_reg, temp_reg, shift_amount, 64 - markWord::epoch_bits);
// branch if epoch bits are != 0, i.e. they differ, because the epoch has been incremented
bne(CCR0, try_rebias);
@@ -2134,9 +2153,9 @@
// fails we will go in to the runtime to revoke the object's bias.
// Note that we first construct the presumed unbiased header so we
// don't accidentally blow away another thread's valid bias.
- andi(mark_reg, mark_reg, (markOopDesc::biased_lock_mask_in_place |
- markOopDesc::age_mask_in_place |
- markOopDesc::epoch_mask_in_place));
+ andi(mark_reg, mark_reg, (markWord::biased_lock_mask_in_place |
+ markWord::age_mask_in_place |
+ markWord::epoch_mask_in_place));
orr(temp_reg, R16_thread, mark_reg);
assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
@@ -2169,7 +2188,7 @@
// bias in the current epoch. In other words, we allow transfer of
// the bias from one thread to another directly in this situation.
load_klass(temp_reg, obj_reg);
- andi(temp2_reg, mark_reg, markOopDesc::age_mask_in_place);
+ andi(temp2_reg, mark_reg, markWord::age_mask_in_place);
orr(temp2_reg, R16_thread, temp2_reg);
ld(temp_reg, in_bytes(Klass::prototype_header_offset()), temp_reg);
orr(temp_reg, temp2_reg, temp_reg);
@@ -2206,7 +2225,7 @@
// normal locking code.
load_klass(temp_reg, obj_reg);
ld(temp_reg, in_bytes(Klass::prototype_header_offset()), temp_reg);
- andi(temp2_reg, mark_reg, markOopDesc::age_mask_in_place);
+ andi(temp2_reg, mark_reg, markWord::age_mask_in_place);
orr(temp_reg, temp_reg, temp2_reg);
assert(oopDesc::mark_offset_in_bytes() == 0, "offset of _mark is not 0");
@@ -2218,7 +2237,7 @@
MacroAssembler::MemBarAcq,
MacroAssembler::cmpxchgx_hint_acquire_lock());
- // reload markOop in mark_reg before continuing with lightweight locking
+ // reload markWord in mark_reg before continuing with lightweight locking
ld(mark_reg, oopDesc::mark_offset_in_bytes(), obj_reg);
// Fall through to the normal CAS-based lock, because no matter what
@@ -2246,9 +2265,9 @@
// the bias bit would be clear.
ld(temp_reg, 0, mark_addr);
- andi(temp_reg, temp_reg, markOopDesc::biased_lock_mask_in_place);
-
- cmpwi(cr_reg, temp_reg, markOopDesc::biased_lock_pattern);
+ andi(temp_reg, temp_reg, markWord::biased_lock_mask_in_place);
+
+ cmpwi(cr_reg, temp_reg, markWord::biased_lock_pattern);
beq(cr_reg, done);
}
@@ -2669,7 +2688,7 @@
load_const_optimized(retry_on_abort_count_Reg, RTMRetryCount); // Retry on abort
bind(L_rtm_retry);
}
- andi_(R0, mark_word, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased
+ andi_(R0, mark_word, markWord::monitor_value); // inflated vs stack-locked|neutral|biased
bne(CCR0, IsInflated);
if (PrintPreciseRTMLockingStatistics || profile_rtm) {
@@ -2687,10 +2706,10 @@
}
tbegin_();
beq(CCR0, L_on_abort);
- ld(mark_word, oopDesc::mark_offset_in_bytes(), obj); // Reload in transaction, conflicts need to be tracked.
- andi(R0, mark_word, markOopDesc::biased_lock_mask_in_place); // look at 3 lock bits
- cmpwi(flag, R0, markOopDesc::unlocked_value); // bits = 001 unlocked
- beq(flag, DONE_LABEL); // all done if unlocked
+ ld(mark_word, oopDesc::mark_offset_in_bytes(), obj); // Reload in transaction, conflicts need to be tracked.
+ andi(R0, mark_word, markWord::biased_lock_mask_in_place); // look at 3 lock bits
+ cmpwi(flag, R0, markWord::unlocked_value); // bits = 001 unlocked
+ beq(flag, DONE_LABEL); // all done if unlocked
if (UseRTMXendForLockBusy) {
tend_();
@@ -2726,9 +2745,9 @@
assert(UseRTMLocking, "why call this otherwise?");
Label L_rtm_retry, L_decrement_retry, L_on_abort;
// Clean monitor_value bit to get valid pointer.
- int owner_offset = ObjectMonitor::owner_offset_in_bytes() - markOopDesc::monitor_value;
-
- // Store non-null, using boxReg instead of (intptr_t)markOopDesc::unused_mark().
+ int owner_offset = ObjectMonitor::owner_offset_in_bytes() - markWord::monitor_value;
+
+ // Store non-null, using boxReg instead of (intptr_t)markWord::unused_mark().
std(boxReg, BasicLock::displaced_header_offset_in_bytes(), boxReg);
const Register tmpReg = boxReg;
const Register owner_addr_Reg = mark_word;
@@ -2773,7 +2792,7 @@
// Restore owner_addr_Reg
ld(mark_word, oopDesc::mark_offset_in_bytes(), obj);
#ifdef ASSERT
- andi_(R0, mark_word, markOopDesc::monitor_value);
+ andi_(R0, mark_word, markWord::monitor_value);
asm_assert_ne("must be inflated", 0xa754); // Deflating only allowed at safepoint.
#endif
addi(owner_addr_Reg, mark_word, owner_offset);
@@ -2815,7 +2834,7 @@
Label object_has_monitor;
Label cas_failed;
- // Load markOop from object into displaced_header.
+ // Load markWord from object into displaced_header.
ld(displaced_header, oopDesc::mark_offset_in_bytes(), oop);
@@ -2833,11 +2852,11 @@
// Handle existing monitor.
// The object has an existing monitor iff (mark & monitor_value) != 0.
- andi_(temp, displaced_header, markOopDesc::monitor_value);
+ andi_(temp, displaced_header, markWord::monitor_value);
bne(CCR0, object_has_monitor);
- // Set displaced_header to be (markOop of object | UNLOCK_VALUE).
- ori(displaced_header, displaced_header, markOopDesc::unlocked_value);
+ // Set displaced_header to be (markWord of object | UNLOCK_VALUE).
+ ori(displaced_header, displaced_header, markWord::unlocked_value);
// Load Compare Value application register.
@@ -2845,7 +2864,7 @@
std(displaced_header, BasicLock::displaced_header_offset_in_bytes(), box);
// Must fence, otherwise, preceding store(s) may float below cmpxchg.
- // Compare object markOop with mark and if equal exchange scratch1 with object markOop.
+ // Compare object markWord with mark and if equal exchange scratch1 with object markWord.
cmpxchgd(/*flag=*/flag,
/*current_value=*/current_header,
/*compare_value=*/displaced_header,
@@ -2865,10 +2884,10 @@
bind(cas_failed);
// We did not see an unlocked object so try the fast recursive case.
- // Check if the owner is self by comparing the value in the markOop of object
+ // Check if the owner is self by comparing the value in the markWord of object
// (current_header) with the stack pointer.
sub(current_header, current_header, R1_SP);
- load_const_optimized(temp, ~(os::vm_page_size()-1) | markOopDesc::lock_mask_in_place);
+ load_const_optimized(temp, ~(os::vm_page_size()-1) | markWord::lock_mask_in_place);
and_(R0/*==0?*/, current_header, temp);
// If condition is true we are cont and hence we can store 0 as the
@@ -2892,7 +2911,7 @@
#endif // INCLUDE_RTM_OPT
// Try to CAS m->owner from NULL to current thread.
- addi(temp, displaced_header, ObjectMonitor::owner_offset_in_bytes()-markOopDesc::monitor_value);
+ addi(temp, displaced_header, ObjectMonitor::owner_offset_in_bytes()-markWord::monitor_value);
cmpxchgd(/*flag=*/flag,
/*current_value=*/current_header,
/*compare_value=*/(intptr_t)0,
@@ -2939,12 +2958,12 @@
if (UseRTMForStackLocks && use_rtm) {
assert(!UseBiasedLocking, "Biased locking is not supported with RTM locking");
Label L_regular_unlock;
- ld(current_header, oopDesc::mark_offset_in_bytes(), oop); // fetch markword
- andi(R0, current_header, markOopDesc::biased_lock_mask_in_place); // look at 3 lock bits
- cmpwi(flag, R0, markOopDesc::unlocked_value); // bits = 001 unlocked
- bne(flag, L_regular_unlock); // else RegularLock
- tend_(); // otherwise end...
- b(cont); // ... and we're done
+ ld(current_header, oopDesc::mark_offset_in_bytes(), oop); // fetch markword
+ andi(R0, current_header, markWord::biased_lock_mask_in_place); // look at 3 lock bits
+ cmpwi(flag, R0, markWord::unlocked_value); // bits = 001 unlocked
+ bne(flag, L_regular_unlock); // else RegularLock
+ tend_(); // otherwise end...
+ b(cont); // ... and we're done
bind(L_regular_unlock);
}
#endif
@@ -2960,11 +2979,11 @@
// The object has an existing monitor iff (mark & monitor_value) != 0.
RTM_OPT_ONLY( if (!(UseRTMForStackLocks && use_rtm)) ) // skip load if already done
ld(current_header, oopDesc::mark_offset_in_bytes(), oop);
- andi_(R0, current_header, markOopDesc::monitor_value);
+ andi_(R0, current_header, markWord::monitor_value);
bne(CCR0, object_has_monitor);
// Check if it is still a light weight lock, this is is true if we see
- // the stack address of the basicLock in the markOop of the object.
+ // the stack address of the basicLock in the markWord of the object.
// Cmpxchg sets flag to cmpd(current_header, box).
cmpxchgd(/*flag=*/flag,
/*current_value=*/current_header,
@@ -2982,7 +3001,8 @@
b(cont);
bind(object_has_monitor);
- addi(current_header, current_header, -markOopDesc::monitor_value); // monitor
+ STATIC_ASSERT(markWord::monitor_value <= INT_MAX);
+ addi(current_header, current_header, -(int)markWord::monitor_value); // monitor
ld(temp, ObjectMonitor::owner_offset_in_bytes(), current_header);
// It's inflated.
@@ -3194,6 +3214,12 @@
resolve_oop_handle(mirror);
}
+void MacroAssembler::load_method_holder(Register holder, Register method) {
+ ld(holder, in_bytes(Method::const_offset()), method);
+ ld(holder, in_bytes(ConstMethod::constants_offset()), holder);
+ ld(holder, ConstantPool::pool_holder_offset_in_bytes(), holder);
+}
+
// Clear Array
// For very short arrays. tmp == R0 is allowed.
void MacroAssembler::clear_memory_unrolled(Register base_ptr, int cnt_dwords, Register tmp, int offset) {