src/hotspot/cpu/ppc/macroAssembler_ppc.cpp
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54825 1b03400e5a8f
child 58679 9c3209ff7550
--- 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) {