agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java

Print this page

        

@@ -30,15 +30,18 @@
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
 public class CodeCache {
-  private static AddressField       heapField;
+  // Number of code heaps in the code cache
+  private static final int HEAP_CNT  = 3;
+  
+  private static AddressField heapField[] = new AddressField[HEAP_CNT];
   private static AddressField       scavengeRootNMethodsField;
   private static VirtualConstructor virtualConstructor;
 
-  private CodeHeap heap;
+  private CodeHeap heap[] = new CodeHeap[HEAP_CNT];
 
   static {
     VM.registerVMInitializedObserver(new Observer() {
         public void update(Observable o, Object data) {
           initialize(VM.getVM().getTypeDataBase());

@@ -47,11 +50,13 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) {
     Type type = db.lookupType("CodeCache");
 
-    heapField = type.getAddressField("_heap");
+    heapField[0] = type.getAddressField("_heap_non_method");
+    heapField[1] = type.getAddressField("_heap_non_profiled");
+    heapField[2] = type.getAddressField("_heap_profiled");
     scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
 
     virtualConstructor = new VirtualConstructor(db);
     // Add mappings for all possible CodeBlob subclasses
     virtualConstructor.addMapping("BufferBlob", BufferBlob.class);

@@ -66,19 +71,26 @@
       virtualConstructor.addMapping("UncommonTrapBlob", UncommonTrapBlob.class);
     }
   }
 
   public CodeCache() {
-    heap = (CodeHeap) VMObjectFactory.newObject(CodeHeap.class, heapField.getValue());
+    for (int i = 0; i < HEAP_CNT; ++i) {
+      heap[i] = (CodeHeap) VMObjectFactory.newObject(CodeHeap.class, heapField[i].getValue());
+    }
   }
 
   public NMethod scavengeRootMethods() {
     return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootNMethodsField.getValue());
   }
 
   public boolean contains(Address p) {
-    return getHeap().contains(p);
+    for (int i = 0; i < HEAP_CNT; ++i) {
+      if (heap[i].contains(p)) {
+        return true;
+      }
+    }
+    return false;
   }
 
   /** When VM.getVM().isDebugging() returns true, this behaves like
       findBlobUnsafe */
   public CodeBlob findBlob(Address start) {

@@ -95,18 +107,28 @@
     return result;
   }
 
   public CodeBlob findBlobUnsafe(Address start) {
     CodeBlob result = null;
+    CodeHeap containing_heap = null;
+    for (int i = 0; i < HEAP_CNT; ++i) {
+      if (heap[i].contains(start)) {
+        containing_heap = heap[i];
+        break;
+      }
+    }
+    if (containing_heap == null) {
+      return null;
+    }
 
     try {
-      result = (CodeBlob) virtualConstructor.instantiateWrapperFor(getHeap().findStart(start));
+      result = (CodeBlob) virtualConstructor.instantiateWrapperFor(containing_heap.findStart(start));
     }
     catch (WrongTypeException wte) {
       Address cbAddr = null;
       try {
-        cbAddr = getHeap().findStart(start);
+        cbAddr = containing_heap.findStart(start);
       }
       catch (Exception findEx) {
         findEx.printStackTrace();
       }
 

@@ -165,42 +187,59 @@
       throw new RuntimeException(message);
     }
   }
 
   public void iterate(CodeCacheVisitor visitor) {
-    CodeHeap heap = getHeap();
-    Address ptr = heap.begin();
-    Address end = heap.end();
-
-    visitor.prologue(ptr, end);
+    visitor.prologue(lowBound(), highBound());
     CodeBlob lastBlob = null;
-    while (ptr != null && ptr.lessThan(end)) {
+    
+    for (int i = 0; i < HEAP_CNT; ++i) {
+      CodeHeap current_heap = heap[i];
+      Address ptr = current_heap.begin();
+      while (ptr != null && ptr.lessThan(current_heap.end())) {
       try {
         // Use findStart to get a pointer inside blob other findBlob asserts
-        CodeBlob blob = findBlobUnsafe(heap.findStart(ptr));
+          CodeBlob blob = findBlobUnsafe(current_heap.findStart(ptr));
         if (blob != null) {
           visitor.visit(blob);
           if (blob == lastBlob) {
             throw new InternalError("saw same blob twice");
           }
           lastBlob = blob;
         }
       } catch (RuntimeException e) {
         e.printStackTrace();
       }
-      Address next = heap.nextBlock(ptr);
+        Address next = current_heap.nextBlock(ptr);
       if (next != null && next.lessThan(ptr)) {
         throw new InternalError("pointer moved backwards");
       }
       ptr = next;
     }
+    }
     visitor.epilogue();
   }
 
   //--------------------------------------------------------------------------------
   // Internals only below this point
   //
 
-  private CodeHeap getHeap() {
-    return heap;
+  private Address lowBound() {
+    Address low = heap[0].begin();
+    for (int i = 1; i < HEAP_CNT; ++i) {
+      if (heap[i].begin().lessThan(low)) {
+        low = heap[i].begin();
+      }
+    }
+    return low;
+  }
+  
+  private Address highBound() {
+    Address high = heap[0].end();
+    for (int i = 1; i < HEAP_CNT; ++i) {
+      if (heap[i].end().greaterThan(high)) {
+        high = heap[i].end();
+      }
+    }
+    return high;
   }
 }