8072774: bigapps/Weblogic+medrec/nowarnings fails due to CodeHeap 'profiled nmethods' exhaustion
authorthartmann
Mon, 23 Feb 2015 07:55:37 +0100
changeset 29338 92297a8bd48e
parent 29337 ef2be52deeaf
child 29339 f0b1b7788a51
8072774: bigapps/Weblogic+medrec/nowarnings fails due to CodeHeap 'profiled nmethods' exhaustion Summary: Store profiled code in the non-profiled code heap (and vice versa) if the code cache is really full. Reviewed-by: kvn, iveresov
hotspot/src/share/vm/code/codeCache.cpp
hotspot/src/share/vm/code/codeCache.hpp
--- a/hotspot/src/share/vm/code/codeCache.cpp	Wed Feb 18 18:14:07 2015 +0100
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Mon Feb 23 07:55:37 2015 +0100
@@ -360,7 +360,7 @@
  * run the constructor for the CodeBlob subclass he is busy
  * instantiating.
  */
-CodeBlob* CodeCache::allocate(int size, int code_blob_type) {
+CodeBlob* CodeCache::allocate(int size, int code_blob_type, bool strict) {
   // Possibly wakes up the sweeper thread.
   NMethodSweeper::notify(code_blob_type);
   assert_locked_or_safepoint(CodeCache_lock);
@@ -379,11 +379,28 @@
     if (cb != NULL) break;
     if (!heap->expand_by(CodeCacheExpansionSize)) {
       // Expansion failed
-      if (SegmentedCodeCache && (code_blob_type == CodeBlobType::NonNMethod)) {
-        // Fallback solution: Store non-nmethod code in the non-profiled code heap.
-        // Note that at in the sweeper, we check the reverse_free_ratio of the non-profiled
-        // code heap and force stack scanning if less than 10% if the code heap are free.
-        return allocate(size, CodeBlobType::MethodNonProfiled);
+      if (SegmentedCodeCache && !strict) {
+        // Fallback solution: Try to store code in another code heap.
+        // Note that in the sweeper, we check the reverse_free_ratio of the code heap
+        // and force stack scanning if less than 10% of the code heap are free.
+        int type = code_blob_type;
+        switch (type) {
+        case CodeBlobType::NonNMethod:
+          type = CodeBlobType::MethodNonProfiled;
+          strict = false;   // Allow recursive search for other heaps
+          break;
+        case CodeBlobType::MethodProfiled:
+          type = CodeBlobType::MethodNonProfiled;
+          strict = true;
+          break;
+        case CodeBlobType::MethodNonProfiled:
+          type = CodeBlobType::MethodProfiled;
+          strict = true;
+          break;
+        }
+        if (heap_available(type)) {
+          return allocate(size, type, strict);
+        }
       }
       MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
       CompileBroker::handle_full_code_cache(code_blob_type);
--- a/hotspot/src/share/vm/code/codeCache.hpp	Wed Feb 18 18:14:07 2015 +0100
+++ b/hotspot/src/share/vm/code/codeCache.hpp	Mon Feb 23 07:55:37 2015 +0100
@@ -122,7 +122,7 @@
   static void initialize();
 
   // Allocation/administration
-  static CodeBlob* allocate(int size, int code_blob_type); // allocates a new CodeBlob
+  static CodeBlob* allocate(int size, int code_blob_type, bool strict = false); // allocates a new CodeBlob
   static void commit(CodeBlob* cb);                        // called when the allocated CodeBlob has been filled
   static int  alignment_unit();                            // guaranteed alignment of all CodeBlobs
   static int  alignment_offset();                          // guaranteed offset of first CodeBlob byte within alignment unit (i.e., allocation header)