< prev index next >

src/cpu/x86/vm/c1_LIRAssembler_x86.cpp

Print this page

        

@@ -1511,10 +1511,33 @@
     }
     __ jcc(acond,*(op->label()));
   }
 }
 
+#if INCLUDE_ALL_GCS
+void LIR_Assembler::emit_opShenandoahWriteBarrier(LIR_OpShenandoahWriteBarrier* op) {
+  Label done;
+  Register obj = op->in_opr()->as_register();
+  Register res = op->result_opr()->as_register();
+
+  if (res != obj) {
+    __ mov(res, obj);
+  }
+
+  // Check for null.
+  if (op->need_null_check()) {
+    __ testptr(res, res);
+    __ jcc(Assembler::zero, done);
+  }
+
+  __ shenandoah_write_barrier(res);
+
+  __ bind(done);
+
+}
+#endif
+
 void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {
   LIR_Opr src  = op->in_opr();
   LIR_Opr dest = op->result_opr();
 
   switch (op->bytecode()) {

@@ -1996,25 +2019,47 @@
     assert(newval != addr, "new value and addr must be in different registers");
 
     if ( op->code() == lir_cas_obj) {
 #ifdef _LP64
       if (UseCompressedOops) {
-        __ encode_heap_oop(cmpval);
-        __ mov(rscratch1, newval);
-        __ encode_heap_oop(rscratch1);
-        if (os::is_MP()) {
-          __ lock();
+#if INCLUDE_ALL_GCS
+        if (UseShenandoahGC && ShenandoahCASBarrier) {
+          Register tmp1 = op->tmp1()->as_register();
+          Register tmp2 = op->tmp2()->as_register();
+
+          __ encode_heap_oop(cmpval);
+          __ mov(rscratch1, newval);
+          __ encode_heap_oop(rscratch1);
+          __ cmpxchg_oop_shenandoah(NULL, Address(addr, 0), cmpval, rscratch1, true, tmp1, tmp2);
+        } else
+#endif
+        {
+          __ encode_heap_oop(cmpval);
+          __ mov(rscratch1, newval);
+          __ encode_heap_oop(rscratch1);
+          if (os::is_MP()) {
+            __ lock();
+          }
+          // cmpval (rax) is implicitly used by this instruction
+          __ cmpxchgl(rscratch1, Address(addr, 0));
         }
-        // cmpval (rax) is implicitly used by this instruction
-        __ cmpxchgl(rscratch1, Address(addr, 0));
       } else
 #endif
       {
-        if (os::is_MP()) {
-          __ lock();
-        }
-        __ cmpxchgptr(newval, Address(addr, 0));
+#if INCLUDE_ALL_GCS
+        if (UseShenandoahGC && ShenandoahCASBarrier) {
+          Register tmp1 = op->tmp1()->as_register();
+          Register tmp2 = op->tmp2()->as_register();
+          __ cmpxchg_oop_shenandoah(NULL, Address(addr, 0), cmpval, newval, true, tmp1, tmp2);
+        } else
+#endif
+        {
+          if (os::is_MP()) {
+            __ lock();
+          }
+          __ cmpxchgptr(newval, Address(addr, 0));
+        }
       }
     } else {
       assert(op->code() == lir_cas_int, "lir_cas_int expected");
       if (os::is_MP()) {
         __ lock();

@@ -2699,19 +2744,19 @@
   if (opr1->is_single_cpu()) {
     Register reg1 = opr1->as_register();
     if (opr2->is_single_cpu()) {
       // cpu register - cpu register
       if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
-        __ cmpptr(reg1, opr2->as_register());
+        __ cmpoops(reg1, opr2->as_register());
       } else {
         assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?");
         __ cmpl(reg1, opr2->as_register());
       }
     } else if (opr2->is_stack()) {
       // cpu register - stack
       if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
-        __ cmpptr(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
+        __ cmpoops(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
       } else {
         __ cmpl(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
       }
     } else if (opr2->is_constant()) {
       // cpu register - constant

@@ -2724,11 +2769,11 @@
         if (o == NULL) {
           __ cmpptr(reg1, (int32_t)NULL_WORD);
         } else {
 #ifdef _LP64
           __ movoop(rscratch1, o);
-          __ cmpptr(reg1, rscratch1);
+          __ cmpoops(reg1, rscratch1);
 #else
           __ cmpoop(reg1, c->as_jobject());
 #endif // _LP64
         }
       } else {

@@ -2837,11 +2882,11 @@
       __ cmpl(as_Address(addr), c->as_jint());
     } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) {
 #ifdef _LP64
       // %%% Make this explode if addr isn't reachable until we figure out a
       // better strategy by giving noreg as the temp for as_Address
-      __ cmpptr(rscratch1, as_Address(addr, noreg));
+      __ cmpoops(rscratch1, as_Address(addr, noreg));
 #else
       __ cmpoop(as_Address(addr), c->as_jobject());
 #endif // _LP64
     } else {
       ShouldNotReachHere();

@@ -3169,15 +3214,15 @@
     } else {
 #ifndef PRODUCT
       if (PrintC1Statistics) {
         __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt));
       }
-#endif
+#endif // PRODUCT
       __ call(RuntimeAddress(copyfunc_addr));
     }
     __ addptr(rsp, 6*wordSize);
-#else
+#else // 
     __ mov(c_rarg4, j_rarg4);
     if (copyfunc_addr == NULL) { // Use C version if stub was not generated
       __ call(RuntimeAddress(C_entry));
     } else {
 #ifndef PRODUCT
< prev index next >