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> TenuredGeneration 41 </ul> 42 <li> DefNewGeneration 43 </ul> 44 </ul> 45 */ 46 47 48 public abstract class Generation extends VMObject { 49 private static long reservedFieldOffset; 50 private static long virtualSpaceFieldOffset; 51 private static CIntegerField levelField; 52 protected static final int K = 1024; 53 // Fields for class StatRecord 54 private static Field statRecordField; 55 private static CIntegerField invocationField; 56 57 // constants from Name enum 58 private static int NAME_DEF_NEW; 59 private static int NAME_PAR_NEW; 60 private static int NAME_MARK_SWEEP_COMPACT; 61 private static int NAME_CONCURRENT_MARK_SWEEP; 62 private static int NAME_OTHER; 63 64 static { 65 VM.registerVMInitializedObserver(new Observer() { 66 public void update(Observable o, Object data) { 67 initialize(VM.getVM().getTypeDataBase()); 68 } 69 }); 70 } 71 72 private static synchronized void initialize(TypeDataBase db) { 73 Type type = db.lookupType("Generation"); 74 75 reservedFieldOffset = type.getField("_reserved").getOffset(); 76 virtualSpaceFieldOffset = type.getField("_virtual_space").getOffset(); 77 levelField = type.getCIntegerField("_level"); 78 // StatRecord 79 statRecordField = type.getField("_stat_record"); 80 type = db.lookupType("Generation::StatRecord"); 81 invocationField = type.getCIntegerField("invocations"); 82 83 // constants from Generation::Name 84 NAME_DEF_NEW = db.lookupIntConstant("Generation::DefNew").intValue(); 85 NAME_PAR_NEW = db.lookupIntConstant("Generation::ParNew").intValue(); 86 NAME_MARK_SWEEP_COMPACT = db.lookupIntConstant("Generation::MarkSweepCompact").intValue(); 87 NAME_CONCURRENT_MARK_SWEEP = db.lookupIntConstant("Generation::ConcurrentMarkSweep").intValue(); 88 NAME_OTHER = db.lookupIntConstant("Generation::Other").intValue(); 89 } 90 91 public Generation(Address addr) { 92 super(addr); 93 } 94 95 public static class Name { 96 public static final Name DEF_NEW = new Name("DefNew"); 97 public static final Name PAR_NEW = new Name("ParNew"); 98 public static final Name MARK_SWEEP_COMPACT = new Name("MarkSweepCompact"); 99 public static final Name CONCURRENT_MARK_SWEEP = new Name("ConcurrentMarkSweep"); 100 public static final Name OTHER = new Name("Other"); 101 102 private Name(String value) { 103 this.value = value; 104 } 105 106 private String value; 107 public String toString() { 108 return value; 109 } 110 } 111 112 public Generation.Name kind() { 113 return Generation.Name.OTHER; 114 } 115 116 static Generation.Name nameForEnum(int value) { 117 if (value == NAME_DEF_NEW) { 118 return Name.DEF_NEW; 119 } else if (value == NAME_PAR_NEW) { 120 return Name.PAR_NEW; 121 } else if (value == NAME_MARK_SWEEP_COMPACT) { 122 return Name.MARK_SWEEP_COMPACT; 123 } else if (value == NAME_CONCURRENT_MARK_SWEEP) { 124 return Name.CONCURRENT_MARK_SWEEP; 125 } else if (value == NAME_OTHER) { 126 return Name.OTHER; 127 } else { 128 throw new RuntimeException("should not reach here"); 129 } 130 } 131 132 public GenerationSpec spec() { 133 return ((GenCollectedHeap) VM.getVM().getUniverse().heap()).spec(level()); 134 } 135 136 public int level() { 137 return (int) levelField.getValue(addr); 138 } 139 140 public int invocations() { 141 return getStatRecord().getInvocations(); 142 } 143 144 /** The maximum number of object bytes the generation can currently 145 hold. */ 146 public abstract long capacity(); 147 148 /** The number of used bytes in the gen. */ 149 public abstract long used(); 150 151 /** The number of free bytes in the gen. */ 152 public abstract long free(); 153 154 /** The largest number of contiguous free words in the generation, 155 including expansion. (VM's version assumes it is called at a 156 safepoint.) */ 157 public abstract long contiguousAvailable(); 158 159 public MemRegion reserved() { 160 return new MemRegion(addr.addOffsetTo(reservedFieldOffset)); 161 } 162 163 /** Returns a region guaranteed to contain all the objects in the 164 generation. */ 165 public MemRegion usedRegion() { 166 return reserved(); 167 } 168 169 /* Returns "TRUE" iff "p" points into an allocated object in the 170 generation. */ 171 public boolean isIn(Address p) { 172 GenerationIsInClosure blk = new GenerationIsInClosure(p); 173 spaceIterate(blk); 174 return (blk.space() != null); 175 } 176 177 /** Returns "TRUE" iff "p" points into the reserved area of the 178 generation. */ 179 public boolean isInReserved(Address p) { 180 return reserved().contains(p); 181 } 182 183 protected VirtualSpace virtualSpace() { 184 return (VirtualSpace) VMObjectFactory.newObject(VirtualSpace.class, addr.addOffsetTo(virtualSpaceFieldOffset)); 185 } 186 187 public abstract String name(); 188 189 /** Equivalent to spaceIterate(blk, false) */ 190 public void spaceIterate(SpaceClosure blk) { 191 spaceIterate(blk, false); 192 } 193 194 /** Iteration - do not use for time critical operations */ 195 public abstract void spaceIterate(SpaceClosure blk, boolean usedOnly); 196 197 public void print() { printOn(System.out); } 198 public abstract void printOn(PrintStream tty); 199 200 public static class StatRecord extends VMObject { 201 public StatRecord(Address addr) { 202 super(addr); 203 } 204 205 public int getInvocations() { 206 return (int) invocationField.getValue(addr); 207 } 208 209 } 210 211 private StatRecord getStatRecord() { 212 return (StatRecord) VMObjectFactory.newObject(Generation.StatRecord.class, addr.addOffsetTo(statRecordField.getOffset())); 213 } 214 }