< prev index next >
src/hotspot/share/opto/callGenerator.cpp
Print this page
*** 651,665 ****
class PredictedCallGenerator : public CallGenerator {
ciKlass* _predicted_receiver;
CallGenerator* _if_missed;
CallGenerator* _if_hit;
float _hit_prob;
public:
PredictedCallGenerator(ciKlass* predicted_receiver,
CallGenerator* if_missed,
! CallGenerator* if_hit, float hit_prob)
: CallGenerator(if_missed->method())
{
// The call profile data may predict the hit_prob as extreme as 0 or 1.
// Remove the extremes values from the range.
if (hit_prob > PROB_MAX) hit_prob = PROB_MAX;
--- 651,667 ----
class PredictedCallGenerator : public CallGenerator {
ciKlass* _predicted_receiver;
CallGenerator* _if_missed;
CallGenerator* _if_hit;
float _hit_prob;
+ bool _exact_check;
public:
PredictedCallGenerator(ciKlass* predicted_receiver,
CallGenerator* if_missed,
! CallGenerator* if_hit, bool exact_check,
! float hit_prob)
: CallGenerator(if_missed->method())
{
// The call profile data may predict the hit_prob as extreme as 0 or 1.
// Remove the extremes values from the range.
if (hit_prob > PROB_MAX) hit_prob = PROB_MAX;
*** 667,676 ****
--- 669,679 ----
_predicted_receiver = predicted_receiver;
_if_missed = if_missed;
_if_hit = if_hit;
_hit_prob = hit_prob;
+ _exact_check = exact_check;
}
virtual bool is_virtual() const { return true; }
virtual bool is_inline() const { return _if_hit->is_inline(); }
virtual bool is_deferred() const { return _if_hit->is_deferred(); }
*** 681,705 ****
CallGenerator* CallGenerator::for_predicted_call(ciKlass* predicted_receiver,
CallGenerator* if_missed,
CallGenerator* if_hit,
float hit_prob) {
! return new PredictedCallGenerator(predicted_receiver, if_missed, if_hit, hit_prob);
}
JVMState* PredictedCallGenerator::generate(JVMState* jvms) {
GraphKit kit(jvms);
kit.C->print_inlining_update(this);
PhaseGVN& gvn = kit.gvn();
// We need an explicit receiver null_check before checking its type.
// We share a map with the caller, so his JVMS gets adjusted.
Node* receiver = kit.argument(0);
CompileLog* log = kit.C->log();
if (log != NULL) {
! log->elem("predicted_call bci='%d' klass='%d'",
! jvms->bci(), log->identify(_predicted_receiver));
}
receiver = kit.null_check_receiver_before_call(method());
if (kit.stopped()) {
return kit.transfer_exceptions_into_jvms();
--- 684,715 ----
CallGenerator* CallGenerator::for_predicted_call(ciKlass* predicted_receiver,
CallGenerator* if_missed,
CallGenerator* if_hit,
float hit_prob) {
! return new PredictedCallGenerator(predicted_receiver, if_missed, if_hit,
! /*exact_check=*/true, hit_prob);
}
+ CallGenerator* CallGenerator::for_guarded_call(ciKlass* guarded_receiver,
+ CallGenerator* if_missed,
+ CallGenerator* if_hit) {
+ return new PredictedCallGenerator(guarded_receiver, if_missed, if_hit,
+ /*exact_check=*/false, PROB_ALWAYS);
+ }
JVMState* PredictedCallGenerator::generate(JVMState* jvms) {
GraphKit kit(jvms);
kit.C->print_inlining_update(this);
PhaseGVN& gvn = kit.gvn();
// We need an explicit receiver null_check before checking its type.
// We share a map with the caller, so his JVMS gets adjusted.
Node* receiver = kit.argument(0);
CompileLog* log = kit.C->log();
if (log != NULL) {
! log->elem("predicted_call bci='%d' exact='%d' klass='%d'",
! jvms->bci(), (_exact_check ? 1 : 0), log->identify(_predicted_receiver));
}
receiver = kit.null_check_receiver_before_call(method());
if (kit.stopped()) {
return kit.transfer_exceptions_into_jvms();
*** 707,720 ****
// Make a copy of the replaced nodes in case we need to restore them
ReplacedNodes replaced_nodes = kit.map()->replaced_nodes();
replaced_nodes.clone();
! Node* exact_receiver = receiver; // will get updated in place...
! Node* slow_ctl = kit.type_check_receiver(receiver,
! _predicted_receiver, _hit_prob,
! &exact_receiver);
SafePointNode* slow_map = NULL;
JVMState* slow_jvms = NULL;
{ PreserveJVMState pjvms(&kit);
kit.set_control(slow_ctl);
--- 717,735 ----
// Make a copy of the replaced nodes in case we need to restore them
ReplacedNodes replaced_nodes = kit.map()->replaced_nodes();
replaced_nodes.clone();
! Node* casted_receiver = receiver; // will get updated in place...
! Node* slow_ctl = NULL;
! if (_exact_check) {
! slow_ctl = kit.type_check_receiver(receiver, _predicted_receiver, _hit_prob,
! &casted_receiver);
! } else {
! slow_ctl = kit.subtype_check_receiver(receiver, _predicted_receiver,
! &casted_receiver);
! }
SafePointNode* slow_map = NULL;
JVMState* slow_jvms = NULL;
{ PreserveJVMState pjvms(&kit);
kit.set_control(slow_ctl);
*** 735,745 ****
kit.set_jvms(slow_jvms);
return kit.transfer_exceptions_into_jvms();
}
// fall through if the instance exactly matches the desired type
! kit.replace_in_map(receiver, exact_receiver);
// Make the hot call:
JVMState* new_jvms = _if_hit->generate(kit.sync_jvms());
if (new_jvms == NULL) {
// Inline failed, so make a direct call.
--- 750,760 ----
kit.set_jvms(slow_jvms);
return kit.transfer_exceptions_into_jvms();
}
// fall through if the instance exactly matches the desired type
! kit.replace_in_map(receiver, casted_receiver);
// Make the hot call:
JVMState* new_jvms = _if_hit->generate(kit.sync_jvms());
if (new_jvms == NULL) {
// Inline failed, so make a direct call.
< prev index next >