提交 be82a9f4 编写于 作者: K kvn

6959430: Make sure raw loads have control edge

Summary: check that raw loads have control edge
Reviewed-by: never, twisti
上级 6f10a24e
...@@ -2000,6 +2000,17 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { ...@@ -2000,6 +2000,17 @@ static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) {
} }
} }
#ifdef ASSERT
if( n->is_Mem() ) {
Compile* C = Compile::current();
int alias_idx = C->get_alias_index(n->as_Mem()->adr_type());
assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw ||
// oop will be recorded in oop map if load crosses safepoint
n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() ||
LoadNode::is_immutable_value(n->in(MemNode::Address))),
"raw memory operations should have control edge");
}
#endif
// Count FPU ops and common calls, implements item (3) // Count FPU ops and common calls, implements item (3)
switch( nop ) { switch( nop ) {
// Count all float operations that may use FPU // Count all float operations that may use FPU
......
...@@ -1789,9 +1789,10 @@ void GraphKit::increment_counter(address counter_addr) { ...@@ -1789,9 +1789,10 @@ void GraphKit::increment_counter(address counter_addr) {
void GraphKit::increment_counter(Node* counter_addr) { void GraphKit::increment_counter(Node* counter_addr) {
int adr_type = Compile::AliasIdxRaw; int adr_type = Compile::AliasIdxRaw;
Node* cnt = make_load(NULL, counter_addr, TypeInt::INT, T_INT, adr_type); Node* ctrl = control();
Node* cnt = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type);
Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1))); Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1)));
store_to_memory( NULL, counter_addr, incr, T_INT, adr_type ); store_to_memory( ctrl, counter_addr, incr, T_INT, adr_type );
} }
...@@ -2771,11 +2772,7 @@ FastLockNode* GraphKit::shared_lock(Node* obj) { ...@@ -2771,11 +2772,7 @@ FastLockNode* GraphKit::shared_lock(Node* obj) {
// Update the counter for this lock. Don't bother using an atomic // Update the counter for this lock. Don't bother using an atomic
// operation since we don't require absolute accuracy. // operation since we don't require absolute accuracy.
lock->create_lock_counter(map()->jvms()); lock->create_lock_counter(map()->jvms());
int adr_type = Compile::AliasIdxRaw; increment_counter(lock->counter()->addr());
Node* counter_addr = makecon(TypeRawPtr::make(lock->counter()->addr()));
Node* cnt = make_load(NULL, counter_addr, TypeInt::INT, T_INT, adr_type);
Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1)));
store_to_memory(control(), counter_addr, incr, T_INT, adr_type);
} }
#endif #endif
......
...@@ -3512,8 +3512,7 @@ bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) { ...@@ -3512,8 +3512,7 @@ bool LibraryCallKit::inline_native_hashcode(bool is_virtual, bool is_static) {
// Get the header out of the object, use LoadMarkNode when available // Get the header out of the object, use LoadMarkNode when available
Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes()); Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
Node* header = make_load(NULL, header_addr, TypeRawPtr::BOTTOM, T_ADDRESS); Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type());
header = _gvn.transform( new (C, 2) CastP2XNode(NULL, header) );
// Test the header to see if it is unlocked. // Test the header to see if it is unlocked.
Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place); Node *lock_mask = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place);
...@@ -5202,7 +5201,7 @@ LibraryCallKit::generate_checkcast_arraycopy(const TypePtr* adr_type, ...@@ -5202,7 +5201,7 @@ LibraryCallKit::generate_checkcast_arraycopy(const TypePtr* adr_type,
// super_check_offset, for the desired klass. // super_check_offset, for the desired klass.
int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc); int sco_offset = Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc);
Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset); Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset);
Node* n3 = new(C, 3) LoadINode(NULL, immutable_memory(), p3, TypeRawPtr::BOTTOM); Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr());
Node* check_offset = _gvn.transform(n3); Node* check_offset = _gvn.transform(n3);
Node* check_value = dest_elem_klass; Node* check_value = dest_elem_klass;
......
...@@ -1431,7 +1431,7 @@ PhaseMacroExpand::initialize_object(AllocateNode* alloc, ...@@ -1431,7 +1431,7 @@ PhaseMacroExpand::initialize_object(AllocateNode* alloc,
Node* mark_node = NULL; Node* mark_node = NULL;
// For now only enable fast locking for non-array types // For now only enable fast locking for non-array types
if (UseBiasedLocking && (length == NULL)) { if (UseBiasedLocking && (length == NULL)) {
mark_node = make_load(NULL, rawmem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeRawPtr::BOTTOM, T_ADDRESS); mark_node = make_load(control, rawmem, klass_node, Klass::prototype_header_offset_in_bytes() + sizeof(oopDesc), TypeRawPtr::BOTTOM, T_ADDRESS);
} else { } else {
mark_node = makecon(TypeRawPtr::make((address)markOopDesc::prototype())); mark_node = makecon(TypeRawPtr::make((address)markOopDesc::prototype()));
} }
......
...@@ -815,6 +815,16 @@ void LoadNode::dump_spec(outputStream *st) const { ...@@ -815,6 +815,16 @@ void LoadNode::dump_spec(outputStream *st) const {
} }
#endif #endif
#ifdef ASSERT
//----------------------------is_immutable_value-------------------------------
// Helper function to allow a raw load without control edge for some cases
bool LoadNode::is_immutable_value(Node* adr) {
return (adr->is_AddP() && adr->in(AddPNode::Base)->is_top() &&
adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal &&
(adr->in(AddPNode::Offset)->find_intptr_t_con(-1) ==
in_bytes(JavaThread::osthread_offset())));
}
#endif
//----------------------------LoadNode::make----------------------------------- //----------------------------LoadNode::make-----------------------------------
// Polymorphic factory method: // Polymorphic factory method:
...@@ -828,6 +838,11 @@ Node *LoadNode::make( PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const Type ...@@ -828,6 +838,11 @@ Node *LoadNode::make( PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const Type
assert(!(adr_type->isa_aryptr() && assert(!(adr_type->isa_aryptr() &&
adr_type->offset() == arrayOopDesc::length_offset_in_bytes()), adr_type->offset() == arrayOopDesc::length_offset_in_bytes()),
"use LoadRangeNode instead"); "use LoadRangeNode instead");
// Check control edge of raw loads
assert( ctl != NULL || C->get_alias_index(adr_type) != Compile::AliasIdxRaw ||
// oop will be recorded in oop map if load crosses safepoint
rt->isa_oopptr() || is_immutable_value(adr),
"raw memory operations should have control edge");
switch (bt) { switch (bt) {
case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() ); case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int() );
case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() ); case T_BYTE: return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int() );
...@@ -2064,6 +2079,8 @@ Node* LoadRangeNode::Identity( PhaseTransform *phase ) { ...@@ -2064,6 +2079,8 @@ Node* LoadRangeNode::Identity( PhaseTransform *phase ) {
// Polymorphic factory method: // Polymorphic factory method:
StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt ) { StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt ) {
Compile* C = gvn.C; Compile* C = gvn.C;
assert( C->get_alias_index(adr_type) != Compile::AliasIdxRaw ||
ctl != NULL, "raw memory operations should have control edge");
switch (bt) { switch (bt) {
case T_BOOLEAN: case T_BOOLEAN:
......
...@@ -189,6 +189,10 @@ public: ...@@ -189,6 +189,10 @@ public:
#ifndef PRODUCT #ifndef PRODUCT
virtual void dump_spec(outputStream *st) const; virtual void dump_spec(outputStream *st) const;
#endif #endif
#ifdef ASSERT
// Helper function to allow a raw load without control edge for some cases
static bool is_immutable_value(Node* adr);
#endif
protected: protected:
const Type* load_array_final_field(const TypeKlassPtr *tkls, const Type* load_array_final_field(const TypeKlassPtr *tkls,
ciKlass* klass) const; ciKlass* klass) const;
......
...@@ -88,15 +88,16 @@ Node *Parse::fetch_interpreter_state(int index, ...@@ -88,15 +88,16 @@ Node *Parse::fetch_interpreter_state(int index,
Node *local_addrs_base) { Node *local_addrs_base) {
Node *mem = memory(Compile::AliasIdxRaw); Node *mem = memory(Compile::AliasIdxRaw);
Node *adr = basic_plus_adr( local_addrs_base, local_addrs, -index*wordSize ); Node *adr = basic_plus_adr( local_addrs_base, local_addrs, -index*wordSize );
Node *ctl = control();
// Very similar to LoadNode::make, except we handle un-aligned longs and // Very similar to LoadNode::make, except we handle un-aligned longs and
// doubles on Sparc. Intel can handle them just fine directly. // doubles on Sparc. Intel can handle them just fine directly.
Node *l; Node *l;
switch( bt ) { // Signature is flattened switch( bt ) { // Signature is flattened
case T_INT: l = new (C, 3) LoadINode( 0, mem, adr, TypeRawPtr::BOTTOM ); break; case T_INT: l = new (C, 3) LoadINode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
case T_FLOAT: l = new (C, 3) LoadFNode( 0, mem, adr, TypeRawPtr::BOTTOM ); break; case T_FLOAT: l = new (C, 3) LoadFNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
case T_ADDRESS: l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); break; case T_ADDRESS: l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); break;
case T_OBJECT: l = new (C, 3) LoadPNode( 0, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break; case T_OBJECT: l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break;
case T_LONG: case T_LONG:
case T_DOUBLE: { case T_DOUBLE: {
// Since arguments are in reverse order, the argument address 'adr' // Since arguments are in reverse order, the argument address 'adr'
...@@ -104,12 +105,12 @@ Node *Parse::fetch_interpreter_state(int index, ...@@ -104,12 +105,12 @@ Node *Parse::fetch_interpreter_state(int index,
adr = basic_plus_adr( local_addrs_base, local_addrs, -(index+1)*wordSize ); adr = basic_plus_adr( local_addrs_base, local_addrs, -(index+1)*wordSize );
if( Matcher::misaligned_doubles_ok ) { if( Matcher::misaligned_doubles_ok ) {
l = (bt == T_DOUBLE) l = (bt == T_DOUBLE)
? (Node*)new (C, 3) LoadDNode( 0, mem, adr, TypeRawPtr::BOTTOM ) ? (Node*)new (C, 3) LoadDNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
: (Node*)new (C, 3) LoadLNode( 0, mem, adr, TypeRawPtr::BOTTOM ); : (Node*)new (C, 3) LoadLNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
} else { } else {
l = (bt == T_DOUBLE) l = (bt == T_DOUBLE)
? (Node*)new (C, 3) LoadD_unalignedNode( 0, mem, adr, TypeRawPtr::BOTTOM ) ? (Node*)new (C, 3) LoadD_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
: (Node*)new (C, 3) LoadL_unalignedNode( 0, mem, adr, TypeRawPtr::BOTTOM ); : (Node*)new (C, 3) LoadL_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
} }
break; break;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册