src/share/vm/oops/instanceKlass.cpp

changeset 2138
d5d065957597
parent 2106
2528b5bd749c
child 2314
f95d63e2154a
     1.1 --- a/src/share/vm/oops/instanceKlass.cpp	Thu Sep 02 11:40:02 2010 -0700
     1.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Fri Sep 03 17:51:07 2010 -0700
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2010, 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 @@ -2200,8 +2200,23 @@
    1.11    assert(n->is_osr_method(), "wrong kind of nmethod");
    1.12    n->set_osr_link(osr_nmethods_head());
    1.13    set_osr_nmethods_head(n);
    1.14 +  // Raise the highest osr level if necessary
    1.15 +  if (TieredCompilation) {
    1.16 +    methodOop m = n->method();
    1.17 +    m->set_highest_osr_comp_level(MAX2(m->highest_osr_comp_level(), n->comp_level()));
    1.18 +  }
    1.19    // Remember to unlock again
    1.20    OsrList_lock->unlock();
    1.21 +
    1.22 +  // Get rid of the osr methods for the same bci that have lower levels.
    1.23 +  if (TieredCompilation) {
    1.24 +    for (int l = CompLevel_limited_profile; l < n->comp_level(); l++) {
    1.25 +      nmethod *inv = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), l, true);
    1.26 +      if (inv != NULL && inv->is_in_use()) {
    1.27 +        inv->make_not_entrant();
    1.28 +      }
    1.29 +    }
    1.30 +  }
    1.31  }
    1.32  
    1.33  
    1.34 @@ -2211,39 +2226,79 @@
    1.35    assert(n->is_osr_method(), "wrong kind of nmethod");
    1.36    nmethod* last = NULL;
    1.37    nmethod* cur  = osr_nmethods_head();
    1.38 +  int max_level = CompLevel_none;  // Find the max comp level excluding n
    1.39 +  methodOop m = n->method();
    1.40    // Search for match
    1.41    while(cur != NULL && cur != n) {
    1.42 +    if (TieredCompilation) {
    1.43 +      // Find max level before n
    1.44 +      max_level = MAX2(max_level, cur->comp_level());
    1.45 +    }
    1.46      last = cur;
    1.47      cur = cur->osr_link();
    1.48    }
    1.49 +  nmethod* next = NULL;
    1.50    if (cur == n) {
    1.51 +    next = cur->osr_link();
    1.52      if (last == NULL) {
    1.53        // Remove first element
    1.54 -      set_osr_nmethods_head(osr_nmethods_head()->osr_link());
    1.55 +      set_osr_nmethods_head(next);
    1.56      } else {
    1.57 -      last->set_osr_link(cur->osr_link());
    1.58 +      last->set_osr_link(next);
    1.59      }
    1.60    }
    1.61    n->set_osr_link(NULL);
    1.62 +  if (TieredCompilation) {
    1.63 +    cur = next;
    1.64 +    while (cur != NULL) {
    1.65 +      // Find max level after n
    1.66 +      max_level = MAX2(max_level, cur->comp_level());
    1.67 +      cur = cur->osr_link();
    1.68 +    }
    1.69 +    m->set_highest_osr_comp_level(max_level);
    1.70 +  }
    1.71    // Remember to unlock again
    1.72    OsrList_lock->unlock();
    1.73  }
    1.74  
    1.75 -nmethod* instanceKlass::lookup_osr_nmethod(const methodOop m, int bci) const {
    1.76 +nmethod* instanceKlass::lookup_osr_nmethod(const methodOop m, int bci, int comp_level, bool match_level) const {
    1.77    // This is a short non-blocking critical region, so the no safepoint check is ok.
    1.78    OsrList_lock->lock_without_safepoint_check();
    1.79    nmethod* osr = osr_nmethods_head();
    1.80 +  nmethod* best = NULL;
    1.81    while (osr != NULL) {
    1.82      assert(osr->is_osr_method(), "wrong kind of nmethod found in chain");
    1.83 +    // There can be a time when a c1 osr method exists but we are waiting
    1.84 +    // for a c2 version. When c2 completes its osr nmethod we will trash
    1.85 +    // the c1 version and only be able to find the c2 version. However
    1.86 +    // while we overflow in the c1 code at back branches we don't want to
    1.87 +    // try and switch to the same code as we are already running
    1.88 +
    1.89      if (osr->method() == m &&
    1.90          (bci == InvocationEntryBci || osr->osr_entry_bci() == bci)) {
    1.91 -      // Found a match - return it.
    1.92 -      OsrList_lock->unlock();
    1.93 -      return osr;
    1.94 +      if (match_level) {
    1.95 +        if (osr->comp_level() == comp_level) {
    1.96 +          // Found a match - return it.
    1.97 +          OsrList_lock->unlock();
    1.98 +          return osr;
    1.99 +        }
   1.100 +      } else {
   1.101 +        if (best == NULL || (osr->comp_level() > best->comp_level())) {
   1.102 +          if (osr->comp_level() == CompLevel_highest_tier) {
   1.103 +            // Found the best possible - return it.
   1.104 +            OsrList_lock->unlock();
   1.105 +            return osr;
   1.106 +          }
   1.107 +          best = osr;
   1.108 +        }
   1.109 +      }
   1.110      }
   1.111      osr = osr->osr_link();
   1.112    }
   1.113    OsrList_lock->unlock();
   1.114 +  if (best != NULL && best->comp_level() >= comp_level && match_level == false) {
   1.115 +    return best;
   1.116 +  }
   1.117    return NULL;
   1.118  }
   1.119  

mercurial