diff src/share/vm/oops/instanceKlass.cpp @ 1930:2d26b0046e0d

Merge.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 30 Nov 2010 14:53:30 +0100
parents a7b84a5e16c6 d5d065957597
children 06f017f7daa7
line wrap: on
line diff
--- a/src/share/vm/oops/instanceKlass.cpp	Mon Nov 29 18:32:30 2010 +0100
+++ b/src/share/vm/oops/instanceKlass.cpp	Tue Nov 30 14:53:30 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -16,9 +16,9 @@
  * 2 along with this work; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  *
  */
 
@@ -382,7 +382,7 @@
       const char* desc = "Could not initialize class ";
       const char* className = this_oop->external_name();
       size_t msglen = strlen(desc) + strlen(className) + 1;
-      char* message = NEW_C_HEAP_ARRAY(char, msglen);
+      char* message = NEW_RESOURCE_ARRAY(char, msglen);
       if (NULL == message) {
         // Out of memory: can't create detailed error message
         THROW_MSG(vmSymbols::java_lang_NoClassDefFoundError(), className);
@@ -968,7 +968,7 @@
       // not found
 #ifdef ASSERT
       int index = linear_search(methods, name, signature);
-      if (index != -1) fatal1("binary search bug: should have found entry %d", index);
+      assert(index == -1, err_msg("binary search should have found entry %d", index));
 #endif
       return NULL;
     } else if (res < 0) {
@@ -979,7 +979,7 @@
   }
 #ifdef ASSERT
   int index = linear_search(methods, name, signature);
-  if (index != -1) fatal1("binary search bug: should have found entry %d", index);
+  assert(index == -1, err_msg("binary search should have found entry %d", index));
 #endif
   return NULL;
 }
@@ -1811,18 +1811,7 @@
 }
 
 #ifndef SERIALGC
-void instanceKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
-  assert(!pm->depth_first(), "invariant");
-  InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
-    obj, \
-    if (PSScavenge::should_scavenge(p)) { \
-      pm->claim_or_forward_breadth(p); \
-    }, \
-    assert_nothing )
-}
-
 void instanceKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
-  assert(pm->depth_first(), "invariant");
   InstanceKlass_OOP_MAP_REVERSE_ITERATE( \
     obj, \
     if (PSScavenge::should_scavenge(p)) { \
@@ -1848,18 +1837,7 @@
   return size_helper();
 }
 
-void instanceKlass::copy_static_fields(PSPromotionManager* pm) {
-  assert(!pm->depth_first(), "invariant");
-  InstanceKlass_OOP_ITERATE( \
-    start_of_static_fields(), static_oop_field_size(), \
-    if (PSScavenge::should_scavenge(p)) { \
-      pm->claim_or_forward_breadth(p); \
-    }, \
-    assert_nothing )
-}
-
 void instanceKlass::push_static_fields(PSPromotionManager* pm) {
-  assert(pm->depth_first(), "invariant");
   InstanceKlass_OOP_ITERATE( \
     start_of_static_fields(), static_oop_field_size(), \
     if (PSScavenge::should_scavenge(p)) { \
@@ -2224,8 +2202,23 @@
   assert(n->is_osr_method(), "wrong kind of nmethod");
   n->set_osr_link(osr_nmethods_head());
   set_osr_nmethods_head(n);
+  // Raise the highest osr level if necessary
+  if (TieredCompilation) {
+    methodOop m = n->method();
+    m->set_highest_osr_comp_level(MAX2(m->highest_osr_comp_level(), n->comp_level()));
+  }
   // Remember to unlock again
   OsrList_lock->unlock();
+
+  // Get rid of the osr methods for the same bci that have lower levels.
+  if (TieredCompilation) {
+    for (int l = CompLevel_limited_profile; l < n->comp_level(); l++) {
+      nmethod *inv = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), l, true);
+      if (inv != NULL && inv->is_in_use()) {
+        inv->make_not_entrant();
+      }
+    }
+  }
 }
 
 
@@ -2235,39 +2228,79 @@
   assert(n->is_osr_method(), "wrong kind of nmethod");
   nmethod* last = NULL;
   nmethod* cur  = osr_nmethods_head();
+  int max_level = CompLevel_none;  // Find the max comp level excluding n
+  methodOop m = n->method();
   // Search for match
   while(cur != NULL && cur != n) {
+    if (TieredCompilation) {
+      // Find max level before n
+      max_level = MAX2(max_level, cur->comp_level());
+    }
     last = cur;
     cur = cur->osr_link();
   }
+  nmethod* next = NULL;
   if (cur == n) {
+    next = cur->osr_link();
     if (last == NULL) {
       // Remove first element
-      set_osr_nmethods_head(osr_nmethods_head()->osr_link());
+      set_osr_nmethods_head(next);
     } else {
-      last->set_osr_link(cur->osr_link());
+      last->set_osr_link(next);
     }
   }
   n->set_osr_link(NULL);
+  if (TieredCompilation) {
+    cur = next;
+    while (cur != NULL) {
+      // Find max level after n
+      max_level = MAX2(max_level, cur->comp_level());
+      cur = cur->osr_link();
+    }
+    m->set_highest_osr_comp_level(max_level);
+  }
   // Remember to unlock again
   OsrList_lock->unlock();
 }
 
-nmethod* instanceKlass::lookup_osr_nmethod(const methodOop m, int bci) const {
+nmethod* instanceKlass::lookup_osr_nmethod(const methodOop m, int bci, int comp_level, bool match_level) const {
   // This is a short non-blocking critical region, so the no safepoint check is ok.
   OsrList_lock->lock_without_safepoint_check();
   nmethod* osr = osr_nmethods_head();
+  nmethod* best = NULL;
   while (osr != NULL) {
     assert(osr->is_osr_method(), "wrong kind of nmethod found in chain");
+    // There can be a time when a c1 osr method exists but we are waiting
+    // for a c2 version. When c2 completes its osr nmethod we will trash
+    // the c1 version and only be able to find the c2 version. However
+    // while we overflow in the c1 code at back branches we don't want to
+    // try and switch to the same code as we are already running
+
     if (osr->method() == m &&
         (bci == InvocationEntryBci || osr->osr_entry_bci() == bci)) {
-      // Found a match - return it.
-      OsrList_lock->unlock();
-      return osr;
+      if (match_level) {
+        if (osr->comp_level() == comp_level) {
+          // Found a match - return it.
+          OsrList_lock->unlock();
+          return osr;
+        }
+      } else {
+        if (best == NULL || (osr->comp_level() > best->comp_level())) {
+          if (osr->comp_level() == CompLevel_highest_tier) {
+            // Found the best possible - return it.
+            OsrList_lock->unlock();
+            return osr;
+          }
+          best = osr;
+        }
+      }
     }
     osr = osr->osr_link();
   }
   OsrList_lock->unlock();
+  if (best != NULL && best->comp_level() >= comp_level && match_level == false) {
+    return best;
+  }
   return NULL;
 }