< prev index next > src/hotspot/share/opto/callGenerator.cpp
Print this page
kit.replace_call(call, C->top(), true);
} else {
// Make a clone of the JVMState that appropriate to use for driving a parse
JVMState* old_jvms = call->jvms();
JVMState* jvms = old_jvms->clone_shallow(C);
+
+ // Clear the allocation state. We assume all inputs are materialized.
+ jvms->alloc_state().clear();
+
uint size = call->req();
SafePointNode* map = new SafePointNode(size, jvms);
for (uint i1 = 0; i1 < size; i1++) {
map->init_req(i1, call->in(i1));
}
return new LateInlineVectorReboxingCallGenerator(method, inline_cg);
}
//------------------------PredictedCallGenerator------------------------------
// Internal class which handles all out-of-line calls checking receiver type.
! class PredictedCallGenerator : public CallGenerator {
ciKlass* _predicted_receiver;
CallGenerator* _if_missed;
CallGenerator* _if_hit;
float _hit_prob;
bool _exact_check;
return new LateInlineVectorReboxingCallGenerator(method, inline_cg);
}
//------------------------PredictedCallGenerator------------------------------
// Internal class which handles all out-of-line calls checking receiver type.
! class PredictedCallGenerator : public InlineCallGenerator {
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;
if (hit_prob < PROB_MIN) hit_prob = PROB_MIN;
public:
PredictedCallGenerator(ciKlass* predicted_receiver,
CallGenerator* if_missed,
CallGenerator* if_hit, bool exact_check,
float hit_prob)
! : InlineCallGenerator(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;
if (hit_prob < PROB_MIN) hit_prob = PROB_MIN;
return kit.transfer_exceptions_into_jvms();
}
// Fall through if the instance 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 == nullptr) {
// Inline failed, so make a direct call.
assert(_if_hit->is_inline(), "must have been a failed inline");
// There are 2 branches and the replaced nodes are only valid on
// one: restore the replaced nodes to what they were before the
// branch.
kit.map()->set_replaced_nodes(replaced_nodes);
+ PEAState& slow_as = slow_jvms->alloc_state();
+ PEAState& as = new_jvms->alloc_state();
+ AllocationStateMerger as_merger(as);
// Finish the diamond.
kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
RegionNode* region = new RegionNode(3);
region->init_req(1, kit.control());
region->init_req(2, slow_map->control());
if (m != n) {
const Type* t = gvn.type(m)->meet_speculative(gvn.type(n));
Node* phi = PhiNode::make(region, m, t);
phi->set_req(2, n);
kit.map()->set_req(i, gvn.transform(phi));
+ if (DoPartialEscapeAnalysis) {
+ as_merger.merge_at_phi_creation(kit.PEA(), slow_as, phi->as_Phi(), m, n);
+ }
}
}
+
+ if (DoPartialEscapeAnalysis) {
+ as_merger.merge(slow_as, &kit, region, 2);
+ }
return kit.transfer_exceptions_into_jvms();
}
CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool allow_inline) {
return nullptr;
}
//------------------------PredicatedIntrinsicGenerator------------------------------
// Internal class which handles all predicated Intrinsic calls.
! class PredicatedIntrinsicGenerator : public CallGenerator {
CallGenerator* _intrinsic;
CallGenerator* _cg;
public:
PredicatedIntrinsicGenerator(CallGenerator* intrinsic,
CallGenerator* cg)
! : CallGenerator(cg->method())
{
_intrinsic = intrinsic;
_cg = cg;
}
virtual bool is_virtual() const { return true; }
- virtual bool is_inline() const { return true; }
virtual bool is_intrinsic() const { return true; }
virtual JVMState* generate(JVMState* jvms);
};
return nullptr;
}
//------------------------PredicatedIntrinsicGenerator------------------------------
// Internal class which handles all predicated Intrinsic calls.
! class PredicatedIntrinsicGenerator : public InlineCallGenerator {
CallGenerator* _intrinsic;
CallGenerator* _cg;
public:
PredicatedIntrinsicGenerator(CallGenerator* intrinsic,
CallGenerator* cg)
! : InlineCallGenerator(cg->method())
{
_intrinsic = intrinsic;
_cg = cg;
}
virtual bool is_virtual() const { return true; }
virtual bool is_intrinsic() const { return true; }
virtual JVMState* generate(JVMState* jvms);
};
assert(old_exc == new_map->next_exception(), "generate_predicate should not add exceptions");
#endif
if (!kit.stopped()) {
PreserveJVMState pjvms(&kit);
// Generate intrinsic code:
+ assert(_intrinsic->is_inline(), "LibraryIntrinsic");
JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms());
if (new_jvms == nullptr) {
// Intrinsic failed, use normal compilation path for this predicate.
slow_region->add_req(kit.control());
} else {
< prev index next >