annotate src/share/vm/oops/methodDataOop.hpp @ 1091:6aa7255741f3

6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
author ysr
date Thu, 03 Dec 2009 15:01:57 -0800
parents 89e0543e1737
children 87684f1a88b5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
948
89e0543e1737 6884624: Update copyright year
xdono
parents: 941
diff changeset
2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 class BytecodeStream;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // The MethodData object collects counts and other profile information
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // during zeroth-tier (interpretive) and first-tier execution.
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // The profile is used later by compilation heuristics. Some heuristics
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // enable use of aggressive (or "heroic") optimizations. An aggressive
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // optimization often has a down-side, a corner case that it handles
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // poorly, but which is thought to be rare. The profile provides
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // evidence of this rarity for a given method or even BCI. It allows
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // the compiler to back out of the optimization at places where it
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // has historically been a poor choice. Other heuristics try to use
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // specific information gathered about types observed at a given site.
a61af66fc99e Initial load
duke
parents:
diff changeset
37 //
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // All data in the profile is approximate. It is expected to be accurate
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // on the whole, but the system expects occasional inaccuraces, due to
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // counter overflow, multiprocessor races during data collection, space
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // limitations, missing MDO blocks, etc. Bad or missing data will degrade
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // optimization quality but will not affect correctness. Also, each MDO
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // is marked with its birth-date ("creation_mileage") which can be used
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // to assess the quality ("maturity") of its data.
a61af66fc99e Initial load
duke
parents:
diff changeset
45 //
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // Short (<32-bit) counters are designed to overflow to a known "saturated"
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // state. Also, certain recorded per-BCI events are given one-bit counters
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // which overflow to a saturated state which applied to all counters at
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // that BCI. In other words, there is a small lattice which approximates
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // the ideal of an infinite-precision counter for each event at each BCI,
a61af66fc99e Initial load
duke
parents:
diff changeset
51 // and the lattice quickly "bottoms out" in a state where all counters
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // are taken to be indefinitely large.
a61af66fc99e Initial load
duke
parents:
diff changeset
53 //
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // The reader will find many data races in profile gathering code, starting
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // with invocation counter incrementation. None of these races harm correct
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // execution of the compiled code.
a61af66fc99e Initial load
duke
parents:
diff changeset
57
941
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
58 // forward decl
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
59 class ProfileData;
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
60
0
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // DataLayout
a61af66fc99e Initial load
duke
parents:
diff changeset
62 //
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // Overlay for generic profiling data.
a61af66fc99e Initial load
duke
parents:
diff changeset
64 class DataLayout VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // Every data layout begins with a header. This header
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // contains a tag, which is used to indicate the size/layout
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // of the data, 4 bits of flags, which can be used in any way,
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // 4 bits of trap history (none/one reason/many reasons),
a61af66fc99e Initial load
duke
parents:
diff changeset
70 // and a bci, which is used to tie this piece of data to a
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // specific bci in the bytecodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
72 union {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 intptr_t _bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 struct {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 u1 _tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 u1 _flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 u2 _bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 } _struct;
a61af66fc99e Initial load
duke
parents:
diff changeset
79 } _header;
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // The data layout has an arbitrary number of cells, each sized
a61af66fc99e Initial load
duke
parents:
diff changeset
82 // to accomodate a pointer or an integer.
a61af66fc99e Initial load
duke
parents:
diff changeset
83 intptr_t _cells[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // Some types of data layouts need a length field.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 static bool needs_array_len(u1 tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
89 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 counter_increment = 1
a61af66fc99e Initial load
duke
parents:
diff changeset
91 };
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 cell_size = sizeof(intptr_t)
a61af66fc99e Initial load
duke
parents:
diff changeset
95 };
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 // Tag values
a61af66fc99e Initial load
duke
parents:
diff changeset
98 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 no_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
100 bit_data_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
101 counter_data_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
102 jump_data_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
103 receiver_type_data_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
104 virtual_call_data_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
105 ret_data_tag,
a61af66fc99e Initial load
duke
parents:
diff changeset
106 branch_data_tag,
45
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
107 multi_branch_data_tag,
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
108 arg_info_data_tag
0
a61af66fc99e Initial load
duke
parents:
diff changeset
109 };
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // The _struct._flags word is formatted as [trap_state:4 | flags:4].
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // The trap state breaks down further as [recompile:1 | reason:3].
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // This further breakdown is defined in deoptimization.cpp.
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // See Deoptimization::trap_state_reason for an assert that
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // trap_bits is big enough to hold reasons < Reason_RECORDED_LIMIT.
a61af66fc99e Initial load
duke
parents:
diff changeset
117 //
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // The trap_state is collected only if ProfileTraps is true.
a61af66fc99e Initial load
duke
parents:
diff changeset
119 trap_bits = 1+3, // 3: enough to distinguish [0..Reason_RECORDED_LIMIT].
a61af66fc99e Initial load
duke
parents:
diff changeset
120 trap_shift = BitsPerByte - trap_bits,
a61af66fc99e Initial load
duke
parents:
diff changeset
121 trap_mask = right_n_bits(trap_bits),
a61af66fc99e Initial load
duke
parents:
diff changeset
122 trap_mask_in_place = (trap_mask << trap_shift),
a61af66fc99e Initial load
duke
parents:
diff changeset
123 flag_limit = trap_shift,
a61af66fc99e Initial load
duke
parents:
diff changeset
124 flag_mask = right_n_bits(flag_limit),
a61af66fc99e Initial load
duke
parents:
diff changeset
125 first_flag = 0
a61af66fc99e Initial load
duke
parents:
diff changeset
126 };
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // Size computation
a61af66fc99e Initial load
duke
parents:
diff changeset
129 static int header_size_in_bytes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 return cell_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132 static int header_size_in_cells() {
a61af66fc99e Initial load
duke
parents:
diff changeset
133 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 static int compute_size_in_bytes(int cell_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
137 return header_size_in_bytes() + cell_count * cell_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // Initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
141 void initialize(u1 tag, u2 bci, int cell_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
144 u1 tag() {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 return _header._struct._tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 // Return a few bits of trap state. Range is [0..trap_mask].
a61af66fc99e Initial load
duke
parents:
diff changeset
149 // The state tells if traps with zero, one, or many reasons have occurred.
a61af66fc99e Initial load
duke
parents:
diff changeset
150 // It also tells whether zero or many recompilations have occurred.
a61af66fc99e Initial load
duke
parents:
diff changeset
151 // The associated trap histogram in the MDO itself tells whether
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // traps are common or not. If a BCI shows that a trap X has
a61af66fc99e Initial load
duke
parents:
diff changeset
153 // occurred, and the MDO shows N occurrences of X, we make the
a61af66fc99e Initial load
duke
parents:
diff changeset
154 // simplifying assumption that all N occurrences can be blamed
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // on that BCI.
a61af66fc99e Initial load
duke
parents:
diff changeset
156 int trap_state() {
a61af66fc99e Initial load
duke
parents:
diff changeset
157 return ((_header._struct._flags >> trap_shift) & trap_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 void set_trap_state(int new_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 assert(ProfileTraps, "used only under +ProfileTraps");
a61af66fc99e Initial load
duke
parents:
diff changeset
162 uint old_flags = (_header._struct._flags & flag_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
163 _header._struct._flags = (new_state << trap_shift) | old_flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 u1 flags() {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 return _header._struct._flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 u2 bci() {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 return _header._struct._bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 void set_header(intptr_t value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 _header._bits = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 void release_set_header(intptr_t value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 OrderAccess::release_store_ptr(&_header._bits, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
180 intptr_t header() {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 return _header._bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 void set_cell_at(int index, intptr_t value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 _cells[index] = value;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186 void release_set_cell_at(int index, intptr_t value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 OrderAccess::release_store_ptr(&_cells[index], value);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189 intptr_t cell_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
190 return _cells[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
192 intptr_t* adr_cell_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 return &_cells[index];
a61af66fc99e Initial load
duke
parents:
diff changeset
194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
195 oop* adr_oop_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 return (oop*)&(_cells[index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 void set_flag_at(int flag_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
200 assert(flag_number < flag_limit, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
201 _header._struct._flags |= (0x1 << flag_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 bool flag_at(int flag_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 assert(flag_number < flag_limit, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
205 return (_header._struct._flags & (0x1 << flag_number)) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // Low-level support for code generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
209 static ByteSize header_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 return byte_offset_of(DataLayout, _header);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212 static ByteSize tag_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return byte_offset_of(DataLayout, _header._struct._tag);
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 static ByteSize flags_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 return byte_offset_of(DataLayout, _header._struct._flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
218 static ByteSize bci_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 return byte_offset_of(DataLayout, _header._struct._bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 static ByteSize cell_offset(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 return byte_offset_of(DataLayout, _cells[index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // Return a value which, when or-ed as a byte into _flags, sets the flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
225 static int flag_number_to_byte_constant(int flag_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
226 assert(0 <= flag_number && flag_number < flag_limit, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
227 DataLayout temp; temp.set_header(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 temp.set_flag_at(flag_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
229 return temp._header._struct._flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // Return a value which, when or-ed as a word into _header, sets the flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
232 static intptr_t flag_mask_to_header_mask(int byte_constant) {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 DataLayout temp; temp.set_header(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 temp._header._struct._flags = byte_constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 return temp._header._bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
941
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
237
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
238 // GC support
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
239 ProfileData* data_in();
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
240 void follow_weak_refs(BoolObjectClosure* cl);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
241 };
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // ProfileData class hierarchy
a61af66fc99e Initial load
duke
parents:
diff changeset
245 class ProfileData;
a61af66fc99e Initial load
duke
parents:
diff changeset
246 class BitData;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 class CounterData;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 class ReceiverTypeData;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 class VirtualCallData;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 class RetData;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 class JumpData;
a61af66fc99e Initial load
duke
parents:
diff changeset
252 class BranchData;
a61af66fc99e Initial load
duke
parents:
diff changeset
253 class ArrayData;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 class MultiBranchData;
45
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
255 class ArgInfoData;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // ProfileData
a61af66fc99e Initial load
duke
parents:
diff changeset
259 //
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // A ProfileData object is created to refer to a section of profiling
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // data in a structured way.
a61af66fc99e Initial load
duke
parents:
diff changeset
262 class ProfileData : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
264 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
265 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
266 tab_width_one = 16,
a61af66fc99e Initial load
duke
parents:
diff changeset
267 tab_width_two = 36
a61af66fc99e Initial load
duke
parents:
diff changeset
268 };
a61af66fc99e Initial load
duke
parents:
diff changeset
269 #endif // !PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // This is a pointer to a section of profiling data.
a61af66fc99e Initial load
duke
parents:
diff changeset
272 DataLayout* _data;
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
275 DataLayout* data() { return _data; }
a61af66fc99e Initial load
duke
parents:
diff changeset
276
a61af66fc99e Initial load
duke
parents:
diff changeset
277 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 cell_size = DataLayout::cell_size
a61af66fc99e Initial load
duke
parents:
diff changeset
279 };
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // How many cells are in this?
a61af66fc99e Initial load
duke
parents:
diff changeset
283 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
285 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // Return the size of this data.
a61af66fc99e Initial load
duke
parents:
diff changeset
289 int size_in_bytes() {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 return DataLayout::compute_size_in_bytes(cell_count());
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Low-level accessors for underlying data
a61af66fc99e Initial load
duke
parents:
diff changeset
295 void set_intptr_at(int index, intptr_t value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 assert(0 <= index && index < cell_count(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
297 data()->set_cell_at(index, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
299 void release_set_intptr_at(int index, intptr_t value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 assert(0 <= index && index < cell_count(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
301 data()->release_set_cell_at(index, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
303 intptr_t intptr_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 assert(0 <= index && index < cell_count(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
305 return data()->cell_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 void set_uint_at(int index, uint value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
308 set_intptr_at(index, (intptr_t) value);
a61af66fc99e Initial load
duke
parents:
diff changeset
309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
310 void release_set_uint_at(int index, uint value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 release_set_intptr_at(index, (intptr_t) value);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313 uint uint_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 return (uint)intptr_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 void set_int_at(int index, int value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 set_intptr_at(index, (intptr_t) value);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319 void release_set_int_at(int index, int value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 release_set_intptr_at(index, (intptr_t) value);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 int int_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 return (int)intptr_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325 int int_at_unchecked(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326 return (int)data()->cell_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328 void set_oop_at(int index, oop value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 set_intptr_at(index, (intptr_t) value);
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331 oop oop_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 return (oop)intptr_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334 oop* adr_oop_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 assert(0 <= index && index < cell_count(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
336 return data()->adr_oop_at(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 void set_flag_at(int flag_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
340 data()->set_flag_at(flag_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342 bool flag_at(int flag_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 return data()->flag_at(flag_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // two convenient imports for use by subclasses:
a61af66fc99e Initial load
duke
parents:
diff changeset
347 static ByteSize cell_offset(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 return DataLayout::cell_offset(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350 static int flag_number_to_byte_constant(int flag_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 return DataLayout::flag_number_to_byte_constant(flag_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 ProfileData(DataLayout* data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
355 _data = data;
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // Constructor for invalid ProfileData.
a61af66fc99e Initial load
duke
parents:
diff changeset
360 ProfileData();
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 u2 bci() {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 return data()->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 address dp() {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 return (address)_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 int trap_state() {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 return data()->trap_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 void set_trap_state(int new_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 data()->set_trap_state(new_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // Type checking
a61af66fc99e Initial load
duke
parents:
diff changeset
378 virtual bool is_BitData() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
379 virtual bool is_CounterData() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
380 virtual bool is_JumpData() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
381 virtual bool is_ReceiverTypeData(){ return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
382 virtual bool is_VirtualCallData() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
383 virtual bool is_RetData() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
384 virtual bool is_BranchData() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
385 virtual bool is_ArrayData() { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
386 virtual bool is_MultiBranchData() { return false; }
45
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
387 virtual bool is_ArgInfoData() { return false; }
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
388
0
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 BitData* as_BitData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 assert(is_BitData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
392 return is_BitData() ? (BitData*) this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
394 CounterData* as_CounterData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 assert(is_CounterData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
396 return is_CounterData() ? (CounterData*) this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 JumpData* as_JumpData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 assert(is_JumpData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
400 return is_JumpData() ? (JumpData*) this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
401 }
a61af66fc99e Initial load
duke
parents:
diff changeset
402 ReceiverTypeData* as_ReceiverTypeData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 assert(is_ReceiverTypeData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
404 return is_ReceiverTypeData() ? (ReceiverTypeData*)this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
406 VirtualCallData* as_VirtualCallData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 assert(is_VirtualCallData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
408 return is_VirtualCallData() ? (VirtualCallData*)this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410 RetData* as_RetData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
411 assert(is_RetData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
412 return is_RetData() ? (RetData*) this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
414 BranchData* as_BranchData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 assert(is_BranchData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
416 return is_BranchData() ? (BranchData*) this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 ArrayData* as_ArrayData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 assert(is_ArrayData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
420 return is_ArrayData() ? (ArrayData*) this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
422 MultiBranchData* as_MultiBranchData() {
a61af66fc99e Initial load
duke
parents:
diff changeset
423 assert(is_MultiBranchData(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
424 return is_MultiBranchData() ? (MultiBranchData*)this : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
425 }
45
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
426 ArgInfoData* as_ArgInfoData() {
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
427 assert(is_ArgInfoData(), "wrong type");
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
428 return is_ArgInfoData() ? (ArgInfoData*)this : NULL;
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
429 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // Subclass specific initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
433 virtual void post_initialize(BytecodeStream* stream, methodDataOop mdo) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // GC support
a61af66fc99e Initial load
duke
parents:
diff changeset
436 virtual void follow_contents() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
437 virtual void oop_iterate(OopClosure* blk) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
438 virtual void oop_iterate_m(OopClosure* blk, MemRegion mr) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
439 virtual void adjust_pointers() {}
941
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
440 virtual void follow_weak_refs(BoolObjectClosure* is_alive_closure) {}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Parallel old support
a61af66fc99e Initial load
duke
parents:
diff changeset
444 virtual void follow_contents(ParCompactionManager* cm) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
445 virtual void update_pointers() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
446 virtual void update_pointers(HeapWord* beg_addr, HeapWord* end_addr) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
447 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // CI translation: ProfileData can represent both MethodDataOop data
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // as well as CIMethodData data. This function is provided for translating
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // an oop in a ProfileData to the ci equivalent. Generally speaking,
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // most ProfileData don't require any translation, so we provide the null
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // translation here, and the required translators are in the ci subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
454 virtual void translate_from(ProfileData* data) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 virtual void print_data_on(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
461 void print_shared(outputStream* st, const char* name);
a61af66fc99e Initial load
duke
parents:
diff changeset
462 void tab(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
463 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
464 };
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // BitData
a61af66fc99e Initial load
duke
parents:
diff changeset
467 //
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // A BitData holds a flag or two in its header.
a61af66fc99e Initial load
duke
parents:
diff changeset
469 class BitData : public ProfileData {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
471 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // null_seen:
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // saw a null operand (cast/aastore/instanceof)
a61af66fc99e Initial load
duke
parents:
diff changeset
474 null_seen_flag = DataLayout::first_flag + 0
a61af66fc99e Initial load
duke
parents:
diff changeset
475 };
a61af66fc99e Initial load
duke
parents:
diff changeset
476 enum { bit_cell_count = 0 }; // no additional data fields needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
477 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
478 BitData(DataLayout* layout) : ProfileData(layout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 virtual bool is_BitData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 static int static_cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 return bit_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 return static_cell_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // Accessor
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493 // The null_seen flag bit is specially known to the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // Consulting it allows the compiler to avoid setting up null_check traps.
a61af66fc99e Initial load
duke
parents:
diff changeset
495 bool null_seen() { return flag_at(null_seen_flag); }
a61af66fc99e Initial load
duke
parents:
diff changeset
496 void set_null_seen() { set_flag_at(null_seen_flag); }
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 // Code generation support
a61af66fc99e Initial load
duke
parents:
diff changeset
500 static int null_seen_byte_constant() {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 return flag_number_to_byte_constant(null_seen_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 }
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 static ByteSize bit_data_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 return cell_offset(bit_cell_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
509 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
511 };
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // CounterData
a61af66fc99e Initial load
duke
parents:
diff changeset
514 //
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // A CounterData corresponds to a simple counter.
a61af66fc99e Initial load
duke
parents:
diff changeset
516 class CounterData : public BitData {
a61af66fc99e Initial load
duke
parents:
diff changeset
517 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
518 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 count_off,
a61af66fc99e Initial load
duke
parents:
diff changeset
520 counter_cell_count
a61af66fc99e Initial load
duke
parents:
diff changeset
521 };
a61af66fc99e Initial load
duke
parents:
diff changeset
522 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
523 CounterData(DataLayout* layout) : BitData(layout) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 virtual bool is_CounterData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 static int static_cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 return counter_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
530
a61af66fc99e Initial load
duke
parents:
diff changeset
531 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 return static_cell_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
533 }
a61af66fc99e Initial load
duke
parents:
diff changeset
534
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // Direct accessor
a61af66fc99e Initial load
duke
parents:
diff changeset
536 uint count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
537 return uint_at(count_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // Code generation support
a61af66fc99e Initial load
duke
parents:
diff changeset
541 static ByteSize count_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
542 return cell_offset(count_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544 static ByteSize counter_data_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
545 return cell_offset(counter_cell_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
549 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
550 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
551 };
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // JumpData
a61af66fc99e Initial load
duke
parents:
diff changeset
554 //
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // A JumpData is used to access profiling information for a direct
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // branch. It is a counter, used for counting the number of branches,
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // plus a data displacement, used for realigning the data pointer to
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // the corresponding target bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
559 class JumpData : public ProfileData {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
561 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
562 taken_off_set,
a61af66fc99e Initial load
duke
parents:
diff changeset
563 displacement_off_set,
a61af66fc99e Initial load
duke
parents:
diff changeset
564 jump_cell_count
a61af66fc99e Initial load
duke
parents:
diff changeset
565 };
a61af66fc99e Initial load
duke
parents:
diff changeset
566
a61af66fc99e Initial load
duke
parents:
diff changeset
567 void set_displacement(int displacement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 set_int_at(displacement_off_set, displacement);
a61af66fc99e Initial load
duke
parents:
diff changeset
569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
572 JumpData(DataLayout* layout) : ProfileData(layout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 assert(layout->tag() == DataLayout::jump_data_tag ||
a61af66fc99e Initial load
duke
parents:
diff changeset
574 layout->tag() == DataLayout::branch_data_tag, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 virtual bool is_JumpData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 static int static_cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
580 return jump_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
584 return static_cell_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // Direct accessor
a61af66fc99e Initial load
duke
parents:
diff changeset
588 uint taken() {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 return uint_at(taken_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Saturating counter
a61af66fc99e Initial load
duke
parents:
diff changeset
592 uint inc_taken() {
a61af66fc99e Initial load
duke
parents:
diff changeset
593 uint cnt = taken() + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // Did we wrap? Will compiler screw us??
a61af66fc99e Initial load
duke
parents:
diff changeset
595 if (cnt == 0) cnt--;
a61af66fc99e Initial load
duke
parents:
diff changeset
596 set_uint_at(taken_off_set, cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 return cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
599
a61af66fc99e Initial load
duke
parents:
diff changeset
600 int displacement() {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 return int_at(displacement_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // Code generation support
a61af66fc99e Initial load
duke
parents:
diff changeset
605 static ByteSize taken_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
606 return cell_offset(taken_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
607 }
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 static ByteSize displacement_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
610 return cell_offset(displacement_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // Specific initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
614 void post_initialize(BytecodeStream* stream, methodDataOop mdo);
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
617 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
619 };
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // ReceiverTypeData
a61af66fc99e Initial load
duke
parents:
diff changeset
622 //
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // A ReceiverTypeData is used to access profiling information about a
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // dynamic type check. It consists of a counter which counts the total times
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // that the check is reached, and a series of (klassOop, count) pairs
a61af66fc99e Initial load
duke
parents:
diff changeset
626 // which are used to store a type profile for the receiver of the check.
a61af66fc99e Initial load
duke
parents:
diff changeset
627 class ReceiverTypeData : public CounterData {
a61af66fc99e Initial load
duke
parents:
diff changeset
628 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
629 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
630 receiver0_offset = counter_cell_count,
a61af66fc99e Initial load
duke
parents:
diff changeset
631 count0_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
632 receiver_type_row_cell_count = (count0_offset + 1) - receiver0_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
633 };
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
636 ReceiverTypeData(DataLayout* layout) : CounterData(layout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 assert(layout->tag() == DataLayout::receiver_type_data_tag ||
a61af66fc99e Initial load
duke
parents:
diff changeset
638 layout->tag() == DataLayout::virtual_call_data_tag, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 virtual bool is_ReceiverTypeData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
642
a61af66fc99e Initial load
duke
parents:
diff changeset
643 static int static_cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
644 return counter_cell_count + (uint) TypeProfileWidth * receiver_type_row_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 return static_cell_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // Direct accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
652 static uint row_limit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 return TypeProfileWidth;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
655 static int receiver_cell_index(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 return receiver0_offset + row * receiver_type_row_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658 static int receiver_count_cell_index(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 return count0_offset + row * receiver_type_row_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // Get the receiver at row. The 'unchecked' version is needed by parallel old
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // gc; it does not assert the receiver is a klass. During compaction of the
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // perm gen, the klass may already have moved, so the is_klass() predicate
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // would fail. The 'normal' version should be used whenever possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
666 klassOop receiver_unchecked(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
667 assert(row < row_limit(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
668 oop recv = oop_at(receiver_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
669 return (klassOop)recv;
a61af66fc99e Initial load
duke
parents:
diff changeset
670 }
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 klassOop receiver(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 klassOop recv = receiver_unchecked(row);
a61af66fc99e Initial load
duke
parents:
diff changeset
674 assert(recv == NULL || ((oop)recv)->is_klass(), "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
675 return recv;
a61af66fc99e Initial load
duke
parents:
diff changeset
676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
677
941
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
678 void set_receiver(uint row, oop p) {
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
679 assert((uint)row < row_limit(), "oob");
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
680 set_oop_at(receiver_cell_index(row), p);
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
681 }
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
682
0
a61af66fc99e Initial load
duke
parents:
diff changeset
683 uint receiver_count(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
684 assert(row < row_limit(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
685 return uint_at(receiver_count_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
687
941
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
688 void set_receiver_count(uint row, uint count) {
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
689 assert(row < row_limit(), "oob");
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
690 set_uint_at(receiver_count_cell_index(row), count);
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
691 }
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
692
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
693 void clear_row(uint row) {
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
694 assert(row < row_limit(), "oob");
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
695 set_receiver(row, NULL);
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
696 set_receiver_count(row, 0);
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
697 }
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
698
0
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // Code generation support
a61af66fc99e Initial load
duke
parents:
diff changeset
700 static ByteSize receiver_offset(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 return cell_offset(receiver_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703 static ByteSize receiver_count_offset(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
704 return cell_offset(receiver_count_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
706 static ByteSize receiver_type_data_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 return cell_offset(static_cell_count());
a61af66fc99e Initial load
duke
parents:
diff changeset
708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // GC support
a61af66fc99e Initial load
duke
parents:
diff changeset
711 virtual void follow_contents();
a61af66fc99e Initial load
duke
parents:
diff changeset
712 virtual void oop_iterate(OopClosure* blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 virtual void oop_iterate_m(OopClosure* blk, MemRegion mr);
a61af66fc99e Initial load
duke
parents:
diff changeset
714 virtual void adjust_pointers();
941
8b46c4d82093 4957990: Perm heap bloat in JVM
ysr
parents: 196
diff changeset
715 virtual void follow_weak_refs(BoolObjectClosure* is_alive_closure);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // Parallel old support
a61af66fc99e Initial load
duke
parents:
diff changeset
719 virtual void follow_contents(ParCompactionManager* cm);
a61af66fc99e Initial load
duke
parents:
diff changeset
720 virtual void update_pointers();
a61af66fc99e Initial load
duke
parents:
diff changeset
721 virtual void update_pointers(HeapWord* beg_addr, HeapWord* end_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
722 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 oop* adr_receiver(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
725 return adr_oop_at(receiver_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
726 }
a61af66fc99e Initial load
duke
parents:
diff changeset
727
a61af66fc99e Initial load
duke
parents:
diff changeset
728 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
729 void print_receiver_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
730 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
731 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
732 };
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // VirtualCallData
a61af66fc99e Initial load
duke
parents:
diff changeset
735 //
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // A VirtualCallData is used to access profiling information about a
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // virtual call. For now, it has nothing more than a ReceiverTypeData.
a61af66fc99e Initial load
duke
parents:
diff changeset
738 class VirtualCallData : public ReceiverTypeData {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
740 VirtualCallData(DataLayout* layout) : ReceiverTypeData(layout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
741 assert(layout->tag() == DataLayout::virtual_call_data_tag, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
743
a61af66fc99e Initial load
duke
parents:
diff changeset
744 virtual bool is_VirtualCallData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 static int static_cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // At this point we could add more profile state, e.g., for arguments.
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // But for now it's the same size as the base record type.
a61af66fc99e Initial load
duke
parents:
diff changeset
749 return ReceiverTypeData::static_cell_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
751
a61af66fc99e Initial load
duke
parents:
diff changeset
752 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
753 return static_cell_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // Direct accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
757 static ByteSize virtual_call_data_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 return cell_offset(static_cell_count());
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
762 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
764 };
a61af66fc99e Initial load
duke
parents:
diff changeset
765
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // RetData
a61af66fc99e Initial load
duke
parents:
diff changeset
767 //
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // A RetData is used to access profiling information for a ret bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // It is composed of a count of the number of times that the ret has
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // been executed, followed by a series of triples of the form
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // (bci, count, di) which count the number of times that some bci was the
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // target of the ret and cache a corresponding data displacement.
a61af66fc99e Initial load
duke
parents:
diff changeset
773 class RetData : public CounterData {
a61af66fc99e Initial load
duke
parents:
diff changeset
774 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
775 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 bci0_offset = counter_cell_count,
a61af66fc99e Initial load
duke
parents:
diff changeset
777 count0_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
778 displacement0_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
779 ret_row_cell_count = (displacement0_offset + 1) - bci0_offset
a61af66fc99e Initial load
duke
parents:
diff changeset
780 };
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 void set_bci(uint row, int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 assert((uint)row < row_limit(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
784 set_int_at(bci0_offset + row * ret_row_cell_count, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786 void release_set_bci(uint row, int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
787 assert((uint)row < row_limit(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // 'release' when setting the bci acts as a valid flag for other
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // threads wrt bci_count and bci_displacement.
a61af66fc99e Initial load
duke
parents:
diff changeset
790 release_set_int_at(bci0_offset + row * ret_row_cell_count, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
792 void set_bci_count(uint row, uint count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
793 assert((uint)row < row_limit(), "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
794 set_uint_at(count0_offset + row * ret_row_cell_count, count);
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
796 void set_bci_displacement(uint row, int disp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
797 set_int_at(displacement0_offset + row * ret_row_cell_count, disp);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
801 RetData(DataLayout* layout) : CounterData(layout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
802 assert(layout->tag() == DataLayout::ret_data_tag, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 virtual bool is_RetData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
806
a61af66fc99e Initial load
duke
parents:
diff changeset
807 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
808 no_bci = -1 // value of bci when bci1/2 are not in use.
a61af66fc99e Initial load
duke
parents:
diff changeset
809 };
a61af66fc99e Initial load
duke
parents:
diff changeset
810
a61af66fc99e Initial load
duke
parents:
diff changeset
811 static int static_cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 return counter_cell_count + (uint) BciProfileWidth * ret_row_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
814
a61af66fc99e Initial load
duke
parents:
diff changeset
815 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
816 return static_cell_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 static uint row_limit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
820 return BciProfileWidth;
a61af66fc99e Initial load
duke
parents:
diff changeset
821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
822 static int bci_cell_index(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
823 return bci0_offset + row * ret_row_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825 static int bci_count_cell_index(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
826 return count0_offset + row * ret_row_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
828 static int bci_displacement_cell_index(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
829 return displacement0_offset + row * ret_row_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
831
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // Direct accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
833 int bci(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
834 return int_at(bci_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
835 }
a61af66fc99e Initial load
duke
parents:
diff changeset
836 uint bci_count(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
837 return uint_at(bci_count_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
839 int bci_displacement(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 return int_at(bci_displacement_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // Interpreter Runtime support
a61af66fc99e Initial load
duke
parents:
diff changeset
844 address fixup_ret(int return_bci, methodDataHandle mdo);
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // Code generation support
a61af66fc99e Initial load
duke
parents:
diff changeset
847 static ByteSize bci_offset(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 return cell_offset(bci_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
850 static ByteSize bci_count_offset(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 return cell_offset(bci_count_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
853 static ByteSize bci_displacement_offset(uint row) {
a61af66fc99e Initial load
duke
parents:
diff changeset
854 return cell_offset(bci_displacement_cell_index(row));
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // Specific initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
858 void post_initialize(BytecodeStream* stream, methodDataOop mdo);
a61af66fc99e Initial load
duke
parents:
diff changeset
859
a61af66fc99e Initial load
duke
parents:
diff changeset
860 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
861 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
862 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
863 };
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // BranchData
a61af66fc99e Initial load
duke
parents:
diff changeset
866 //
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // A BranchData is used to access profiling data for a two-way branch.
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // It consists of taken and not_taken counts as well as a data displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // for the taken case.
a61af66fc99e Initial load
duke
parents:
diff changeset
870 class BranchData : public JumpData {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
872 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 not_taken_off_set = jump_cell_count,
a61af66fc99e Initial load
duke
parents:
diff changeset
874 branch_cell_count
a61af66fc99e Initial load
duke
parents:
diff changeset
875 };
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 void set_displacement(int displacement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
878 set_int_at(displacement_off_set, displacement);
a61af66fc99e Initial load
duke
parents:
diff changeset
879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
882 BranchData(DataLayout* layout) : JumpData(layout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
883 assert(layout->tag() == DataLayout::branch_data_tag, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 virtual bool is_BranchData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
887
a61af66fc99e Initial load
duke
parents:
diff changeset
888 static int static_cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
889 return branch_cell_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
893 return static_cell_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
895
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // Direct accessor
a61af66fc99e Initial load
duke
parents:
diff changeset
897 uint not_taken() {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 return uint_at(not_taken_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 uint inc_not_taken() {
a61af66fc99e Initial load
duke
parents:
diff changeset
902 uint cnt = not_taken() + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // Did we wrap? Will compiler screw us??
a61af66fc99e Initial load
duke
parents:
diff changeset
904 if (cnt == 0) cnt--;
a61af66fc99e Initial load
duke
parents:
diff changeset
905 set_uint_at(not_taken_off_set, cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
906 return cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
908
a61af66fc99e Initial load
duke
parents:
diff changeset
909 // Code generation support
a61af66fc99e Initial load
duke
parents:
diff changeset
910 static ByteSize not_taken_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
911 return cell_offset(not_taken_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
913 static ByteSize branch_data_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 return cell_offset(branch_cell_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // Specific initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
918 void post_initialize(BytecodeStream* stream, methodDataOop mdo);
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
921 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
922 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
923 };
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // ArrayData
a61af66fc99e Initial load
duke
parents:
diff changeset
926 //
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // A ArrayData is a base class for accessing profiling data which does
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // not have a statically known size. It consists of an array length
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // and an array start.
a61af66fc99e Initial load
duke
parents:
diff changeset
930 class ArrayData : public ProfileData {
a61af66fc99e Initial load
duke
parents:
diff changeset
931 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
932 friend class DataLayout;
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 array_len_off_set,
a61af66fc99e Initial load
duke
parents:
diff changeset
936 array_start_off_set
a61af66fc99e Initial load
duke
parents:
diff changeset
937 };
a61af66fc99e Initial load
duke
parents:
diff changeset
938
a61af66fc99e Initial load
duke
parents:
diff changeset
939 uint array_uint_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 int aindex = index + array_start_off_set;
a61af66fc99e Initial load
duke
parents:
diff changeset
941 return uint_at(aindex);
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943 int array_int_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
944 int aindex = index + array_start_off_set;
a61af66fc99e Initial load
duke
parents:
diff changeset
945 return int_at(aindex);
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947 oop array_oop_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
948 int aindex = index + array_start_off_set;
a61af66fc99e Initial load
duke
parents:
diff changeset
949 return oop_at(aindex);
a61af66fc99e Initial load
duke
parents:
diff changeset
950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
951 void array_set_int_at(int index, int value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
952 int aindex = index + array_start_off_set;
a61af66fc99e Initial load
duke
parents:
diff changeset
953 set_int_at(aindex, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 // Code generation support for subclasses.
a61af66fc99e Initial load
duke
parents:
diff changeset
957 static ByteSize array_element_offset(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
958 return cell_offset(array_start_off_set + index);
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
962 ArrayData(DataLayout* layout) : ProfileData(layout) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
963
a61af66fc99e Initial load
duke
parents:
diff changeset
964 virtual bool is_ArrayData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
965
a61af66fc99e Initial load
duke
parents:
diff changeset
966 static int static_cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
967 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
969
a61af66fc99e Initial load
duke
parents:
diff changeset
970 int array_len() {
a61af66fc99e Initial load
duke
parents:
diff changeset
971 return int_at_unchecked(array_len_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974 virtual int cell_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
975 return array_len() + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 // Code generation support
a61af66fc99e Initial load
duke
parents:
diff changeset
979 static ByteSize array_len_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
980 return cell_offset(array_len_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
982 static ByteSize array_start_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 return cell_offset(array_start_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985 };
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // MultiBranchData
a61af66fc99e Initial load
duke
parents:
diff changeset
988 //
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // A MultiBranchData is used to access profiling information for
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // a multi-way branch (*switch bytecodes). It consists of a series
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // of (count, displacement) pairs, which count the number of times each
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // case was taken and specify the data displacment for each branch target.
a61af66fc99e Initial load
duke
parents:
diff changeset
993 class MultiBranchData : public ArrayData {
a61af66fc99e Initial load
duke
parents:
diff changeset
994 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
995 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 default_count_off_set,
a61af66fc99e Initial load
duke
parents:
diff changeset
997 default_disaplacement_off_set,
a61af66fc99e Initial load
duke
parents:
diff changeset
998 case_array_start
a61af66fc99e Initial load
duke
parents:
diff changeset
999 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 relative_count_off_set,
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 relative_displacement_off_set,
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 per_case_cell_count
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1005
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 void set_default_displacement(int displacement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 array_set_int_at(default_disaplacement_off_set, displacement);
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 void set_displacement_at(int index, int displacement) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 array_set_int_at(case_array_start +
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 index * per_case_cell_count +
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 relative_displacement_off_set,
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 displacement);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1015
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 MultiBranchData(DataLayout* layout) : ArrayData(layout) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 assert(layout->tag() == DataLayout::multi_branch_data_tag, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 virtual bool is_MultiBranchData() { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1022
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 static int compute_cell_count(BytecodeStream* stream);
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 int number_of_cases() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 int alen = array_len() - 2; // get rid of default case here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 assert(alen % per_case_cell_count == 0, "must be even");
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 return (alen / per_case_cell_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1030
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 uint default_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 return array_uint_at(default_count_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 int default_displacement() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 return array_int_at(default_disaplacement_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1037
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 uint count_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 return array_uint_at(case_array_start +
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 index * per_case_cell_count +
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 relative_count_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 int displacement_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 return array_int_at(case_array_start +
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 index * per_case_cell_count +
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 relative_displacement_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1048
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // Code generation support
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 static ByteSize default_count_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 return array_element_offset(default_count_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 static ByteSize default_displacement_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 return array_element_offset(default_disaplacement_off_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 static ByteSize case_count_offset(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 return case_array_offset() +
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 (per_case_size() * index) +
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 relative_count_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 static ByteSize case_array_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 return array_element_offset(case_array_start);
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 static ByteSize per_case_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 return in_ByteSize(per_case_cell_count) * cell_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 static ByteSize relative_count_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 return in_ByteSize(relative_count_off_set) * cell_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 static ByteSize relative_displacement_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 return in_ByteSize(relative_displacement_off_set) * cell_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 // Specific initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 void post_initialize(BytecodeStream* stream, methodDataOop mdo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1081
45
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1082 class ArgInfoData : public ArrayData {
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1083
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1084 public:
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1085 ArgInfoData(DataLayout* layout) : ArrayData(layout) {
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1086 assert(layout->tag() == DataLayout::arg_info_data_tag, "wrong type");
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1087 }
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1088
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1089 virtual bool is_ArgInfoData() { return true; }
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1090
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1091
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1092 int number_of_args() {
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1093 return array_len();
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1094 }
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1095
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1096 uint arg_modified(int arg) {
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1097 return array_uint_at(arg);
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1098 }
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1099
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1100 void set_arg_modified(int arg, uint val) {
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1101 array_set_int_at(arg, val);
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1102 }
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1103
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1104 #ifndef PRODUCT
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1105 void print_data_on(outputStream* st);
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1106 #endif
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1107 };
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1108
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // methodDataOop
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 // A methodDataOop holds information which has been collected about
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // a method. Its layout looks like this:
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 // -----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 // | header |
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // | klass |
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // -----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 // | method |
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 // | size of the methodDataOop |
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 // -----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 // | Data entries... |
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 // | (variable size) |
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 // . .
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // . .
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // . .
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // | |
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // -----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 // The data entry area is a heterogeneous array of DataLayouts. Each
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // DataLayout in the array corresponds to a specific bytecode in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // method. The entries in the array are sorted by the corresponding
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // bytecode. Access to the data is via resource-allocated ProfileData,
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // which point to the underlying blocks of DataLayout structures.
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // During interpretation, if profiling in enabled, the interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // maintains a method data pointer (mdp), which points at the entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // in the array corresponding to the current bci. In the course of
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // intepretation, when a bytecode is encountered that has profile data
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // associated with it, the entry pointed to by mdp is updated, then the
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // mdp is adjusted to point to the next appropriate DataLayout. If mdp
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // is NULL to begin with, the interpreter assumes that the current method
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // is not (yet) being profiled.
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // In methodDataOop parlance, "dp" is a "data pointer", the actual address
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // of a DataLayout element. A "di" is a "data index", the offset in bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // from the base of the data entry array. A "displacement" is the byte offset
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // in certain ProfileData objects that indicate the amount the mdp must be
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // adjusted in the event of a change in control flow.
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1151
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 class methodDataOopDesc : public oopDesc {
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 friend class VMStructs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 friend class ProfileData;
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 // Back pointer to the methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 methodOop _method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1159
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // Size of this oop in bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 int _size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1162
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 // Cached hint for bci_to_dp and bci_to_data
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 int _hint_di;
a61af66fc99e Initial load
duke
parents:
diff changeset
1165
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 // Whole-method sticky bits and flags
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 _trap_hist_limit = 16, // decoupled from Deoptimization::Reason_LIMIT
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 _trap_hist_mask = max_jubyte,
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 _extra_data_count = 4 // extra DataLayout headers, for trap history
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 }; // Public flag values
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 uint _nof_decompiles; // count of all nmethod removals
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 uint _nof_overflow_recompiles; // recompile count, excluding recomp. bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 uint _nof_overflow_traps; // trap count, excluding _trap_hist
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 union {
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 intptr_t _align;
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 u1 _array[_trap_hist_limit];
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 } _trap_hist;
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // Support for interprocedural escape analysis, from Thomas Kotzmann.
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 intx _eflags; // flags on escape information
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 intx _arg_local; // bit set of non-escaping arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 intx _arg_stack; // bit set of stack-allocatable arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 intx _arg_returned; // bit set of returned arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1187
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 int _creation_mileage; // method mileage at MDO creation
a61af66fc99e Initial load
duke
parents:
diff changeset
1189
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 // Size of _data array in bytes. (Excludes header and extra_data fields.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 int _data_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1192
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // Beginning of the data entries
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 intptr_t _data[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
1195
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // Helper for size computation
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 static int compute_data_size(BytecodeStream* stream);
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 static int bytecode_cell_count(Bytecodes::Code code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 enum { no_profile_data = -1, variable_cell_count = -2 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1200
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // Helper for initialization
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 DataLayout* data_layout_at(int data_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 assert(data_index % sizeof(intptr_t) == 0, "unaligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 return (DataLayout*) (((address)_data) + data_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1206
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // Initialize an individual data segment. Returns the size of
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 // the segment in bytes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 int initialize_data(BytecodeStream* stream, int data_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1210
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 // Helper for data_at
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 DataLayout* limit_data_position() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 return (DataLayout*)((address)data_base() + _data_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 bool out_of_bounds(int data_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 return data_index >= data_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // Give each of the data entries a chance to perform specific
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // data initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 void post_initialize(BytecodeStream* stream);
a61af66fc99e Initial load
duke
parents:
diff changeset
1222
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 // hint accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 int hint_di() const { return _hint_di; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 void set_hint_di(int di) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 assert(!out_of_bounds(di), "hint_di out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 _hint_di = di;
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 ProfileData* data_before(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 // avoid SEGV on this edge case
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 if (data_size() == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 int hint = hint_di();
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 if (data_layout_at(hint)->bci() <= bci)
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 return data_at(hint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 return first_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 // What is the index of the first data entry?
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 int first_di() { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1241
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // Find or create an extra ProfileData:
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 ProfileData* bci_to_extra_data(int bci, bool create_if_missing);
a61af66fc99e Initial load
duke
parents:
diff changeset
1244
45
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1245 // return the argument info cell
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1246 ArgInfoData *arg_info();
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1247
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 static int header_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 return sizeof(methodDataOopDesc)/wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 // Compute the size of a methodDataOop before it is created.
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 static int compute_allocation_size_in_bytes(methodHandle method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 static int compute_allocation_size_in_words(methodHandle method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 static int compute_extra_data_count(int data_size, int empty_bc_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1257
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 // Determine if a given bytecode can have profile information.
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 static bool bytecode_has_profile(Bytecodes::Code code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 return bytecode_cell_count(code) != no_profile_data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // Perform initialization of a new methodDataOop
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 void initialize(methodHandle method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1265
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 // My size
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 int object_size_in_bytes() { return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 int object_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 return align_object_size(align_size_up(_size, BytesPerWord)/BytesPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1271
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 int creation_mileage() const { return _creation_mileage; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 void set_creation_mileage(int x) { _creation_mileage = x; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 bool is_mature() const; // consult mileage and ProfileMaturityPercentage
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 static int mileage_of(methodOop m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // Support for interprocedural escape analysis, from Thomas Kotzmann.
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 enum EscapeFlag {
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 estimated = 1 << 0,
78
e1e86702e43e 6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents: 45
diff changeset
1280 return_local = 1 << 1,
e1e86702e43e 6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents: 45
diff changeset
1281 return_allocated = 1 << 2,
e1e86702e43e 6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents: 45
diff changeset
1282 allocated_escapes = 1 << 3,
e1e86702e43e 6680665: bytecode Escape Analyzer produces incorrect escape information for methods without oop arguments
kvn
parents: 45
diff changeset
1283 unknown_modified = 1 << 4
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1285
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 intx eflags() { return _eflags; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 intx arg_local() { return _arg_local; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 intx arg_stack() { return _arg_stack; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 intx arg_returned() { return _arg_returned; }
45
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1290 uint arg_modified(int a) { ArgInfoData *aid = arg_info();
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1291 assert(a >= 0 && a < aid->number_of_args(), "valid argument number");
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1292 return aid->arg_modified(a); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1293
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 void set_eflags(intx v) { _eflags = v; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 void set_arg_local(intx v) { _arg_local = v; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 void set_arg_stack(intx v) { _arg_stack = v; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 void set_arg_returned(intx v) { _arg_returned = v; }
45
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1298 void set_arg_modified(int a, uint v) { ArgInfoData *aid = arg_info();
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1299 assert(a >= 0 && a < aid->number_of_args(), "valid argument number");
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1300
48a3fa21394b 6667615: (Escape Analysis) extend MDO to cache arguments escape state
kvn
parents: 0
diff changeset
1301 aid->set_arg_modified(a, v); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1302
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 void clear_escape_info() { _eflags = _arg_local = _arg_stack = _arg_returned = 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1304
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // Location and size of data area
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 address data_base() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 return (address) _data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 int data_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 return _data_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1312
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 methodOop method() { return _method; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1315
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // Get the data at an arbitrary (sort of) data index.
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 ProfileData* data_at(int data_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1318
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // Walk through the data in order.
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 ProfileData* first_data() { return data_at(first_di()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 ProfileData* next_data(ProfileData* current);
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 bool is_valid(ProfileData* current) { return current != NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // Convert a dp (data pointer) to a di (data index).
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 int dp_to_di(address dp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 return dp - ((address)_data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1328
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 address di_to_dp(int di) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 return (address)data_layout_at(di);
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1332
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 // bci to di/dp conversion.
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 address bci_to_dp(int bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 int bci_to_di(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 return dp_to_di(bci_to_dp(bci));
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 // Get the data at an arbitrary bci, or NULL if there is none.
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 ProfileData* bci_to_data(int bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1341
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // Same, but try to create an extra_data record if one is needed:
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 ProfileData* allocate_bci_to_data(int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 ProfileData* data = bci_to_data(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 return (data != NULL) ? data : bci_to_extra_data(bci, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1347
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 // Add a handful of extra data records, for trap tracking.
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 DataLayout* extra_data_base() { return limit_data_position(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 DataLayout* extra_data_limit() { return (DataLayout*)((address)this + object_size_in_bytes()); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 int extra_data_size() { return (address)extra_data_limit()
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 - (address)extra_data_base(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 static DataLayout* next_extra(DataLayout* dp) { return (DataLayout*)((address)dp + in_bytes(DataLayout::cell_offset(0))); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 // Return (uint)-1 for overflow.
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 uint trap_count(int reason) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 assert((uint)reason < _trap_hist_limit, "oob");
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // For loops:
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 static uint trap_reason_limit() { return _trap_hist_limit; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 static uint trap_count_limit() { return _trap_hist_mask; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 uint inc_trap_count(int reason) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 // Count another trap, anywhere in this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 assert(reason >= 0, "must be single trap");
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 if ((uint)reason < _trap_hist_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 uint cnt1 = 1 + _trap_hist._array[reason];
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow...
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 _trap_hist._array[reason] = cnt1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 return cnt1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 return _trap_hist_mask + (++_nof_overflow_traps);
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 // Could not represent the count in the histogram.
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 return (++_nof_overflow_traps);
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1379
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 uint overflow_trap_count() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 return _nof_overflow_traps;
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 uint overflow_recompile_count() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 return _nof_overflow_recompiles;
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 void inc_overflow_recompile_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 _nof_overflow_recompiles += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 uint decompile_count() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 return _nof_decompiles;
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 void inc_decompile_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 _nof_decompiles += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1395
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // Support for code generation
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 static ByteSize data_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 return byte_offset_of(methodDataOopDesc, _data[0]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // GC support
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 oop* adr_method() const { return (oop*)&_method; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 bool object_is_parsable() const { return _size != 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 void set_object_is_parsable(int object_size_in_bytes) { _size = object_size_in_bytes; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1405
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 // printing support for method data
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 void print_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1410
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 // verification
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 void verify_data_on(outputStream* st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 };