提交 e48f372e 编写于 作者: K kvn

6880053: assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL)

Summary: Removed second CheckCastPP and use MembarCPUOrder after arraycopy to cloned object.
Reviewed-by: never
上级 c07c50fa
...@@ -3894,7 +3894,6 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b ...@@ -3894,7 +3894,6 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b
assert(obj_size != NULL, ""); assert(obj_size != NULL, "");
Node* raw_obj = alloc_obj->in(1); Node* raw_obj = alloc_obj->in(1);
assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); assert(alloc_obj->is_CheckCastPP() && raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), "");
assert(alloc_obj->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL, "should be more precise than Object");
if (ReduceBulkZeroing) { if (ReduceBulkZeroing) {
// We will be completely responsible for initializing this object - // We will be completely responsible for initializing this object -
...@@ -3904,19 +3903,10 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b ...@@ -3904,19 +3903,10 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b
guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), ""); guarantee(alloc != NULL && alloc->maybe_set_complete(&_gvn), "");
} }
// Cast to Object for arraycopy.
// We can't use the original CheckCastPP since it should be moved
// after the arraycopy to prevent stores flowing above it.
Node* new_obj = new(C, 2) CheckCastPPNode(alloc_obj->in(0), raw_obj,
TypeInstPtr::NOTNULL);
new_obj = _gvn.transform(new_obj);
// Substitute in the locally valid dest_oop.
replace_in_map(alloc_obj, new_obj);
// Copy the fastest available way. // Copy the fastest available way.
// TODO: generate fields copies for small objects instead. // TODO: generate fields copies for small objects instead.
Node* src = obj; Node* src = obj;
Node* dest = new_obj; Node* dest = alloc_obj;
Node* size = _gvn.transform(obj_size); Node* size = _gvn.transform(obj_size);
// Exclude the header but include array length to copy by 8 bytes words. // Exclude the header but include array length to copy by 8 bytes words.
...@@ -3962,7 +3952,7 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b ...@@ -3962,7 +3952,7 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b
int raw_adr_idx = Compile::AliasIdxRaw; int raw_adr_idx = Compile::AliasIdxRaw;
post_barrier(control(), post_barrier(control(),
memory(raw_adr_type), memory(raw_adr_type),
new_obj, alloc_obj,
no_particular_field, no_particular_field,
raw_adr_idx, raw_adr_idx,
no_particular_value, no_particular_value,
...@@ -3970,16 +3960,8 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b ...@@ -3970,16 +3960,8 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b
false); false);
} }
// Move the original CheckCastPP after arraycopy. // Do not let reads from the cloned object float above the arraycopy.
_gvn.hash_delete(alloc_obj); insert_mem_bar(Op_MemBarCPUOrder);
alloc_obj->set_req(0, control());
// Replace raw memory edge with new CheckCastPP to have a live oop
// at safepoints instead of raw value.
assert(new_obj->is_CheckCastPP() && new_obj->in(1) == alloc_obj->in(1), "sanity");
alloc_obj->set_req(1, new_obj); // cast to the original type
_gvn.hash_find_insert(alloc_obj); // put back into GVN table
// Restore in the locally valid dest_oop.
replace_in_map(new_obj, alloc_obj);
} }
//------------------------inline_native_clone---------------------------- //------------------------inline_native_clone----------------------------
...@@ -4448,17 +4430,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, ...@@ -4448,17 +4430,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type,
InitializeNode* init = alloc->initialization(); InitializeNode* init = alloc->initialization();
assert(init->is_complete(), "we just did this"); assert(init->is_complete(), "we just did this");
assert(dest->is_CheckCastPP(), "sanity"); assert(dest->is_CheckCastPP(), "sanity");
assert(dest->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL, "type should be more precise than Object");
assert(dest->in(0)->in(0) == init, "dest pinned"); assert(dest->in(0)->in(0) == init, "dest pinned");
// Cast to Object for arraycopy.
// We can't use the original CheckCastPP since it should be moved
// after the arraycopy to prevent stores flowing above it.
Node* new_obj = new(C, 2) CheckCastPPNode(dest->in(0), dest->in(1),
TypeInstPtr::NOTNULL);
dest = _gvn.transform(new_obj);
// Substitute in the locally valid dest_oop.
replace_in_map(original_dest, dest);
adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory
// From this point on, every exit path is responsible for // From this point on, every exit path is responsible for
// initializing any non-copied parts of the object to zero. // initializing any non-copied parts of the object to zero.
...@@ -4788,18 +4760,6 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, ...@@ -4788,18 +4760,6 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type,
set_i_o( _gvn.transform(result_i_o) ); set_i_o( _gvn.transform(result_i_o) );
set_memory( _gvn.transform(result_memory), adr_type ); set_memory( _gvn.transform(result_memory), adr_type );
if (dest != original_dest) {
// Pin the "finished" array node after the arraycopy/zeroing operations.
_gvn.hash_delete(original_dest);
original_dest->set_req(0, control());
// Replace raw memory edge with new CheckCastPP to have a live oop
// at safepoints instead of raw value.
assert(dest->is_CheckCastPP() && dest->in(1) == original_dest->in(1), "sanity");
original_dest->set_req(1, dest); // cast to the original type
_gvn.hash_find_insert(original_dest); // put back into GVN table
// Restore in the locally valid dest_oop.
replace_in_map(dest, original_dest);
}
// The memory edges above are precise in order to model effects around // The memory edges above are precise in order to model effects around
// array copies accurately to allow value numbering of field loads around // array copies accurately to allow value numbering of field loads around
// arraycopy. Such field loads, both before and after, are common in Java // arraycopy. Such field loads, both before and after, are common in Java
...@@ -4810,7 +4770,9 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type, ...@@ -4810,7 +4770,9 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type,
// The next memory barrier is added to avoid it. If the arraycopy can be // The next memory barrier is added to avoid it. If the arraycopy can be
// optimized away (which it can, sometimes) then we can manually remove // optimized away (which it can, sometimes) then we can manually remove
// the membar also. // the membar also.
if (InsertMemBarAfterArraycopy) //
// Do not let reads from the cloned object float above the arraycopy.
if (InsertMemBarAfterArraycopy || alloc != NULL)
insert_mem_bar(Op_MemBarCPUOrder); insert_mem_bar(Op_MemBarCPUOrder);
} }
......
...@@ -2236,12 +2236,12 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int ...@@ -2236,12 +2236,12 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int
//------------------------------make------------------------------------------- //------------------------------make-------------------------------------------
const TypeOopPtr *TypeOopPtr::make(PTR ptr, const TypeOopPtr *TypeOopPtr::make(PTR ptr,
int offset) { int offset, int instance_id) {
assert(ptr != Constant, "no constant generic pointers"); assert(ptr != Constant, "no constant generic pointers");
ciKlass* k = ciKlassKlass::make(); ciKlass* k = ciKlassKlass::make();
bool xk = false; bool xk = false;
ciObject* o = NULL; ciObject* o = NULL;
return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, InstanceBot))->hashcons(); return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id))->hashcons();
} }
...@@ -2330,7 +2330,8 @@ const Type *TypeOopPtr::xmeet( const Type *t ) const { ...@@ -2330,7 +2330,8 @@ const Type *TypeOopPtr::xmeet( const Type *t ) const {
case OopPtr: { // Meeting to other OopPtrs case OopPtr: { // Meeting to other OopPtrs
const TypeOopPtr *tp = t->is_oopptr(); const TypeOopPtr *tp = t->is_oopptr();
return make( meet_ptr(tp->ptr()), meet_offset(tp->offset()) ); int instance_id = meet_instance_id(tp->instance_id());
return make( meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id );
} }
case InstPtr: // For these, flip the call around to cut down case InstPtr: // For these, flip the call around to cut down
...@@ -2801,7 +2802,7 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const { ...@@ -2801,7 +2802,7 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const {
case OopPtr: { // Meeting to OopPtrs case OopPtr: { // Meeting to OopPtrs
// Found a OopPtr type vs self-InstPtr type // Found a OopPtr type vs self-InstPtr type
const TypePtr *tp = t->is_oopptr(); const TypeOopPtr *tp = t->is_oopptr();
int offset = meet_offset(tp->offset()); int offset = meet_offset(tp->offset());
PTR ptr = meet_ptr(tp->ptr()); PTR ptr = meet_ptr(tp->ptr());
switch (tp->ptr()) { switch (tp->ptr()) {
...@@ -2812,8 +2813,10 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const { ...@@ -2812,8 +2813,10 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const {
(ptr == Constant ? const_oop() : NULL), offset, instance_id); (ptr == Constant ? const_oop() : NULL), offset, instance_id);
} }
case NotNull: case NotNull:
case BotPTR: case BotPTR: {
return TypeOopPtr::make(ptr, offset); int instance_id = meet_instance_id(tp->instance_id());
return TypeOopPtr::make(ptr, offset, instance_id);
}
default: typerr(t); default: typerr(t);
} }
} }
...@@ -3259,7 +3262,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { ...@@ -3259,7 +3262,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
case OopPtr: { // Meeting to OopPtrs case OopPtr: { // Meeting to OopPtrs
// Found a OopPtr type vs self-AryPtr type // Found a OopPtr type vs self-AryPtr type
const TypePtr *tp = t->is_oopptr(); const TypeOopPtr *tp = t->is_oopptr();
int offset = meet_offset(tp->offset()); int offset = meet_offset(tp->offset());
PTR ptr = meet_ptr(tp->ptr()); PTR ptr = meet_ptr(tp->ptr());
switch (tp->ptr()) { switch (tp->ptr()) {
...@@ -3270,8 +3273,10 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { ...@@ -3270,8 +3273,10 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
_ary, _klass, _klass_is_exact, offset, instance_id); _ary, _klass, _klass_is_exact, offset, instance_id);
} }
case BotPTR: case BotPTR:
case NotNull: case NotNull: {
return TypeOopPtr::make(ptr, offset); int instance_id = meet_instance_id(tp->instance_id());
return TypeOopPtr::make(ptr, offset, instance_id);
}
default: ShouldNotReachHere(); default: ShouldNotReachHere();
} }
} }
......
...@@ -714,7 +714,7 @@ public: ...@@ -714,7 +714,7 @@ public:
static const TypeOopPtr* make_from_constant(ciObject* o); static const TypeOopPtr* make_from_constant(ciObject* o);
// Make a generic (unclassed) pointer to an oop. // Make a generic (unclassed) pointer to an oop.
static const TypeOopPtr* make(PTR ptr, int offset); static const TypeOopPtr* make(PTR ptr, int offset, int instance_id = InstanceBot);
ciObject* const_oop() const { return _const_oop; } ciObject* const_oop() const { return _const_oop; }
virtual ciKlass* klass() const { return _klass; } virtual ciKlass* klass() const { return _klass; }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册