1 /* 2 * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.memory; 26 27 import java.io.*; 28 import java.util.*; 29 import sun.jvm.hotspot.debugger.*; 30 import sun.jvm.hotspot.types.*; 31 import sun.jvm.hotspot.runtime.*; 32 33 /** <P> The (supported) Generation hierarchy currently looks like this: </P> 34 35 <ul> 36 <li> Generation 37 <ul> 38 <li> CardGeneration 39 <ul> 40 <li> OneContigSpaceCardGeneration 41 <ul> 42 <li> TenuredGeneration 43 </ul> 44 </ul> 45 <li> DefNewGeneration 46 </ul> 47 </ul> 48 */ 49 50 51 public abstract class Generation extends VMObject { 52 private static long reservedFieldOffset; 53 private static long virtualSpaceFieldOffset; 54 private static CIntegerField levelField; 55 protected static final int K = 1024; 56 // Fields for class StatRecord 57 private static Field statRecordField; 58 private static CIntegerField invocationField; 59 60 // constants from Name enum 61 private static int NAME_DEF_NEW; 62 private static int NAME_PAR_NEW; 63 private static int NAME_MARK_SWEEP_COMPACT; 64 private static int NAME_CONCURRENT_MARK_SWEEP; 65 private static int NAME_OTHER; 66 67 static { 68 VM.registerVMInitializedObserver(new Observer() { 69 public void update(Observable o, Object data) { 70 initialize(VM.getVM().getTypeDataBase()); 71 } 72 }); 73 } 74 75 private static synchronized void initialize(TypeDataBase db) { 76 Type type = db.lookupType("Generation"); 77 78 reservedFieldOffset = type.getField("_reserved").getOffset(); 79 virtualSpaceFieldOffset = type.getField("_virtual_space").getOffset(); 80 levelField = type.getCIntegerField("_level"); 81 // StatRecord 82 statRecordField = type.getField("_stat_record"); 83 type = db.lookupType("Generation::StatRecord"); 84 invocationField = type.getCIntegerField("invocations"); 85 86 // constants from Generation::Name 87 NAME_DEF_NEW = db.lookupIntConstant("Generation::DefNew").intValue(); 88 NAME_PAR_NEW = db.lookupIntConstant("Generation::ParNew").intValue(); 89 NAME_MARK_SWEEP_COMPACT = db.lookupIntConstant("Generation::MarkSweepCompact").intValue(); 90 NAME_CONCURRENT_MARK_SWEEP = db.lookupIntConstant("Generation::ConcurrentMarkSweep").intValue(); 91 NAME_OTHER = db.lookupIntConstant("Generation::Other").intValue(); 92 } 93 94 public Generation(Address addr) { 95 super(addr); 96 } 97 98 public static class Name { 99 public static final Name DEF_NEW = new Name("DefNew"); 100 public static final Name PAR_NEW = new Name("ParNew"); 101 public static final Name MARK_SWEEP_COMPACT = new Name("MarkSweepCompact"); 102 public static final Name CONCURRENT_MARK_SWEEP = new Name("ConcurrentMarkSweep"); 103 public static final Name OTHER = new Name("Other"); 104 105 private Name(String value) { 106 this.value = value; 107 } 108 109 private String value; 110 public String toString() { 111 return value; 112 } 113 } 114 115 public Generation.Name kind() { 116 return Generation.Name.OTHER; 117 } 118 119 static Generation.Name nameForEnum(int value) { 120 if (value == NAME_DEF_NEW) { 121 return Name.DEF_NEW; 122 } else if (value == NAME_PAR_NEW) { 123 return Name.PAR_NEW; 124 } else if (value == NAME_MARK_SWEEP_COMPACT) { 125 return Name.MARK_SWEEP_COMPACT; 126 } else if (value == NAME_CONCURRENT_MARK_SWEEP) { 127 return Name.CONCURRENT_MARK_SWEEP; 128 } else if (value == NAME_OTHER) { 129 return Name.OTHER; 130 } else { 131 throw new RuntimeException("should not reach here"); 132 } 133 } 134 135 public GenerationSpec spec() { 136 return ((GenCollectedHeap) VM.getVM().getUniverse().heap()).spec(level()); 137 } 138 139 public int level() { 140 return (int) levelField.getValue(addr); 141 } 142 143 public int invocations() { 144 return getStatRecord().getInvocations(); 145 } 146 147 /** The maximum number of object bytes the generation can currently 148 hold. */ 149 public abstract long capacity(); 150 151 /** The number of used bytes in the gen. */ 152 public abstract long used(); 153 154 /** The number of free bytes in the gen. */ 155 public abstract long free(); 156 157 /** The largest number of contiguous free words in the generation, 158 including expansion. (VM's version assumes it is called at a 159 safepoint.) */ 160 public abstract long contiguousAvailable(); 161 162 public MemRegion reserved() { 163 return new MemRegion(addr.addOffsetTo(reservedFieldOffset)); 164 } 165 166 /** Returns a region guaranteed to contain all the objects in the 167 generation. */ 168 public MemRegion usedRegion() { 169 return reserved(); 170 } 171 172 /* Returns "TRUE" iff "p" points into an allocated object in the 173 generation. */ 174 public boolean isIn(Address p) { 175 GenerationIsInClosure blk = new GenerationIsInClosure(p); 176 spaceIterate(blk); 177 return (blk.space() != null); 178 } 179 180 /** Returns "TRUE" iff "p" points into the reserved area of the 181 generation. */ 182 public boolean isInReserved(Address p) { 183 return reserved().contains(p); 184 } 185 186 protected VirtualSpace virtualSpace() { 187 return (VirtualSpace) VMObjectFactory.newObject(VirtualSpace.class, addr.addOffsetTo(virtualSpaceFieldOffset)); 188 } 189 190 public abstract String name(); 191 192 /** Equivalent to spaceIterate(blk, false) */ 193 public void spaceIterate(SpaceClosure blk) { 194 spaceIterate(blk, false); 195 } 196 197 /** Iteration - do not use for time critical operations */ 198 public abstract void spaceIterate(SpaceClosure blk, boolean usedOnly); 199 200 public void print() { printOn(System.out); } 201 public abstract void printOn(PrintStream tty); 202 203 public static class StatRecord extends VMObject { 204 public StatRecord(Address addr) { 205 super(addr); 206 } 207 208 public int getInvocations() { 209 return (int) invocationField.getValue(addr); 210 } 211 212 } 213 214 private StatRecord getStatRecord() { 215 return (StatRecord) VMObjectFactory.newObject(Generation.StatRecord.class, addr.addOffsetTo(statRecordField.getOffset())); 216 } 217 }