annotate src/share/vm/opto/callGenerator.hpp @ 4710:41406797186b

7113012: G1: rename not-fully-young GCs as "mixed" Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets). Reviewed-by: johnc, brutisso
author tonyp
date Fri, 16 Dec 2011 02:14:27 -0500
parents a04a201f0f5a
children 04b9a2566eec 1d7922586cf6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
2 * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1138
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1138
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1138
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #ifndef SHARE_VM_OPTO_CALLGENERATOR_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #define SHARE_VM_OPTO_CALLGENERATOR_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "opto/compile.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "opto/type.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "runtime/deoptimization.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32
0
a61af66fc99e Initial load
duke
parents:
diff changeset
33 //---------------------------CallGenerator-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // The subclasses of this class handle generation of ideal nodes for
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // call sites and method entry points.
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 class CallGenerator : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
38 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
39 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
40 xxxunusedxxx
a61af66fc99e Initial load
duke
parents:
diff changeset
41 };
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
44 ciMethod* _method; // The method being called.
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
47 CallGenerator(ciMethod* method);
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
51 ciMethod* method() const { return _method; }
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // is_inline: At least some code implementing the method is copied here.
a61af66fc99e Initial load
duke
parents:
diff changeset
54 virtual bool is_inline() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // is_intrinsic: There's a method-specific way of generating the inline code.
a61af66fc99e Initial load
duke
parents:
diff changeset
56 virtual bool is_intrinsic() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // is_parse: Bytecodes implementing the specific method are copied here.
a61af66fc99e Initial load
duke
parents:
diff changeset
58 virtual bool is_parse() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // is_virtual: The call uses the receiver type to select or check the method.
a61af66fc99e Initial load
duke
parents:
diff changeset
60 virtual bool is_virtual() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // is_deferred: The decision whether to inline or not is deferred.
a61af66fc99e Initial load
duke
parents:
diff changeset
62 virtual bool is_deferred() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // is_predicted: Uses an explicit check against a predicted type.
a61af66fc99e Initial load
duke
parents:
diff changeset
64 virtual bool is_predicted() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // is_trap: Does not return to the caller. (E.g., uncommon trap.)
a61af66fc99e Initial load
duke
parents:
diff changeset
66 virtual bool is_trap() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
67
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
68 // is_late_inline: supports conversion of call into an inline
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
69 virtual bool is_late_inline() const { return false; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
70 // Replace the call with an inline version of the code
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
71 virtual void do_late_inline() { ShouldNotReachHere(); }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
72
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
73 virtual CallStaticJavaNode* call_node() const { ShouldNotReachHere(); return NULL; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
74
0
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // Note: It is possible for a CG to be both inline and virtual.
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // (The hashCode intrinsic does a vtable check and an inlined fast path.)
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // Utilities:
a61af66fc99e Initial load
duke
parents:
diff changeset
79 const TypeFunc* tf() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // The given jvms has state and arguments for a call to my method.
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // Edges after jvms->argoff() carry all (pre-popped) argument values.
a61af66fc99e Initial load
duke
parents:
diff changeset
83 //
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // Update the map with state and return values (if any) and return it.
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // The return values (0, 1, or 2) must be pushed on the map's stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // and the sp of the jvms incremented accordingly.
a61af66fc99e Initial load
duke
parents:
diff changeset
87 //
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // The jvms is returned on success. Alternatively, a copy of the
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // given jvms, suitably updated, may be returned, in which case the
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // caller should discard the original jvms.
a61af66fc99e Initial load
duke
parents:
diff changeset
91 //
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // The non-Parm edges of the returned map will contain updated global state,
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // and one or two edges before jvms->sp() will carry any return values.
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // Other map edges may contain locals or monitors, and should not
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // be changed in meaning.
a61af66fc99e Initial load
duke
parents:
diff changeset
96 //
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // If the call traps, the returned map must have a control edge of top.
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // If the call can throw, the returned map must report has_exceptions().
a61af66fc99e Initial load
duke
parents:
diff changeset
99 //
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // If the result is NULL, it means that this CallGenerator was unable
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // to handle the given call, and another CallGenerator should be consulted.
a61af66fc99e Initial load
duke
parents:
diff changeset
102 virtual JVMState* generate(JVMState* jvms) = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // How to generate a call site that is inlined:
a61af66fc99e Initial load
duke
parents:
diff changeset
105 static CallGenerator* for_inline(ciMethod* m, float expected_uses = -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // How to generate code for an on-stack replacement handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
107 static CallGenerator* for_osr(ciMethod* m, int osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // How to generate vanilla out-of-line call sites:
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
110 static CallGenerator* for_direct_call(ciMethod* m, bool separate_io_projs = false); // static, special
4117
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 3852
diff changeset
111 static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
112 static CallGenerator* for_dynamic_call(ciMethod* m); // invokedynamic
4117
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 3852
diff changeset
113
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 3852
diff changeset
114 static CallGenerator* for_method_handle_call(Node* method_handle, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile);
a04a201f0f5a 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
twisti
parents: 3852
diff changeset
115 static CallGenerator* for_invokedynamic_call( JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
116
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
117 static CallGenerator* for_method_handle_inline(Node* method_handle, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile);
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
118 static CallGenerator* for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile);
3752
f918d6096e23 7050554: JSR 292 - need optimization for selectAlternative
never
parents: 2443
diff changeset
119
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
120 // How to generate a replace a direct call with an inline version
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
121 static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
122
0
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // How to make a call but defer the decision whether to inline or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
124 static CallGenerator* for_warm_call(WarmCallInfo* ci,
a61af66fc99e Initial load
duke
parents:
diff changeset
125 CallGenerator* if_cold,
a61af66fc99e Initial load
duke
parents:
diff changeset
126 CallGenerator* if_hot);
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // How to make a call that optimistically assumes a receiver type:
a61af66fc99e Initial load
duke
parents:
diff changeset
129 static CallGenerator* for_predicted_call(ciKlass* predicted_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
130 CallGenerator* if_missed,
a61af66fc99e Initial load
duke
parents:
diff changeset
131 CallGenerator* if_hit,
a61af66fc99e Initial load
duke
parents:
diff changeset
132 float hit_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
133
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
134 // How to make a call that optimistically assumes a MethodHandle target:
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
135 static CallGenerator* for_predicted_dynamic_call(ciMethodHandle* predicted_method_handle,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
136 CallGenerator* if_missed,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
137 CallGenerator* if_hit,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
138 float hit_prob);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
139
0
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // How to make a call that gives up and goes back to the interpreter:
a61af66fc99e Initial load
duke
parents:
diff changeset
141 static CallGenerator* for_uncommon_trap(ciMethod* m,
a61af66fc99e Initial load
duke
parents:
diff changeset
142 Deoptimization::DeoptReason reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
143 Deoptimization::DeoptAction action);
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Registry for intrinsics:
a61af66fc99e Initial load
duke
parents:
diff changeset
146 static CallGenerator* for_intrinsic(ciMethod* m);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 static void register_intrinsic(ciMethod* m, CallGenerator* cg);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 };
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 class InlineCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 virtual bool is_inline() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
154 InlineCallGenerator(ciMethod* method) : CallGenerator(method) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
155 };
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 //---------------------------WarmCallInfo--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
159 // A struct to collect information about a given call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // Helps sort call sites into "hot", "medium", and "cold".
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Participates in the queueing of "medium" call sites for possible inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
162 class WarmCallInfo : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
163 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 CallNode* _call; // The CallNode which may be inlined.
a61af66fc99e Initial load
duke
parents:
diff changeset
166 CallGenerator* _hot_cg;// CG for expanding the call node
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // These are the metrics we use to evaluate call sites:
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 float _count; // How often do we expect to reach this site?
a61af66fc99e Initial load
duke
parents:
diff changeset
171 float _profit; // How much time do we expect to save by inlining?
a61af66fc99e Initial load
duke
parents:
diff changeset
172 float _work; // How long do we expect the average call to take?
a61af66fc99e Initial load
duke
parents:
diff changeset
173 float _size; // How big do we expect the inlined code to be?
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 float _heat; // Combined score inducing total order on call sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
176 WarmCallInfo* _next; // Next cooler call info in pending queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // Count is the number of times this call site is expected to be executed.
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Large count is favorable for inlining, because the extra compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // work will be amortized more completely.
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // Profit is a rough measure of the amount of time we expect to save
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // per execution of this site if we inline it. (1.0 == call overhead)
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Large profit favors inlining. Negative profit disables inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // Work is a rough measure of the amount of time a typical out-of-line
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // call from this site is expected to take. (1.0 == call, no-op, return)
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // Small work is somewhat favorable for inlining, since methods with
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // short "hot" traces are more likely to inline smoothly.
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // Size is the number of graph nodes we expect this method to produce,
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // not counting the inlining of any further warm calls it may include.
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // Small size favors inlining, since small methods are more likely to
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // inline smoothly. The size is estimated by examining the native code
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // if available. The method bytecodes are also examined, assuming
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // empirically observed node counts for each kind of bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // Heat is the combined "goodness" of a site's inlining. If we were
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // omniscient, it would be the difference of two sums of future execution
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // times of code emitted for this site (amortized across multiple sites if
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // sharing applies). The two sums are for versions of this call site with
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // and without inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // We approximate this mythical quantity by playing with averages,
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // rough estimates, and assumptions that history repeats itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // The basic formula count * profit is heuristically adjusted
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // by looking at the expected compilation and execution times of
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // of the inlined call.
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // Note: Some of these metrics may not be present in the final product,
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // but exist in development builds to experiment with inline policy tuning.
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // This heuristic framework does not model well the very significant
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // effects of multiple-level inlining. It is possible to see no immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // profit from inlining X->Y, but to get great profit from a subsequent
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // inlining X->Y->Z.
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // This framework does not take well into account the problem of N**2 code
a61af66fc99e Initial load
duke
parents:
diff changeset
219 // size in a clique of mutually inlinable methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 WarmCallInfo* next() const { return _next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
222 void set_next(WarmCallInfo* n) { _next = n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
2443
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
224 static WarmCallInfo _always_hot;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
225 static WarmCallInfo _always_cold;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
226
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
227 // Constructor intitialization of always_hot and always_cold
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
228 WarmCallInfo(float c, float p, float w, float s) {
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
229 _call = NULL;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
230 _hot_cg = NULL;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
231 _next = NULL;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
232 _count = c;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
233 _profit = p;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
234 _work = w;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
235 _size = s;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
236 _heat = 0;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
237 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // Because WarmInfo objects live over the entire lifetime of the
a61af66fc99e Initial load
duke
parents:
diff changeset
241 // Compile object, they are allocated into the comp_arena, which
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // does not get resource marked or reset during the compile process
a61af66fc99e Initial load
duke
parents:
diff changeset
243 void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); }
a61af66fc99e Initial load
duke
parents:
diff changeset
244 void operator delete( void * ) { } // fast deallocation
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 static WarmCallInfo* always_hot();
a61af66fc99e Initial load
duke
parents:
diff changeset
247 static WarmCallInfo* always_cold();
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 WarmCallInfo() {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 _call = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 _hot_cg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 _next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
253 _count = _profit = _work = _size = _heat = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255
a61af66fc99e Initial load
duke
parents:
diff changeset
256 CallNode* call() const { return _call; }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 float count() const { return _count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 float size() const { return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
259 float work() const { return _work; }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 float profit() const { return _profit; }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 float heat() const { return _heat; }
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 void set_count(float x) { _count = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 void set_size(float x) { _size = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
265 void set_work(float x) { _work = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
266 void set_profit(float x) { _profit = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 void set_heat(float x) { _heat = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 // Load initial heuristics from profiles, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // The heuristics can be tweaked further by the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
271 void init(JVMState* call_site, ciMethod* call_method, ciCallProfile& profile, float prof_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 static float MAX_VALUE() { return +1.0e10; }
a61af66fc99e Initial load
duke
parents:
diff changeset
274 static float MIN_VALUE() { return -1.0e10; }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 float compute_heat() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 void set_call(CallNode* call) { _call = call; }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 void set_hot_cg(CallGenerator* cg) { _hot_cg = cg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // Do not queue very hot or very cold calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Make very cold ones out of line immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Inline very hot ones immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // These queries apply various tunable limits
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // to the above metrics in a systematic way.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // Test for coldness before testing for hotness.
a61af66fc99e Initial load
duke
parents:
diff changeset
287 bool is_cold() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
288 bool is_hot() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // Force a warm call to be hot. This worklists the call node for inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 void make_hot();
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // Force a warm call to be cold. This worklists the call node for out-of-lining.
a61af66fc99e Initial load
duke
parents:
diff changeset
294 void make_cold();
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // A reproducible total ordering, in which heat is the major key.
a61af66fc99e Initial load
duke
parents:
diff changeset
297 bool warmer_than(WarmCallInfo* that);
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // List management. These methods are called with the list head,
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // and return the new list head, inserting or removing the receiver.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 WarmCallInfo* insert_into(WarmCallInfo* head);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 WarmCallInfo* remove_from(WarmCallInfo* head);
a61af66fc99e Initial load
duke
parents:
diff changeset
303
a61af66fc99e Initial load
duke
parents:
diff changeset
304 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
305 void print() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
306 void print_all() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 int count_all() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
309 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
310
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
311 #endif // SHARE_VM_OPTO_CALLGENERATOR_HPP