hotspot/src/share/vm/code/codeCache.cpp
changeset 38133 78b95467b9f1
parent 38055 9dddf9056918
child 40863 f5fec6a2dc9e
--- a/hotspot/src/share/vm/code/codeCache.cpp	Mon Apr 25 21:25:22 2016 +0300
+++ b/hotspot/src/share/vm/code/codeCache.cpp	Tue Apr 26 10:28:51 2016 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -561,12 +561,12 @@
 // what you are doing)
 CodeBlob* CodeCache::find_blob_unsafe(void* start) {
   // NMT can walk the stack before code cache is created
-  if (_heaps == NULL || _heaps->is_empty()) return NULL;
-
-  FOR_ALL_HEAPS(heap) {
-    CodeBlob* result = (CodeBlob*) (*heap)->find_start(start);
-    if (result != NULL && result->blob_contains((address)start)) {
-      return result;
+  if (_heaps != NULL && !_heaps->is_empty()) {
+    FOR_ALL_HEAPS(heap) {
+      CodeBlob* result = (CodeBlob*) (*heap)->find_start(start);
+      if (result != NULL && result->blob_contains((address)start)) {
+        return result;
+      }
     }
   }
   return NULL;
@@ -595,11 +595,11 @@
   }
 }
 
-void CodeCache::alive_nmethods_do(void f(nmethod* nm)) {
+void CodeCache::metadata_do(void f(Metadata* m)) {
   assert_locked_or_safepoint(CodeCache_lock);
   NMethodIterator iter;
   while(iter.next_alive()) {
-    f(iter.method());
+    iter.method()->metadata_do(f);
   }
 }
 
@@ -614,7 +614,7 @@
 // Mark nmethods for unloading if they contain otherwise unreachable oops.
 void CodeCache::do_unloading(BoolObjectClosure* is_alive, bool unloading_occurred) {
   assert_locked_or_safepoint(CodeCache_lock);
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
     iter.method()->do_unloading(is_alive, unloading_occurred);
   }
@@ -841,17 +841,18 @@
 void CodeCache::gc_epilogue() {
   assert_locked_or_safepoint(CodeCache_lock);
   NOT_DEBUG(if (needs_cache_clean())) {
-    NMethodIterator iter;
+    CompiledMethodIterator iter;
     while(iter.next_alive()) {
-      nmethod* nm = iter.method();
-      assert(!nm->is_unloaded(), "Tautology");
+      CompiledMethod* cm = iter.method();
+      assert(!cm->is_unloaded(), "Tautology");
       DEBUG_ONLY(if (needs_cache_clean())) {
-        nm->cleanup_inline_caches();
+        cm->cleanup_inline_caches();
       }
-      DEBUG_ONLY(nm->verify());
-      DEBUG_ONLY(nm->verify_oop_relocations());
+      DEBUG_ONLY(cm->verify());
+      DEBUG_ONLY(cm->verify_oop_relocations());
     }
   }
+
   set_needs_cache_clean(false);
   prune_scavenge_root_nmethods();
 
@@ -1036,7 +1037,7 @@
 
 void CodeCache::clear_inline_caches() {
   assert_locked_or_safepoint(CodeCache_lock);
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
     iter.method()->clear_inline_caches();
   }
@@ -1083,6 +1084,11 @@
   return number_of_marked_CodeBlobs;
 }
 
+CompiledMethod* CodeCache::find_compiled(void* start) {
+  CodeBlob *cb = find_blob(start);
+  assert(cb == NULL || cb->is_compiled(), "did not find an compiled_method");
+  return (CompiledMethod*)cb;
+}
 
 #ifdef HOTSWAP
 int CodeCache::mark_for_evol_deoptimization(instanceKlassHandle dependee) {
@@ -1094,16 +1100,16 @@
   for (int i = 0; i < old_methods->length(); i++) {
     ResourceMark rm;
     Method* old_method = old_methods->at(i);
-    nmethod *nm = old_method->code();
+    CompiledMethod* nm = old_method->code();
     if (nm != NULL) {
       nm->mark_for_deoptimization();
       number_of_marked_CodeBlobs++;
     }
   }
 
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    nmethod* nm = iter.method();
+    CompiledMethod* nm = iter.method();
     if (nm->is_marked_for_deoptimization()) {
       // ...Already marked in the previous pass; don't count it again.
     } else if (nm->is_evol_dependent_on(dependee())) {
@@ -1124,9 +1130,9 @@
 // Deoptimize all methods
 void CodeCache::mark_all_nmethods_for_deoptimization() {
   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    nmethod* nm = iter.method();
+    CompiledMethod* nm = iter.method();
     if (!nm->method()->is_method_handle_intrinsic()) {
       nm->mark_for_deoptimization();
     }
@@ -1137,9 +1143,9 @@
   MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   int number_of_marked_CodeBlobs = 0;
 
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    nmethod* nm = iter.method();
+    CompiledMethod* nm = iter.method();
     if (nm->is_dependent_on_method(dependee)) {
       ResourceMark rm;
       nm->mark_for_deoptimization();
@@ -1152,9 +1158,9 @@
 
 void CodeCache::make_marked_nmethods_not_entrant() {
   assert_locked_or_safepoint(CodeCache_lock);
-  NMethodIterator iter;
+  CompiledMethodIterator iter;
   while(iter.next_alive()) {
-    nmethod* nm = iter.method();
+    CompiledMethod* nm = iter.method();
     if (nm->is_marked_for_deoptimization()) {
       nm->make_not_entrant();
     }
@@ -1549,3 +1555,36 @@
             blob_count(), nmethod_count(), adapter_count(),
             unallocated_capacity());
 }
+
+// Initialize iterator to given compiled method
+void CompiledMethodIterator::initialize(CompiledMethod* cm) {
+  _code_blob = (CodeBlob*)cm;
+  if (!SegmentedCodeCache) {
+    // Iterate over all CodeBlobs
+    _code_blob_type = CodeBlobType::All;
+  } else if (cm != NULL) {
+    _code_blob_type = CodeCache::get_code_blob_type(cm);
+  } else {
+    // Only iterate over method code heaps, starting with non-profiled
+    _code_blob_type = CodeBlobType::MethodNonProfiled;
+  }
+}
+
+// Advance iterator to the next compiled method in the current code heap
+bool CompiledMethodIterator::next_compiled_method() {
+  // Get first method CodeBlob
+  if (_code_blob == NULL) {
+    _code_blob = CodeCache::first_blob(_code_blob_type);
+    if (_code_blob == NULL) {
+      return false;
+    } else if (_code_blob->is_nmethod()) {
+      return true;
+    }
+  }
+  // Search for next method CodeBlob
+  _code_blob = CodeCache::next_blob(_code_blob);
+  while (_code_blob != NULL && !_code_blob->is_compiled()) {
+    _code_blob = CodeCache::next_blob(_code_blob);
+  }
+  return _code_blob != NULL;
+}