callGenerator.cpp revision 1080
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * CA 95054 USA or visit www.sun.com if you need additional information or #
include "incls/_precompiled.incl"//-----------------------------ParseGenerator--------------------------------- // Internal class which handles all direct bytecode traversal. // Can we build either an OSR or a regular parser for this method? virtual bool is_parse()
const {
return true; }
// The JVMS for a OSR has a single argument (see its TypeFunc). return NULL;
// bailing out of the compile; do not try to parse "Must invalidate if TypeFuncs differ");
// Simply return the exit state of the parser, // augmented by any exceptional states. //---------------------------DirectCallGenerator------------------------------ // Internal class which handles all out-of-line calls w/o receiver type checks. // Force separate memory and I/O projections for the exceptional // paths to facilitate late inlinig. // Make an explicit receiver null_check as part of this call. // Since we share a map with the caller, his JVMS gets adjusted. // And dump it back to the caller, decorated with any exceptions: // Mark the call node as virtual, sort of: //--------------------------VirtualCallGenerator------------------------------ // Internal class which handles all out-of-line calls checking receiver type. // If the receiver is a constant null, do not torture the system // by attempting to call through it. The compile will proceed // correctly, but may bail out in final_graph_reshaping, because // the call instruction will have a seemingly deficient out-count. // (The bailout says something misleading about an "infinite loop".) // Ideally we would unconditionally do a null check here and let it // be converted to an implicit check based on profile information. // However currently the conversion to implicit null checks in // Block::implicit_null_check() only looks for loads and stores, not calls. // Make an explicit receiver null_check as part of this call. // Since we share a map with the caller, his JVMS gets adjusted. // And dump it back to the caller, decorated with any exceptions: "no vtable calls if +UseInlineCaches ");
// Normal inline cache used for call // Represent the effect of an implicit receiver null_check // as part of this call. Since we share a map with the caller, // his JVMS gets adjusted. // Certain methods cannot be parsed at all: // (Methods may bail out for other reasons, after the parser is run. // We try to avoid this, but if forced, we must return (Node*)NULL. // The user of the CallGenerator must check for this condition.) // As a special case, the JVMS passed to this CallGenerator is // for the method execution already in progress, not just the JVMS // of the caller. Thus, this CallGenerator cannot be mixed with others! // Allow inlining decisions to be delayed // Convert the CallStaticJava into an inline // Record that this call site should be revisited once the main // Emit the CallStaticJava and request separate projections so // that the late inlining logic can distinguish between fall // through and exceptional uses of the memory and io projections // as is done for allocations and macro expansion. // Make a clone of the JVMState that appropriate to use for driving a parse // Make sure the state is a MergeMem for parsing. // Make enough space for the expression stack and transfer the incoming arguments // Setup default node notes to be picked up by the inlining // Now perform the inling using the synthesized JVMState // Capture any exceptional control flow // Find the result object //---------------------------WarmCallGenerator-------------------------------- // Internal class which handles initial deferral of inlining decisions. // No action: Just dequeue. //------------------------PredictedCallGenerator------------------------------ // Internal class which handles all out-of-line calls checking receiver type. // The call profile data may predict the hit_prob as extreme as 0 or 1. // Remove the extremes values from the range. // We need an explicit receiver null_check before checking its type. // We share a map with the caller, so his JVMS gets adjusted. log->
elem(
"predicted_call bci='%d' klass='%d'",
// Instance exactly does not matches the desired type. // fall through if the instance exactly matches the desired type // Inline failed, so make a direct call. // Need to merge slow and fast? // The fast path is the only path remaining. // Inlined method threw an exception, so it's just the slow path after all. // Skip unused stack slots; fast forward to monoff(); //-------------------------UncommonTrapCallGenerator----------------------------- // Internal class which handles all out-of-line calls checking receiver type. virtual bool is_trap()
const {
return true; }
// Take the trap with arguments pushed on the stack. (Cf. null_check_receiver). // Don't allow uncommon_trap to override our decision to recompile in the event // of a class cast failure for a monomorphic call as it will never let us convert // the call to either bi-morphic or megamorphic and can lead to unc-trap loops // (Note: Moved hook_up_call to GraphKit::set_edges_for_java_call.) // (Node: Merged hook_up_exits into ParseGenerator::generate.) // Expected execution count is based on the historical count: // Expected profit from inlining, in units of simple call-overheads. // Expected work performed by the call in units of call-overheads. // %%% need an empirical curve fit for "work" (time in call) // Expected size of compilation graph: // -XX:+PrintParseStatistics once reported: // Methods seen: 9184 Methods parsed: 9184 Nodes created: 1582391 // Histogram of 144298 parsed bytecodes: // %%% Need an better predictor for graph size. // is_cold: Return true if the node should never be inlined. // This is true if any of the key metrics are extreme. // is_hot: Return true if the node should be inlined immediately. // This is true if any of the key metrics are extreme. assert(!
is_cold(),
"eliminate is_cold cases before testing is_hot");
assert(
this !=
that,
"compare only different WCIs");
// Equal heat. Break the tie some other way. //#define UNINIT_NEXT ((WarmCallInfo*)badAddress) // Install this between prev_p and next_p. // Remove this from between prev_p and next_p. tty->
print(
"%s : C=%6.1f P=%6.1f W=%6.1f S=%6.1f H=%6.1f -> %p",