/* * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ package sun.jvm.hotspot.oops; import java.io.*; import java.util.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.types.*; import sun.jvm.hotspot.utilities.*; public class DataLayout { public static final int noTag = 0; public static final int bitDataTag = 1; public static final int counterDataTag = 2; public static final int jumpDataTag= 3; public static final int receiverTypeDataTag = 4; public static final int virtualCallDataTag = 5; public static final int retDataTag = 6; public static final int branchDataTag = 7; public static final int multiBranchDataTag = 8; public static final int argInfoDataTag = 9; public static final int callTypeDataTag = 10; public static final int virtualCallTypeDataTag = 11; public static final int parametersTypeDataTag = 12; public static final int speculativeTrapDataTag = 13; // The _struct._flags word is formatted as [trapState:4 | flags:4]. // The trap state breaks down further as [recompile:1 | reason:3]. // This further breakdown is defined in deoptimization.cpp. // See Deoptimization.trapStateReason for an assert that // trapBits is big enough to hold reasons < reasonRecordedLimit. // // The trapState is collected only if ProfileTraps is true. public static final int trapBits = 1+3; // 3: enough to distinguish [0..reasonRecordedLimit]. public static final int trapShift = 8 - trapBits; public static final int trapMask = Bits.rightNBits(trapBits); public static final int trapMaskInPlace = (trapMask << trapShift); public static final int flagLimit = trapShift; public static final int flagMask = Bits.rightNBits(flagLimit); public static final int firstFlag = 0; private Address data; private int offset; public DataLayout(MethodData d, int o) { data = d.getAddress(); offset = o; } public DataLayout(Address d, int o) { data = d; offset = o; } public int dp() { return offset; } private int getU11(int at) { return data.getJByteAt(offset + at) & 0xff; } private int getU22(int at) { return data.getJShortAt(offset + at) & 0xffff; } int cellAt(int index) { // Cells are intptr_t sized but only contain ints as raw values return (int)data.getCIntegerAt(offset + cellOffset(index), MethodData.cellSize, false); } public Address addressAt(int index) { return data.getAddressAt(offset + cellOffset(index)); } // Every data layout begins with a header. This header // contains a tag, which is used to indicate the size/layout // of the data, 4 bits of flags, which can be used in any way, // 4 bits of trap history (none/one reason/many reasons), // and a bci, which is used to tie this piece of data to a // specific bci in the bytecodes. // union { // intptrT _bits; // struct { // u1 _tag; // u1 _flags; // u2 _bci; // } _struct; // } _header; // Some types of data layouts need a length field. static boolean needsArrayLen(int tag) { return (tag == multiBranchDataTag); } public static final int counterIncrement = 1; // Size computation static int headerSizeInBytes() { return MethodData.cellSize; } static int headerSizeInCells() { return 1; } static public int computeSizeInBytes(int cellCount) { return headerSizeInBytes() + cellCount * MethodData.cellSize; } // Initialization // void initialize(int tag, int bci, int cellCount); // Accessors public int tag() { return getU11(0); } // Return a few bits of trap state. Range is [0..trapMask]. // The state tells if traps with zero, one, or many reasons have occurred. // It also tells whether zero or many recompilations have occurred. // The associated trap histogram in the MDO itself tells whether // traps are common or not. If a BCI shows that a trap X has // occurred, and the MDO shows N occurrences of X, we make the // simplifying assumption that all N occurrences can be blamed // on that BCI. int trapState() { return (flags() >> trapShift) & trapMask; } int flags() { return getU11(1); } int bci() { return getU22(2); } boolean flagAt(int flagNumber) { // assert(flagNumber < flagLimit, "oob"); return (flags() & (0x1 << flagNumber)) != 0; } // Low-level support for code generation. static int headerOffset() { return 0; } static int tagOffset() { return 0; } static int flagsOffset() { return 1; } static int bciOffset() { return 2; } public static int cellOffset(int index) { return MethodData.cellSize + index * MethodData.cellSize; } // // Return a value which, when or-ed as a byte into _flags, sets the flag. // static int flagNumberToByteConstant(int flagNumber) { // assert(0 <= flagNumber && flagNumber < flagLimit, "oob"); // DataLayout temp; temp.setHeader(0); // temp.setFlagAt(flagNumber); // return temp._header._struct._flags; // } // // Return a value which, when or-ed as a word into _header, sets the flag. // static intptrT flagMaskToHeaderMask(int byteConstant) { // DataLayout temp; temp.setHeader(0); // temp._header._struct._flags = byteConstant; // return temp._header._bits; // } }