/*
* Copyright (c) 2000, 2015, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package sun.jvm.hotspot.memory;
import java.util.*;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.types.*;
public class CodeHeap extends VMObject {
private static Field memoryField;
private static Field segmapField;
// private static CIntegerField numberOfCommittedSegmentsField;
// private static CIntegerField numberOfReservedSegmentsField;
// private static CIntegerField segmentSizeField;
private static CIntegerField log2SegmentSizeField;
// private static CIntegerField nextSegmentField;
// private static AddressField freelistField;
// private static CIntegerField freeSegmentsField;
private VirtualSpace memory;
private VirtualSpace segmentMap;
private int log2SegmentSize;
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static void initialize(TypeDataBase db) {
Type type = db.lookupType("CodeHeap");
memoryField = type.getField("_memory");
segmapField = type.getField("_segmap");
log2SegmentSizeField = type.getCIntegerField("_log2_segment_size");
}
public CodeHeap(Address addr) {
super(addr);
log2SegmentSize = (int) log2SegmentSizeField.getValue(addr);
segmentMap = new VirtualSpace(addr.addOffsetTo(segmapField.getOffset()));
memory = new VirtualSpace(addr.addOffsetTo(memoryField.getOffset()));
}
public Address begin() {
return getMemory().low();
}
public Address end() {
return getMemory().high();
}
public boolean contains(Address p) {
return (begin().lessThanOrEqual(p) && end().greaterThan(p));
}
/** Returns the start of the block containing p or null */
public Address findStart(Address p) {
if (!contains(p)) return null;
HeapBlock h = blockStart(p);
if (h == null || h.isFree()) {
return null;
}
return h.getAllocatedSpace();
}
private Address nextBlock(Address ptr) {
Address base = blockBase(ptr);
if (base == null) {
return null;
}
HeapBlock block = getBlockAt(base);
return base.addOffsetTo(block.getLength() * (1 << getLog2SegmentSize()));
}
public void iterate(CodeCacheVisitor visitor, CodeCache cache) {
CodeBlob lastBlob = null;
Address ptr = begin();
while (ptr != null && ptr.lessThan(end())) {
try {
// Use findStart to get a pointer inside blob other findBlob asserts
CodeBlob blob = cache.createCodeBlobWrapper(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 = nextBlock(ptr);
if (next != null && next.lessThan(ptr)) {
throw new InternalError("pointer moved backwards");
}
ptr = next;
}
}
//--------------------------------------------------------------------------------
// Internals only below this point
//
private VirtualSpace getMemory() {
return memory;
}
private VirtualSpace getSegmentMap() {
return segmentMap;
}
private long segmentFor(Address p) {
return p.minus(getMemory().low()) >> getLog2SegmentSize();
}
private int getLog2SegmentSize() {
return log2SegmentSize;
}
private HeapBlock getBlockAt(Address addr) {
/**代码未完, 请加载全部代码(NowJava.com).**/