annotate src/share/vm/opto/callGenerator.hpp @ 3992:d1bdeef3e3e2

7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76 Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing. Reviewed-by: tonyp, brutisso, ysr
author johnc
date Wed, 12 Oct 2011 10:25:51 -0700
parents fdb992d83a87
children a04a201f0f5a
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
1137
97125851f396 6829187: compiler optimizations required for JSR 292
twisti
parents: 1080
diff changeset
111 static CallGenerator* for_dynamic_call(ciMethod* m); // invokedynamic
0
a61af66fc99e Initial load
duke
parents:
diff changeset
112 static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface
a61af66fc99e Initial load
duke
parents:
diff changeset
113
3852
fdb992d83a87 7071653: JSR 292: call site change notification should be pushed not pulled
twisti
parents: 3752
diff changeset
114 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
115 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
116
1080
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
117 // 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
118 static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg);
7c57aead6d3e 6892658: C2 should optimize some stringbuilder patterns
never
parents: 0
diff changeset
119
0
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // How to make a call but defer the decision whether to inline or not.
a61af66fc99e Initial load
duke
parents:
diff changeset
121 static CallGenerator* for_warm_call(WarmCallInfo* ci,
a61af66fc99e Initial load
duke
parents:
diff changeset
122 CallGenerator* if_cold,
a61af66fc99e Initial load
duke
parents:
diff changeset
123 CallGenerator* if_hot);
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // How to make a call that optimistically assumes a receiver type:
a61af66fc99e Initial load
duke
parents:
diff changeset
126 static CallGenerator* for_predicted_call(ciKlass* predicted_receiver,
a61af66fc99e Initial load
duke
parents:
diff changeset
127 CallGenerator* if_missed,
a61af66fc99e Initial load
duke
parents:
diff changeset
128 CallGenerator* if_hit,
a61af66fc99e Initial load
duke
parents:
diff changeset
129 float hit_prob);
a61af66fc99e Initial load
duke
parents:
diff changeset
130
1138
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
131 // 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
132 static CallGenerator* for_predicted_dynamic_call(ciMethodHandle* predicted_method_handle,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
133 CallGenerator* if_missed,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
134 CallGenerator* if_hit,
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
135 float hit_prob);
dd57230ba8fe 6893268: additional dynamic language related optimizations in C2
twisti
parents: 1137
diff changeset
136
0
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // How to make a call that gives up and goes back to the interpreter:
a61af66fc99e Initial load
duke
parents:
diff changeset
138 static CallGenerator* for_uncommon_trap(ciMethod* m,
a61af66fc99e Initial load
duke
parents:
diff changeset
139 Deoptimization::DeoptReason reason,
a61af66fc99e Initial load
duke
parents:
diff changeset
140 Deoptimization::DeoptAction action);
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 // Registry for intrinsics:
a61af66fc99e Initial load
duke
parents:
diff changeset
143 static CallGenerator* for_intrinsic(ciMethod* m);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 static void register_intrinsic(ciMethod* m, CallGenerator* cg);
a61af66fc99e Initial load
duke
parents:
diff changeset
145 };
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 class InlineCallGenerator : public CallGenerator {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 virtual bool is_inline() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
151 InlineCallGenerator(ciMethod* method) : CallGenerator(method) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
152 };
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 //---------------------------WarmCallInfo--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // A struct to collect information about a given call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // Helps sort call sites into "hot", "medium", and "cold".
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // Participates in the queueing of "medium" call sites for possible inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
159 class WarmCallInfo : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 CallNode* _call; // The CallNode which may be inlined.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 CallGenerator* _hot_cg;// CG for expanding the call node
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // These are the metrics we use to evaluate call sites:
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 float _count; // How often do we expect to reach this site?
a61af66fc99e Initial load
duke
parents:
diff changeset
168 float _profit; // How much time do we expect to save by inlining?
a61af66fc99e Initial load
duke
parents:
diff changeset
169 float _work; // How long do we expect the average call to take?
a61af66fc99e Initial load
duke
parents:
diff changeset
170 float _size; // How big do we expect the inlined code to be?
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 float _heat; // Combined score inducing total order on call sites.
a61af66fc99e Initial load
duke
parents:
diff changeset
173 WarmCallInfo* _next; // Next cooler call info in pending queue.
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // Count is the number of times this call site is expected to be executed.
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // Large count is favorable for inlining, because the extra compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // work will be amortized more completely.
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // Profit is a rough measure of the amount of time we expect to save
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // per execution of this site if we inline it. (1.0 == call overhead)
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Large profit favors inlining. Negative profit disables inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // Work is a rough measure of the amount of time a typical out-of-line
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // call from this site is expected to take. (1.0 == call, no-op, return)
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Small work is somewhat favorable for inlining, since methods with
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // short "hot" traces are more likely to inline smoothly.
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // Size is the number of graph nodes we expect this method to produce,
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // not counting the inlining of any further warm calls it may include.
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // Small size favors inlining, since small methods are more likely to
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // inline smoothly. The size is estimated by examining the native code
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // if available. The method bytecodes are also examined, assuming
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // empirically observed node counts for each kind of bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
194
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // Heat is the combined "goodness" of a site's inlining. If we were
a61af66fc99e Initial load
duke
parents:
diff changeset
196 // omniscient, it would be the difference of two sums of future execution
a61af66fc99e Initial load
duke
parents:
diff changeset
197 // times of code emitted for this site (amortized across multiple sites if
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // sharing applies). The two sums are for versions of this call site with
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // and without inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // We approximate this mythical quantity by playing with averages,
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // rough estimates, and assumptions that history repeats itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // The basic formula count * profit is heuristically adjusted
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // by looking at the expected compilation and execution times of
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // of the inlined call.
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // Note: Some of these metrics may not be present in the final product,
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // but exist in development builds to experiment with inline policy tuning.
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // This heuristic framework does not model well the very significant
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // effects of multiple-level inlining. It is possible to see no immediate
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // profit from inlining X->Y, but to get great profit from a subsequent
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // inlining X->Y->Z.
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // This framework does not take well into account the problem of N**2 code
a61af66fc99e Initial load
duke
parents:
diff changeset
216 // size in a clique of mutually inlinable methods.
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 WarmCallInfo* next() const { return _next; }
a61af66fc99e Initial load
duke
parents:
diff changeset
219 void set_next(WarmCallInfo* n) { _next = n; }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
2443
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
221 static WarmCallInfo _always_hot;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
222 static WarmCallInfo _always_cold;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
223
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
224 // 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
225 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
226 _call = NULL;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
227 _hot_cg = NULL;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
228 _next = NULL;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
229 _count = c;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
230 _profit = p;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
231 _work = w;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
232 _size = s;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
233 _heat = 0;
f8b038506985 6909440: C2 fails with assertion (_always_cold->is_cold(),"must always be cold")
never
parents: 1972
diff changeset
234 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // Because WarmInfo objects live over the entire lifetime of the
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // Compile object, they are allocated into the comp_arena, which
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // does not get resource marked or reset during the compile process
a61af66fc99e Initial load
duke
parents:
diff changeset
240 void *operator new( size_t x, Compile* C ) { return C->comp_arena()->Amalloc(x); }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 void operator delete( void * ) { } // fast deallocation
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 static WarmCallInfo* always_hot();
a61af66fc99e Initial load
duke
parents:
diff changeset
244 static WarmCallInfo* always_cold();
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 WarmCallInfo() {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 _call = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 _hot_cg = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 _next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 _count = _profit = _work = _size = _heat = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 CallNode* call() const { return _call; }
a61af66fc99e Initial load
duke
parents:
diff changeset
254 float count() const { return _count; }
a61af66fc99e Initial load
duke
parents:
diff changeset
255 float size() const { return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
256 float work() const { return _work; }
a61af66fc99e Initial load
duke
parents:
diff changeset
257 float profit() const { return _profit; }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 float heat() const { return _heat; }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 void set_count(float x) { _count = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 void set_size(float x) { _size = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
262 void set_work(float x) { _work = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 void set_profit(float x) { _profit = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
264 void set_heat(float x) { _heat = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 // Load initial heuristics from profiles, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // The heuristics can be tweaked further by the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
268 void init(JVMState* call_site, ciMethod* call_method, ciCallProfile& profile, float prof_factor);
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 static float MAX_VALUE() { return +1.0e10; }
a61af66fc99e Initial load
duke
parents:
diff changeset
271 static float MIN_VALUE() { return -1.0e10; }
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 float compute_heat() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275 void set_call(CallNode* call) { _call = call; }
a61af66fc99e Initial load
duke
parents:
diff changeset
276 void set_hot_cg(CallGenerator* cg) { _hot_cg = cg; }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // Do not queue very hot or very cold calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // Make very cold ones out of line immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // Inline very hot ones immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // These queries apply various tunable limits
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // to the above metrics in a systematic way.
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // Test for coldness before testing for hotness.
a61af66fc99e Initial load
duke
parents:
diff changeset
284 bool is_cold() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
285 bool is_hot() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
286
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // Force a warm call to be hot. This worklists the call node for inlining.
a61af66fc99e Initial load
duke
parents:
diff changeset
288 void make_hot();
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 // Force a warm call to be cold. This worklists the call node for out-of-lining.
a61af66fc99e Initial load
duke
parents:
diff changeset
291 void make_cold();
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // A reproducible total ordering, in which heat is the major key.
a61af66fc99e Initial load
duke
parents:
diff changeset
294 bool warmer_than(WarmCallInfo* that);
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 // List management. These methods are called with the list head,
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // and return the new list head, inserting or removing the receiver.
a61af66fc99e Initial load
duke
parents:
diff changeset
298 WarmCallInfo* insert_into(WarmCallInfo* head);
a61af66fc99e Initial load
duke
parents:
diff changeset
299 WarmCallInfo* remove_from(WarmCallInfo* head);
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
302 void print() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
303 void print_all() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 int count_all() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
306 };
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
307
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
308 #endif // SHARE_VM_OPTO_CALLGENERATOR_HPP