1 /* 2 * Copyright (c) 2011, 2012, 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.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 public static final int argInfoDataTag = 9; 45 public static final int callTypeDataTag = 10; 46 public static final int virtualCallTypeDataTag = 11; 47 public static final int parametersTypeDataTag = 12; 48 public static final int speculativeTrapDataTag = 13; 49 50 // The trap state breaks down as [recompile:1 | reason:31]. 51 // This further breakdown is defined in deoptimization.cpp. 52 // See Deoptimization.trapStateReason for an assert that 53 // trapBits is big enough to hold reasons < reasonRecordedLimit. 54 // 55 // The trapState is collected only if ProfileTraps is true. 56 public static final int trapBits = 1+31; // 31: enough to distinguish [0..reasonRecordedLimit]. 57 public static final int trapMask = Bits.rightNBits(trapBits); 58 public static final int firstFlag = 0; 59 60 private Address data; 61 62 private int offset; 63 64 public DataLayout(MethodData d, int o) { 65 data = d.getAddress(); 66 offset = o; 67 } 68 69 public DataLayout(Address d, int o) { 70 data = d; 71 offset = o; 72 } 73 74 public int dp() { return offset; } 75 76 private int getU11(int at) { 77 return data.getJByteAt(offset + at) & 0xff; 78 } 79 80 private int getU22(int at) { 81 return data.getJShortAt(offset + at) & 0xffff; 82 } 83 84 int cellAt(int index) { 85 // Cells are intptr_t sized but only contain ints as raw values 86 return (int)data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false); 87 } 88 89 public Address addressAt(int index) { 90 return data.getAddressAt(offset + cellOffset(index)); 91 } 92 93 // Every data layout begins with a header. This header 94 // contains a tag, which is used to indicate the size/layout 95 // of the data, 8 bits of flags, which can be used in any way, 96 // 32 bits of trap history (none/one reason/many reasons), 97 // and a bci, which is used to tie this piece of data to a 98 // specific bci in the bytecodes. 99 // union { 100 // u8 _bits; 101 // struct { 102 // u1 _tag; 103 // u1 _flags; 104 // u2 _bci; 105 // u4 _traps; 106 // } _struct; 107 // } _header; 108 109 // Some types of data layouts need a length field. 110 static boolean needsArrayLen(int tag) { 111 return (tag == multiBranchDataTag); 112 } 113 114 public static final int counterIncrement = 1; 115 116 // Size computation 117 static int headerSizeInBytes() { 118 return MethodData.cellSize * headerSizeInCells(); 119 } 120 static int headerSizeInCells() { 121 return VM.getVM().isLP64() ? 1 : 2; 122 } 123 124 static public int computeSizeInBytes(int cellCount) { 125 return headerSizeInBytes() + cellCount * MethodData.cellSize; 126 } 127 128 // Initialization 129 // void initialize(int tag, int bci, int cellCount); 130 131 // Accessors 132 public int tag() { 133 return getU11(0); 134 } 135 136 // Return a few bits of trap state. Range is [0..trapMask]. 137 // The state tells if traps with zero, one, or many reasons have occurred. 138 // It also tells whether zero or many recompilations have occurred. 139 // The associated trap histogram in the MDO itself tells whether 140 // traps are common or not. If a BCI shows that a trap X has 141 // occurred, and the MDO shows N occurrences of X, we make the 142 // simplifying assumption that all N occurrences can be blamed 143 // on that BCI. 144 int trapState() { 145 return data.getJIntAt(offset+4); 146 } 147 148 int flags() { 149 return getU11(1); 150 } 151 152 int bci() { 153 return getU22(2); 154 } 155 156 boolean flagAt(int flagNumber) { 157 // assert(flagNumber < flagLimit, "oob"); 158 return (flags() & (0x1 << flagNumber)) != 0; 159 } 160 161 // Low-level support for code generation. 162 static int headerOffset() { 163 return 0; 164 } 165 static int tagOffset() { 166 return 0; 167 } 168 static int flagsOffset() { 169 return 1; 170 } 171 static int bciOffset() { 172 return 2; 173 } 174 public static int cellOffset(int index) { 175 return MethodData.cellSize + index * MethodData.cellSize; 176 } 177 // // Return a value which, when or-ed as a byte into _flags, sets the flag. 178 // static int flagNumberToByteConstant(int flagNumber) { 179 // assert(0 <= flagNumber && flagNumber < flagLimit, "oob"); 180 // DataLayout temp; temp.setHeader(0); 181 // temp.setFlagAt(flagNumber); 182 // return temp._header._struct._flags; 183 // } 184 // // Return a value which, when or-ed as a word into _header, sets the flag. 185 // static intptrT flagMaskToHeaderMask(int byteConstant) { 186 // DataLayout temp; temp.setHeader(0); 187 // temp._header._struct._flags = byteConstant; 188 // return temp._header._bits; 189 // } 190 }