callGenerator.cpp revision 4172
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * This code is free software; you can redistribute it and/or modify it
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * under the terms of the GNU General Public License version 2 only, as
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * published by the Free Software Foundation.
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * This code is distributed in the hope that it will be useful, but WITHOUT
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * version 2 for more details (a copy is included in the LICENSE file that
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * accompanied this code).
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * You should have received a copy of the GNU General Public License version
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * 2 along with this work; if not, write to the Free Software Foundation,
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni * or visit www.oracle.com if you need additional information or have any
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni// Utility function.
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings//-----------------------------ParseGenerator---------------------------------
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings// Internal class which handles all direct bytecode traversal.
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbingsclass ParseGenerator : public InlineCallGenerator {
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni ParseGenerator(ciMethod* method, float expected_uses, bool is_osr = false)
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni assert(InlineTree::check_can_parse(method) == NULL, "parse must be possible");
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings virtual bool is_parse() const { return true; }
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen StubbingsJVMState* ParseGenerator::generate(JVMState* jvms) {
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings // The JVMS for a OSR has a single argument (see its TypeFunc).
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni assert(jvms->depth() == 1, "no inline OSR");
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni return NULL; // bailing out of the compile; do not try to parse
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings // Grab signature for matching/allocation
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings if (parser.tf() != (parser.depth() == 1 ? C->tf() : tf())) {
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings MutexLockerEx ml(Compile_lock, Mutex::_no_safepoint_check_flag);
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings assert(C->env()->system_dictionary_modification_counter_changed(),
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings "Must invalidate if TypeFuncs differ");
b3a21de0a0e0a5dea71bece7e5c0356700136fbcDiego Colantoni while (exits.pop_exception_state() != NULL) ;
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings assert(exits.jvms()->same_calls_as(jvms), "sanity");
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings // Simply return the exit state of the parser,
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings // augmented by any exceptional states.
a1e92b2783be4bfeb0c7e267223cc7779a6f324cKen Stubbings//---------------------------DirectCallGenerator------------------------------
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings// Internal class which handles all out-of-line calls w/o receiver type checks.
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbingsclass DirectCallGenerator : public CallGenerator {
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings // Force separate memory and I/O projections for the exceptional
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings // paths to facilitate late inlinig.
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings DirectCallGenerator(ciMethod* method, bool separate_io_proj)
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings CallStaticJavaNode* call_node() const { return _call_node; }
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken StubbingsJVMState* DirectCallGenerator::generate(JVMState* jvms) {
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings address target = is_static ? SharedRuntime::get_resolve_static_call_stub()
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings : SharedRuntime::get_resolve_opt_virtual_call_stub();
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings kit.C->log()->elem("direct_call bci='%d'", jvms->bci());
if (!is_static) {
int _vtable_index;
virtual bool is_virtual() const { return true; }
CallDynamicJavaNode *call = new (kit.C) CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci());
virtual bool is_late_inline() const { return true; }
virtual void do_late_inline();
C->print_inlining_skip(this);
if (!is_mh_late_inline()) {
C->add_late_inline(this);
C->print_inlining_insert(this);
if (nargs > 0) {
C->print_inlining_insert(this);
while (p != NULL) {
p = p->caller();
if (C->failing()) return;
C->set_inlining_progress(true);
int _attempt;
bool _input_not_const;
LateInlineCallGenerator(callee, NULL), _caller(caller), _attempt(0), _input_not_const(input_not_const) {}
virtual bool is_mh_late_inline() const { return true; }
if (_input_not_const) {
return new_jvms;
if (!_input_not_const) return;
if (!_input_not_const) {
_attempt++;
CallGenerator* CallGenerator::for_mh_late_inline(ciMethod* caller, ciMethod* callee, bool input_not_const) {
return cg;
C->print_inlining_skip(this);
C->add_string_late_inline(this);
return new_jvms;
virtual bool is_deferred() const { return true; }
if (m->is_CallJava()) {
#ifndef PRODUCT
return jvms;
float _hit_prob;
virtual bool is_virtual() const { return true; }
float hit_prob) {
if (i == tos) {
if( i >= limit ) break;
CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool delayed_forbidden) {
bool input_not_const;
return cg;
CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee, bool& input_not_const) {
input_not_const = true;
switch (iid) {
input_not_const = false;
CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS, true, true);
return cg;
input_not_const = false;
if (t->is_klass()) {
bool call_does_dispatch = false;
if (is_virtual_or_interface) {
CallGenerator* cg = C->call_generator(target, vtable_index, call_does_dispatch, jvms, true, PROB_ALWAYS, true, true);
return cg;
return NULL;
virtual bool is_virtual() const { return true; }
virtual bool is_inlined() const { return true; }
virtual bool is_intrinsic() const { return true; }
if (i == tos) {
if( i >= limit ) break;
: CallGenerator(m)
virtual bool is_trap() const { return true; }
bool keep_exact_action = true;
void WarmCallInfo::init(JVMState* call_site, ciMethod* call_method, ciCallProfile& profile, float prof_factor) {
float size_factor;
head = this;
return head;
while (next_p != this) {
return head;
return &_always_hot;
return &_always_cold;
#ifndef PRODUCT
p->print();
int cnt = 0;
cnt++;
return cnt;