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 CIntegerField used;
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 used = type.getCIntegerField("_used");
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 return used.getValue(addr);
93 }
94
95 public long committed() {
96 return committed.getValue(addr);
97 }
98
99 public int getLogMinObjAlignmentInBytes() {
100 return logMinObjAlignmentInBytes.getJInt(addr);
101 }
102
103 public ShenandoahHeapRegion getRegion(long index) {
104 if (index < numOfRegions()) {
105 Address arrayAddr = regions.getValue(addr);
106 Address regAddr = arrayAddr.getAddressAt(index * regionPtrFieldSize);
107 ShenandoahHeapRegion region = VMObjectFactory.newObject(ShenandoahHeapRegion.class, regAddr);
108 region.setHeap(this);
109 return region;
110 }
111 return null;
112 }
113
114 public ShenandoahHeapRegion regionAtOffset(long offset) {
115 long index = offset >>> ShenandoahHeapRegion.regionSizeBytesShift();
116 if (index < 0 || index >= numOfRegions()) {
117 throw new RuntimeException("Invalid offset: " + offset);
118 }
119 return getRegion(index);
120 }
121
122 @Override
123 public void liveRegionsIterate(LiveRegionsClosure closure) {
124 for (long index = 0; index < numOfRegions(); index ++) {
125 ShenandoahHeapRegion region = getRegion(index);
126 closure.doLiveRegions(region);
127 }
128 }
129
130 @Override
131 public void printOn(PrintStream tty) {
132 MemRegion mr = reservedRegion();
133 tty.print("Shenandoah heap");
134 tty.print(" [" + mr.start() + ", " + mr.end() + "]");
135 tty.println(" region size " + ShenandoahHeapRegion.regionSizeBytes() / 1024 + " K");
136 }
137
138 @Override
139 public BitMapInterface createBitMap(long bits) {
140 return new ShenandoahBitMap(this);
141 }
142
143 }