< prev index next >

src/cpu/x86/vm/c1_LIRGenerator_x86.cpp

Print this page

        

@@ -31,10 +31,11 @@
 #include "c1/c1_Runtime1.hpp"
 #include "c1/c1_ValueStack.hpp"
 #include "ci/ciArray.hpp"
 #include "ci/ciObjArrayKlass.hpp"
 #include "ci/ciTypeArrayKlass.hpp"
+#include "prims/unsafe.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "vmreg_x86.inline.hpp"
 
 #ifdef ASSERT

@@ -717,11 +718,11 @@
 
 
 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
   assert(x->number_of_arguments() == 4, "wrong type");
   LIRItem obj   (x->argument_at(0), this);  // object
-  LIRItem offset(x->argument_at(1), this);  // offset of field
+  LIRItem off   (x->argument_at(1), this);  // offset of field
   LIRItem cmp   (x->argument_at(2), this);  // value to compare with field
   LIRItem val   (x->argument_at(3), this);  // replace field with val if matches cmp
 
   assert(obj.type()->tag() == objectTag, "invalid type");
 

@@ -731,11 +732,13 @@
   assert(cmp.type()->tag() == type->tag(), "invalid type");
   assert(val.type()->tag() == type->tag(), "invalid type");
 
   // get address of field
   obj.load_item();
-  offset.load_nonconstant();
+  off.load_nonconstant();
+
+  LIR_Opr offset = unpack_offset(obj.result(), off.result());
 
   if (type == objectType) {
     cmp.load_item_force(FrameMap::rax_oop_opr);
     val.load_item();
   } else if (type == intType) {

@@ -748,32 +751,32 @@
     ShouldNotReachHere();
   }
 
   LIR_Opr addr = new_pointer_register();
   LIR_Address* a;
-  if(offset.result()->is_constant()) {
+  if(offset->is_constant()) {
 #ifdef _LP64
-    jlong c = offset.result()->as_jlong();
+    jlong c = offset->as_jlong();
     if ((jlong)((jint)c) == c) {
       a = new LIR_Address(obj.result(),
                           (jint)c,
                           as_BasicType(type));
     } else {
       LIR_Opr tmp = new_register(T_LONG);
-      __ move(offset.result(), tmp);
+      __ move(offset, tmp);
       a = new LIR_Address(obj.result(),
                           tmp,
                           as_BasicType(type));
     }
 #else
     a = new LIR_Address(obj.result(),
-                        offset.result()->as_jint(),
+                        offset->as_jint(),
                         as_BasicType(type));
 #endif
   } else {
     a = new LIR_Address(obj.result(),
-                        offset.result(),
+                        offset,
                         LIR_Address::times_1,
                         0,
                         as_BasicType(type));
   }
   __ leal(LIR_OprFact::address(a), addr);

@@ -1431,24 +1434,36 @@
       __ move(data, addr);
     }
   }
 }
 
+LIR_Opr LIRGenerator::unpack_offset(LIR_Opr src, LIR_Opr off) {
+  LIR_Opr tmp = new_register(NOT_LP64(T_INT) LP64_ONLY(T_LONG));
+  LabelObj* Lcont = new LabelObj();
+  __ move(off, tmp);
+  __ cmp(lir_cond_equal, src, LIR_OprFact::oopConst(NULL));
+  __ branch(lir_cond_equal, T_OBJECT, Lcont->label());
+  __ shift_right(tmp, Unsafe::offset_shift, tmp);
+  __ branch_destination(Lcont->label());
+  return tmp;
+}
+
 void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
   BasicType type = x->basic_type();
   LIRItem src(x->object(), this);
   LIRItem off(x->offset(), this);
   LIRItem value(x->value(), this);
 
   src.load_item();
   value.load_item();
   off.load_nonconstant();
 
+  LIR_Opr offset = unpack_offset(src.result(), off.result());
+
   LIR_Opr dst = rlock_result(x, type);
   LIR_Opr data = value.result();
   bool is_obj = (type == T_ARRAY || type == T_OBJECT);
-  LIR_Opr offset = off.result();
 
   assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type");
   LIR_Address* addr;
   if (offset->is_constant()) {
 #ifdef _LP64
< prev index next >