1 /* 2 * Copyright (c) 2018, 2021, 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.z; 26 27 import java.util.ArrayList; 28 import java.util.List; 29 30 import sun.jvm.hotspot.debugger.Address; 31 import sun.jvm.hotspot.debugger.OopHandle; 32 import sun.jvm.hotspot.gc.shared.LiveRegionsProvider; 33 import sun.jvm.hotspot.memory.MemRegion; 34 import sun.jvm.hotspot.oops.Oop; 35 import sun.jvm.hotspot.oops.UnknownOopException; 36 import sun.jvm.hotspot.runtime.VM; 37 import sun.jvm.hotspot.runtime.VMObject; 38 import sun.jvm.hotspot.runtime.VMObjectFactory; 39 import sun.jvm.hotspot.types.AddressField; 40 import sun.jvm.hotspot.types.CIntegerField; 41 import sun.jvm.hotspot.types.Type; 42 import sun.jvm.hotspot.types.TypeDataBase; 43 44 public class ZPage extends VMObject implements LiveRegionsProvider { 45 private static CIntegerField typeField; 46 private static CIntegerField seqnumField; 47 private static long virtualFieldOffset; 48 private static AddressField topField; 49 50 static { VM.registerVMInitializedObserver(o, d) -> initialize(VM.getVM().getTypeDataBase())51 VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase())); 52 } 53 initialize(TypeDataBase db)54 static private synchronized void initialize(TypeDataBase db) { 55 Type type = db.lookupType("ZPage"); 56 57 typeField = type.getCIntegerField("_type"); 58 seqnumField = type.getCIntegerField("_seqnum"); 59 virtualFieldOffset = type.getField("_virtual").getOffset(); 60 topField = type.getAddressField("_top"); 61 } 62 ZPage(Address addr)63 public ZPage(Address addr) { 64 super(addr); 65 } 66 type()67 private byte type() { 68 return typeField.getJByte(addr); 69 } 70 seqnum()71 private int seqnum() { 72 return seqnumField.getJInt(addr); 73 } 74 virtual()75 private ZVirtualMemory virtual() { 76 return VMObjectFactory.newObject(ZVirtualMemory.class, addr.addOffsetTo(virtualFieldOffset)); 77 } 78 top()79 private Address top() { 80 return topField.getValue(addr); 81 } 82 is_relocatable()83 private boolean is_relocatable() { 84 return seqnum() < ZGlobals.ZGlobalSeqNum(); 85 } 86 start()87 long start() { 88 return virtual().start(); 89 } 90 size()91 long size() { 92 return virtual().end() - virtual().start(); 93 } 94 object_alignment_shift()95 long object_alignment_shift() { 96 if (type() == ZGlobals.ZPageTypeSmall) { 97 return ZGlobals.ZObjectAlignmentSmallShift(); 98 } else if (type() == ZGlobals.ZPageTypeMedium) { 99 return ZGlobals.ZObjectAlignmentMediumShift; 100 } else { 101 assert(type() == ZGlobals.ZPageTypeLarge); 102 return ZGlobals.ZObjectAlignmentLargeShift; 103 } 104 } 105 objectAlignmentSize()106 long objectAlignmentSize() { 107 return 1 << object_alignment_shift(); 108 } 109 isIn(Address addr)110 public boolean isIn(Address addr) { 111 long offset = ZAddress.offset(addr); 112 // FIXME: it does not consider the sign. 113 return (offset >= start()) && (offset < top().asLongValue()); 114 } 115 getObjectSize(Address good)116 private long getObjectSize(Address good) { 117 OopHandle handle = good.addOffsetToAsOopHandle(0); 118 Oop obj = null; 119 120 try { 121 obj = VM.getVM().getObjectHeap().newOop(handle); 122 } catch (UnknownOopException exp) { 123 throw new RuntimeException(" UnknownOopException " + exp); 124 } 125 126 return VM.getVM().alignUp(obj.getObjectSize(), objectAlignmentSize()); 127 } 128 getLiveRegions()129 public List<MemRegion> getLiveRegions() { 130 Address start = ZAddress.good(ZUtils.longToAddress(start())); 131 132 // Can't convert top() to a "good" address because it might 133 // be at the top of the "offset" range, and therefore also 134 // looks like one of the color bits. Instead use the "good" 135 // address and add the size. 136 long size = top().asLongValue() - start(); 137 Address end = start.addOffsetTo(size); 138 139 return List.of(new MemRegion(start, end)); 140 } 141 } 142