8166689: PPC64: Race condition between stack bang and non-entrant patching
authormdoerr
Tue, 27 Sep 2016 09:26:30 +0200
changeset 41693 ad7de42d606b
parent 41338 310c87628696
child 41694 225750a49720
8166689: PPC64: Race condition between stack bang and non-entrant patching Reviewed-by: goetz
hotspot/src/cpu/ppc/vm/c1_MacroAssembler_ppc.cpp
hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp
--- a/hotspot/src/cpu/ppc/vm/c1_MacroAssembler_ppc.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/cpu/ppc/vm/c1_MacroAssembler_ppc.cpp	Tue Sep 27 09:26:30 2016 +0200
@@ -64,17 +64,16 @@
 
 
 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
+  // Avoid stack bang as first instruction. It may get overwritten by patch_verified_entry.
+  const Register return_pc = R20;
+  mflr(return_pc);
+
+  // Make sure there is enough stack space for this method's activation.
   assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
-  // Make sure there is enough stack space for this method's activation.
   generate_stack_overflow_check(bang_size_in_bytes);
 
-  // Create the frame.
-  const Register return_pc  = R0;
-
-  mflr(return_pc);
-  // Get callers sp.
-  std(return_pc, _abi(lr), R1_SP);           // SP->lr = return_pc
-  push_frame(frame_size_in_bytes, R0);       // SP -= frame_size_in_bytes
+  std(return_pc, _abi(lr), R1_SP);     // SP->lr = return_pc
+  push_frame(frame_size_in_bytes, R0); // SP -= frame_size_in_bytes
 }
 
 
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Mon Sep 26 14:21:21 2016 -0400
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp	Tue Sep 27 09:26:30 2016 +0200
@@ -2550,7 +2550,7 @@
   __ lbzx(R17_tos, Rclass_or_obj, Roffset);
   __ extsb(R17_tos, R17_tos);
   __ push(ztos);
-  if (!is_static) {
+  if (!is_static && rc == may_rewrite) {
     // use btos rewriting, no truncating to t/f bit is needed for getfield.
     patch_bytecode(Bytecodes::_fast_bgetfield, Rbc, Rscratch);
   }
@@ -2874,7 +2874,9 @@
   if (!is_static) { pop_and_check_object(Rclass_or_obj); } // Kills R11_scratch1.
   __ andi(R17_tos, R17_tos, 0x1);
   __ stbx(R17_tos, Rclass_or_obj, Roffset);
-  if (!is_static) { patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no); }
+  if (!is_static && rc == may_rewrite) {
+    patch_bytecode(Bytecodes::_fast_zputfield, Rbc, Rscratch, true, byte_no);
+  }
   if (!support_IRIW_for_not_multiple_copy_atomic_cpu) {
     __ beq(CR_is_vol, Lvolatile); // Volatile?
   }