< prev index next >
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
Print this page
rev 12906 : [mq]: gc_interface
*** 31,40 ****
--- 31,41 ----
#include "c1/c1_Runtime1.hpp"
#include "c1/c1_ValueStack.hpp"
#include "ci/ciArray.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciTypeArrayKlass.hpp"
+ #include "gc/shared/c1BarrierSetCodeGen.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "vmreg_x86.inline.hpp"
#ifdef ASSERT
*** 149,161 ****
LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
int shift, int disp, BasicType type) {
assert(base->is_register(), "must be");
if (index->is_constant()) {
return new LIR_Address(base,
! ((intx)(index->as_constant_ptr()->as_jint()) << shift) + disp,
type);
} else {
return new LIR_Address(base, index, (LIR_Address::Scale)shift, disp, type);
}
}
--- 150,180 ----
LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
int shift, int disp, BasicType type) {
assert(base->is_register(), "must be");
if (index->is_constant()) {
+ LIR_Const *constant = index->as_constant_ptr();
+ #ifdef _LP64
+ jlong c;
+ if (constant->type() == T_INT) {
+ c = (jlong(index->as_jint()) << shift) + disp;
+ } else {
+ assert(constant->type() == T_LONG, "should be");
+ c = (index->as_jlong() << shift) + disp;
+ }
+ if ((jlong)((jint)c) == c) {
+ return new LIR_Address(base, (jint)c, type);
+ } else {
+ LIR_Opr tmp = new_register(T_LONG);
+ __ move(index, tmp);
+ return new LIR_Address(base, tmp, type);
+ }
+ #else
return new LIR_Address(base,
! ((intx)(constant->as_jint()) << shift) + disp,
type);
+ #endif
} else {
return new LIR_Address(base, index, (LIR_Address::Scale)shift, disp, type);
}
}
*** 255,344 ****
void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) {
BasicType type = item->type();
__ store(item, new LIR_Address(FrameMap::rsp_opr, in_bytes(offset_from_sp), type));
}
! //----------------------------------------------------------------------
! // visitor functions
! //----------------------------------------------------------------------
!
!
! void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
! assert(x->is_pinned(),"");
! bool needs_range_check = x->compute_needs_range_check();
! bool use_length = x->length() != NULL;
! bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT;
! bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL ||
! !get_jobject_constant(x->value())->is_null_object() ||
! x->should_profile());
!
! LIRItem array(x->array(), this);
! LIRItem index(x->index(), this);
! LIRItem value(x->value(), this);
! LIRItem length(this);
!
! array.load_item();
! index.load_nonconstant();
!
! if (use_length && needs_range_check) {
! length.set_instruction(x->length());
! length.load_item();
!
! }
! if (needs_store_check || x->check_boolean()) {
! value.load_item();
! } else {
! value.load_for_store(x->elt_type());
! }
!
! set_no_result(x);
!
! // the CodeEmitInfo must be duplicated for each different
! // LIR-instruction because spilling can occur anywhere between two
! // instructions and so the debug information must be different
! CodeEmitInfo* range_check_info = state_for(x);
! CodeEmitInfo* null_check_info = NULL;
! if (x->needs_null_check()) {
! null_check_info = new CodeEmitInfo(range_check_info);
! }
!
! // emit array address setup early so it schedules better
! LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store);
!
! if (GenerateRangeChecks && needs_range_check) {
! if (use_length) {
! __ cmp(lir_cond_belowEqual, length.result(), index.result());
! __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
! } else {
! array_range_check(array.result(), index.result(), null_check_info, range_check_info);
! // range_check also does the null check
! null_check_info = NULL;
! }
! }
!
! if (GenerateArrayStoreCheck && needs_store_check) {
LIR_Opr tmp1 = new_register(objectType);
LIR_Opr tmp2 = new_register(objectType);
LIR_Opr tmp3 = new_register(objectType);
!
! CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info);
! __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci());
! }
!
! if (obj_store) {
! // Needs GC write barriers.
! pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
! true /* do_load */, false /* patch */, NULL);
! __ move(value.result(), array_addr, null_check_info);
! // Seems to be a precise
! post_barrier(LIR_OprFact::address(array_addr), value.result());
! } else {
! LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
! __ move(result, array_addr, null_check_info);
! }
}
void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
assert(x->is_pinned(),"");
LIRItem obj(x->obj(), this);
obj.load_item();
--- 274,293 ----
void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) {
BasicType type = item->type();
__ store(item, new LIR_Address(FrameMap::rsp_opr, in_bytes(offset_from_sp), type));
}
! void LIRGenerator::array_store_check(LIR_Opr value, LIR_Opr array, CodeEmitInfo* store_check_info, ciMethod* profiled_method, int profiled_bci) {
LIR_Opr tmp1 = new_register(objectType);
LIR_Opr tmp2 = new_register(objectType);
LIR_Opr tmp3 = new_register(objectType);
! __ store_check(value, array, tmp1, tmp2, tmp3, store_check_info, profiled_method, profiled_bci);
}
+ //----------------------------------------------------------------------
+ // visitor functions
+ //----------------------------------------------------------------------
void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
assert(x->is_pinned(),"");
LIRItem obj(x->obj(), this);
obj.load_item();
*** 715,811 ****
} else {
Unimplemented();
}
}
!
! 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 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");
!
! // In 64bit the type can be long, sparc doesn't have this assert
! // assert(offset.type()->tag() == intTag, "invalid type");
!
! 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();
!
! LIR_Opr addr = new_pointer_register();
! LIR_Address* a;
! if(offset.result()->is_constant()) {
! #ifdef _LP64
! jlong c = offset.result()->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);
! a = new LIR_Address(obj.result(),
! tmp,
! as_BasicType(type));
! }
! #else
! a = new LIR_Address(obj.result(),
! offset.result()->as_jint(),
! as_BasicType(type));
! #endif
! } else {
! a = new LIR_Address(obj.result(),
! offset.result(),
! 0,
! as_BasicType(type));
! }
! __ leal(LIR_OprFact::address(a), addr);
!
! if (type == objectType) { // Write-barrier needed for Object fields.
! // Do the pre-write barrier, if any.
! pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
! true /* do_load */, false /* patch */, NULL);
! }
!
! if (type == objectType) {
! cmp.load_item_force(FrameMap::rax_oop_opr);
! val.load_item();
! } else if (type == intType) {
! cmp.load_item_force(FrameMap::rax_opr);
! val.load_item();
! } else if (type == longType) {
! cmp.load_item_force(FrameMap::long0_opr);
! val.load_item_force(FrameMap::long1_opr);
} else {
! ShouldNotReachHere();
}
! LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience
! if (type == objectType)
! __ cas_obj(addr, cmp.result(), val.result(), ill, ill);
! else if (type == intType)
! __ cas_int(addr, cmp.result(), val.result(), ill, ill);
! else if (type == longType)
! __ cas_long(addr, cmp.result(), val.result(), ill, ill);
! else {
! ShouldNotReachHere();
! }
! // generate conditional move of boolean result
! LIR_Opr result = rlock_result(x);
! __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
! result, as_BasicType(type));
! if (type == objectType) { // Write-barrier needed for Object fields.
! // Seems to be precise
! post_barrier(addr, val.result());
! }
}
void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
assert(x->number_of_arguments() == 3, "wrong type");
assert(UseFMA, "Needs FMA instructions support.");
--- 664,715 ----
} else {
Unimplemented();
}
}
! LIR_Opr LIRGenerator::cas(BasicType type, LIR_Opr addr, LIRItem& cmp_value, LIRItem& new_value) {
! LIR_Opr result = new_register(T_INT);
! LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience
! if (type == T_OBJECT || type == T_ARRAY) {
! cmp_value.load_item_force(FrameMap::rax_oop_opr);
! new_value.load_item();
! __ cas_obj(addr, cmp_value.result(), new_value.result(), ill, ill);
! } else if (type == T_INT) {
! cmp_value.load_item_force(FrameMap::rax_opr);
! new_value.load_item();
! __ cas_int(addr, cmp_value.result(), new_value.result(), ill, ill);
! } else if (type == T_LONG) {
! cmp_value.load_item_force(FrameMap::long0_opr);
! new_value.load_item_force(FrameMap::long1_opr);
! __ cas_long(addr, cmp_value.result(), new_value.result(), ill, ill);
} else {
! Unimplemented();
}
+ __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
+ result, as_BasicType(new_value.type()));
+ return result;
+ }
! LIR_Opr LIRGenerator::swap(BasicType type, LIR_Opr addr, LIRItem& value) {
! bool is_oop = type == T_OBJECT || type == T_ARRAY;
! LIR_Opr result = new_register(type);
! value.load_item();
! // Because we want a 2-arg form of xchg and xadd
! __ move(value.result(), result);
! assert(type == T_INT || is_oop LP64_ONLY( || type == T_LONG ), "unexpected type");
! __ xchg(addr, result, result, LIR_OprFact::illegalOpr);
! return result;
! }
! LIR_Opr LIRGenerator::add(BasicType type, LIR_Opr addr, LIRItem& value) {
! LIR_Opr result = new_register(type);
! value.load_item();
! // Because we want a 2-arg form of xchg and xadd
! __ move(value.result(), result);
! assert(type == T_INT LP64_ONLY( || type == T_LONG ), "unexpected type");
! __ xadd(addr, result, result, LIR_OprFact::illegalOpr);
! return result;
}
void LIRGenerator::do_FmaIntrinsic(Intrinsic* x) {
assert(x->number_of_arguments() == 3, "wrong type");
assert(UseFMA, "Needs FMA instructions support.");
*** 1565,1576 ****
} else {
__ store(value, address, info);
}
}
-
-
void LIRGenerator::volatile_field_load(LIR_Address* address, LIR_Opr result,
CodeEmitInfo* info) {
if (address->type() == T_LONG) {
address = new LIR_Address(address->base(),
address->index(), address->scale(),
--- 1469,1478 ----
*** 1588,1689 ****
}
} else {
__ load(address, result, info);
}
}
-
- void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
- BasicType type, bool is_volatile) {
- if (is_volatile && type == T_LONG) {
- LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE);
- LIR_Opr tmp = new_register(T_DOUBLE);
- __ load(addr, tmp);
- LIR_Opr spill = new_register(T_LONG);
- set_vreg_flag(spill, must_start_in_memory);
- __ move(tmp, spill);
- __ move(spill, dst);
- } else {
- LIR_Address* addr = new LIR_Address(src, offset, type);
- __ load(addr, dst);
- }
- }
-
-
- void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
- BasicType type, bool is_volatile) {
- if (is_volatile && type == T_LONG) {
- LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE);
- LIR_Opr tmp = new_register(T_DOUBLE);
- LIR_Opr spill = new_register(T_DOUBLE);
- set_vreg_flag(spill, must_start_in_memory);
- __ move(data, spill);
- __ move(spill, tmp);
- __ move(tmp, addr);
- } else {
- LIR_Address* addr = new LIR_Address(src, offset, type);
- bool is_obj = (type == T_ARRAY || type == T_OBJECT);
- if (is_obj) {
- // Do the pre-write barrier, if any.
- pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
- true /* do_load */, false /* patch */, NULL);
- __ move(data, addr);
- assert(src->is_register(), "must be register");
- // Seems to be a precise address
- post_barrier(LIR_OprFact::address(addr), data);
- } else {
- __ move(data, addr);
- }
- }
- }
-
- 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();
-
- 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
- jlong c = offset->as_jlong();
- if ((jlong)((jint)c) == c) {
- addr = new LIR_Address(src.result(), (jint)c, type);
- } else {
- LIR_Opr tmp = new_register(T_LONG);
- __ move(offset, tmp);
- addr = new LIR_Address(src.result(), tmp, type);
- }
- #else
- addr = new LIR_Address(src.result(), offset->as_jint(), type);
- #endif
- } else {
- addr = new LIR_Address(src.result(), offset, type);
- }
-
- // Because we want a 2-arg form of xchg and xadd
- __ move(data, dst);
-
- if (x->is_add()) {
- __ xadd(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr);
- } else {
- if (is_obj) {
- // Do the pre-write barrier, if any.
- pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
- true /* do_load */, false /* patch */, NULL);
- }
- __ xchg(LIR_OprFact::address(addr), dst, dst, LIR_OprFact::illegalOpr);
- if (is_obj) {
- // Seems to be a precise address
- post_barrier(LIR_OprFact::address(addr), data);
- }
- }
- }
--- 1490,1494 ----
< prev index next >