comparison src/share/vm/opto/graphKit.cpp @ 10185:d50cc62e94ff

8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t Summary: 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 Contributed-by: Martin Doerr <martin.doerr@sap.com>
author johnc
date Wed, 24 Apr 2013 14:48:43 -0700
parents 30f42e691e70
children 6f3fd5150b67
comparison
equal deleted inserted replaced
10184:9d75bcd7c890 10185:d50cc62e94ff
3562 3562
3563 Node* tls = __ thread(); // ThreadLocalStorage 3563 Node* tls = __ thread(); // ThreadLocalStorage
3564 3564
3565 Node* no_ctrl = NULL; 3565 Node* no_ctrl = NULL;
3566 Node* no_base = __ top(); 3566 Node* no_base = __ top();
3567 Node* zero = __ ConI(0); 3567 Node* zero = __ ConI(0);
3568 Node* zeroX = __ ConX(0);
3568 3569
3569 float likely = PROB_LIKELY(0.999); 3570 float likely = PROB_LIKELY(0.999);
3570 float unlikely = PROB_UNLIKELY(0.999); 3571 float unlikely = PROB_UNLIKELY(0.999);
3571 3572
3572 BasicType active_type = in_bytes(PtrQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE; 3573 BasicType active_type = in_bytes(PtrQueue::byte_width_of_active()) == 4 ? T_INT : T_BYTE;
3588 // Now some of the values 3589 // Now some of the values
3589 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw); 3590 Node* marking = __ load(__ ctrl(), marking_adr, TypeInt::INT, active_type, Compile::AliasIdxRaw);
3590 3591
3591 // if (!marking) 3592 // if (!marking)
3592 __ if_then(marking, BoolTest::ne, zero); { 3593 __ if_then(marking, BoolTest::ne, zero); {
3593 Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); 3594 BasicType index_bt = TypeX_X->basic_type();
3595 assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 PtrQueue::_index with wrong size.");
3596 Node* index = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw);
3594 3597
3595 if (do_load) { 3598 if (do_load) {
3596 // load original value 3599 // load original value
3597 // alias_idx correct?? 3600 // alias_idx correct??
3598 pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx); 3601 pre_val = __ load(no_ctrl, adr, val_type, bt, alias_idx);
3601 // if (pre_val != NULL) 3604 // if (pre_val != NULL)
3602 __ if_then(pre_val, BoolTest::ne, null()); { 3605 __ if_then(pre_val, BoolTest::ne, null()); {
3603 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); 3606 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
3604 3607
3605 // is the queue for this thread full? 3608 // is the queue for this thread full?
3606 __ if_then(index, BoolTest::ne, zero, likely); { 3609 __ if_then(index, BoolTest::ne, zeroX, likely); {
3607 3610
3608 // decrement the index 3611 // decrement the index
3609 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); 3612 Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
3610 Node* next_indexX = next_index;
3611 #ifdef _LP64
3612 // We could refine the type for what it's worth
3613 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
3614 next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
3615 #endif
3616 3613
3617 // Now get the buffer location we will log the previous value into and store it 3614 // Now get the buffer location we will log the previous value into and store it
3618 Node *log_addr = __ AddP(no_base, buffer, next_indexX); 3615 Node *log_addr = __ AddP(no_base, buffer, next_index);
3619 __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw); 3616 __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw);
3620 // update the index 3617 // update the index
3621 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); 3618 __ store(__ ctrl(), index_adr, next_index, index_bt, Compile::AliasIdxRaw);
3622 3619
3623 } __ else_(); { 3620 } __ else_(); {
3624 3621
3625 // logging buffer is full, call the runtime 3622 // logging buffer is full, call the runtime
3626 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type(); 3623 const TypeFunc *tf = OptoRuntime::g1_wb_pre_Type();
3643 Node* index, 3640 Node* index,
3644 Node* index_adr, 3641 Node* index_adr,
3645 Node* buffer, 3642 Node* buffer,
3646 const TypeFunc* tf) { 3643 const TypeFunc* tf) {
3647 3644
3648 Node* zero = __ ConI(0); 3645 Node* zero = __ ConI(0);
3646 Node* zeroX = __ ConX(0);
3649 Node* no_base = __ top(); 3647 Node* no_base = __ top();
3650 BasicType card_bt = T_BYTE; 3648 BasicType card_bt = T_BYTE;
3651 // Smash zero into card. MUST BE ORDERED WRT TO STORE 3649 // Smash zero into card. MUST BE ORDERED WRT TO STORE
3652 __ storeCM(__ ctrl(), card_adr, zero, oop_store, oop_alias_idx, card_bt, Compile::AliasIdxRaw); 3650 __ storeCM(__ ctrl(), card_adr, zero, oop_store, oop_alias_idx, card_bt, Compile::AliasIdxRaw);
3653 3651
3654 // Now do the queue work 3652 // Now do the queue work
3655 __ if_then(index, BoolTest::ne, zero); { 3653 __ if_then(index, BoolTest::ne, zeroX); {
3656 3654
3657 Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); 3655 Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
3658 Node* next_indexX = next_index; 3656 Node* log_addr = __ AddP(no_base, buffer, next_index);
3659 #ifdef _LP64
3660 // We could refine the type for what it's worth
3661 // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
3662 next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
3663 #endif // _LP64
3664 Node* log_addr = __ AddP(no_base, buffer, next_indexX);
3665 3657
3666 __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw); 3658 __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw);
3667 __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); 3659 __ store(__ ctrl(), index_adr, next_index, TypeX_X->basic_type(), Compile::AliasIdxRaw);
3668 3660
3669 } __ else_(); { 3661 } __ else_(); {
3670 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread()); 3662 __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread());
3671 } __ end_if(); 3663 } __ end_if();
3672 3664
3723 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset)); 3715 Node* index_adr = __ AddP(no_base, tls, __ ConX(index_offset));
3724 3716
3725 // Now some values 3717 // Now some values
3726 // Use ctrl to avoid hoisting these values past a safepoint, which could 3718 // Use ctrl to avoid hoisting these values past a safepoint, which could
3727 // potentially reset these fields in the JavaThread. 3719 // potentially reset these fields in the JavaThread.
3728 Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); 3720 Node* index = __ load(__ ctrl(), index_adr, TypeX_X, TypeX_X->basic_type(), Compile::AliasIdxRaw);
3729 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); 3721 Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw);
3730 3722
3731 // Convert the store obj pointer to an int prior to doing math on it 3723 // Convert the store obj pointer to an int prior to doing math on it
3732 // Must use ctrl to prevent "integerized oop" existing across safepoint 3724 // Must use ctrl to prevent "integerized oop" existing across safepoint
3733 Node* cast = __ CastPX(__ ctrl(), adr); 3725 Node* cast = __ CastPX(__ ctrl(), adr);