1 /*
2 * Copyright (c) 2017, 2021, Red Hat, 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 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.shenandoah;
26
27 import sun.jvm.hotspot.gc.shared.CollectedHeap;
28 import sun.jvm.hotspot.gc.shared.CollectedHeapName;
29 import sun.jvm.hotspot.gc.shared.LiveRegionsClosure;
30 import sun.jvm.hotspot.debugger.Address;
31 import sun.jvm.hotspot.runtime.VM;
32 import sun.jvm.hotspot.runtime.VMObjectFactory;
33 import sun.jvm.hotspot.types.AddressField;
34 import sun.jvm.hotspot.types.Type;
35 import sun.jvm.hotspot.types.TypeDataBase;
36 import sun.jvm.hotspot.memory.MemRegion;
37 import sun.jvm.hotspot.types.CIntegerField;
38 import sun.jvm.hotspot.utilities.BitMapInterface;
39
40 import java.io.PrintStream;
41 import sun.jvm.hotspot.utilities.Observable;
42 import sun.jvm.hotspot.utilities.Observer;
43
44 public class ShenandoahHeap extends CollectedHeap {
45 private static CIntegerField numRegions;
46 private static AddressField globalGeneration;
47 private static CIntegerField committed;
48 private static AddressField regions;
49 private static CIntegerField logMinObjAlignmentInBytes;
50
51 private static long regionPtrFieldSize;
52 static {
53 VM.registerVMInitializedObserver(new Observer() {
54 public void update(Observable o, Object data) {
55 initialize(VM.getVM().getTypeDataBase());
56 }
57 });
58 }
59
60 private static synchronized void initialize(TypeDataBase db) {
61 Type type = db.lookupType("ShenandoahHeap");
62 numRegions = type.getCIntegerField("_num_regions");
63 globalGeneration = type.getAddressField("_global_generation");
64 committed = type.getCIntegerField("_committed");
65 regions = type.getAddressField("_regions");
66 logMinObjAlignmentInBytes = type.getCIntegerField("_log_min_obj_alignment_in_bytes");
67
68 Type regionPtrType = db.lookupType("ShenandoahHeapRegion*");
69 regionPtrFieldSize = regionPtrType.getSize();
70 }
71
72 public ShenandoahHeap(Address addr) {
73 super(addr);
74 }
75
76 @Override
77 public CollectedHeapName kind() {
78 return CollectedHeapName.SHENANDOAH;
79 }
80
81 public long numOfRegions() {
82 return numRegions.getValue(addr);
83 }
84
85 @Override
86 public long capacity() {
87 return numOfRegions() * ShenandoahHeapRegion.regionSizeBytes();
88 }
89
90 @Override
91 public long used() {
92 Address globalGenerationAddress = globalGeneration.getValue(addr);
93 ShenandoahGeneration global = VMObjectFactory.newObject(ShenandoahGeneration.class, globalGenerationAddress);
94 return global.used();
95 }
96
97 public long committed() {
98 return committed.getValue(addr);
99 }
100
101 public int getLogMinObjAlignmentInBytes() {
102 return logMinObjAlignmentInBytes.getJInt(addr);
103 }
104
105 public ShenandoahHeapRegion getRegion(long index) {
106 if (index < numOfRegions()) {
107 Address arrayAddr = regions.getValue(addr);
108 Address regAddr = arrayAddr.getAddressAt(index * regionPtrFieldSize);
109 ShenandoahHeapRegion region = VMObjectFactory.newObject(ShenandoahHeapRegion.class, regAddr);
110 region.setHeap(this);
111 return region;
112 }
113 return null;
114 }
115
116 public ShenandoahHeapRegion regionAtOffset(long offset) {
117 long index = offset >>> ShenandoahHeapRegion.regionSizeBytesShift();
118 if (index < 0 || index >= numOfRegions()) {
119 throw new RuntimeException("Invalid offset: " + offset);
120 }
121 return getRegion(index);
122 }
123
124 @Override
125 public void liveRegionsIterate(LiveRegionsClosure closure) {
126 for (long index = 0; index < numOfRegions(); index ++) {
127 ShenandoahHeapRegion region = getRegion(index);
128 closure.doLiveRegions(region);
129 }
130 }
131
132 @Override
133 public void printOn(PrintStream tty) {
134 MemRegion mr = reservedRegion();
135 tty.print("Shenandoah heap");
136 tty.print(" [" + mr.start() + ", " + mr.end() + "]");
137 tty.println(" region size " + ShenandoahHeapRegion.regionSizeBytes() / 1024 + " K");
138 }
139
140 @Override
141 public BitMapInterface createBitMap(long bits) {
142 return new ShenandoahBitMap(this);
143 }
144
145 }