diff options
Diffstat (limited to 'src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp')
-rw-r--r-- | src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index 75b7b6cdf..2d4b3a2f1 100644 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -1204,3 +1204,58 @@ void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset, __ load(addr, dst); } } + +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 dst = rlock_result(x, type); + LIR_Opr data = value.result(); + bool is_obj = (type == T_ARRAY || type == T_OBJECT); + LIR_Opr offset = off.result(); + + if (data != dst) { + __ move(data, dst); + data = dst; + } + + assert (!x->is_add() && (type == T_INT || (is_obj LP64_ONLY(&& UseCompressedOops))), "unexpected type"); + LIR_Address* addr; + if (offset->is_constant()) { + +#ifdef _LP64 + jlong l = offset->as_jlong(); + assert((jlong)((jint)l) == l, "offset too large for constant"); + jint c = (jint)l; +#else + jint c = offset->as_jint(); +#endif + addr = new LIR_Address(src.result(), c, type); + } else { + addr = new LIR_Address(src.result(), offset, type); + } + + LIR_Opr tmp = LIR_OprFact::illegalOpr; + LIR_Opr ptr = LIR_OprFact::illegalOpr; + + if (is_obj) { + // Do the pre-write barrier, if any. + // barriers on sparc don't work with a base + index address + tmp = FrameMap::G3_opr; + ptr = new_pointer_register(); + __ add(src.result(), off.result(), ptr); + pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */, + true /* do_load */, false /* patch */, NULL); + } + __ xchg(LIR_OprFact::address(addr), data, dst, tmp); + if (is_obj) { + // Seems to be a precise address + post_barrier(ptr, data); + } +} |