< 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 >