Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/advancedThresholdPolicy.cpp @ 3979:4dfb2df418f2
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author | johnc |
---|---|
date | Thu, 22 Sep 2011 10:57:37 -0700 |
parents | 43f9d800f276 |
children | abcceac2f7cd |
rev | line source |
---|---|
2348 | 1 /* |
3358 | 2 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
2348 | 24 |
25 #include "precompiled.hpp" | |
26 #include "runtime/advancedThresholdPolicy.hpp" | |
27 #include "runtime/simpleThresholdPolicy.inline.hpp" | |
28 | |
29 #ifdef TIERED | |
30 // Print an event. | |
31 void AdvancedThresholdPolicy::print_specific(EventType type, methodHandle mh, methodHandle imh, | |
32 int bci, CompLevel level) { | |
33 tty->print(" rate: "); | |
34 if (mh->prev_time() == 0) tty->print("n/a"); | |
35 else tty->print("%f", mh->rate()); | |
36 | |
37 tty->print(" k: %.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback), | |
38 threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback)); | |
39 | |
40 } | |
41 | |
42 void AdvancedThresholdPolicy::initialize() { | |
43 // Turn on ergonomic compiler count selection | |
44 if (FLAG_IS_DEFAULT(CICompilerCountPerCPU) && FLAG_IS_DEFAULT(CICompilerCount)) { | |
45 FLAG_SET_DEFAULT(CICompilerCountPerCPU, true); | |
46 } | |
47 int count = CICompilerCount; | |
48 if (CICompilerCountPerCPU) { | |
49 // Simple log n seems to grow too slowly for tiered, try something faster: log n * log log n | |
50 int log_cpu = log2_intptr(os::active_processor_count()); | |
51 int loglog_cpu = log2_intptr(MAX2(log_cpu, 1)); | |
52 count = MAX2(log_cpu * loglog_cpu, 1) * 3 / 2; | |
53 } | |
54 | |
55 set_c1_count(MAX2(count / 3, 1)); | |
56 set_c2_count(MAX2(count - count / 3, 1)); | |
57 | |
58 // Some inlining tuning | |
59 #ifdef X86 | |
60 if (FLAG_IS_DEFAULT(InlineSmallCode)) { | |
61 FLAG_SET_DEFAULT(InlineSmallCode, 2000); | |
62 } | |
63 #endif | |
64 | |
65 #ifdef SPARC | |
66 if (FLAG_IS_DEFAULT(InlineSmallCode)) { | |
67 FLAG_SET_DEFAULT(InlineSmallCode, 2500); | |
68 } | |
69 #endif | |
70 | |
71 | |
72 set_start_time(os::javaTimeMillis()); | |
73 } | |
74 | |
75 // update_rate() is called from select_task() while holding a compile queue lock. | |
76 void AdvancedThresholdPolicy::update_rate(jlong t, methodOop m) { | |
77 if (is_old(m)) { | |
78 // We don't remove old methods from the queue, | |
79 // so we can just zero the rate. | |
80 m->set_rate(0); | |
81 return; | |
82 } | |
83 | |
84 // We don't update the rate if we've just came out of a safepoint. | |
85 // delta_s is the time since last safepoint in milliseconds. | |
86 jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); | |
87 jlong delta_t = t - (m->prev_time() != 0 ? m->prev_time() : start_time()); // milliseconds since the last measurement | |
88 // How many events were there since the last time? | |
89 int event_count = m->invocation_count() + m->backedge_count(); | |
90 int delta_e = event_count - m->prev_event_count(); | |
91 | |
92 // We should be running for at least 1ms. | |
93 if (delta_s >= TieredRateUpdateMinTime) { | |
94 // And we must've taken the previous point at least 1ms before. | |
95 if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) { | |
96 m->set_prev_time(t); | |
97 m->set_prev_event_count(event_count); | |
98 m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond | |
99 } else | |
100 if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) { | |
101 // If nothing happened for 25ms, zero the rate. Don't modify prev values. | |
102 m->set_rate(0); | |
103 } | |
104 } | |
105 } | |
106 | |
107 // Check if this method has been stale from a given number of milliseconds. | |
108 // See select_task(). | |
109 bool AdvancedThresholdPolicy::is_stale(jlong t, jlong timeout, methodOop m) { | |
110 jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); | |
111 jlong delta_t = t - m->prev_time(); | |
112 if (delta_t > timeout && delta_s > timeout) { | |
113 int event_count = m->invocation_count() + m->backedge_count(); | |
114 int delta_e = event_count - m->prev_event_count(); | |
115 // Return true if there were no events. | |
116 return delta_e == 0; | |
117 } | |
118 return false; | |
119 } | |
120 | |
121 // We don't remove old methods from the compile queue even if they have | |
122 // very low activity. See select_task(). | |
123 bool AdvancedThresholdPolicy::is_old(methodOop method) { | |
124 return method->invocation_count() > 50000 || method->backedge_count() > 500000; | |
125 } | |
126 | |
127 double AdvancedThresholdPolicy::weight(methodOop method) { | |
128 return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1)); | |
129 } | |
130 | |
131 // Apply heuristics and return true if x should be compiled before y | |
132 bool AdvancedThresholdPolicy::compare_methods(methodOop x, methodOop y) { | |
133 if (x->highest_comp_level() > y->highest_comp_level()) { | |
134 // recompilation after deopt | |
135 return true; | |
136 } else | |
137 if (x->highest_comp_level() == y->highest_comp_level()) { | |
138 if (weight(x) > weight(y)) { | |
139 return true; | |
140 } | |
141 } | |
142 return false; | |
143 } | |
144 | |
145 // Is method profiled enough? | |
146 bool AdvancedThresholdPolicy::is_method_profiled(methodOop method) { | |
147 methodDataOop mdo = method->method_data(); | |
148 if (mdo != NULL) { | |
149 int i = mdo->invocation_count_delta(); | |
150 int b = mdo->backedge_count_delta(); | |
151 return call_predicate_helper<CompLevel_full_profile>(i, b, 1); | |
152 } | |
153 return false; | |
154 } | |
155 | |
156 // Called with the queue locked and with at least one element | |
157 CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { | |
158 CompileTask *max_task = NULL; | |
159 methodOop max_method; | |
160 jlong t = os::javaTimeMillis(); | |
161 // Iterate through the queue and find a method with a maximum rate. | |
162 for (CompileTask* task = compile_queue->first(); task != NULL;) { | |
163 CompileTask* next_task = task->next(); | |
164 methodOop method = (methodOop)JNIHandles::resolve(task->method_handle()); | |
165 methodDataOop mdo = method->method_data(); | |
166 update_rate(t, method); | |
167 if (max_task == NULL) { | |
168 max_task = task; | |
169 max_method = method; | |
170 } else { | |
171 // If a method has been stale for some time, remove it from the queue. | |
172 if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { | |
173 if (PrintTieredEvents) { | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
174 print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); |
2348 | 175 } |
176 CompileTaskWrapper ctw(task); // Frees the task | |
177 compile_queue->remove(task); | |
178 method->clear_queued_for_compilation(); | |
179 task = next_task; | |
180 continue; | |
181 } | |
182 | |
183 // Select a method with a higher rate | |
184 if (compare_methods(method, max_method)) { | |
185 max_task = task; | |
186 max_method = method; | |
187 } | |
188 } | |
189 task = next_task; | |
190 } | |
191 | |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
192 if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
193 && is_method_profiled(max_method)) { |
2348 | 194 max_task->set_comp_level(CompLevel_limited_profile); |
195 if (PrintTieredEvents) { | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
196 print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); |
2348 | 197 } |
198 } | |
199 | |
200 return max_task; | |
201 } | |
202 | |
203 double AdvancedThresholdPolicy::threshold_scale(CompLevel level, int feedback_k) { | |
204 double queue_size = CompileBroker::queue_size(level); | |
205 int comp_count = compiler_count(level); | |
206 double k = queue_size / (feedback_k * comp_count) + 1; | |
207 return k; | |
208 } | |
209 | |
210 // Call and loop predicates determine whether a transition to a higher | |
211 // compilation level should be performed (pointers to predicate functions | |
212 // are passed to common()). | |
213 // Tier?LoadFeedback is basically a coefficient that determines of | |
214 // how many methods per compiler thread can be in the queue before | |
215 // the threshold values double. | |
216 bool AdvancedThresholdPolicy::loop_predicate(int i, int b, CompLevel cur_level) { | |
217 switch(cur_level) { | |
218 case CompLevel_none: | |
219 case CompLevel_limited_profile: { | |
220 double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); | |
221 return loop_predicate_helper<CompLevel_none>(i, b, k); | |
222 } | |
223 case CompLevel_full_profile: { | |
224 double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); | |
225 return loop_predicate_helper<CompLevel_full_profile>(i, b, k); | |
226 } | |
227 default: | |
228 return true; | |
229 } | |
230 } | |
231 | |
232 bool AdvancedThresholdPolicy::call_predicate(int i, int b, CompLevel cur_level) { | |
233 switch(cur_level) { | |
234 case CompLevel_none: | |
235 case CompLevel_limited_profile: { | |
236 double k = threshold_scale(CompLevel_full_profile, Tier3LoadFeedback); | |
237 return call_predicate_helper<CompLevel_none>(i, b, k); | |
238 } | |
239 case CompLevel_full_profile: { | |
240 double k = threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback); | |
241 return call_predicate_helper<CompLevel_full_profile>(i, b, k); | |
242 } | |
243 default: | |
244 return true; | |
245 } | |
246 } | |
247 | |
248 // If a method is old enough and is still in the interpreter we would want to | |
249 // start profiling without waiting for the compiled method to arrive. | |
250 // We also take the load on compilers into the account. | |
251 bool AdvancedThresholdPolicy::should_create_mdo(methodOop method, CompLevel cur_level) { | |
252 if (cur_level == CompLevel_none && | |
253 CompileBroker::queue_size(CompLevel_full_optimization) <= | |
254 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { | |
255 int i = method->invocation_count(); | |
256 int b = method->backedge_count(); | |
257 double k = Tier0ProfilingStartPercentage / 100.0; | |
258 return call_predicate_helper<CompLevel_none>(i, b, k) || loop_predicate_helper<CompLevel_none>(i, b, k); | |
259 } | |
260 return false; | |
261 } | |
262 | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
263 // Inlining control: if we're compiling a profiled method with C1 and the callee |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
264 // is known to have OSRed in a C2 version, don't inline it. |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
265 bool AdvancedThresholdPolicy::should_not_inline(ciEnv* env, ciMethod* callee) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
266 CompLevel comp_level = (CompLevel)env->comp_level(); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
267 if (comp_level == CompLevel_full_profile || |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
268 comp_level == CompLevel_limited_profile) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
269 return callee->highest_osr_comp_level() == CompLevel_full_optimization; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
270 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
271 return false; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
272 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
273 |
2348 | 274 // Create MDO if necessary. |
275 void AdvancedThresholdPolicy::create_mdo(methodHandle mh, TRAPS) { | |
276 if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return; | |
277 if (mh->method_data() == NULL) { | |
278 methodOopDesc::build_interpreter_method_data(mh, THREAD); | |
279 if (HAS_PENDING_EXCEPTION) { | |
280 CLEAR_PENDING_EXCEPTION; | |
281 } | |
282 } | |
283 } | |
284 | |
285 | |
286 /* | |
287 * Method states: | |
288 * 0 - interpreter (CompLevel_none) | |
289 * 1 - pure C1 (CompLevel_simple) | |
290 * 2 - C1 with invocation and backedge counting (CompLevel_limited_profile) | |
291 * 3 - C1 with full profiling (CompLevel_full_profile) | |
292 * 4 - C2 (CompLevel_full_optimization) | |
293 * | |
294 * Common state transition patterns: | |
295 * a. 0 -> 3 -> 4. | |
296 * The most common path. But note that even in this straightforward case | |
297 * profiling can start at level 0 and finish at level 3. | |
298 * | |
299 * b. 0 -> 2 -> 3 -> 4. | |
300 * This case occures when the load on C2 is deemed too high. So, instead of transitioning | |
301 * into state 3 directly and over-profiling while a method is in the C2 queue we transition to | |
302 * level 2 and wait until the load on C2 decreases. This path is disabled for OSRs. | |
303 * | |
304 * c. 0 -> (3->2) -> 4. | |
305 * In this case we enqueue a method for compilation at level 3, but the C1 queue is long enough | |
306 * to enable the profiling to fully occur at level 0. In this case we change the compilation level | |
307 * of the method to 2, because it'll allow it to run much faster without full profiling while c2 | |
308 * is compiling. | |
309 * | |
310 * d. 0 -> 3 -> 1 or 0 -> 2 -> 1. | |
311 * After a method was once compiled with C1 it can be identified as trivial and be compiled to | |
312 * level 1. These transition can also occur if a method can't be compiled with C2 but can with C1. | |
313 * | |
314 * e. 0 -> 4. | |
315 * This can happen if a method fails C1 compilation (it will still be profiled in the interpreter) | |
316 * or because of a deopt that didn't require reprofiling (compilation won't happen in this case because | |
317 * the compiled version already exists). | |
318 * | |
319 * Note that since state 0 can be reached from any other state via deoptimization different loops | |
320 * are possible. | |
321 * | |
322 */ | |
323 | |
324 // Common transition function. Given a predicate determines if a method should transition to another level. | |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
325 CompLevel AdvancedThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level, bool disable_feedback) { |
2348 | 326 CompLevel next_level = cur_level; |
327 int i = method->invocation_count(); | |
328 int b = method->backedge_count(); | |
329 | |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
330 if (is_trivial(method)) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
331 next_level = CompLevel_simple; |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
332 } else { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
333 switch(cur_level) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
334 case CompLevel_none: |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
335 // If we were at full profile level, would we switch to full opt? |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
336 if (common(p, method, CompLevel_full_profile, disable_feedback) == CompLevel_full_optimization) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
337 next_level = CompLevel_full_optimization; |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
338 } else if ((this->*p)(i, b, cur_level)) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
339 // C1-generated fully profiled code is about 30% slower than the limited profile |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
340 // code that has only invocation and backedge counters. The observation is that |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
341 // if C2 queue is large enough we can spend too much time in the fully profiled code |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
342 // while waiting for C2 to pick the method from the queue. To alleviate this problem |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
343 // we introduce a feedback on the C2 queue size. If the C2 queue is sufficiently long |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
344 // we choose to compile a limited profiled version and then recompile with full profiling |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
345 // when the load on C2 goes down. |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
346 if (!disable_feedback && CompileBroker::queue_size(CompLevel_full_optimization) > |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
347 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
348 next_level = CompLevel_limited_profile; |
2348 | 349 } else { |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
350 next_level = CompLevel_full_profile; |
2348 | 351 } |
352 } | |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
353 break; |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
354 case CompLevel_limited_profile: |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
355 if (is_method_profiled(method)) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
356 // Special case: we got here because this method was fully profiled in the interpreter. |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
357 next_level = CompLevel_full_optimization; |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
358 } else { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
359 methodDataOop mdo = method->method_data(); |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
360 if (mdo != NULL) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
361 if (mdo->would_profile()) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
362 if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
363 Tier3DelayOff * compiler_count(CompLevel_full_optimization) && |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
364 (this->*p)(i, b, cur_level))) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
365 next_level = CompLevel_full_profile; |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
366 } |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
367 } else { |
2348 | 368 next_level = CompLevel_full_optimization; |
369 } | |
370 } | |
371 } | |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
372 break; |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
373 case CompLevel_full_profile: |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
374 { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
375 methodDataOop mdo = method->method_data(); |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
376 if (mdo != NULL) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
377 if (mdo->would_profile()) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
378 int mdo_i = mdo->invocation_count_delta(); |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
379 int mdo_b = mdo->backedge_count_delta(); |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
380 if ((this->*p)(mdo_i, mdo_b, cur_level)) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
381 next_level = CompLevel_full_optimization; |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
382 } |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
383 } else { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
384 next_level = CompLevel_full_optimization; |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
385 } |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
386 } |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
387 } |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
388 break; |
2348 | 389 } |
390 } | |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
391 return MIN2(next_level, (CompLevel)TieredStopAtLevel); |
2348 | 392 } |
393 | |
394 // Determine if a method should be compiled with a normal entry point at a different level. | |
3790
6f6e91603a45
7058689: Tiered: Reprofiling doesn't happen in presence of level 4 OSR methods
iveresov
parents:
3358
diff
changeset
|
395 CompLevel AdvancedThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { |
6f6e91603a45
7058689: Tiered: Reprofiling doesn't happen in presence of level 4 OSR methods
iveresov
parents:
3358
diff
changeset
|
396 CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(), |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
397 common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true)); |
2348 | 398 CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level); |
399 | |
400 // If OSR method level is greater than the regular method level, the levels should be | |
401 // equalized by raising the regular method level in order to avoid OSRs during each | |
402 // invocation of the method. | |
403 if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) { | |
404 methodDataOop mdo = method->method_data(); | |
405 guarantee(mdo != NULL, "MDO should not be NULL"); | |
406 if (mdo->invocation_count() >= 1) { | |
407 next_level = CompLevel_full_optimization; | |
408 } | |
409 } else { | |
410 next_level = MAX2(osr_level, next_level); | |
411 } | |
412 return next_level; | |
413 } | |
414 | |
415 // Determine if we should do an OSR compilation of a given method. | |
416 CompLevel AdvancedThresholdPolicy::loop_event(methodOop method, CompLevel cur_level) { | |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
417 CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true); |
2348 | 418 if (cur_level == CompLevel_none) { |
419 // If there is a live OSR method that means that we deopted to the interpreter | |
420 // for the transition. | |
3790
6f6e91603a45
7058689: Tiered: Reprofiling doesn't happen in presence of level 4 OSR methods
iveresov
parents:
3358
diff
changeset
|
421 CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level); |
2348 | 422 if (osr_level > CompLevel_none) { |
423 return osr_level; | |
424 } | |
425 } | |
3790
6f6e91603a45
7058689: Tiered: Reprofiling doesn't happen in presence of level 4 OSR methods
iveresov
parents:
3358
diff
changeset
|
426 return next_level; |
2348 | 427 } |
428 | |
429 // Update the rate and submit compile | |
430 void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, TRAPS) { | |
431 int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count(); | |
432 update_rate(os::javaTimeMillis(), mh()); | |
433 CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", THREAD); | |
434 } | |
435 | |
436 // Handle the invocation event. | |
437 void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh, | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
438 CompLevel level, nmethod* nm, TRAPS) { |
2348 | 439 if (should_create_mdo(mh(), level)) { |
440 create_mdo(mh, THREAD); | |
441 } | |
442 if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) { | |
443 CompLevel next_level = call_event(mh(), level); | |
444 if (next_level != level) { | |
445 compile(mh, InvocationEntryBci, next_level, THREAD); | |
446 } | |
447 } | |
448 } | |
449 | |
450 // Handle the back branch event. Notice that we can compile the method | |
451 // with a regular entry from here. | |
452 void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh, | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
453 int bci, CompLevel level, nmethod* nm, TRAPS) { |
2348 | 454 if (should_create_mdo(mh(), level)) { |
455 create_mdo(mh, THREAD); | |
456 } | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
457 // Check if MDO should be created for the inlined method |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
458 if (should_create_mdo(imh(), level)) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
459 create_mdo(imh, THREAD); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
460 } |
2348 | 461 |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
462 if (is_compilation_enabled()) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
463 CompLevel next_osr_level = loop_event(imh(), level); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
464 CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level(); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
465 // At the very least compile the OSR version |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
466 if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_osr_level != level) { |
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3791
diff
changeset
|
467 compile(imh, bci, next_osr_level, THREAD); |
2348 | 468 } |
469 | |
3791
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
470 // Use loop event as an opportunity to also check if there's been |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
471 // enough calls. |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
472 CompLevel cur_level, next_level; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
473 if (mh() != imh()) { // If there is an enclosing method |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
474 guarantee(nm != NULL, "Should have nmethod here"); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
475 cur_level = comp_level(mh()); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
476 next_level = call_event(mh(), cur_level); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
477 |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
478 if (max_osr_level == CompLevel_full_optimization) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
479 // The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
480 bool make_not_entrant = false; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
481 if (nm->is_osr_method()) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
482 // This is an osr method, just make it not entrant and recompile later if needed |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
483 make_not_entrant = true; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
484 } else { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
485 if (next_level != CompLevel_full_optimization) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
486 // next_level is not full opt, so we need to recompile the |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
487 // enclosing method without the inlinee |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
488 cur_level = CompLevel_none; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
489 make_not_entrant = true; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
490 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
491 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
492 if (make_not_entrant) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
493 if (PrintTieredEvents) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
494 int osr_bci = nm->is_osr_method() ? nm->osr_entry_bci() : InvocationEntryBci; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
495 print_event(MAKE_NOT_ENTRANT, mh(), mh(), osr_bci, level); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
496 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
497 nm->make_not_entrant(); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
498 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
499 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
500 if (!CompileBroker::compilation_is_in_queue(mh, InvocationEntryBci)) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
501 // Fix up next_level if necessary to avoid deopts |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
502 if (next_level == CompLevel_limited_profile && max_osr_level == CompLevel_full_profile) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
503 next_level = CompLevel_full_profile; |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
504 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
505 if (cur_level != next_level) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
506 compile(mh, InvocationEntryBci, next_level, THREAD); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
507 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
508 } |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
509 } else { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
510 cur_level = comp_level(imh()); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
511 next_level = call_event(imh(), cur_level); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
512 if (!CompileBroker::compilation_is_in_queue(imh, bci) && next_level != cur_level) { |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
513 compile(imh, InvocationEntryBci, next_level, THREAD); |
2c359f27615c
7057120: Tiered: Allow C1 to inline methods with loops
iveresov
parents:
3790
diff
changeset
|
514 } |
2348 | 515 } |
516 } | |
517 } | |
518 | |
519 #endif // TIERED |