Wed, 09 Feb 2011 16:34:34 -0800
7017434: Tiered needs to support reprofiling
Summary: Tiered needs to support proper method reprofiling after deopts.
Reviewed-by: kvn
1.1 --- a/src/share/vm/c1/c1_Compilation.cpp Tue Feb 08 16:12:16 2011 -0800 1.2 +++ b/src/share/vm/c1/c1_Compilation.cpp Wed Feb 09 16:34:34 2011 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -491,10 +491,11 @@ 1.11 // to start profiling on its own. 1.12 _method->ensure_method_data(); 1.13 } 1.14 - } else if (is_profiling() && _would_profile) { 1.15 + } else if (is_profiling()) { 1.16 ciMethodData *md = method->method_data_or_null(); 1.17 - assert(md != NULL, "Sanity"); 1.18 - md->set_would_profile(_would_profile); 1.19 + if (md != NULL) { 1.20 + md->set_would_profile(_would_profile); 1.21 + } 1.22 } 1.23 } 1.24
2.1 --- a/src/share/vm/oops/methodDataOop.cpp Tue Feb 08 16:12:16 2011 -0800 2.2 +++ b/src/share/vm/oops/methodDataOop.cpp Wed Feb 09 16:34:34 2011 -0800 2.3 @@ -764,11 +764,13 @@ 2.4 if (TieredCompilation) { 2.5 _invocation_counter.init(); 2.6 _backedge_counter.init(); 2.7 + _invocation_counter_start = 0; 2.8 + _backedge_counter_start = 0; 2.9 _num_loops = 0; 2.10 _num_blocks = 0; 2.11 _highest_comp_level = 0; 2.12 _highest_osr_comp_level = 0; 2.13 - _would_profile = false; 2.14 + _would_profile = true; 2.15 } 2.16 set_creation_mileage(mileage_of(method())); 2.17
3.1 --- a/src/share/vm/oops/methodDataOop.hpp Tue Feb 08 16:12:16 2011 -0800 3.2 +++ b/src/share/vm/oops/methodDataOop.hpp Wed Feb 09 16:34:34 2011 -0800 3.3 @@ -1224,6 +1224,9 @@ 3.4 InvocationCounter _invocation_counter; 3.5 // Same for backedges. 3.6 InvocationCounter _backedge_counter; 3.7 + // Counter values at the time profiling started. 3.8 + int _invocation_counter_start; 3.9 + int _backedge_counter_start; 3.10 // Number of loops and blocks is computed when compiling the first 3.11 // time with C1. It is used to determine if method is trivial. 3.12 short _num_loops; 3.13 @@ -1333,6 +1336,28 @@ 3.14 return backedge_counter()->count(); 3.15 } 3.16 3.17 + int invocation_count_start() { 3.18 + if (invocation_counter()->carry()) { 3.19 + return 0; 3.20 + } 3.21 + return _invocation_counter_start; 3.22 + } 3.23 + 3.24 + int backedge_count_start() { 3.25 + if (backedge_counter()->carry()) { 3.26 + return 0; 3.27 + } 3.28 + return _backedge_counter_start; 3.29 + } 3.30 + 3.31 + int invocation_count_delta() { return invocation_count() - invocation_count_start(); } 3.32 + int backedge_count_delta() { return backedge_count() - backedge_count_start(); } 3.33 + 3.34 + void reset_start_counters() { 3.35 + _invocation_counter_start = invocation_count(); 3.36 + _backedge_counter_start = backedge_count(); 3.37 + } 3.38 + 3.39 InvocationCounter* invocation_counter() { return &_invocation_counter; } 3.40 InvocationCounter* backedge_counter() { return &_backedge_counter; } 3.41
4.1 --- a/src/share/vm/runtime/simpleThresholdPolicy.cpp Tue Feb 08 16:12:16 2011 -0800 4.2 +++ b/src/share/vm/runtime/simpleThresholdPolicy.cpp Wed Feb 09 16:34:34 2011 -0800 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -28,6 +28,7 @@ 4.11 #include "runtime/arguments.hpp" 4.12 #include "runtime/simpleThresholdPolicy.hpp" 4.13 #include "runtime/simpleThresholdPolicy.inline.hpp" 4.14 +#include "code/scopeDesc.hpp" 4.15 4.16 // Print an event. 4.17 void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodHandle imh, 4.18 @@ -48,6 +49,18 @@ 4.19 break; 4.20 case COMPILE: 4.21 tty->print("compile"); 4.22 + break; 4.23 + case KILL: 4.24 + tty->print("kill"); 4.25 + break; 4.26 + case UPDATE: 4.27 + tty->print("update"); 4.28 + break; 4.29 + case REPROFILE: 4.30 + tty->print("reprofile"); 4.31 + break; 4.32 + default: 4.33 + tty->print("unknown"); 4.34 } 4.35 4.36 tty->print(" level: %d ", level); 4.37 @@ -69,13 +82,17 @@ 4.38 if (type != COMPILE) { 4.39 methodDataHandle mdh = mh->method_data(); 4.40 int mdo_invocations = 0, mdo_backedges = 0; 4.41 + int mdo_invocations_start = 0, mdo_backedges_start = 0; 4.42 if (mdh() != NULL) { 4.43 mdo_invocations = mdh->invocation_count(); 4.44 mdo_backedges = mdh->backedge_count(); 4.45 + mdo_invocations_start = mdh->invocation_count_start(); 4.46 + mdo_backedges_start = mdh->backedge_count_start(); 4.47 } 4.48 - tty->print(" total: %d,%d mdo: %d,%d", 4.49 + tty->print(" total: %d,%d mdo: %d(%d),%d(%d)", 4.50 invocation_count, backedge_count, 4.51 - mdo_invocations, mdo_backedges); 4.52 + mdo_invocations, mdo_invocations_start, 4.53 + mdo_backedges, mdo_backedges_start); 4.54 tty->print(" max levels: %d,%d", 4.55 mh->highest_comp_level(), mh->highest_osr_comp_level()); 4.56 if (inlinee_event) { 4.57 @@ -138,6 +155,20 @@ 4.58 return compile_queue->first(); 4.59 } 4.60 4.61 +void SimpleThresholdPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) { 4.62 + for (ScopeDesc* sd = trap_scope;; sd = sd->sender()) { 4.63 + if (PrintTieredEvents) { 4.64 + methodHandle mh(sd->method()); 4.65 + print_event(REPROFILE, mh, mh, InvocationEntryBci, CompLevel_none); 4.66 + } 4.67 + methodDataOop mdo = sd->method()->method_data(); 4.68 + if (mdo != NULL) { 4.69 + mdo->reset_start_counters(); 4.70 + } 4.71 + if (sd->is_top()) break; 4.72 + } 4.73 +} 4.74 + 4.75 nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee, 4.76 int branch_bci, int bci, CompLevel comp_level, TRAPS) { 4.77 if (comp_level == CompLevel_none && 4.78 @@ -254,46 +285,35 @@ 4.79 4.80 // Common transition function. Given a predicate determines if a method should transition to another level. 4.81 CompLevel SimpleThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level) { 4.82 + if (is_trivial(method)) return CompLevel_simple; 4.83 + 4.84 CompLevel next_level = cur_level; 4.85 int i = method->invocation_count(); 4.86 int b = method->backedge_count(); 4.87 4.88 switch(cur_level) { 4.89 case CompLevel_none: 4.90 - { 4.91 - methodDataOop mdo = method->method_data(); 4.92 - if (mdo != NULL) { 4.93 - int mdo_i = mdo->invocation_count(); 4.94 - int mdo_b = mdo->backedge_count(); 4.95 - // If we were at full profile level, would we switch to full opt? 4.96 - if ((this->*p)(mdo_i, mdo_b, CompLevel_full_profile)) { 4.97 - next_level = CompLevel_full_optimization; 4.98 - } 4.99 - } 4.100 - } 4.101 - if (next_level == cur_level && (this->*p)(i, b, cur_level)) { 4.102 - if (is_trivial(method)) { 4.103 - next_level = CompLevel_simple; 4.104 - } else { 4.105 - next_level = CompLevel_full_profile; 4.106 - } 4.107 + // If we were at full profile level, would we switch to full opt? 4.108 + if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) { 4.109 + next_level = CompLevel_full_optimization; 4.110 + } else if ((this->*p)(i, b, cur_level)) { 4.111 + next_level = CompLevel_full_profile; 4.112 } 4.113 break; 4.114 case CompLevel_limited_profile: 4.115 case CompLevel_full_profile: 4.116 - if (is_trivial(method)) { 4.117 - next_level = CompLevel_simple; 4.118 - } else { 4.119 + { 4.120 methodDataOop mdo = method->method_data(); 4.121 - guarantee(mdo != NULL, "MDO should always exist"); 4.122 - if (mdo->would_profile()) { 4.123 - int mdo_i = mdo->invocation_count(); 4.124 - int mdo_b = mdo->backedge_count(); 4.125 - if ((this->*p)(mdo_i, mdo_b, cur_level)) { 4.126 + if (mdo != NULL) { 4.127 + if (mdo->would_profile()) { 4.128 + int mdo_i = mdo->invocation_count_delta(); 4.129 + int mdo_b = mdo->backedge_count_delta(); 4.130 + if ((this->*p)(mdo_i, mdo_b, cur_level)) { 4.131 + next_level = CompLevel_full_optimization; 4.132 + } 4.133 + } else { 4.134 next_level = CompLevel_full_optimization; 4.135 } 4.136 - } else { 4.137 - next_level = CompLevel_full_optimization; 4.138 } 4.139 } 4.140 break; 4.141 @@ -303,12 +323,6 @@ 4.142 4.143 // Determine if a method should be compiled with a normal entry point at a different level. 4.144 CompLevel SimpleThresholdPolicy::call_event(methodOop method, CompLevel cur_level) { 4.145 - CompLevel highest_level = (CompLevel)method->highest_comp_level(); 4.146 - if (cur_level == CompLevel_none && highest_level > cur_level) { 4.147 - // TODO: We may want to try to do more extensive reprofiling in this case. 4.148 - return highest_level; 4.149 - } 4.150 - 4.151 CompLevel osr_level = (CompLevel) method->highest_osr_comp_level(); 4.152 CompLevel next_level = common(&SimpleThresholdPolicy::call_predicate, method, cur_level); 4.153
5.1 --- a/src/share/vm/runtime/simpleThresholdPolicy.hpp Tue Feb 08 16:12:16 2011 -0800 5.2 +++ b/src/share/vm/runtime/simpleThresholdPolicy.hpp Wed Feb 09 16:34:34 2011 -0800 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -62,7 +62,7 @@ 5.11 void set_c1_count(int x) { _c1_count = x; } 5.12 void set_c2_count(int x) { _c2_count = x; } 5.13 5.14 - enum EventType { CALL, LOOP, COMPILE }; 5.15 + enum EventType { CALL, LOOP, COMPILE, KILL, UPDATE, REPROFILE }; 5.16 void print_event(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level); 5.17 // Print policy-specific information if necessary 5.18 virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { } 5.19 @@ -103,7 +103,7 @@ 5.20 virtual void disable_compilation(methodOop method) { } 5.21 // TODO: we should honour reprofiling requests in the future. Currently reprofiling 5.22 // would happen but not to the extent we would ideally like. 5.23 - virtual void reprofile(ScopeDesc* trap_scope, bool is_osr) { } 5.24 + virtual void reprofile(ScopeDesc* trap_scope, bool is_osr); 5.25 virtual nmethod* event(methodHandle method, methodHandle inlinee, 5.26 int branch_bci, int bci, CompLevel comp_level, TRAPS); 5.27 // Select task is called by CompileBroker. We should return a task or NULL.