6991512: G1 barriers fail with 64bit C1
authoriveresov
Tue, 12 Oct 2010 23:51:20 -0700
changeset 6774 a224d6a24120
parent 6773 48d5e03f373f
child 6776 b8ce967085dd
6991512: G1 barriers fail with 64bit C1 Summary: Fix compare-and-swap intrinsic problem with G1 post-barriers and issue with branch ranges in G1 stubs on sparc Reviewed-by: never, kvn
hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Tue Oct 12 02:21:06 2010 -0700
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp	Tue Oct 12 23:51:20 2010 -0700
@@ -825,6 +825,12 @@
   // test if -4096 <= x <= 4095
   static bool is_simm13(int x) { return is_simm(x, 13); }
 
+  // test if label is in simm16 range in words (wdisp16).
+  bool is_in_wdisp16_range(Label& L) {
+    intptr_t d = intptr_t(pc()) - intptr_t(target(L));
+    return is_simm(d, 18);
+  }
+
   enum ASIs { // page 72, v9
     ASI_PRIMARY        = 0x80,
     ASI_PRIMARY_LITTLE = 0x88
--- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Oct 12 02:21:06 2010 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp	Tue Oct 12 23:51:20 2010 -0700
@@ -425,8 +425,13 @@
   Register pre_val_reg = pre_val()->as_register();
 
   ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false);
-  __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
-                    pre_val_reg, _continuation);
+  if (__ is_in_wdisp16_range(_continuation)) {
+    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
+                      pre_val_reg, _continuation);
+  } else {
+    __ cmp(pre_val_reg, G0);
+    __ brx(Assembler::equal, false, Assembler::pn, _continuation);
+  }
   __ delayed()->nop();
 
   __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id));
@@ -452,8 +457,13 @@
   assert(new_val()->is_register(), "Precondition.");
   Register addr_reg = addr()->as_pointer_register();
   Register new_val_reg = new_val()->as_register();
-  __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
-                    new_val_reg, _continuation);
+  if (__ is_in_wdisp16_range(_continuation)) {
+    __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
+                      new_val_reg, _continuation);
+  } else {
+    __ cmp(new_val_reg, G0);
+    __ brx(Assembler::equal, false, Assembler::pn, _continuation);
+  }
   __ delayed()->nop();
 
   __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id));
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Tue Oct 12 02:21:06 2010 -0700
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Tue Oct 12 23:51:20 2010 -0700
@@ -664,7 +664,7 @@
   // Use temps to avoid kills
   LIR_Opr t1 = FrameMap::G1_opr;
   LIR_Opr t2 = FrameMap::G3_opr;
-  LIR_Opr addr = new_pointer_register();
+  LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
 
   // get address of field
   obj.load_item();
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Oct 12 02:21:06 2010 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Oct 12 23:51:20 2010 -0700
@@ -1941,8 +1941,6 @@
       __ cmpxchgptr(newval, Address(addr, 0));
     } else if (op->code() == lir_cas_int) {
       __ cmpxchgl(newval, Address(addr, 0));
-    } else {
-      LP64_ONLY(__ cmpxchgq(newval, Address(addr, 0)));
     }
 #ifdef _LP64
   } else if (op->code() == lir_cas_long) {
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Tue Oct 12 02:21:06 2010 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Tue Oct 12 23:51:20 2010 -0700
@@ -765,7 +765,7 @@
     ShouldNotReachHere();
   }
 
-  LIR_Opr addr = new_pointer_register();
+  LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
   LIR_Address* a;
   if(offset.result()->is_constant()) {
     a = new LIR_Address(obj.result(),
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Oct 12 02:21:06 2010 -0700
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Oct 12 23:51:20 2010 -0700
@@ -1350,6 +1350,7 @@
     addr = ptr;
   }
   assert(addr->is_register(), "must be a register at this point");
+  assert(addr->type() == T_OBJECT, "addr should point to an object");
 
   LIR_Opr xor_res = new_pointer_register();
   LIR_Opr xor_shift_res = new_pointer_register();