src/share/vm/opto/graphKit.cpp

Print this page
rev 4495 : 8012715: Fix G1 bug in graphKit.cpp: Access of PtrQueue::_index was int not 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.

*** 3563,3572 **** --- 3563,3573 ---- Node* tls = __ thread(); // ThreadLocalStorage Node* no_ctrl = NULL; Node* no_base = __ top(); Node* zero = __ ConI(0); + Node* zeroX = __ ConX(0); float likely = PROB_LIKELY(0.999); float unlikely = PROB_UNLIKELY(0.999); BasicType active_type = in_bytes(PtrQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE;
*** 3588,3598 **** // Now some of the values Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); // if (!marking) __ if_then(marking, BoolTest::ne, zero); { ! Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); if (do_load) { // load original value // alias_idx correct?? pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx); --- 3589,3601 ---- // Now some of the values Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); // if (!marking) __ if_then(marking, BoolTest::ne, zero); { ! 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 // alias_idx correct?? pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx);
*** 3601,3626 **** // if (pre_val != NULL) __ if_then(pre_val, BoolTest::ne, null()); { 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); { // 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 // Now get the buffer location we will log the previous value into and store it ! Node *log_addr = __ AddP(no_base, buffer, next_indexX); __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw); // update the index ! __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); } __ else_(); { // logging buffer is full, call the runtime const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type(); --- 3604,3623 ---- // if (pre_val != NULL) __ if_then(pre_val, BoolTest::ne, null()); { Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); // is the queue for this thread full? ! __ if_then(index, BoolTest::ne, zeroX, likely); { // decrement the index ! 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_index); __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw); // update the index ! __ store(__ ctrl(), index_adr, next_index, index_bt, Compile::AliasIdxRaw); } __ else_(); { // logging buffer is full, call the runtime const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type();
*** 3644,3672 **** Node* index_adr, Node* buffer, const TypeFunc* tf) { Node* zero = __ ConI(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); { ! 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); __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw); ! __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); } __ else_(); { __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread()); } __ end_if(); --- 3641,3664 ---- Node* index_adr, Node* buffer, const TypeFunc* tf) { 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, zeroX); { ! 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, 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()); } __ end_if();
*** 3723,3733 **** Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset)); // 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* 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 // Must use ctrl to prevent "integerized oop" existing across safepoint Node* cast = __ CastPX(__ ctrl(), adr); --- 3715,3725 ---- Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset)); // 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, 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 // Must use ctrl to prevent "integerized oop" existing across safepoint Node* cast = __ CastPX(__ ctrl(), adr);