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