Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/advancedThresholdPolicy.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | 20334ed5ed3c |
children | 9191895df19d |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
71 | 71 |
72 set_start_time(os::javaTimeMillis()); | 72 set_start_time(os::javaTimeMillis()); |
73 } | 73 } |
74 | 74 |
75 // update_rate() is called from select_task() while holding a compile queue lock. | 75 // update_rate() is called from select_task() while holding a compile queue lock. |
76 void AdvancedThresholdPolicy::update_rate(jlong t, methodOop m) { | 76 void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) { |
77 if (is_old(m)) { | 77 if (is_old(m)) { |
78 // We don't remove old methods from the queue, | 78 // We don't remove old methods from the queue, |
79 // so we can just zero the rate. | 79 // so we can just zero the rate. |
80 m->set_rate(0); | 80 m->set_rate(0); |
81 return; | 81 return; |
104 } | 104 } |
105 } | 105 } |
106 | 106 |
107 // Check if this method has been stale from a given number of milliseconds. | 107 // Check if this method has been stale from a given number of milliseconds. |
108 // See select_task(). | 108 // See select_task(). |
109 bool AdvancedThresholdPolicy::is_stale(jlong t, jlong timeout, methodOop m) { | 109 bool AdvancedThresholdPolicy::is_stale(jlong t, jlong timeout, Method* m) { |
110 jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); | 110 jlong delta_s = t - SafepointSynchronize::end_of_last_safepoint(); |
111 jlong delta_t = t - m->prev_time(); | 111 jlong delta_t = t - m->prev_time(); |
112 if (delta_t > timeout && delta_s > timeout) { | 112 if (delta_t > timeout && delta_s > timeout) { |
113 int event_count = m->invocation_count() + m->backedge_count(); | 113 int event_count = m->invocation_count() + m->backedge_count(); |
114 int delta_e = event_count - m->prev_event_count(); | 114 int delta_e = event_count - m->prev_event_count(); |
118 return false; | 118 return false; |
119 } | 119 } |
120 | 120 |
121 // We don't remove old methods from the compile queue even if they have | 121 // We don't remove old methods from the compile queue even if they have |
122 // very low activity. See select_task(). | 122 // very low activity. See select_task(). |
123 bool AdvancedThresholdPolicy::is_old(methodOop method) { | 123 bool AdvancedThresholdPolicy::is_old(Method* method) { |
124 return method->invocation_count() > 50000 || method->backedge_count() > 500000; | 124 return method->invocation_count() > 50000 || method->backedge_count() > 500000; |
125 } | 125 } |
126 | 126 |
127 double AdvancedThresholdPolicy::weight(methodOop method) { | 127 double AdvancedThresholdPolicy::weight(Method* method) { |
128 return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1)); | 128 return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1)); |
129 } | 129 } |
130 | 130 |
131 // Apply heuristics and return true if x should be compiled before y | 131 // Apply heuristics and return true if x should be compiled before y |
132 bool AdvancedThresholdPolicy::compare_methods(methodOop x, methodOop y) { | 132 bool AdvancedThresholdPolicy::compare_methods(Method* x, Method* y) { |
133 if (x->highest_comp_level() > y->highest_comp_level()) { | 133 if (x->highest_comp_level() > y->highest_comp_level()) { |
134 // recompilation after deopt | 134 // recompilation after deopt |
135 return true; | 135 return true; |
136 } else | 136 } else |
137 if (x->highest_comp_level() == y->highest_comp_level()) { | 137 if (x->highest_comp_level() == y->highest_comp_level()) { |
141 } | 141 } |
142 return false; | 142 return false; |
143 } | 143 } |
144 | 144 |
145 // Is method profiled enough? | 145 // Is method profiled enough? |
146 bool AdvancedThresholdPolicy::is_method_profiled(methodOop method) { | 146 bool AdvancedThresholdPolicy::is_method_profiled(Method* method) { |
147 methodDataOop mdo = method->method_data(); | 147 MethodData* mdo = method->method_data(); |
148 if (mdo != NULL) { | 148 if (mdo != NULL) { |
149 int i = mdo->invocation_count_delta(); | 149 int i = mdo->invocation_count_delta(); |
150 int b = mdo->backedge_count_delta(); | 150 int b = mdo->backedge_count_delta(); |
151 return call_predicate_helper<CompLevel_full_profile>(i, b, 1); | 151 return call_predicate_helper<CompLevel_full_profile>(i, b, 1); |
152 } | 152 } |
154 } | 154 } |
155 | 155 |
156 // Called with the queue locked and with at least one element | 156 // Called with the queue locked and with at least one element |
157 CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { | 157 CompileTask* AdvancedThresholdPolicy::select_task(CompileQueue* compile_queue) { |
158 CompileTask *max_task = NULL; | 158 CompileTask *max_task = NULL; |
159 methodHandle max_method; | 159 Method* max_method; |
160 jlong t = os::javaTimeMillis(); | 160 jlong t = os::javaTimeMillis(); |
161 // Iterate through the queue and find a method with a maximum rate. | 161 // Iterate through the queue and find a method with a maximum rate. |
162 for (CompileTask* task = compile_queue->first(); task != NULL;) { | 162 for (CompileTask* task = compile_queue->first(); task != NULL;) { |
163 CompileTask* next_task = task->next(); | 163 CompileTask* next_task = task->next(); |
164 methodHandle method = (methodOop)JNIHandles::resolve(task->method_handle()); | 164 Method* method = task->method(); |
165 update_rate(t, method()); | 165 MethodData* mdo = method->method_data(); |
166 update_rate(t, method); | |
166 if (max_task == NULL) { | 167 if (max_task == NULL) { |
167 max_task = task; | 168 max_task = task; |
168 max_method = method; | 169 max_method = method; |
169 } else { | 170 } else { |
170 // If a method has been stale for some time, remove it from the queue. | 171 // If a method has been stale for some time, remove it from the queue. |
171 if (is_stale(t, TieredCompileTaskTimeout, method()) && !is_old(method())) { | 172 if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { |
172 if (PrintTieredEvents) { | 173 if (PrintTieredEvents) { |
173 print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); | 174 print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); |
174 } | 175 } |
175 CompileTaskWrapper ctw(task); // Frees the task | 176 CompileTaskWrapper ctw(task); // Frees the task |
176 compile_queue->remove(task); | 177 compile_queue->remove(task); |
178 task = next_task; | 179 task = next_task; |
179 continue; | 180 continue; |
180 } | 181 } |
181 | 182 |
182 // Select a method with a higher rate | 183 // Select a method with a higher rate |
183 if (compare_methods(method(), max_method())) { | 184 if (compare_methods(method, max_method)) { |
184 max_task = task; | 185 max_task = task; |
185 max_method = method; | 186 max_method = method; |
186 } | 187 } |
187 } | 188 } |
188 task = next_task; | 189 task = next_task; |
189 } | 190 } |
190 | 191 |
191 if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile | 192 if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile |
192 && is_method_profiled(max_method())) { | 193 && is_method_profiled(max_method)) { |
193 max_task->set_comp_level(CompLevel_limited_profile); | 194 max_task->set_comp_level(CompLevel_limited_profile); |
194 if (PrintTieredEvents) { | 195 if (PrintTieredEvents) { |
195 print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); | 196 print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level()); |
196 } | 197 } |
197 } | 198 } |
245 } | 246 } |
246 | 247 |
247 // If a method is old enough and is still in the interpreter we would want to | 248 // If a method is old enough and is still in the interpreter we would want to |
248 // start profiling without waiting for the compiled method to arrive. | 249 // start profiling without waiting for the compiled method to arrive. |
249 // We also take the load on compilers into the account. | 250 // We also take the load on compilers into the account. |
250 bool AdvancedThresholdPolicy::should_create_mdo(methodOop method, CompLevel cur_level) { | 251 bool AdvancedThresholdPolicy::should_create_mdo(Method* method, CompLevel cur_level) { |
251 if (cur_level == CompLevel_none && | 252 if (cur_level == CompLevel_none && |
252 CompileBroker::queue_size(CompLevel_full_optimization) <= | 253 CompileBroker::queue_size(CompLevel_full_optimization) <= |
253 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { | 254 Tier3DelayOn * compiler_count(CompLevel_full_optimization)) { |
254 int i = method->invocation_count(); | 255 int i = method->invocation_count(); |
255 int b = method->backedge_count(); | 256 int b = method->backedge_count(); |
272 | 273 |
273 // Create MDO if necessary. | 274 // Create MDO if necessary. |
274 void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) { | 275 void AdvancedThresholdPolicy::create_mdo(methodHandle mh, JavaThread* THREAD) { |
275 if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return; | 276 if (mh->is_native() || mh->is_abstract() || mh->is_accessor()) return; |
276 if (mh->method_data() == NULL) { | 277 if (mh->method_data() == NULL) { |
277 methodOopDesc::build_interpreter_method_data(mh, CHECK_AND_CLEAR); | 278 Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR); |
278 } | 279 } |
279 } | 280 } |
280 | 281 |
281 | 282 |
282 /* | 283 /* |
316 * are possible. | 317 * are possible. |
317 * | 318 * |
318 */ | 319 */ |
319 | 320 |
320 // Common transition function. Given a predicate determines if a method should transition to another level. | 321 // Common transition function. Given a predicate determines if a method should transition to another level. |
321 CompLevel AdvancedThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level, bool disable_feedback) { | 322 CompLevel AdvancedThresholdPolicy::common(Predicate p, Method* method, CompLevel cur_level, bool disable_feedback) { |
322 CompLevel next_level = cur_level; | 323 CompLevel next_level = cur_level; |
323 int i = method->invocation_count(); | 324 int i = method->invocation_count(); |
324 int b = method->backedge_count(); | 325 int b = method->backedge_count(); |
325 | 326 |
326 if (is_trivial(method)) { | 327 if (is_trivial(method)) { |
350 case CompLevel_limited_profile: | 351 case CompLevel_limited_profile: |
351 if (is_method_profiled(method)) { | 352 if (is_method_profiled(method)) { |
352 // Special case: we got here because this method was fully profiled in the interpreter. | 353 // Special case: we got here because this method was fully profiled in the interpreter. |
353 next_level = CompLevel_full_optimization; | 354 next_level = CompLevel_full_optimization; |
354 } else { | 355 } else { |
355 methodDataOop mdo = method->method_data(); | 356 MethodData* mdo = method->method_data(); |
356 if (mdo != NULL) { | 357 if (mdo != NULL) { |
357 if (mdo->would_profile()) { | 358 if (mdo->would_profile()) { |
358 if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= | 359 if (disable_feedback || (CompileBroker::queue_size(CompLevel_full_optimization) <= |
359 Tier3DelayOff * compiler_count(CompLevel_full_optimization) && | 360 Tier3DelayOff * compiler_count(CompLevel_full_optimization) && |
360 (this->*p)(i, b, cur_level))) { | 361 (this->*p)(i, b, cur_level))) { |
366 } | 367 } |
367 } | 368 } |
368 break; | 369 break; |
369 case CompLevel_full_profile: | 370 case CompLevel_full_profile: |
370 { | 371 { |
371 methodDataOop mdo = method->method_data(); | 372 MethodData* mdo = method->method_data(); |
372 if (mdo != NULL) { | 373 if (mdo != NULL) { |
373 if (mdo->would_profile()) { | 374 if (mdo->would_profile()) { |
374 int mdo_i = mdo->invocation_count_delta(); | 375 int mdo_i = mdo->invocation_count_delta(); |
375 int mdo_b = mdo->backedge_count_delta(); | 376 int mdo_b = mdo->backedge_count_delta(); |
376 if ((this->*p)(mdo_i, mdo_b, cur_level)) { | 377 if ((this->*p)(mdo_i, mdo_b, cur_level)) { |
386 } | 387 } |
387 return MIN2(next_level, (CompLevel)TieredStopAtLevel); | 388 return MIN2(next_level, (CompLevel)TieredStopAtLevel); |
388 } | 389 } |
389 | 390 |
390 // Determine if a method should be compiled with a normal entry point at a different level. | 391 // Determine if a method should be compiled with a normal entry point at a different level. |
391 CompLevel AdvancedThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { | 392 CompLevel AdvancedThresholdPolicy::call_event(Method* method, CompLevel cur_level) { |
392 CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(), | 393 CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(), |
393 common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true)); | 394 common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true)); |
394 CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level); | 395 CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level); |
395 | 396 |
396 // If OSR method level is greater than the regular method level, the levels should be | 397 // If OSR method level is greater than the regular method level, the levels should be |
397 // equalized by raising the regular method level in order to avoid OSRs during each | 398 // equalized by raising the regular method level in order to avoid OSRs during each |
398 // invocation of the method. | 399 // invocation of the method. |
399 if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) { | 400 if (osr_level == CompLevel_full_optimization && cur_level == CompLevel_full_profile) { |
400 methodDataOop mdo = method->method_data(); | 401 MethodData* mdo = method->method_data(); |
401 guarantee(mdo != NULL, "MDO should not be NULL"); | 402 guarantee(mdo != NULL, "MDO should not be NULL"); |
402 if (mdo->invocation_count() >= 1) { | 403 if (mdo->invocation_count() >= 1) { |
403 next_level = CompLevel_full_optimization; | 404 next_level = CompLevel_full_optimization; |
404 } | 405 } |
405 } else { | 406 } else { |
407 } | 408 } |
408 return next_level; | 409 return next_level; |
409 } | 410 } |
410 | 411 |
411 // Determine if we should do an OSR compilation of a given method. | 412 // Determine if we should do an OSR compilation of a given method. |
412 CompLevel AdvancedThresholdPolicy::loop_event(methodOop method, CompLevel cur_level) { | 413 CompLevel AdvancedThresholdPolicy::loop_event(Method* method, CompLevel cur_level) { |
413 CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true); | 414 CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true); |
414 if (cur_level == CompLevel_none) { | 415 if (cur_level == CompLevel_none) { |
415 // If there is a live OSR method that means that we deopted to the interpreter | 416 // If there is a live OSR method that means that we deopted to the interpreter |
416 // for the transition. | 417 // for the transition. |
417 CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level); | 418 CompLevel osr_level = MIN2((CompLevel)method->highest_osr_comp_level(), next_level); |