annotate src/share/vm/opto/callGenerator.hpp @ 1941:79d04223b8a5

Added caching for resolved types and resolved fields. This is crucial, because the local load elimination will lead to wrong results, if field equality (of two RiField objects with the same object and the same RiType) is not given. The caching makes sure that the default equals implementation is sufficient.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 28 Dec 2010 18:33:26 +0100
parents c18cbe5936b8
children f95d63e2154a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1138
diff changeset
2 * Copyright (c) 2000, 2005, 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
a61af66fc99e Initial load
duke
parents:
diff changeset
25 //---------------------------CallGenerator-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
26 // The subclasses of this class handle generation of ideal nodes for
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // call sites and method entry points.
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 class CallGenerator : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
30 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
31 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
32 xxxunusedxxx
a61af66fc99e Initial load
duke
parents:
diff changeset
33 };
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
36 ciMethod* _method; // The method being called.
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
39 CallGenerator(ciMethod* method);
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
43 ciMethod* method() const { return _method; }
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // is_inline: At least some code implementing the method is copied here.
a61af66fc99e Initial load
duke
parents:
diff changeset
46 virtual bool is_inline() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // is_intrinsic: There's a method-specific way of generating the inline code.
a61af66fc99e Initial load
duke
parents:
diff changeset
48 virtual bool is_intrinsic() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // is_parse: Bytecodes implementing the specific method are copied here.
a61af66fc99e Initial load
duke
parents:
diff changeset
50 virtual bool is_parse() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // is_virtual: The call uses the receiver type to select or check the method.
a61af66fc99e Initial load
duke
parents:
diff changeset
52 virtual bool is_virtual() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // is_deferred: The decision whether to inline or not is deferred.
a61af66fc99e Initial load
duke
parents:
diff changeset
54 virtual bool is_deferred() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // is_predicted: Uses an explicit check against a predicted type.
a61af66fc99e Initial load
duke
parents:
diff changeset
56 virtual bool is_predicted() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // is_trap: Does not return to the caller. (E.g., uncommon trap.)
a61af66fc99e Initial load
duke
parents:
diff changeset
58 virtual bool is_trap() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
59
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
60 // is_late_inline: supports conversion of call into an inline
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
61 virtual bool is_late_inline() const { return false; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
62 // Replace the call with an inline version of the code
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
63 virtual void do_late_inline() { ShouldNotReachHere(); }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
64
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
65 virtual CallStaticJavaNode* call_node() const { ShouldNotReachHere(); return NULL; }
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
66
0
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // Note: It is possible for a CG to be both inline and virtual.
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // (The hashCode intrinsic does a vtable check and an inlined fast path.)
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // Utilities:
a61af66fc99e Initial load
duke
parents:
diff changeset
71 const TypeFunc* tf() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // The given jvms has state and arguments for a call to my method.
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Edges after jvms->argoff() carry all (pre-popped) argument values.
a61af66fc99e Initial load
duke
parents:
diff changeset
75 //
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // Update the map with state and return values (if any) and return it.
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // The return values (0, 1, or 2) must be pushed on the map's stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // and the sp of the jvms incremented accordingly.
a61af66fc99e Initial load
duke
parents:
diff changeset
79 //
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // The jvms is returned on success. Alternatively, a copy of the
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // given jvms, suitably updated, may be returned, in which case the
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // caller should discard the original jvms.
a61af66fc99e Initial load
duke
parents:
diff changeset
83 //
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // The non-Parm edges of the returned map will contain updated global state,
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // and one or two edges before jvms->sp() will carry any return values.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // Other map edges may contain locals or monitors, and should not
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // be changed in meaning.
a61af66fc99e Initial load
duke
parents:
diff changeset
88 //
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // If the call traps, the returned map must have a control edge of top.
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // If the call can throw, the returned map must report has_exceptions().
a61af66fc99e Initial load
duke
parents:
diff changeset
91 //
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // If the result is NULL, it means that this CallGenerator was unable
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // to handle the given call, and another CallGenerator should be consulted.
a61af66fc99e Initial load
duke
parents:
diff changeset
94 virtual JVMState* generate(JVMState* jvms) = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // How to generate a call site that is inlined:
a61af66fc99e Initial load
duke
parents:
diff changeset
97 static CallGenerator* for_inline(ciMethod* m, float expected_uses = -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // How to generate code for an on-stack replacement handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
99 static CallGenerator* for_osr(ciMethod* m, int osr_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // How to generate vanilla out-of-line call sites:
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
102 static CallGenerator* for_direct_call(ciMethod* m, bool separate_io_projs = false); // static, special
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
103 static CallGenerator* for_dynamic_call(ciMethod* m); // invokedynamic
0
a61af66fc99e Initial load
duke
parents:
diff changeset
104 static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface
a61af66fc99e Initial load
duke
parents:
diff changeset
105
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
106 // 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
107 static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
108
0
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // How to make a call but defer the decision whether to inline or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 static CallGenerator* for_warm_call(WarmCallInfo* ci,
a61af66fc99e Initial load
duke
parents:
diff changeset
111 CallGenerator* if_cold,
a61af66fc99e Initial load
duke
parents:
diff changeset
112 CallGenerator* if_hot);
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // How to make a call that optimistically assumes a receiver type:
a61af66fc99e Initial load
duke
parents:
diff changeset
115 static CallGenerator* for_predicted_call(ciKlass* predicted_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
116 CallGenerator* if_missed,
a61af66fc99e Initial load
duke
parents:
diff changeset
117 CallGenerator* if_hit,
a61af66fc99e Initial load
duke
parents:
diff changeset
118 float hit_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
119
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
120 // 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
121 static CallGenerator* for_predicted_dynamic_call(ciMethodHandle* predicted_method_handle,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
122 CallGenerator* if_missed,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
123 CallGenerator* if_hit,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
124 float hit_prob);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
125
0
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // How to make a call that gives up and goes back to the interpreter:
a61af66fc99e Initial load
duke
parents:
diff changeset
127 static CallGenerator* for_uncommon_trap(ciMethod* m,
a61af66fc99e Initial load
duke
parents:
diff changeset
128 Deoptimization::DeoptReason reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
129 Deoptimization::DeoptAction action);
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // Registry for intrinsics:
a61af66fc99e Initial load
duke
parents:
diff changeset
132 static CallGenerator* for_intrinsic(ciMethod* m);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 static void register_intrinsic(ciMethod* m, CallGenerator* cg);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 };
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 class InlineCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 virtual bool is_inline() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
140 InlineCallGenerator(ciMethod* method) : CallGenerator(method) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 };
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 //---------------------------WarmCallInfo--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // A struct to collect information about a given call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Helps sort call sites into "hot", "medium", and "cold".
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // Participates in the queueing of "medium" call sites for possible inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
148 class WarmCallInfo : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 CallNode* _call; // The CallNode which may be inlined.
a61af66fc99e Initial load
duke
parents:
diff changeset
152 CallGenerator* _hot_cg;// CG for expanding the call node
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // These are the metrics we use to evaluate call sites:
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 float _count; // How often do we expect to reach this site?
a61af66fc99e Initial load
duke
parents:
diff changeset
157 float _profit; // How much time do we expect to save by inlining?
a61af66fc99e Initial load
duke
parents:
diff changeset
158 float _work; // How long do we expect the average call to take?
a61af66fc99e Initial load
duke
parents:
diff changeset
159 float _size; // How big do we expect the inlined code to be?
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 float _heat; // Combined score inducing total order on call sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
162 WarmCallInfo* _next; // Next cooler call info in pending queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Count is the number of times this call site is expected to be executed.
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // Large count is favorable for inlining, because the extra compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // work will be amortized more completely.
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 // Profit is a rough measure of the amount of time we expect to save
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // per execution of this site if we inline it. (1.0 == call overhead)
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // Large profit favors inlining. Negative profit disables inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // Work is a rough measure of the amount of time a typical out-of-line
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // call from this site is expected to take. (1.0 == call, no-op, return)
a61af66fc99e Initial load
duke
parents:
diff changeset
174 // Small work is somewhat favorable for inlining, since methods with
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // short "hot" traces are more likely to inline smoothly.
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // Size is the number of graph nodes we expect this method to produce,
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // not counting the inlining of any further warm calls it may include.
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Small size favors inlining, since small methods are more likely to
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // inline smoothly. The size is estimated by examining the native code
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // if available. The method bytecodes are also examined, assuming
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // empirically observed node counts for each kind of bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // Heat is the combined "goodness" of a site's inlining. If we were
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // omniscient, it would be the difference of two sums of future execution
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // times of code emitted for this site (amortized across multiple sites if
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // sharing applies). The two sums are for versions of this call site with
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // and without inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // We approximate this mythical quantity by playing with averages,
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // rough estimates, and assumptions that history repeats itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // The basic formula count * profit is heuristically adjusted
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // by looking at the expected compilation and execution times of
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // of the inlined call.
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // Note: Some of these metrics may not be present in the final product,
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // but exist in development builds to experiment with inline policy tuning.
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // This heuristic framework does not model well the very significant
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // effects of multiple-level inlining. It is possible to see no immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // profit from inlining X->Y, but to get great profit from a subsequent
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // inlining X->Y->Z.
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // This framework does not take well into account the problem of N**2 code
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // size in a clique of mutually inlinable methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 WarmCallInfo* next() const { return _next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 void set_next(WarmCallInfo* n) { _next = n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 static WarmCallInfo* _always_hot;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 static WarmCallInfo* _always_cold;
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // Because WarmInfo objects live over the entire lifetime of the
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // Compile object, they are allocated into the comp_arena, which
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // does not get resource marked or reset during the compile process
a61af66fc99e Initial load
duke
parents:
diff changeset
217 void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); }
a61af66fc99e Initial load
duke
parents:
diff changeset
218 void operator delete( void * ) { } // fast deallocation
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 static WarmCallInfo* always_hot();
a61af66fc99e Initial load
duke
parents:
diff changeset
221 static WarmCallInfo* always_cold();
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 WarmCallInfo() {
a61af66fc99e Initial load
duke
parents:
diff changeset
224 _call = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
225 _hot_cg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 _next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
227 _count = _profit = _work = _size = _heat = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 CallNode* call() const { return _call; }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 float count() const { return _count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
232 float size() const { return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
233 float work() const { return _work; }
a61af66fc99e Initial load
duke
parents:
diff changeset
234 float profit() const { return _profit; }
a61af66fc99e Initial load
duke
parents:
diff changeset
235 float heat() const { return _heat; }
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 void set_count(float x) { _count = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
238 void set_size(float x) { _size = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
239 void set_work(float x) { _work = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
240 void set_profit(float x) { _profit = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 void set_heat(float x) { _heat = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // Load initial heuristics from profiles, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // The heuristics can be tweaked further by the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
245 void init(JVMState* call_site, ciMethod* call_method, ciCallProfile& profile, float prof_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 static float MAX_VALUE() { return +1.0e10; }
a61af66fc99e Initial load
duke
parents:
diff changeset
248 static float MIN_VALUE() { return -1.0e10; }
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 float compute_heat() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 void set_call(CallNode* call) { _call = call; }
a61af66fc99e Initial load
duke
parents:
diff changeset
253 void set_hot_cg(CallGenerator* cg) { _hot_cg = cg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // Do not queue very hot or very cold calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // Make very cold ones out of line immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // Inline very hot ones immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // These queries apply various tunable limits
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // to the above metrics in a systematic way.
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // Test for coldness before testing for hotness.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 bool is_cold() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 bool is_hot() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
263
a61af66fc99e Initial load
duke
parents:
diff changeset
264 // Force a warm call to be hot. This worklists the call node for inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
265 void make_hot();
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Force a warm call to be cold. This worklists the call node for out-of-lining.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 void make_cold();
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // A reproducible total ordering, in which heat is the major key.
a61af66fc99e Initial load
duke
parents:
diff changeset
271 bool warmer_than(WarmCallInfo* that);
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // List management. These methods are called with the list head,
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // and return the new list head, inserting or removing the receiver.
a61af66fc99e Initial load
duke
parents:
diff changeset
275 WarmCallInfo* insert_into(WarmCallInfo* head);
a61af66fc99e Initial load
duke
parents:
diff changeset
276 WarmCallInfo* remove_from(WarmCallInfo* head);
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
279 void print() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
280 void print_all() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
281 int count_all() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
282 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
283 };