1 /* 2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 3 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 * 21 * 22 * 23 */ 24 25 package sun.jvm.hotspot.oops; 26 27 import java.io.*; 28 import java.util.*; 29 import sun.jvm.hotspot.debugger.*; 30 import sun.jvm.hotspot.runtime.*; 31 import sun.jvm.hotspot.types.*; 32 import sun.jvm.hotspot.utilities.*; 33 34 public class DataLayout { 35 public static final int noTag = 0; 36 public static final int bitDataTag = 1; 37 public static final int counterDataTag = 2; 38 public static final int jumpDataTag= 3; 39 public static final int receiverTypeDataTag = 4; 40 public static final int virtualCallDataTag = 5; 41 public static final int retDataTag = 6; 42 public static final int branchDataTag = 7; 43 public static final int multiBranchDataTag = 8; 44 45 // The _struct._flags word is formatted as [trapState:4 | flags:4]. 46 // The trap state breaks down further as [recompile:1 | reason:3]. 47 // This further breakdown is defined in deoptimization.cpp. 48 // See Deoptimization.trapStateReason for an assert that 49 // trapBits is big enough to hold reasons < reasonRecordedLimit. 50 // 51 // The trapState is collected only if ProfileTraps is true. 52 public static final int trapBits = 1+3; // 3: enough to distinguish [0..reasonRecordedLimit]. 53 public static final int trapShift = 8 - trapBits; 54 public static final int trapMask = Bits.rightNBits(trapBits); 55 public static final int trapMaskInPlace = (trapMask << trapShift); 56 public static final int flagLimit = trapShift; 57 public static final int flagMask = Bits.rightNBits(flagLimit); 58 public static final int firstFlag = 0; 59 60 private Address data; 61 62 private int offset; 63 64 private boolean handlized; 65 66 public DataLayout(MethodData d, int o) { 67 data = d.getHandle(); 68 offset = o; 69 } 70 71 public DataLayout(Address d, int o) { 72 data = d; 73 offset = o; 74 handlized = true; 75 } 76 77 public int dp() { return offset; } 78 79 private int getU11(int at) { 80 return data.getJByteAt(offset + at) & 0xff; 81 } 82 83 private int getU22(int at) { 84 return data.getJShortAt(offset + at) & 0xffff; 85 } 86 87 int cellAt(int index) { 88 // Cells are intptr_t sized but only contain ints as raw values 89 return (int)data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false); 90 } 91 92 Oop oopAt(int index) { 93 OopHandle handle; 94 if (handlized) { 95 throw new InternalError("unsupported"); 96 } 97 handle = data.getOopHandleAt(offset + cellOffset(index)); 98 return VM.getVM().getObjectHeap().newOop(handle); 99 } 100 101 public Address addressAt(int index) { 102 OopHandle handle; 103 if (handlized) { 104 return data.getAddressAt(offset + cellOffset(index)); 105 } else { 106 return data.getOopHandleAt(offset + cellOffset(index)); 107 } 108 } 109 110 // Every data layout begins with a header. This header 111 // contains a tag, which is used to indicate the size/layout 112 // of the data, 4 bits of flags, which can be used in any way, 113 // 4 bits of trap history (none/one reason/many reasons), 114 // and a bci, which is used to tie this piece of data to a 115 // specific bci in the bytecodes. 116 // union { 117 // intptrT _bits; 118 // struct { 119 // u1 _tag; 120 // u1 _flags; 121 // u2 _bci; 122 // } _struct; 123 // } _header; 124 125 // Some types of data layouts need a length field. 126 static boolean needsArrayLen(int tag) { 127 return (tag == multiBranchDataTag); 128 } 129 130 public static final int counterIncrement = 1; 131 132 // Size computation 133 static int headerSizeInBytes() { 134 return MethodData.cellSize; 135 } 136 static int headerSizeInCells() { 137 return 1; 138 } 139 140 static int computeSizeInBytes(int cellCount) { 141 return headerSizeInBytes() + cellCount * MethodData.cellSize; 142 } 143 144 // Initialization 145 // void initialize(int tag, int bci, int cellCount); 146 147 // Accessors 148 public int tag() { 149 return getU11(0); 150 } 151 152 // Return a few bits of trap state. Range is [0..trapMask]. 153 // The state tells if traps with zero, one, or many reasons have occurred. 154 // It also tells whether zero or many recompilations have occurred. 155 // The associated trap histogram in the MDO itself tells whether 156 // traps are common or not. If a BCI shows that a trap X has 157 // occurred, and the MDO shows N occurrences of X, we make the 158 // simplifying assumption that all N occurrences can be blamed 159 // on that BCI. 160 int trapState() { 161 return (flags() >> trapShift) & trapMask; 162 } 163 164 int flags() { 165 return getU11(1); 166 } 167 168 int bci() { 169 return getU22(2); 170 } 171 172 boolean flagAt(int flagNumber) { 173 // assert(flagNumber < flagLimit, "oob"); 174 return (flags() & (0x1 << flagNumber)) != 0; 175 } 176 177 // Low-level support for code generation. 178 static int headerOffset() { 179 return 0; 180 } 181 static int tagOffset() { 182 return 0; 183 } 184 static int flagsOffset() { 185 return 1; 186 } 187 static int bciOffset() { 188 return 2; 189 } 190 public static int cellOffset(int index) { 191 return MethodData.cellSize + index * MethodData.cellSize; 192 } 193 // // Return a value which, when or-ed as a byte into _flags, sets the flag. 194 // static int flagNumberToByteConstant(int flagNumber) { 195 // assert(0 <= flagNumber && flagNumber < flagLimit, "oob"); 196 // DataLayout temp; temp.setHeader(0); 197 // temp.setFlagAt(flagNumber); 198 // return temp._header._struct._flags; 199 // } 200 // // Return a value which, when or-ed as a word into _header, sets the flag. 201 // static intptrT flagMaskToHeaderMask(int byteConstant) { 202 // DataLayout temp; temp.setHeader(0); 203 // temp._header._struct._flags = byteConstant; 204 // return temp._header._bits; 205 // } 206 }