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