< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page

3826 
3827   // If this is a virtual call, we generate a funny guard.  We pull out
3828   // the vtable entry corresponding to hashCode() from the target object.
3829   // If the target method which we are calling happens to be the native
3830   // Object hashCode() method, we pass the guard.  We do not need this
3831   // guard for non-virtual calls -- the caller is known to be the native
3832   // Object hashCode().
3833   if (is_virtual) {
3834     // After null check, get the object's klass.
3835     Node* obj_klass = load_object_klass(obj);
3836     generate_virtual_guard(obj_klass, slow_region);
3837   }
3838 
3839   // Get the header out of the object, use LoadMarkNode when available
3840   Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
3841   // The control of the load must be null. Otherwise, the load can move before
3842   // the null check after castPP removal.
3843   Node* no_ctrl = nullptr;
3844   Node* header = make_load(no_ctrl, header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
3845 
3846   // Test the header to see if it is unlocked.
3847   Node *lock_mask      = _gvn.MakeConX(markWord::biased_lock_mask_in_place);
3848   Node *lmasked_header = _gvn.transform(new AndXNode(header, lock_mask));
3849   Node *unlocked_val   = _gvn.MakeConX(markWord::unlocked_value);
3850   Node *chk_unlocked   = _gvn.transform(new CmpXNode( lmasked_header, unlocked_val));
3851   Node *test_unlocked  = _gvn.transform(new BoolNode( chk_unlocked, BoolTest::ne));

3852 
3853   generate_slow_guard(test_unlocked, slow_region);







3854 
3855   // Get the hash value and check to see that it has been properly assigned.
3856   // We depend on hash_mask being at most 32 bits and avoid the use of
3857   // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
3858   // vm: see markWord.hpp.
3859   Node *hash_mask      = _gvn.intcon(markWord::hash_mask);
3860   Node *hash_shift     = _gvn.intcon(markWord::hash_shift);
3861   Node *hshifted_header= _gvn.transform(new URShiftXNode(header, hash_shift));
3862   // This hack lets the hash bits live anywhere in the mark object now, as long
3863   // as the shift drops the relevant bits into the low 32 bits.  Note that
3864   // Java spec says that HashCode is an int so there's no point in capturing
3865   // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build).
3866   hshifted_header      = ConvX2I(hshifted_header);
3867   Node *hash_val       = _gvn.transform(new AndINode(hshifted_header, hash_mask));
3868 
3869   Node *no_hash_val    = _gvn.intcon(markWord::no_hash);
3870   Node *chk_assigned   = _gvn.transform(new CmpINode( hash_val, no_hash_val));
3871   Node *test_assigned  = _gvn.transform(new BoolNode( chk_assigned, BoolTest::eq));
3872 
3873   generate_slow_guard(test_assigned, slow_region);
3874 
3875   Node* init_mem = reset_memory();
3876   // fill in the rest of the null path:
3877   result_io ->init_req(_null_path, i_o());
3878   result_mem->init_req(_null_path, init_mem);
3879 
3880   result_val->init_req(_fast_path, hash_val);

3826 
3827   // If this is a virtual call, we generate a funny guard.  We pull out
3828   // the vtable entry corresponding to hashCode() from the target object.
3829   // If the target method which we are calling happens to be the native
3830   // Object hashCode() method, we pass the guard.  We do not need this
3831   // guard for non-virtual calls -- the caller is known to be the native
3832   // Object hashCode().
3833   if (is_virtual) {
3834     // After null check, get the object's klass.
3835     Node* obj_klass = load_object_klass(obj);
3836     generate_virtual_guard(obj_klass, slow_region);
3837   }
3838 
3839   // Get the header out of the object, use LoadMarkNode when available
3840   Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
3841   // The control of the load must be null. Otherwise, the load can move before
3842   // the null check after castPP removal.
3843   Node* no_ctrl = nullptr;
3844   Node* header = make_load(no_ctrl, header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
3845 
3846   // Test the header to see if it is safe to read w.r.t. locking.
3847   Node *lock_mask      = _gvn.MakeConX(markWord::biased_lock_mask_in_place);
3848   Node *lmasked_header = _gvn.transform(new AndXNode(header, lock_mask));
3849   if (LockingMode == LM_LIGHTWEIGHT) {
3850     Node *monitor_val   = _gvn.MakeConX(markWord::monitor_value);
3851     Node *chk_monitor   = _gvn.transform(new CmpXNode(lmasked_header, monitor_val));
3852     Node *test_monitor  = _gvn.transform(new BoolNode(chk_monitor, BoolTest::eq));
3853 
3854     generate_slow_guard(test_monitor, slow_region);
3855   } else {
3856     Node *unlocked_val      = _gvn.MakeConX(markWord::unlocked_value);
3857     Node *chk_unlocked      = _gvn.transform(new CmpXNode(lmasked_header, unlocked_val));
3858     Node *test_not_unlocked = _gvn.transform(new BoolNode(chk_unlocked, BoolTest::ne));
3859 
3860     generate_slow_guard(test_not_unlocked, slow_region);
3861   }
3862 
3863   // Get the hash value and check to see that it has been properly assigned.
3864   // We depend on hash_mask being at most 32 bits and avoid the use of
3865   // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
3866   // vm: see markWord.hpp.
3867   Node *hash_mask      = _gvn.intcon(UseCompactObjectHeaders ? markWord::hash_mask_compact  : markWord::hash_mask);
3868   Node *hash_shift     = _gvn.intcon(UseCompactObjectHeaders ? markWord::hash_shift_compact : markWord::hash_shift);
3869   Node *hshifted_header= _gvn.transform(new URShiftXNode(header, hash_shift));
3870   // This hack lets the hash bits live anywhere in the mark object now, as long
3871   // as the shift drops the relevant bits into the low 32 bits.  Note that
3872   // Java spec says that HashCode is an int so there's no point in capturing
3873   // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build).
3874   hshifted_header      = ConvX2I(hshifted_header);
3875   Node *hash_val       = _gvn.transform(new AndINode(hshifted_header, hash_mask));
3876 
3877   Node *no_hash_val    = _gvn.intcon(markWord::no_hash);
3878   Node *chk_assigned   = _gvn.transform(new CmpINode( hash_val, no_hash_val));
3879   Node *test_assigned  = _gvn.transform(new BoolNode( chk_assigned, BoolTest::eq));
3880 
3881   generate_slow_guard(test_assigned, slow_region);
3882 
3883   Node* init_mem = reset_memory();
3884   // fill in the rest of the null path:
3885   result_io ->init_req(_null_path, i_o());
3886   result_mem->init_req(_null_path, init_mem);
3887 
3888   result_val->init_req(_fast_path, hash_val);
< prev index next >