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