src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/opto/library_call.cpp
src/share/vm/opto/library_call.cpp
Print this page
rev 5462 : 8024069: replace_in_map() should operate on parent maps
Summary: type information gets lost because replace_in_map() doesn't update parent maps
Reviewed-by:
rev 5464 : 8024070: C2 needs some form of type speculation
Summary: record unused type profile information with type system, propagate and use it.
Reviewed-by:
rev 5465 : imported patch speculative-cleanup
*** 3351,3371 ****
// Side-effects region with the control path if the klass is null.
Node* kls = load_klass_from_mirror(mirror, never_see_null, region, _prim_path);
// If kls is null, we have a primitive mirror.
phi->init_req(_prim_path, prim_return_value);
if (stopped()) { set_result(region, phi); return true; }
Node* p; // handy temp
Node* null_ctl;
// Now that we have the non-null klass, we can perform the real query.
// For constant classes, the query will constant-fold in LoadNode::Value.
Node* query_value = top();
switch (id) {
case vmIntrinsics::_isInstance:
// nothing is an instance of a primitive type
! query_value = gen_instanceof(obj, kls);
break;
case vmIntrinsics::_getModifiers:
p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset()));
query_value = make_load(NULL, p, TypeInt::INT, T_INT);
--- 3351,3372 ----
// Side-effects region with the control path if the klass is null.
Node* kls = load_klass_from_mirror(mirror, never_see_null, region, _prim_path);
// If kls is null, we have a primitive mirror.
phi->init_req(_prim_path, prim_return_value);
if (stopped()) { set_result(region, phi); return true; }
+ bool safe_for_replace = (region->in(_prim_path) == top());
Node* p; // handy temp
Node* null_ctl;
// Now that we have the non-null klass, we can perform the real query.
// For constant classes, the query will constant-fold in LoadNode::Value.
Node* query_value = top();
switch (id) {
case vmIntrinsics::_isInstance:
// nothing is an instance of a primitive type
! query_value = gen_instanceof(obj, kls, safe_for_replace);
break;
case vmIntrinsics::_getModifiers:
p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset()));
query_value = make_load(NULL, p, TypeInt::INT, T_INT);
*** 4551,4562 ****
// (1) src and dest are arrays.
const Type* src_type = src->Value(&_gvn);
const Type* dest_type = dest->Value(&_gvn);
const TypeAryPtr* top_src = src_type->isa_aryptr();
const TypeAryPtr* top_dest = dest_type->isa_aryptr();
! if (top_src == NULL || top_src->klass() == NULL ||
! top_dest == NULL || top_dest->klass() == NULL) {
// Conservatively insert a memory barrier on all memory slices.
// Do not let writes into the source float below the arraycopy.
insert_mem_bar(Op_MemBarCPUOrder);
// Call StubRoutines::generic_arraycopy stub.
--- 4552,4617 ----
// (1) src and dest are arrays.
const Type* src_type = src->Value(&_gvn);
const Type* dest_type = dest->Value(&_gvn);
const TypeAryPtr* top_src = src_type->isa_aryptr();
const TypeAryPtr* top_dest = dest_type->isa_aryptr();
!
! // Do we have the type of src?
! bool has_src = (top_src != NULL && top_src->klass() != NULL);
! // Do we have the type of dest?
! bool has_dest = (top_dest != NULL && top_dest->klass() != NULL);
! // Is the type for src from speculation?
! bool src_spec = false;
! // Is the type for dest from speculation?
! bool dest_spec = false;
!
! if (!has_src || !has_dest) {
! // We don't have sufficient type information, let's see if
! // speculative types can help. We need to have types for both src
! // and dest so that it pays off.
!
! // Do we already have or could we have type information for src
! bool could_have_src = has_src;
! // Do we already have or could we have type information for dest
! bool could_have_dest = has_dest;
!
! ciKlass* src_k = NULL;
! if (!has_src) {
! src_k = src_type->is_oopptr()->speculative_type();
! if (src_k != NULL && src_k->is_array_klass()) {
! could_have_src = true;
! }
! }
!
! ciKlass* dest_k = NULL;
! if (!has_dest) {
! dest_k = dest_type->speculative_type();
! if (dest_k != NULL && dest_k->is_array_klass()) {
! could_have_dest = true;
! }
! }
!
! if (could_have_src && could_have_dest) {
! // This is going to pay off so emit the required guards
! if (!has_src) {
! src = maybe_cast_profiled_obj(src, src_k);
! src_type = _gvn.type(src);
! top_src = src_type->isa_aryptr();
! has_src = (top_src != NULL && top_src->klass() != NULL);
! src_spec = true;
! }
! if (!has_dest) {
! dest = maybe_cast_profiled_obj(dest, dest_k);
! dest_type = _gvn.type(dest);
! top_dest = dest_type->isa_aryptr();
! has_dest = (top_dest != NULL && top_dest->klass() != NULL);
! dest_spec = true;
! }
! }
! }
!
! if (!has_src || !has_dest) {
// Conservatively insert a memory barrier on all memory slices.
// Do not let writes into the source float below the arraycopy.
insert_mem_bar(Op_MemBarCPUOrder);
// Call StubRoutines::generic_arraycopy stub.
*** 4587,4596 ****
--- 4642,4684 ----
src, src_offset, dest, dest_offset, length,
/*dest_uninitialized*/false);
return true;
}
+ if (src_elem == T_OBJECT) {
+ // If both arrays are object arrays then having the exact types
+ // for both will remove the need for a subtype check at runtime
+ // before the call and may make it possible to pick a faster copy
+ // routine (without a subtype check on every element)
+ // Do we have the exact type of src?
+ bool could_have_src = src_spec;
+ // Do we have the exact type of dest?
+ bool could_have_dest = dest_spec;
+ ciKlass* src_k = top_src->klass(), *dest_k = top_dest->klass();
+ if (!src_spec) {
+ src_k = src_type->speculative_type();
+ if (src_k != NULL && src_k->is_array_klass()) {
+ could_have_src = true;
+ }
+ }
+ if (!dest_spec) {
+ dest_k = dest_type->speculative_type();
+ if (dest_k != NULL && dest_k->is_array_klass()) {
+ could_have_dest = true;
+ }
+ }
+ if (could_have_src && could_have_dest) {
+ // If we can have both exact types, emit the missing guards
+ if (could_have_src && !src_spec) {
+ src = maybe_cast_profiled_obj(src, src_k);
+ }
+ if (could_have_dest && !dest_spec) {
+ dest = maybe_cast_profiled_obj(dest, dest_k);
+ }
+ }
+ }
+
//---------------------------------------------------------------------------
// We will make a fast path for this call to arraycopy.
// We have the following tests left to perform:
//
src/share/vm/opto/library_call.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File