agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
Print this page
*** 30,44 ****
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;
public class CodeCache {
! private static AddressField heapField;
private static AddressField scavengeRootNMethodsField;
private static VirtualConstructor virtualConstructor;
! private CodeHeap heap;
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
--- 30,47 ----
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;
public class CodeCache {
! // 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[] = new CodeHeap[HEAP_CNT];
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
*** 47,57 ****
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("CodeCache");
! heapField = type.getAddressField("_heap");
scavengeRootNMethodsField = type.getAddressField("_scavenge_root_nmethods");
virtualConstructor = new VirtualConstructor(db);
// Add mappings for all possible CodeBlob subclasses
virtualConstructor.addMapping("BufferBlob", BufferBlob.class);
--- 50,62 ----
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("CodeCache");
! 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,84 ****
virtualConstructor.addMapping("UncommonTrapBlob", UncommonTrapBlob.class);
}
}
public CodeCache() {
! heap = (CodeHeap) VMObjectFactory.newObject(CodeHeap.class, heapField.getValue());
}
public NMethod scavengeRootMethods() {
return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootNMethodsField.getValue());
}
public boolean contains(Address p) {
! return getHeap().contains(p);
}
/** When VM.getVM().isDebugging() returns true, this behaves like
findBlobUnsafe */
public CodeBlob findBlob(Address start) {
--- 71,96 ----
virtualConstructor.addMapping("UncommonTrapBlob", UncommonTrapBlob.class);
}
}
public CodeCache() {
! 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) {
! 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,112 ****
return result;
}
public CodeBlob findBlobUnsafe(Address start) {
CodeBlob result = null;
try {
! result = (CodeBlob) virtualConstructor.instantiateWrapperFor(getHeap().findStart(start));
}
catch (WrongTypeException wte) {
Address cbAddr = null;
try {
! cbAddr = getHeap().findStart(start);
}
catch (Exception findEx) {
findEx.printStackTrace();
}
--- 107,134 ----
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(containing_heap.findStart(start));
}
catch (WrongTypeException wte) {
Address cbAddr = null;
try {
! cbAddr = containing_heap.findStart(start);
}
catch (Exception findEx) {
findEx.printStackTrace();
}
*** 165,206 ****
throw new RuntimeException(message);
}
}
public void iterate(CodeCacheVisitor visitor) {
! CodeHeap heap = getHeap();
! Address ptr = heap.begin();
! Address end = heap.end();
!
! visitor.prologue(ptr, end);
CodeBlob lastBlob = null;
! while (ptr != null && ptr.lessThan(end)) {
try {
// Use findStart to get a pointer inside blob other findBlob asserts
! CodeBlob blob = findBlobUnsafe(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);
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;
}
}
--- 187,245 ----
throw new RuntimeException(message);
}
}
public void iterate(CodeCacheVisitor visitor) {
! visitor.prologue(lowBound(), highBound());
CodeBlob lastBlob = null;
!
! 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(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 = 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 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;
}
}