1 /*
   2  * Copyright (c) 2011, 2019, 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 (headerSizeInCells() + 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 }