7017434: Tiered needs to support reprofiling
Summary: Tiered needs to support proper method reprofiling after deopts.
Reviewed-by: kvn
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp Tue Feb 08 16:12:16 2011 -0800
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp Wed Feb 09 16:34:34 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -491,10 +491,11 @@
// to start profiling on its own.
_method->ensure_method_data();
}
- } else if (is_profiling() && _would_profile) {
+ } else if (is_profiling()) {
ciMethodData *md = method->method_data_or_null();
- assert(md != NULL, "Sanity");
- md->set_would_profile(_would_profile);
+ if (md != NULL) {
+ md->set_would_profile(_would_profile);
+ }
}
}
--- a/hotspot/src/share/vm/oops/methodDataOop.cpp Tue Feb 08 16:12:16 2011 -0800
+++ b/hotspot/src/share/vm/oops/methodDataOop.cpp Wed Feb 09 16:34:34 2011 -0800
@@ -764,11 +764,13 @@
if (TieredCompilation) {
_invocation_counter.init();
_backedge_counter.init();
+ _invocation_counter_start = 0;
+ _backedge_counter_start = 0;
_num_loops = 0;
_num_blocks = 0;
_highest_comp_level = 0;
_highest_osr_comp_level = 0;
- _would_profile = false;
+ _would_profile = true;
}
set_creation_mileage(mileage_of(method()));
--- a/hotspot/src/share/vm/oops/methodDataOop.hpp Tue Feb 08 16:12:16 2011 -0800
+++ b/hotspot/src/share/vm/oops/methodDataOop.hpp Wed Feb 09 16:34:34 2011 -0800
@@ -1224,6 +1224,9 @@
InvocationCounter _invocation_counter;
// Same for backedges.
InvocationCounter _backedge_counter;
+ // Counter values at the time profiling started.
+ int _invocation_counter_start;
+ int _backedge_counter_start;
// Number of loops and blocks is computed when compiling the first
// time with C1. It is used to determine if method is trivial.
short _num_loops;
@@ -1333,6 +1336,28 @@
return backedge_counter()->count();
}
+ int invocation_count_start() {
+ if (invocation_counter()->carry()) {
+ return 0;
+ }
+ return _invocation_counter_start;
+ }
+
+ int backedge_count_start() {
+ if (backedge_counter()->carry()) {
+ return 0;
+ }
+ return _backedge_counter_start;
+ }
+
+ int invocation_count_delta() { return invocation_count() - invocation_count_start(); }
+ int backedge_count_delta() { return backedge_count() - backedge_count_start(); }
+
+ void reset_start_counters() {
+ _invocation_counter_start = invocation_count();
+ _backedge_counter_start = backedge_count();
+ }
+
InvocationCounter* invocation_counter() { return &_invocation_counter; }
InvocationCounter* backedge_counter() { return &_backedge_counter; }
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Tue Feb 08 16:12:16 2011 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Wed Feb 09 16:34:34 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
#include "runtime/arguments.hpp"
#include "runtime/simpleThresholdPolicy.hpp"
#include "runtime/simpleThresholdPolicy.inline.hpp"
+#include "code/scopeDesc.hpp"
// Print an event.
void SimpleThresholdPolicy::print_event(EventType type, methodHandle mh, methodHandle imh,
@@ -48,6 +49,18 @@
break;
case COMPILE:
tty->print("compile");
+ break;
+ case KILL:
+ tty->print("kill");
+ break;
+ case UPDATE:
+ tty->print("update");
+ break;
+ case REPROFILE:
+ tty->print("reprofile");
+ break;
+ default:
+ tty->print("unknown");
}
tty->print(" level: %d ", level);
@@ -69,13 +82,17 @@
if (type != COMPILE) {
methodDataHandle mdh = mh->method_data();
int mdo_invocations = 0, mdo_backedges = 0;
+ int mdo_invocations_start = 0, mdo_backedges_start = 0;
if (mdh() != NULL) {
mdo_invocations = mdh->invocation_count();
mdo_backedges = mdh->backedge_count();
+ mdo_invocations_start = mdh->invocation_count_start();
+ mdo_backedges_start = mdh->backedge_count_start();
}
- tty->print(" total: %d,%d mdo: %d,%d",
+ tty->print(" total: %d,%d mdo: %d(%d),%d(%d)",
invocation_count, backedge_count,
- mdo_invocations, mdo_backedges);
+ mdo_invocations, mdo_invocations_start,
+ mdo_backedges, mdo_backedges_start);
tty->print(" max levels: %d,%d",
mh->highest_comp_level(), mh->highest_osr_comp_level());
if (inlinee_event) {
@@ -138,6 +155,20 @@
return compile_queue->first();
}
+void SimpleThresholdPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) {
+ for (ScopeDesc* sd = trap_scope;; sd = sd->sender()) {
+ if (PrintTieredEvents) {
+ methodHandle mh(sd->method());
+ print_event(REPROFILE, mh, mh, InvocationEntryBci, CompLevel_none);
+ }
+ methodDataOop mdo = sd->method()->method_data();
+ if (mdo != NULL) {
+ mdo->reset_start_counters();
+ }
+ if (sd->is_top()) break;
+ }
+}
+
nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee,
int branch_bci, int bci, CompLevel comp_level, TRAPS) {
if (comp_level == CompLevel_none &&
@@ -254,46 +285,35 @@
// Common transition function. Given a predicate determines if a method should transition to another level.
CompLevel SimpleThresholdPolicy::common(Predicate p, methodOop method, CompLevel cur_level) {
+ if (is_trivial(method)) return CompLevel_simple;
+
CompLevel next_level = cur_level;
int i = method->invocation_count();
int b = method->backedge_count();
switch(cur_level) {
case CompLevel_none:
- {
- methodDataOop mdo = method->method_data();
- if (mdo != NULL) {
- int mdo_i = mdo->invocation_count();
- int mdo_b = mdo->backedge_count();
- // If we were at full profile level, would we switch to full opt?
- if ((this->*p)(mdo_i, mdo_b, CompLevel_full_profile)) {
- next_level = CompLevel_full_optimization;
- }
- }
- }
- if (next_level == cur_level && (this->*p)(i, b, cur_level)) {
- if (is_trivial(method)) {
- next_level = CompLevel_simple;
- } else {
- next_level = CompLevel_full_profile;
- }
+ // If we were at full profile level, would we switch to full opt?
+ if (common(p, method, CompLevel_full_profile) == CompLevel_full_optimization) {
+ next_level = CompLevel_full_optimization;
+ } else if ((this->*p)(i, b, cur_level)) {
+ next_level = CompLevel_full_profile;
}
break;
case CompLevel_limited_profile:
case CompLevel_full_profile:
- if (is_trivial(method)) {
- next_level = CompLevel_simple;
- } else {
+ {
methodDataOop mdo = method->method_data();
- guarantee(mdo != NULL, "MDO should always exist");
- if (mdo->would_profile()) {
- int mdo_i = mdo->invocation_count();
- int mdo_b = mdo->backedge_count();
- if ((this->*p)(mdo_i, mdo_b, cur_level)) {
+ if (mdo != NULL) {
+ if (mdo->would_profile()) {
+ int mdo_i = mdo->invocation_count_delta();
+ int mdo_b = mdo->backedge_count_delta();
+ if ((this->*p)(mdo_i, mdo_b, cur_level)) {
+ next_level = CompLevel_full_optimization;
+ }
+ } else {
next_level = CompLevel_full_optimization;
}
- } else {
- next_level = CompLevel_full_optimization;
}
}
break;
@@ -303,12 +323,6 @@
// Determine if a method should be compiled with a normal entry point at a different level.
CompLevel SimpleThresholdPolicy::call_event(methodOop method, CompLevel cur_level) {
- CompLevel highest_level = (CompLevel)method->highest_comp_level();
- if (cur_level == CompLevel_none && highest_level > cur_level) {
- // TODO: We may want to try to do more extensive reprofiling in this case.
- return highest_level;
- }
-
CompLevel osr_level = (CompLevel) method->highest_osr_comp_level();
CompLevel next_level = common(&SimpleThresholdPolicy::call_predicate, method, cur_level);
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp Tue Feb 08 16:12:16 2011 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp Wed Feb 09 16:34:34 2011 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@
void set_c1_count(int x) { _c1_count = x; }
void set_c2_count(int x) { _c2_count = x; }
- enum EventType { CALL, LOOP, COMPILE };
+ enum EventType { CALL, LOOP, COMPILE, KILL, UPDATE, REPROFILE };
void print_event(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level);
// Print policy-specific information if necessary
virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { }
@@ -103,7 +103,7 @@
virtual void disable_compilation(methodOop method) { }
// TODO: we should honour reprofiling requests in the future. Currently reprofiling
// would happen but not to the extent we would ideally like.
- virtual void reprofile(ScopeDesc* trap_scope, bool is_osr) { }
+ virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
virtual nmethod* event(methodHandle method, methodHandle inlinee,
int branch_bci, int bci, CompLevel comp_level, TRAPS);
// Select task is called by CompileBroker. We should return a task or NULL.