1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/opto/callGenerator.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,266 @@ 1.4 +/* 1.5 + * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +//---------------------------CallGenerator------------------------------------- 1.29 +// The subclasses of this class handle generation of ideal nodes for 1.30 +// call sites and method entry points. 1.31 + 1.32 +class CallGenerator : public ResourceObj { 1.33 + public: 1.34 + enum { 1.35 + xxxunusedxxx 1.36 + }; 1.37 + 1.38 + private: 1.39 + ciMethod* _method; // The method being called. 1.40 + 1.41 + protected: 1.42 + CallGenerator(ciMethod* method); 1.43 + 1.44 + public: 1.45 + // Accessors 1.46 + ciMethod* method() const { return _method; } 1.47 + 1.48 + // is_inline: At least some code implementing the method is copied here. 1.49 + virtual bool is_inline() const { return false; } 1.50 + // is_intrinsic: There's a method-specific way of generating the inline code. 1.51 + virtual bool is_intrinsic() const { return false; } 1.52 + // is_parse: Bytecodes implementing the specific method are copied here. 1.53 + virtual bool is_parse() const { return false; } 1.54 + // is_virtual: The call uses the receiver type to select or check the method. 1.55 + virtual bool is_virtual() const { return false; } 1.56 + // is_deferred: The decision whether to inline or not is deferred. 1.57 + virtual bool is_deferred() const { return false; } 1.58 + // is_predicted: Uses an explicit check against a predicted type. 1.59 + virtual bool is_predicted() const { return false; } 1.60 + // is_trap: Does not return to the caller. (E.g., uncommon trap.) 1.61 + virtual bool is_trap() const { return false; } 1.62 + 1.63 + // Note: It is possible for a CG to be both inline and virtual. 1.64 + // (The hashCode intrinsic does a vtable check and an inlined fast path.) 1.65 + 1.66 + // Utilities: 1.67 + const TypeFunc* tf() const; 1.68 + 1.69 + // The given jvms has state and arguments for a call to my method. 1.70 + // Edges after jvms->argoff() carry all (pre-popped) argument values. 1.71 + // 1.72 + // Update the map with state and return values (if any) and return it. 1.73 + // The return values (0, 1, or 2) must be pushed on the map's stack, 1.74 + // and the sp of the jvms incremented accordingly. 1.75 + // 1.76 + // The jvms is returned on success. Alternatively, a copy of the 1.77 + // given jvms, suitably updated, may be returned, in which case the 1.78 + // caller should discard the original jvms. 1.79 + // 1.80 + // The non-Parm edges of the returned map will contain updated global state, 1.81 + // and one or two edges before jvms->sp() will carry any return values. 1.82 + // Other map edges may contain locals or monitors, and should not 1.83 + // be changed in meaning. 1.84 + // 1.85 + // If the call traps, the returned map must have a control edge of top. 1.86 + // If the call can throw, the returned map must report has_exceptions(). 1.87 + // 1.88 + // If the result is NULL, it means that this CallGenerator was unable 1.89 + // to handle the given call, and another CallGenerator should be consulted. 1.90 + virtual JVMState* generate(JVMState* jvms) = 0; 1.91 + 1.92 + // How to generate a call site that is inlined: 1.93 + static CallGenerator* for_inline(ciMethod* m, float expected_uses = -1); 1.94 + // How to generate code for an on-stack replacement handler. 1.95 + static CallGenerator* for_osr(ciMethod* m, int osr_bci); 1.96 + 1.97 + // How to generate vanilla out-of-line call sites: 1.98 + static CallGenerator* for_direct_call(ciMethod* m); // static, special 1.99 + static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface 1.100 + 1.101 + // How to make a call but defer the decision whether to inline or not. 1.102 + static CallGenerator* for_warm_call(WarmCallInfo* ci, 1.103 + CallGenerator* if_cold, 1.104 + CallGenerator* if_hot); 1.105 + 1.106 + // How to make a call that optimistically assumes a receiver type: 1.107 + static CallGenerator* for_predicted_call(ciKlass* predicted_receiver, 1.108 + CallGenerator* if_missed, 1.109 + CallGenerator* if_hit, 1.110 + float hit_prob); 1.111 + 1.112 + // How to make a call that gives up and goes back to the interpreter: 1.113 + static CallGenerator* for_uncommon_trap(ciMethod* m, 1.114 + Deoptimization::DeoptReason reason, 1.115 + Deoptimization::DeoptAction action); 1.116 + 1.117 + // Registry for intrinsics: 1.118 + static CallGenerator* for_intrinsic(ciMethod* m); 1.119 + static void register_intrinsic(ciMethod* m, CallGenerator* cg); 1.120 +}; 1.121 + 1.122 +class InlineCallGenerator : public CallGenerator { 1.123 + virtual bool is_inline() const { return true; } 1.124 + 1.125 + protected: 1.126 + InlineCallGenerator(ciMethod* method) : CallGenerator(method) { } 1.127 +}; 1.128 + 1.129 + 1.130 +//---------------------------WarmCallInfo-------------------------------------- 1.131 +// A struct to collect information about a given call site. 1.132 +// Helps sort call sites into "hot", "medium", and "cold". 1.133 +// Participates in the queueing of "medium" call sites for possible inlining. 1.134 +class WarmCallInfo : public ResourceObj { 1.135 + private: 1.136 + 1.137 + CallNode* _call; // The CallNode which may be inlined. 1.138 + CallGenerator* _hot_cg;// CG for expanding the call node 1.139 + 1.140 + // These are the metrics we use to evaluate call sites: 1.141 + 1.142 + float _count; // How often do we expect to reach this site? 1.143 + float _profit; // How much time do we expect to save by inlining? 1.144 + float _work; // How long do we expect the average call to take? 1.145 + float _size; // How big do we expect the inlined code to be? 1.146 + 1.147 + float _heat; // Combined score inducing total order on call sites. 1.148 + WarmCallInfo* _next; // Next cooler call info in pending queue. 1.149 + 1.150 + // Count is the number of times this call site is expected to be executed. 1.151 + // Large count is favorable for inlining, because the extra compilation 1.152 + // work will be amortized more completely. 1.153 + 1.154 + // Profit is a rough measure of the amount of time we expect to save 1.155 + // per execution of this site if we inline it. (1.0 == call overhead) 1.156 + // Large profit favors inlining. Negative profit disables inlining. 1.157 + 1.158 + // Work is a rough measure of the amount of time a typical out-of-line 1.159 + // call from this site is expected to take. (1.0 == call, no-op, return) 1.160 + // Small work is somewhat favorable for inlining, since methods with 1.161 + // short "hot" traces are more likely to inline smoothly. 1.162 + 1.163 + // Size is the number of graph nodes we expect this method to produce, 1.164 + // not counting the inlining of any further warm calls it may include. 1.165 + // Small size favors inlining, since small methods are more likely to 1.166 + // inline smoothly. The size is estimated by examining the native code 1.167 + // if available. The method bytecodes are also examined, assuming 1.168 + // empirically observed node counts for each kind of bytecode. 1.169 + 1.170 + // Heat is the combined "goodness" of a site's inlining. If we were 1.171 + // omniscient, it would be the difference of two sums of future execution 1.172 + // times of code emitted for this site (amortized across multiple sites if 1.173 + // sharing applies). The two sums are for versions of this call site with 1.174 + // and without inlining. 1.175 + 1.176 + // We approximate this mythical quantity by playing with averages, 1.177 + // rough estimates, and assumptions that history repeats itself. 1.178 + // The basic formula count * profit is heuristically adjusted 1.179 + // by looking at the expected compilation and execution times of 1.180 + // of the inlined call. 1.181 + 1.182 + // Note: Some of these metrics may not be present in the final product, 1.183 + // but exist in development builds to experiment with inline policy tuning. 1.184 + 1.185 + // This heuristic framework does not model well the very significant 1.186 + // effects of multiple-level inlining. It is possible to see no immediate 1.187 + // profit from inlining X->Y, but to get great profit from a subsequent 1.188 + // inlining X->Y->Z. 1.189 + 1.190 + // This framework does not take well into account the problem of N**2 code 1.191 + // size in a clique of mutually inlinable methods. 1.192 + 1.193 + WarmCallInfo* next() const { return _next; } 1.194 + void set_next(WarmCallInfo* n) { _next = n; } 1.195 + 1.196 + static WarmCallInfo* _always_hot; 1.197 + static WarmCallInfo* _always_cold; 1.198 + 1.199 + public: 1.200 + // Because WarmInfo objects live over the entire lifetime of the 1.201 + // Compile object, they are allocated into the comp_arena, which 1.202 + // does not get resource marked or reset during the compile process 1.203 + void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); } 1.204 + void operator delete( void * ) { } // fast deallocation 1.205 + 1.206 + static WarmCallInfo* always_hot(); 1.207 + static WarmCallInfo* always_cold(); 1.208 + 1.209 + WarmCallInfo() { 1.210 + _call = NULL; 1.211 + _hot_cg = NULL; 1.212 + _next = NULL; 1.213 + _count = _profit = _work = _size = _heat = 0; 1.214 + } 1.215 + 1.216 + CallNode* call() const { return _call; } 1.217 + float count() const { return _count; } 1.218 + float size() const { return _size; } 1.219 + float work() const { return _work; } 1.220 + float profit() const { return _profit; } 1.221 + float heat() const { return _heat; } 1.222 + 1.223 + void set_count(float x) { _count = x; } 1.224 + void set_size(float x) { _size = x; } 1.225 + void set_work(float x) { _work = x; } 1.226 + void set_profit(float x) { _profit = x; } 1.227 + void set_heat(float x) { _heat = x; } 1.228 + 1.229 + // Load initial heuristics from profiles, etc. 1.230 + // The heuristics can be tweaked further by the caller. 1.231 + void init(JVMState* call_site, ciMethod* call_method, ciCallProfile& profile, float prof_factor); 1.232 + 1.233 + static float MAX_VALUE() { return +1.0e10; } 1.234 + static float MIN_VALUE() { return -1.0e10; } 1.235 + 1.236 + float compute_heat() const; 1.237 + 1.238 + void set_call(CallNode* call) { _call = call; } 1.239 + void set_hot_cg(CallGenerator* cg) { _hot_cg = cg; } 1.240 + 1.241 + // Do not queue very hot or very cold calls. 1.242 + // Make very cold ones out of line immediately. 1.243 + // Inline very hot ones immediately. 1.244 + // These queries apply various tunable limits 1.245 + // to the above metrics in a systematic way. 1.246 + // Test for coldness before testing for hotness. 1.247 + bool is_cold() const; 1.248 + bool is_hot() const; 1.249 + 1.250 + // Force a warm call to be hot. This worklists the call node for inlining. 1.251 + void make_hot(); 1.252 + 1.253 + // Force a warm call to be cold. This worklists the call node for out-of-lining. 1.254 + void make_cold(); 1.255 + 1.256 + // A reproducible total ordering, in which heat is the major key. 1.257 + bool warmer_than(WarmCallInfo* that); 1.258 + 1.259 + // List management. These methods are called with the list head, 1.260 + // and return the new list head, inserting or removing the receiver. 1.261 + WarmCallInfo* insert_into(WarmCallInfo* head); 1.262 + WarmCallInfo* remove_from(WarmCallInfo* head); 1.263 + 1.264 +#ifndef PRODUCT 1.265 + void print() const; 1.266 + void print_all() const; 1.267 + int count_all() const; 1.268 +#endif 1.269 +};