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