3939
|
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 }
|