8131682: C1 should use multibyte nops everywhere
authorshade
Tue, 11 Aug 2015 12:24:26 +0300
changeset 32203 01a3716ed455
parent 32202 7e7ad8b06f5b
child 32204 2c4da498285f
8131682: C1 should use multibyte nops everywhere Reviewed-by: dlong, goetz, adinn, aph, vlivanov
hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp
hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
--- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Mon Aug 10 10:39:19 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp	Tue Aug 11 12:24:26 2015 +0300
@@ -416,7 +416,8 @@
   int jmp_off = __ offset();
   __ jmp(_patch_site_entry);
   // Add enough nops so deoptimization can overwrite the jmp above with a call
-  // and not destroy the world.
+  // and not destroy the world. We cannot use fat nops here, since the concurrent
+  // code rewrite may transiently create the illegal instruction sequence.
   for (int j = __ offset() ; j < jmp_off + 5 ; j++ ) {
     __ nop();
   }
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Aug 10 10:39:19 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Aug 11 12:24:26 2015 +0300
@@ -345,9 +345,7 @@
   const bool do_post_padding = VerifyOops || UseCompressedClassPointers;
   if (!do_post_padding) {
     // insert some nops so that the verified entry point is aligned on CodeEntryAlignment
-    while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) {
-      __ nop();
-    }
+    __ align(CodeEntryAlignment, __ offset() + ic_cmp_size);
   }
   int offset = __ offset();
   __ inline_cache_check(receiver, IC_Klass);
@@ -2861,9 +2859,7 @@
       case lir_virtual_call:  // currently, sparc-specific for niagara
       default: ShouldNotReachHere();
     }
-    while (offset++ % BytesPerWord != 0) {
-      __ nop();
-    }
+    __ align(BytesPerWord, offset);
   }
 }
 
@@ -2902,10 +2898,7 @@
   int start = __ offset();
   if (os::is_MP()) {
     // make sure that the displacement word of the call ends up word aligned
-    int offset = __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset;
-    while (offset++ % BytesPerWord != 0) {
-      __ nop();
-    }
+    __ align(BytesPerWord, __ offset() + NativeMovConstReg::instruction_size + NativeCall::displacement_offset);
   }
   __ relocate(static_stub_Relocation::spec(call_pc));
   __ mov_metadata(rbx, (Metadata*)NULL);
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Mon Aug 10 10:39:19 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	Tue Aug 11 12:24:26 2015 +0300
@@ -970,8 +970,12 @@
 }
 
 void MacroAssembler::align(int modulus) {
-  if (offset() % modulus != 0) {
-    nop(modulus - (offset() % modulus));
+  align(modulus, offset());
+}
+
+void MacroAssembler::align(int modulus, int target) {
+  if (target % modulus != 0) {
+    nop(modulus - (target % modulus));
   }
 }
 
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Mon Aug 10 10:39:19 2015 -0700
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp	Tue Aug 11 12:24:26 2015 +0300
@@ -192,6 +192,7 @@
 
   // Alignment
   void align(int modulus);
+  void align(int modulus, int target);
 
   // A 5 byte nop that is safe for patching (see patch_verified_entry)
   void fat_nop();
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Mon Aug 10 10:39:19 2015 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp	Tue Aug 11 12:24:26 2015 +0300
@@ -33,7 +33,9 @@
 #include "runtime/os.hpp"
 
 void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
-  // we must have enough patching space so that call can be inserted
+  // We must have enough patching space so that call can be inserted.
+  // We cannot use fat nops here, since the concurrent code rewrite may transiently
+  // create the illegal instruction sequence.
   while ((intx) _masm->pc() - (intx) patch->pc_start() < NativeCall::instruction_size) {
     _masm->nop();
   }
@@ -592,9 +594,7 @@
 void LIR_Assembler::emit_op0(LIR_Op0* op) {
   switch (op->code()) {
     case lir_word_align: {
-      while (code_offset() % BytesPerWord != 0) {
-        _masm->nop();
-      }
+      _masm->align(BytesPerWord);
       break;
     }