0N/A/*
1472N/A * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
1472N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1472N/A * or visit www.oracle.com if you need additional information or have any
1472N/A * questions.
0N/A *
0N/A */
0N/A
0N/Apackage sun.jvm.hotspot.memory;
0N/A
0N/Aimport java.io.*;
0N/Aimport java.util.*;
0N/Aimport sun.jvm.hotspot.debugger.*;
0N/Aimport sun.jvm.hotspot.types.*;
0N/Aimport sun.jvm.hotspot.runtime.*;
0N/A
0N/A/** <P> The (supported) Generation hierarchy currently looks like this: </P>
0N/A
0N/A <ul>
0N/A <li> Generation
0N/A <ul>
0N/A <li> CardGeneration
0N/A <ul>
0N/A <li> OneContigSpaceCardGeneration
0N/A <ul>
0N/A <li> CompactingPermGenGen
0N/A <li> TenuredGeneration
0N/A </ul>
0N/A </ul>
0N/A <li> DefNewGeneration
0N/A </ul>
0N/A </ul>
0N/A*/
0N/A
0N/A
0N/Apublic abstract class Generation extends VMObject {
0N/A private static long reservedFieldOffset;
0N/A private static long virtualSpaceFieldOffset;
0N/A private static CIntegerField levelField;
0N/A protected static final int K = 1024;
0N/A // Fields for class StatRecord
0N/A private static Field statRecordField;
0N/A private static CIntegerField invocationField;
0N/A
0N/A // constants from Name enum
0N/A private static int NAME_DEF_NEW;
0N/A private static int NAME_PAR_NEW;
0N/A private static int NAME_MARK_SWEEP_COMPACT;
0N/A private static int NAME_CONCURRENT_MARK_SWEEP;
0N/A private static int NAME_OTHER;
0N/A
0N/A static {
0N/A VM.registerVMInitializedObserver(new Observer() {
0N/A public void update(Observable o, Object data) {
0N/A initialize(VM.getVM().getTypeDataBase());
0N/A }
0N/A });
0N/A }
0N/A
0N/A private static synchronized void initialize(TypeDataBase db) {
0N/A Type type = db.lookupType("Generation");
0N/A
0N/A reservedFieldOffset = type.getField("_reserved").getOffset();
0N/A virtualSpaceFieldOffset = type.getField("_virtual_space").getOffset();
0N/A levelField = type.getCIntegerField("_level");
0N/A // StatRecord
0N/A statRecordField = type.getField("_stat_record");
0N/A type = db.lookupType("Generation::StatRecord");
0N/A invocationField = type.getCIntegerField("invocations");
0N/A
0N/A // constants from Generation::Name
0N/A NAME_DEF_NEW = db.lookupIntConstant("Generation::DefNew").intValue();
0N/A NAME_PAR_NEW = db.lookupIntConstant("Generation::ParNew").intValue();
0N/A NAME_MARK_SWEEP_COMPACT = db.lookupIntConstant("Generation::MarkSweepCompact").intValue();
0N/A NAME_CONCURRENT_MARK_SWEEP = db.lookupIntConstant("Generation::ConcurrentMarkSweep").intValue();
0N/A NAME_OTHER = db.lookupIntConstant("Generation::Other").intValue();
0N/A }
0N/A
0N/A public Generation(Address addr) {
0N/A super(addr);
0N/A }
0N/A
0N/A public static class Name {
0N/A public static final Name DEF_NEW = new Name("DefNew");
0N/A public static final Name PAR_NEW = new Name("ParNew");
0N/A public static final Name MARK_SWEEP_COMPACT = new Name("MarkSweepCompact");
0N/A public static final Name CONCURRENT_MARK_SWEEP = new Name("ConcurrentMarkSweep");
0N/A public static final Name OTHER = new Name("Other");
0N/A
0N/A private Name(String value) {
0N/A this.value = value;
0N/A }
0N/A
0N/A private String value;
0N/A public String toString() {
0N/A return value;
0N/A }
0N/A }
0N/A
0N/A public Generation.Name kind() {
0N/A return Generation.Name.OTHER;
0N/A }
0N/A
0N/A static Generation.Name nameForEnum(int value) {
0N/A if (value == NAME_DEF_NEW) {
0N/A return Name.DEF_NEW;
0N/A } else if (value == NAME_PAR_NEW) {
0N/A return Name.PAR_NEW;
0N/A } else if (value == NAME_MARK_SWEEP_COMPACT) {
0N/A return Name.MARK_SWEEP_COMPACT;
0N/A } else if (value == NAME_CONCURRENT_MARK_SWEEP) {
0N/A return Name.CONCURRENT_MARK_SWEEP;
0N/A } else if (value == NAME_OTHER) {
0N/A return Name.OTHER;
0N/A } else {
0N/A throw new RuntimeException("should not reach here");
0N/A }
0N/A }
0N/A
0N/A public GenerationSpec spec() {
0N/A return ((GenCollectedHeap) VM.getVM().getUniverse().heap()).spec(level());
0N/A }
0N/A
0N/A public int level() {
0N/A return (int) levelField.getValue(addr);
0N/A }
0N/A
0N/A public int invocations() {
0N/A return getStatRecord().getInvocations();
0N/A }
0N/A
0N/A /** The maximum number of object bytes the generation can currently
0N/A hold. */
0N/A public abstract long capacity();
0N/A
0N/A /** The number of used bytes in the gen. */
0N/A public abstract long used();
0N/A
0N/A /** The number of free bytes in the gen. */
0N/A public abstract long free();
0N/A
0N/A /** The largest number of contiguous free words in the generation,
0N/A including expansion. (VM's version assumes it is called at a
0N/A safepoint.) */
0N/A public abstract long contiguousAvailable();
0N/A
0N/A public MemRegion reserved() {
0N/A return new MemRegion(addr.addOffsetTo(reservedFieldOffset));
0N/A }
0N/A
0N/A /** Returns a region guaranteed to contain all the objects in the
0N/A generation. */
0N/A public MemRegion usedRegion() {
0N/A return reserved();
0N/A }
0N/A
0N/A /* Returns "TRUE" iff "p" points into an allocated object in the
0N/A generation. */
0N/A public boolean isIn(Address p) {
0N/A GenerationIsInClosure blk = new GenerationIsInClosure(p);
0N/A spaceIterate(blk);
0N/A return (blk.space() != null);
0N/A }
0N/A
0N/A /** Returns "TRUE" iff "p" points into the reserved area of the
0N/A generation. */
0N/A public boolean isInReserved(Address p) {
0N/A return reserved().contains(p);
0N/A }
0N/A
0N/A protected VirtualSpace virtualSpace() {
0N/A return (VirtualSpace) VMObjectFactory.newObject(VirtualSpace.class, addr.addOffsetTo(virtualSpaceFieldOffset));
0N/A }
0N/A
0N/A public abstract String name();
0N/A
0N/A /** Equivalent to spaceIterate(blk, false) */
0N/A public void spaceIterate(SpaceClosure blk) {
0N/A spaceIterate(blk, false);
0N/A }
0N/A
0N/A /** Iteration - do not use for time critical operations */
0N/A public abstract void spaceIterate(SpaceClosure blk, boolean usedOnly);
0N/A
0N/A public void print() { printOn(System.out); }
0N/A public abstract void printOn(PrintStream tty);
0N/A
0N/A public static class StatRecord extends VMObject {
0N/A public StatRecord(Address addr) {
0N/A super(addr);
0N/A }
0N/A
0N/A public int getInvocations() {
0N/A return (int) invocationField.getValue(addr);
0N/A }
0N/A
0N/A }
0N/A
0N/A private StatRecord getStatRecord() {
0N/A return (StatRecord) VMObjectFactory.newObject(Generation.StatRecord.class, addr.addOffsetTo(statRecordField.getOffset()));
0N/A }
0N/A}