< prev index next >
src/share/vm/opto/graphKit.cpp
Print this page
*** 1292,1302 ****
//-----------
// Branch to failure if null
float ok_prob = PROB_MAX; // a priori estimate: nulls never happen
Deoptimization::DeoptReason reason;
if (assert_null) {
! reason = Deoptimization::Reason_null_assert;
} else if (type == T_OBJECT) {
reason = Deoptimization::reason_null_check(speculative);
} else {
reason = Deoptimization::Reason_div0_check;
}
--- 1292,1302 ----
//-----------
// Branch to failure if null
float ok_prob = PROB_MAX; // a priori estimate: nulls never happen
Deoptimization::DeoptReason reason;
if (assert_null) {
! reason = Deoptimization::reason_null_assert(speculative);
} else if (type == T_OBJECT) {
reason = Deoptimization::reason_null_check(speculative);
} else {
reason = Deoptimization::Reason_div0_check;
}
*** 2131,2141 ****
* @param exact_kls type from profiling
* @param maybe_null did profiling see null?
*
* @return node with improved type
*/
! Node* GraphKit::record_profile_for_speculation(Node* n, ciKlass* exact_kls, bool maybe_null) {
const Type* current_type = _gvn.type(n);
assert(UseTypeSpeculation, "type speculation must be on");
const TypePtr* speculative = current_type->speculative();
--- 2131,2141 ----
* @param exact_kls type from profiling
* @param maybe_null did profiling see null?
*
* @return node with improved type
*/
! Node* GraphKit::record_profile_for_speculation(Node* n, ciKlass* exact_kls, ProfilePtrKind ptr_kind) {
const Type* current_type = _gvn.type(n);
assert(UseTypeSpeculation, "type speculation must be on");
const TypePtr* speculative = current_type->speculative();
*** 2143,2165 ****
if (current_type->would_improve_type(exact_kls, jvms()->depth())) {
const TypeKlassPtr* tklass = TypeKlassPtr::make(exact_kls);
const TypeOopPtr* xtype = tklass->as_instance_type();
assert(xtype->klass_is_exact(), "Should be exact");
// Any reason to believe n is not null (from this profiling or a previous one)?
! const TypePtr* ptr = (maybe_null && current_type->speculative_maybe_null()) ? TypePtr::BOTTOM : TypePtr::NOTNULL;
// record the new speculative type's depth
speculative = xtype->cast_to_ptr_type(ptr->ptr())->is_ptr();
speculative = speculative->with_inline_depth(jvms()->depth());
! } else if (current_type->would_improve_ptr(maybe_null)) {
// Profiling report that null was never seen so we can change the
// speculative type to non null ptr.
! assert(!maybe_null, "nothing to improve");
! if (speculative == NULL) {
! speculative = TypePtr::NOTNULL;
} else {
const TypePtr* ptr = TypePtr::NOTNULL;
speculative = speculative->cast_to_ptr_type(ptr->ptr())->is_ptr();
}
}
if (speculative != current_type->speculative()) {
// Build a type with a speculative type (what we think we know
--- 2143,2170 ----
if (current_type->would_improve_type(exact_kls, jvms()->depth())) {
const TypeKlassPtr* tklass = TypeKlassPtr::make(exact_kls);
const TypeOopPtr* xtype = tklass->as_instance_type();
assert(xtype->klass_is_exact(), "Should be exact");
// Any reason to believe n is not null (from this profiling or a previous one)?
! assert(ptr_kind != ProfileAlwaysNull, "impossible here");
! const TypePtr* ptr = (ptr_kind == ProfileMaybeNull && current_type->speculative_maybe_null()) ? TypePtr::BOTTOM : TypePtr::NOTNULL;
// record the new speculative type's depth
speculative = xtype->cast_to_ptr_type(ptr->ptr())->is_ptr();
speculative = speculative->with_inline_depth(jvms()->depth());
! } else if (current_type->would_improve_ptr(ptr_kind)) {
// Profiling report that null was never seen so we can change the
// speculative type to non null ptr.
! if (ptr_kind == ProfileAlwaysNull) {
! speculative = TypePtr::NULL_PTR;
} else {
+ assert(ptr_kind == ProfileNeverNull, "nothing else is an improvement");
const TypePtr* ptr = TypePtr::NOTNULL;
+ if (speculative != NULL) {
speculative = speculative->cast_to_ptr_type(ptr->ptr())->is_ptr();
+ } else {
+ speculative = ptr;
+ }
}
}
if (speculative != current_type->speculative()) {
// Build a type with a speculative type (what we think we know
*** 2189,2206 ****
Node* GraphKit::record_profiled_receiver_for_speculation(Node* n) {
if (!UseTypeSpeculation) {
return n;
}
ciKlass* exact_kls = profile_has_unique_klass();
! bool maybe_null = true;
! if (java_bc() == Bytecodes::_checkcast ||
java_bc() == Bytecodes::_instanceof ||
! java_bc() == Bytecodes::_aastore) {
ciProfileData* data = method()->method_data()->bci_to_data(bci());
! maybe_null = data == NULL ? true : data->as_BitData()->null_seen();
}
! return record_profile_for_speculation(n, exact_kls, maybe_null);
}
/**
* Record profiling data from argument profiling at an invoke with the
* type system so that it can propagate it (speculation)
--- 2194,2227 ----
Node* GraphKit::record_profiled_receiver_for_speculation(Node* n) {
if (!UseTypeSpeculation) {
return n;
}
ciKlass* exact_kls = profile_has_unique_klass();
! ProfilePtrKind ptr_kind = ProfileMaybeNull;
! if ((java_bc() == Bytecodes::_checkcast ||
java_bc() == Bytecodes::_instanceof ||
! java_bc() == Bytecodes::_aastore) &&
! method()->method_data()->is_mature()) {
ciProfileData* data = method()->method_data()->bci_to_data(bci());
! if (data != NULL) {
! if (!data->as_BitData()->null_seen()) {
! ptr_kind = ProfileNeverNull;
! } else {
! assert(data->is_ReceiverTypeData(), "bad profile data type");
! ciReceiverTypeData* call = (ciReceiverTypeData*)data->as_ReceiverTypeData();
! uint i = 0;
! for (; i < call->row_limit(); i++) {
! ciKlass* receiver = call->receiver(i);
! if (receiver != NULL) {
! break;
! }
! }
! ptr_kind = (i == call->row_limit()) ? ProfileAlwaysNull : ProfileMaybeNull;
}
! }
! }
! return record_profile_for_speculation(n, exact_kls, ptr_kind);
}
/**
* Record profiling data from argument profiling at an invoke with the
* type system so that it can propagate it (speculation)
*** 2216,2229 ****
int nargs = tf->domain()->cnt() - TypeFunc::Parms;
int skip = Bytecodes::has_receiver(bc) ? 1 : 0;
for (int j = skip, i = 0; j < nargs && i < TypeProfileArgsLimit; j++) {
const Type *targ = tf->domain()->field_at(j + TypeFunc::Parms);
if (targ->basic_type() == T_OBJECT || targ->basic_type() == T_ARRAY) {
! bool maybe_null = true;
ciKlass* better_type = NULL;
! if (method()->argument_profiled_type(bci(), i, better_type, maybe_null)) {
! record_profile_for_speculation(argument(j), better_type, maybe_null);
}
i++;
}
}
}
--- 2237,2250 ----
int nargs = tf->domain()->cnt() - TypeFunc::Parms;
int skip = Bytecodes::has_receiver(bc) ? 1 : 0;
for (int j = skip, i = 0; j < nargs && i < TypeProfileArgsLimit; j++) {
const Type *targ = tf->domain()->field_at(j + TypeFunc::Parms);
if (targ->basic_type() == T_OBJECT || targ->basic_type() == T_ARRAY) {
! ProfilePtrKind ptr_kind = ProfileMaybeNull;
ciKlass* better_type = NULL;
! if (method()->argument_profiled_type(bci(), i, better_type, ptr_kind)) {
! record_profile_for_speculation(argument(j), better_type, ptr_kind);
}
i++;
}
}
}
*** 2236,2249 ****
if (!UseTypeSpeculation) {
return;
}
for (int i = 0, j = 0; i < method()->arg_size() ; i++) {
if (_gvn.type(local(i))->isa_oopptr()) {
! bool maybe_null = true;
ciKlass* better_type = NULL;
! if (method()->parameter_profiled_type(j, better_type, maybe_null)) {
! record_profile_for_speculation(local(i), better_type, maybe_null);
}
j++;
}
}
}
--- 2257,2270 ----
if (!UseTypeSpeculation) {
return;
}
for (int i = 0, j = 0; i < method()->arg_size() ; i++) {
if (_gvn.type(local(i))->isa_oopptr()) {
! ProfilePtrKind ptr_kind = ProfileMaybeNull;
ciKlass* better_type = NULL;
! if (method()->parameter_profiled_type(j, better_type, ptr_kind)) {
! record_profile_for_speculation(local(i), better_type, ptr_kind);
}
j++;
}
}
}
*** 2254,2270 ****
*/
void GraphKit::record_profiled_return_for_speculation() {
if (!UseTypeSpeculation) {
return;
}
! bool maybe_null = true;
ciKlass* better_type = NULL;
! if (method()->return_profiled_type(bci(), better_type, maybe_null)) {
// If profiling reports a single type for the return value,
// feed it to the type system so it can propagate it as a
// speculative type
! record_profile_for_speculation(stack(sp()-1), better_type, maybe_null);
}
}
void GraphKit::round_double_result(ciMethod* dest_method) {
// A non-strict method may return a double value which has an extended
--- 2275,2291 ----
*/
void GraphKit::record_profiled_return_for_speculation() {
if (!UseTypeSpeculation) {
return;
}
! ProfilePtrKind ptr_kind = ProfileMaybeNull;
ciKlass* better_type = NULL;
! if (method()->return_profiled_type(bci(), better_type, ptr_kind)) {
// If profiling reports a single type for the return value,
// feed it to the type system so it can propagate it as a
// speculative type
! record_profile_for_speculation(stack(sp()-1), better_type, ptr_kind);
}
}
void GraphKit::round_double_result(ciMethod* dest_method) {
// A non-strict method may return a double value which has an extended
*** 2936,2951 ****
int static_res = C->static_subtype_check(superk, subk);
known_statically = (static_res == Compile::SSC_always_true || static_res == Compile::SSC_always_false);
}
}
! if (known_statically && UseTypeSpeculation) {
! // If we know the type check always succeeds then we don't use the
! // profiling data at this bytecode. Don't lose it, feed it to the
! // type system as a speculative type.
! not_null_obj = record_profiled_receiver_for_speculation(not_null_obj);
! } else {
const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr();
// We may not have profiling here or it may not help us. If we
// have a speculative type use it to perform an exact cast.
ciKlass* spec_obj_type = obj_type->speculative_type();
if (spec_obj_type != NULL || (ProfileDynamicTypes && data != NULL)) {
--- 2957,2967 ----
int static_res = C->static_subtype_check(superk, subk);
known_statically = (static_res == Compile::SSC_always_true || static_res == Compile::SSC_always_false);
}
}
! if (!known_statically) {
const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr();
// We may not have profiling here or it may not help us. If we
// have a speculative type use it to perform an exact cast.
ciKlass* spec_obj_type = obj_type->speculative_type();
if (spec_obj_type != NULL || (ProfileDynamicTypes && data != NULL)) {
*** 2975,2984 ****
--- 2991,3009 ----
phi ->init_req(_fail_path, intcon(0));
// Return final merged results
set_control( _gvn.transform(region) );
record_for_igvn(region);
+
+ // If we know the type check always succeeds then we don't use the
+ // profiling data at this bytecode. Don't lose it, feed it to the
+ // type system as a speculative type.
+ if (safe_for_replace) {
+ Node* casted_obj = record_profiled_receiver_for_speculation(obj);
+ replace_in_map(obj, casted_obj);
+ }
+
return _gvn.transform(phi);
}
//-------------------------------gen_checkcast---------------------------------
// Generate a checkcast idiom. Used by both the checkcast bytecode and the
*** 3115,3125 ****
// replace_in_map( obj, res );
// Return final merged results
set_control( _gvn.transform(region) );
record_for_igvn(region);
! return res;
}
//------------------------------next_monitor-----------------------------------
// What number should be given to the next monitor?
int GraphKit::next_monitor() {
--- 3140,3151 ----
// replace_in_map( obj, res );
// Return final merged results
set_control( _gvn.transform(region) );
record_for_igvn(region);
!
! return record_profiled_receiver_for_speculation(res);
}
//------------------------------next_monitor-----------------------------------
// What number should be given to the next monitor?
int GraphKit::next_monitor() {
< prev index next >