提交 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
assert(obj_size != NULL, "");
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->as_CheckCastPP()->type() != TypeInstPtr::NOTNULL, "should be more precise than Object");
if (ReduceBulkZeroing) {
// 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
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.
// TODO: generate fields copies for small objects instead.
Node* src = obj;
Node* dest = new_obj;
Node* dest = alloc_obj;
Node* size = _gvn.transform(obj_size);
// 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
int raw_adr_idx = Compile::AliasIdxRaw;
post_barrier(control(),
memory(raw_adr_type),
new_obj,
alloc_obj,
no_particular_field,
raw_adr_idx,
no_particular_value,
......@@ -3970,16 +3960,8 @@ void LibraryCallKit::copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, b
false);
}
// Move the original CheckCastPP after arraycopy.
_gvn.hash_delete(alloc_obj);
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);
// Do not let reads from the cloned object float above the arraycopy.
insert_mem_bar(Op_MemBarCPUOrder);
}
//------------------------inline_native_clone----------------------------
......@@ -4448,17 +4430,7 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type,
InitializeNode* init = alloc->initialization();
assert(init->is_complete(), "we just did this");
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");
// 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
// From this point on, every exit path is responsible for
// initializing any non-copied parts of the object to zero.
......@@ -4788,18 +4760,6 @@ LibraryCallKit::generate_arraycopy(const TypePtr* adr_type,
set_i_o( _gvn.transform(result_i_o) );
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
// array copies accurately to allow value numbering of field loads around
// arraycopy. Such field loads, both before and after, are common in Java
......@@ -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
// optimized away (which it can, sometimes) then we can manually remove
// 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);
}
......
......@@ -2236,12 +2236,12 @@ TypeOopPtr::TypeOopPtr( TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int
//------------------------------make-------------------------------------------
const TypeOopPtr *TypeOopPtr::make(PTR ptr,
int offset) {
int offset, int instance_id) {
assert(ptr != Constant, "no constant generic pointers");
ciKlass* k = ciKlassKlass::make();
bool xk = false;
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 {
case OopPtr: { // Meeting to other OopPtrs
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
......@@ -2801,7 +2802,7 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const {
case OopPtr: { // Meeting to OopPtrs
// 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());
PTR ptr = meet_ptr(tp->ptr());
switch (tp->ptr()) {
......@@ -2812,8 +2813,10 @@ const Type *TypeInstPtr::xmeet( const Type *t ) const {
(ptr == Constant ? const_oop() : NULL), offset, instance_id);
}
case NotNull:
case BotPTR:
return TypeOopPtr::make(ptr, offset);
case BotPTR: {
int instance_id = meet_instance_id(tp->instance_id());
return TypeOopPtr::make(ptr, offset, instance_id);
}
default: typerr(t);
}
}
......@@ -3259,7 +3262,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
case OopPtr: { // Meeting to OopPtrs
// 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());
PTR ptr = meet_ptr(tp->ptr());
switch (tp->ptr()) {
......@@ -3270,8 +3273,10 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const {
_ary, _klass, _klass_is_exact, offset, instance_id);
}
case BotPTR:
case NotNull:
return TypeOopPtr::make(ptr, offset);
case NotNull: {
int instance_id = meet_instance_id(tp->instance_id());
return TypeOopPtr::make(ptr, offset, instance_id);
}
default: ShouldNotReachHere();
}
}
......
......@@ -714,7 +714,7 @@ public:
static const TypeOopPtr* make_from_constant(ciObject* o);
// 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; }
virtual ciKlass* klass() const { return _klass; }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册