1 /* 2 * Copyright (c) 1997, 2017, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 /* 28 * The Original Code is HAT. The Initial Developer of the 29 * Original Code is Bill Foote, with contributions from others 30 * at JavaSoft/Sun. 31 */ 32 33 package jdk.test.lib.hprof.model; 34 35 import java.io.IOException; 36 import jdk.test.lib.hprof.parser.ReadBuffer; 37 38 /* 39 * Base class for lazily read Java heap objects. 40 */ 41 public abstract class JavaLazyReadObject extends JavaHeapObject { 42 43 // file offset from which this object data starts 44 private final long offset; 45 46 protected JavaLazyReadObject(long offset) { 47 this.offset = offset; 48 } 49 50 @Override 51 public final long getSize() { 52 return getValueLength() + getClazz().getMinimumObjectSize(); 53 } 54 55 protected final long getOffset() { 56 return offset; 57 } 58 59 protected ReadBuffer buf() { 60 return getClazz().getReadBuffer(); 61 } 62 63 protected int idSize() { 64 return getClazz().getIdentifierSize(); 65 } 66 67 // return the length of the data for this object 68 protected final long getValueLength() { 69 try { 70 return readValueLength(); 71 } catch (IOException exp) { 72 System.err.println("lazy read failed at offset " + offset); 73 exp.printStackTrace(); 74 return 0; 75 } 76 } 77 78 // get this object's content as byte array 79 protected final JavaThing[] getValue() { 80 try { 81 return readValue(); 82 } catch (IOException exp) { 83 System.err.println("lazy read failed at offset " + offset); 84 exp.printStackTrace(); 85 return Snapshot.EMPTY_JAVATHING_ARRAY; 86 } 87 } 88 89 // get ID of this object 90 public final long getId() { 91 try { 92 if (idSize() == 4) { 93 return ((long)buf().getInt(offset)) & Snapshot.SMALL_ID_MASK; 94 } else { 95 return buf().getLong(offset); 96 } 97 } catch (IOException exp) { 98 System.err.println("lazy read failed at offset " + offset); 99 exp.printStackTrace(); 100 return -1; 101 } 102 } 103 104 protected abstract long readValueLength() throws IOException; 105 protected abstract JavaThing[] readValue() throws IOException; 106 107 // make Integer or Long for given object ID 108 protected static Number makeId(long id) { 109 if ((id & ~Snapshot.SMALL_ID_MASK) == 0) { 110 return (int)id; 111 } else { 112 return id; 113 } 114 } 115 116 // get ID as long value from Number 117 protected static long getIdValue(Number num) { 118 long id = num.longValue(); 119 if (num instanceof Integer) { 120 id &= Snapshot.SMALL_ID_MASK; 121 } 122 return id; 123 } 124 125 // read object ID from given index from given byte array 126 protected final long objectIdAt(long offset) throws IOException { 127 if (idSize() == 4) { 128 return ((long)intAt(offset)) & Snapshot.SMALL_ID_MASK; 129 } else { 130 return longAt(offset); 131 } 132 } 133 134 // utility methods to read primitive types from byte array 135 protected byte byteAt(long offset) throws IOException { 136 return buf().getByte(offset); 137 } 138 139 protected boolean booleanAt(long offset) throws IOException { 140 return byteAt(offset) == 0 ? false : true; 141 } 142 143 protected char charAt(long offset) throws IOException { 144 return buf().getChar(offset); 145 } 146 147 protected short shortAt(long offset) throws IOException { 148 return buf().getShort(offset); 149 } 150 151 protected int intAt(long offset) throws IOException { 152 return buf().getInt(offset); 153 } 154 155 protected long longAt(long offset) throws IOException { 156 return buf().getLong(offset); 157 } 158 159 protected float floatAt(long offset) throws IOException { 160 int val = intAt(offset); 161 return Float.intBitsToFloat(val); 162 } 163 164 protected double doubleAt(long offset) throws IOException { 165 long val = longAt(offset); 166 return Double.longBitsToDouble(val); 167 } 168 }