7017434: Tiered needs to support reprofiling

Wed, 09 Feb 2011 16:34:34 -0800

author
iveresov
date
Wed, 09 Feb 2011 16:34:34 -0800
changeset 2559
72d6c57d0658
parent 2558
336d17dff7cc
child 2560
62a8557e8f36

7017434: Tiered needs to support reprofiling
Summary: Tiered needs to support proper method reprofiling after deopts.
Reviewed-by: kvn

src/share/vm/c1/c1_Compilation.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/methodDataOop.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/methodDataOop.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/simpleThresholdPolicy.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/simpleThresholdPolicy.hpp file | annotate | diff | comparison | revisions
     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.

mercurial