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