< prev index next >

src/hotspot/share/opto/library_call.cpp

Print this page

4587 
4588   // If this is a virtual call, we generate a funny guard.  We pull out
4589   // the vtable entry corresponding to hashCode() from the target object.
4590   // If the target method which we are calling happens to be the native
4591   // Object hashCode() method, we pass the guard.  We do not need this
4592   // guard for non-virtual calls -- the caller is known to be the native
4593   // Object hashCode().
4594   if (is_virtual) {
4595     // After null check, get the object's klass.
4596     Node* obj_klass = load_object_klass(obj);
4597     generate_virtual_guard(obj_klass, slow_region);
4598   }
4599 
4600   // Get the header out of the object, use LoadMarkNode when available
4601   Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
4602   // The control of the load must be null. Otherwise, the load can move before
4603   // the null check after castPP removal.
4604   Node* no_ctrl = nullptr;
4605   Node* header = make_load(no_ctrl, header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
4606 
4607   // Test the header to see if it is safe to read w.r.t. locking.
4608   Node *lock_mask      = _gvn.MakeConX(markWord::lock_mask_in_place);
4609   Node *lmasked_header = _gvn.transform(new AndXNode(header, lock_mask));
4610   if (LockingMode == LM_LIGHTWEIGHT) {
4611     Node *monitor_val   = _gvn.MakeConX(markWord::monitor_value);
4612     Node *chk_monitor   = _gvn.transform(new CmpXNode(lmasked_header, monitor_val));
4613     Node *test_monitor  = _gvn.transform(new BoolNode(chk_monitor, BoolTest::eq));
4614 
4615     generate_slow_guard(test_monitor, slow_region);
4616   } else {
4617     Node *unlocked_val      = _gvn.MakeConX(markWord::unlocked_value);
4618     Node *chk_unlocked      = _gvn.transform(new CmpXNode(lmasked_header, unlocked_val));
4619     Node *test_not_unlocked = _gvn.transform(new BoolNode(chk_unlocked, BoolTest::ne));

4620 
4621     generate_slow_guard(test_not_unlocked, slow_region);

4622   }
4623 
4624   // Get the hash value and check to see that it has been properly assigned.
4625   // We depend on hash_mask being at most 32 bits and avoid the use of
4626   // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
4627   // vm: see markWord.hpp.
4628   Node *hash_mask      = _gvn.intcon(markWord::hash_mask);
4629   Node *hash_shift     = _gvn.intcon(markWord::hash_shift);
4630   Node *hshifted_header= _gvn.transform(new URShiftXNode(header, hash_shift));
4631   // This hack lets the hash bits live anywhere in the mark object now, as long
4632   // as the shift drops the relevant bits into the low 32 bits.  Note that
4633   // Java spec says that HashCode is an int so there's no point in capturing
4634   // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build).
4635   hshifted_header      = ConvX2I(hshifted_header);
4636   Node *hash_val       = _gvn.transform(new AndINode(hshifted_header, hash_mask));
4637 
4638   Node *no_hash_val    = _gvn.intcon(markWord::no_hash);
4639   Node *chk_assigned   = _gvn.transform(new CmpINode( hash_val, no_hash_val));
4640   Node *test_assigned  = _gvn.transform(new BoolNode( chk_assigned, BoolTest::eq));
4641 
4642   generate_slow_guard(test_assigned, slow_region);
4643 
4644   Node* init_mem = reset_memory();
4645   // fill in the rest of the null path:
4646   result_io ->init_req(_null_path, i_o());
4647   result_mem->init_req(_null_path, init_mem);
4648 
4649   result_val->init_req(_fast_path, hash_val);

4587 
4588   // If this is a virtual call, we generate a funny guard.  We pull out
4589   // the vtable entry corresponding to hashCode() from the target object.
4590   // If the target method which we are calling happens to be the native
4591   // Object hashCode() method, we pass the guard.  We do not need this
4592   // guard for non-virtual calls -- the caller is known to be the native
4593   // Object hashCode().
4594   if (is_virtual) {
4595     // After null check, get the object's klass.
4596     Node* obj_klass = load_object_klass(obj);
4597     generate_virtual_guard(obj_klass, slow_region);
4598   }
4599 
4600   // Get the header out of the object, use LoadMarkNode when available
4601   Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
4602   // The control of the load must be null. Otherwise, the load can move before
4603   // the null check after castPP removal.
4604   Node* no_ctrl = nullptr;
4605   Node* header = make_load(no_ctrl, header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
4606 
4607   if (!UseObjectMonitorTable) {
4608     // Test the header to see if it is safe to read w.r.t. locking.
4609     Node *lock_mask      = _gvn.MakeConX(markWord::lock_mask_in_place);
4610     Node *lmasked_header = _gvn.transform(new AndXNode(header, lock_mask));
4611     if (LockingMode == LM_LIGHTWEIGHT) {
4612       Node *monitor_val   = _gvn.MakeConX(markWord::monitor_value);
4613       Node *chk_monitor   = _gvn.transform(new CmpXNode(lmasked_header, monitor_val));
4614       Node *test_monitor  = _gvn.transform(new BoolNode(chk_monitor, BoolTest::eq));
4615 
4616       generate_slow_guard(test_monitor, slow_region);
4617     } else {
4618       Node *unlocked_val      = _gvn.MakeConX(markWord::unlocked_value);
4619       Node *chk_unlocked      = _gvn.transform(new CmpXNode(lmasked_header, unlocked_val));
4620       Node *test_not_unlocked = _gvn.transform(new BoolNode(chk_unlocked, BoolTest::ne));
4621 
4622       generate_slow_guard(test_not_unlocked, slow_region);
4623     }
4624   }
4625 
4626   // Get the hash value and check to see that it has been properly assigned.
4627   // We depend on hash_mask being at most 32 bits and avoid the use of
4628   // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
4629   // vm: see markWord.hpp.
4630   Node *hash_mask      = _gvn.intcon(UseCompactObjectHeaders ? markWord::hash_mask_compact  : markWord::hash_mask);
4631   Node *hash_shift     = _gvn.intcon(UseCompactObjectHeaders ? markWord::hash_shift_compact : markWord::hash_shift);
4632   Node *hshifted_header= _gvn.transform(new URShiftXNode(header, hash_shift));
4633   // This hack lets the hash bits live anywhere in the mark object now, as long
4634   // as the shift drops the relevant bits into the low 32 bits.  Note that
4635   // Java spec says that HashCode is an int so there's no point in capturing
4636   // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build).
4637   hshifted_header      = ConvX2I(hshifted_header);
4638   Node *hash_val       = _gvn.transform(new AndINode(hshifted_header, hash_mask));
4639 
4640   Node *no_hash_val    = _gvn.intcon(markWord::no_hash);
4641   Node *chk_assigned   = _gvn.transform(new CmpINode( hash_val, no_hash_val));
4642   Node *test_assigned  = _gvn.transform(new BoolNode( chk_assigned, BoolTest::eq));
4643 
4644   generate_slow_guard(test_assigned, slow_region);
4645 
4646   Node* init_mem = reset_memory();
4647   // fill in the rest of the null path:
4648   result_io ->init_req(_null_path, i_o());
4649   result_mem->init_req(_null_path, init_mem);
4650 
4651   result_val->init_req(_fast_path, hash_val);
< prev index next >