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;
}
}