8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t

In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.

Reviewed-by: twisti, johnc
This commit is contained in:
Martin Doerr 2013-04-24 14:48:43 -07:00 committed by John Cuthbertson
parent 316993b3db
commit 19d99e3d92

View File

@ -3564,7 +3564,8 @@ void GraphKit::g1_write_barrier_pre(bool do_load,
Node* no_ctrl = NULL;
Node* no_base = __ top();
Node* zero = __ ConI(0);
Node* zero = __ ConI(0);
Node* zeroX = __ ConX(0);
float likely = PROB_LIKELY(0.999);
float unlikely = PROB_UNLIKELY(0.999);
@ -3590,7 +3591,9 @@ void GraphKit::g1_write_barrier_pre(bool do_load,
// if (!marking)
__ if_then(marking, BoolTest::ne, zero); {
Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw);
BasicType index_bt = TypeX_X->basic_type();
assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 PtrQueue::_index with wrong size.");
Node* index = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw);
if (do_load) {
// load original value
@ -3603,22 +3606,16 @@ void GraphKit::g1_write_barrier_pre(bool do_load,
Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
// is the queue for this thread full?
__ if_then(index, BoolTest::ne, zero, likely); {
__ if_then(index, BoolTest::ne, zeroX, likely); {
// decrement the index
Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t)));
Node* next_indexX = next_index;
#ifdef _LP64
// We could refine the type for what it's worth
// const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
#endif
Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
// Now get the buffer location we will log the previous value into and store it
Node *log_addr = __ AddP(no_base, buffer, next_indexX);
Node *log_addr = __ AddP(no_base, buffer, next_index);
__ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw);
// update the index
__ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw);
__ store(__ ctrl(), index_adr, next_index, index_bt, Compile::AliasIdxRaw);
} __ else_(); {
@ -3645,26 +3642,21 @@ void GraphKit::g1_mark_card(IdealKit& ideal,
Node* buffer,
const TypeFunc* tf) {
Node* zero = __ ConI(0);
Node* zero = __ ConI(0);
Node* zeroX = __ ConX(0);
Node* no_base = __ top();
BasicType card_bt = T_BYTE;
// Smash zero into card. MUST BE ORDERED WRT TO STORE
__ storeCM(__ ctrl(), card_adr, zero, oop_store, oop_alias_idx, card_bt, Compile::AliasIdxRaw);
// Now do the queue work
__ if_then(index, BoolTest::ne, zero); {
__ if_then(index, BoolTest::ne, zeroX); {
Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t)));
Node* next_indexX = next_index;
#ifdef _LP64
// We could refine the type for what it's worth
// const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
#endif // _LP64
Node* log_addr = __ AddP(no_base, buffer, next_indexX);
Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
Node* log_addr = __ AddP(no_base, buffer, next_index);
__ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw);
__ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw);
__ store(__ ctrl(), index_adr, next_index, TypeX_X->basic_type(), Compile::AliasIdxRaw);
} __ else_(); {
__ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread());
@ -3725,7 +3717,7 @@ void GraphKit::g1_write_barrier_post(Node* oop_store,
// Now some values
// Use ctrl to avoid hoisting these values past a safepoint, which could
// potentially reset these fields in the JavaThread.
Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw);
Node* index = __ load(__ ctrl(), index_adr, TypeX_X, TypeX_X->basic_type(), Compile::AliasIdxRaw);
Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
// Convert the store obj pointer to an int prior to doing math on it