Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/deoptimization.hpp @ 1716:be3f9c242c9d
6948538: CMS: BOT walkers can fall into object allocation and initialization cracks
Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode.
Reviewed-by: chrisphi, johnc, poonam
author | ysr |
---|---|
date | Mon, 16 Aug 2010 15:58:42 -0700 |
parents | c18cbe5936b8 |
children | d5d065957597 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1206
diff
changeset
|
2 * Copyright (c) 1997, 2008, 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:
1206
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1206
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:
1206
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 class ProfileData; | |
26 class vframeArray; | |
27 class MonitorValue; | |
28 class ObjectValue; | |
29 | |
30 class Deoptimization : AllStatic { | |
31 public: | |
32 // What condition caused the deoptimization? | |
33 enum DeoptReason { | |
34 Reason_many = -1, // indicates presence of several reasons | |
35 Reason_none = 0, // indicates absence of a relevant deopt. | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1172
diff
changeset
|
36 // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits |
0 | 37 Reason_null_check, // saw unexpected null or zero divisor (@bci) |
38 Reason_null_assert, // saw unexpected non-null or non-zero (@bci) | |
39 Reason_range_check, // saw unexpected array index (@bci) | |
40 Reason_class_check, // saw unexpected object class (@bci) | |
41 Reason_array_check, // saw unexpected array class (aastore @bci) | |
42 Reason_intrinsic, // saw unexpected operand to intrinsic (@bci) | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1172
diff
changeset
|
43 Reason_bimorphic, // saw unexpected object class in bimorphic inlining (@bci) |
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1172
diff
changeset
|
44 |
0 | 45 Reason_unloaded, // unloaded class or constant pool entry |
46 Reason_uninitialized, // bad class state (uninitialized) | |
47 Reason_unreached, // code is not reached, compiler | |
48 Reason_unhandled, // arbitrary compiler limitation | |
49 Reason_constraint, // arbitrary runtime constraint violated | |
50 Reason_div0_check, // a null_check due to division by zero | |
51 Reason_age, // nmethod too old; tier threshold reached | |
1172 | 52 Reason_predicate, // compiler generated predicate failed |
0 | 53 Reason_LIMIT, |
54 // Note: Keep this enum in sync. with _trap_reason_name. | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1172
diff
changeset
|
55 Reason_RECORDED_LIMIT = Reason_bimorphic // some are not recorded per bc |
0 | 56 // Note: Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of |
57 // DataLayout::trap_bits. This dependency is enforced indirectly | |
58 // via asserts, to avoid excessive direct header-to-header dependencies. | |
59 // See Deoptimization::trap_state_reason and class DataLayout. | |
60 }; | |
61 | |
62 // What action must be taken by the runtime? | |
63 enum DeoptAction { | |
64 Action_none, // just interpret, do not invalidate nmethod | |
65 Action_maybe_recompile, // recompile the nmethod; need not invalidate | |
66 Action_reinterpret, // invalidate the nmethod, reset IC, maybe recompile | |
67 Action_make_not_entrant, // invalidate the nmethod, recompile (probably) | |
68 Action_make_not_compilable, // invalidate the nmethod and do not compile | |
69 Action_LIMIT | |
70 // Note: Keep this enum in sync. with _trap_action_name. | |
71 }; | |
72 | |
73 enum { | |
74 _action_bits = 3, | |
75 _reason_bits = 4, | |
76 _action_shift = 0, | |
77 _reason_shift = _action_shift+_action_bits, | |
78 BC_CASE_LIMIT = PRODUCT_ONLY(1) NOT_PRODUCT(4) // for _deoptimization_hist | |
79 }; | |
80 | |
81 enum UnpackType { | |
82 Unpack_deopt = 0, // normal deoptimization, use pc computed in unpack_vframe_on_stack | |
83 Unpack_exception = 1, // exception is pending | |
84 Unpack_uncommon_trap = 2, // redo last byte code (C2 only) | |
85 Unpack_reexecute = 3 // reexecute bytecode (C1 only) | |
86 }; | |
87 | |
88 // Checks all compiled methods. Invalid methods are deleted and | |
89 // corresponding activations are deoptimized. | |
90 static int deoptimize_dependents(); | |
91 | |
92 // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame | |
93 static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map); | |
94 | |
95 private: | |
96 // Does the actual work for deoptimizing a single frame | |
97 static void deoptimize_single_frame(JavaThread* thread, frame fr); | |
98 | |
99 // Helper function to revoke biases of all monitors in frame if UseBiasedLocking | |
100 // is enabled | |
101 static void revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map); | |
102 // Helper function to revoke biases of all monitors in frames | |
103 // executing in a particular CodeBlob if UseBiasedLocking is enabled | |
104 static void revoke_biases_of_monitors(CodeBlob* cb); | |
105 | |
106 #ifdef COMPILER2 | |
107 // Support for restoring non-escaping objects | |
108 static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS); | |
109 static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); | |
110 static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj); | |
111 static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects); | |
83
d3cd40645d0d
6681646: Relocking of a scalar replaced object during deoptimization is broken
kvn
parents:
0
diff
changeset
|
112 static void relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread); |
0 | 113 NOT_PRODUCT(static void print_objects(GrowableArray<ScopeValue*>* objects);) |
114 #endif // COMPILER2 | |
115 | |
116 public: | |
117 static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk); | |
118 | |
119 // Interface used for unpacking deoptimized frames | |
120 | |
121 // UnrollBlock is returned by fetch_unroll_info() to the deoptimization handler (blob). | |
122 // This is only a CheapObj to ease debugging after a deopt failure | |
123 class UnrollBlock : public CHeapObj { | |
124 private: | |
125 int _size_of_deoptimized_frame; // Size, in bytes, of current deoptimized frame | |
126 int _caller_adjustment; // Adjustment, in bytes, to caller's SP by initial interpreted frame | |
127 int _number_of_frames; // Number frames to unroll | |
128 int _total_frame_sizes; // Total of number*sizes frames | |
129 intptr_t* _frame_sizes; // Array of frame sizes, in bytes, for unrolling the stack | |
130 address* _frame_pcs; // Array of frame pc's, in bytes, for unrolling the stack | |
131 intptr_t* _register_block; // Block for storing callee-saved registers. | |
132 BasicType _return_type; // Tells if we have to restore double or long return value | |
133 // The following fields are used as temps during the unpacking phase | |
134 // (which is tight on registers, especially on x86). They really ought | |
135 // to be PD variables but that involves moving this class into its own | |
136 // file to use the pd include mechanism. Maybe in a later cleanup ... | |
137 intptr_t _counter_temp; // SHOULD BE PD VARIABLE (x86 frame count temp) | |
138 intptr_t _initial_fp; // SHOULD BE PD VARIABLE (x86/c2 initial ebp) | |
139 intptr_t _unpack_kind; // SHOULD BE PD VARIABLE (x86 unpack kind) | |
140 intptr_t _sender_sp_temp; // SHOULD BE PD VARIABLE (x86 sender_sp) | |
141 public: | |
142 // Constructor | |
143 UnrollBlock(int size_of_deoptimized_frame, | |
144 int caller_adjustment, | |
145 int number_of_frames, | |
146 intptr_t* frame_sizes, | |
147 address* frames_pcs, | |
148 BasicType return_type); | |
149 ~UnrollBlock(); | |
150 | |
151 // Returns where a register is located. | |
152 intptr_t* value_addr_at(int register_number) const; | |
153 | |
154 // Accessors | |
155 intptr_t* frame_sizes() const { return _frame_sizes; } | |
156 int number_of_frames() const { return _number_of_frames; } | |
157 address* frame_pcs() const { return _frame_pcs ; } | |
158 | |
159 // Returns the total size of frames | |
160 int size_of_frames() const; | |
161 | |
162 // Accessors used by the code generator for the unpack stub. | |
163 static int size_of_deoptimized_frame_offset_in_bytes() { return offset_of(UnrollBlock, _size_of_deoptimized_frame); } | |
164 static int caller_adjustment_offset_in_bytes() { return offset_of(UnrollBlock, _caller_adjustment); } | |
165 static int number_of_frames_offset_in_bytes() { return offset_of(UnrollBlock, _number_of_frames); } | |
166 static int frame_sizes_offset_in_bytes() { return offset_of(UnrollBlock, _frame_sizes); } | |
167 static int total_frame_sizes_offset_in_bytes() { return offset_of(UnrollBlock, _total_frame_sizes); } | |
168 static int frame_pcs_offset_in_bytes() { return offset_of(UnrollBlock, _frame_pcs); } | |
169 static int register_block_offset_in_bytes() { return offset_of(UnrollBlock, _register_block); } | |
170 static int return_type_offset_in_bytes() { return offset_of(UnrollBlock, _return_type); } | |
171 static int counter_temp_offset_in_bytes() { return offset_of(UnrollBlock, _counter_temp); } | |
172 static int initial_fp_offset_in_bytes() { return offset_of(UnrollBlock, _initial_fp); } | |
173 static int unpack_kind_offset_in_bytes() { return offset_of(UnrollBlock, _unpack_kind); } | |
174 static int sender_sp_temp_offset_in_bytes() { return offset_of(UnrollBlock, _sender_sp_temp); } | |
175 | |
176 BasicType return_type() const { return _return_type; } | |
177 void print(); | |
178 }; | |
179 | |
180 //** Returns an UnrollBlock continuing information | |
181 // how to make room for the resulting interpreter frames. | |
182 // Called by assembly stub after execution has returned to | |
183 // deoptimized frame. | |
184 // @argument thread. Thread where stub_frame resides. | |
185 // @see OptoRuntime::deoptimization_fetch_unroll_info_C | |
186 static UnrollBlock* fetch_unroll_info(JavaThread* thread); | |
187 | |
188 //** Unpacks vframeArray onto execution stack | |
189 // Called by assembly stub after execution has returned to | |
190 // deoptimized frame and after the stack unrolling. | |
191 // @argument thread. Thread where stub_frame resides. | |
192 // @argument exec_mode. Determines how execution should be continuted in top frame. | |
193 // 0 means continue after current byte code | |
194 // 1 means exception has happened, handle exception | |
195 // 2 means reexecute current bytecode (for uncommon traps). | |
196 // @see OptoRuntime::deoptimization_unpack_frames_C | |
197 // Return BasicType of call return type, if any | |
198 static BasicType unpack_frames(JavaThread* thread, int exec_mode); | |
199 | |
200 // Cleans up deoptimization bits on thread after unpacking or in the | |
201 // case of an exception. | |
202 static void cleanup_deopt_info(JavaThread *thread, | |
203 vframeArray * array); | |
204 | |
205 // Restores callee saved values from deoptimized frame into oldest interpreter frame | |
206 // so caller of the deoptimized frame will get back the values it expects. | |
207 static void unwind_callee_save_values(frame* f, vframeArray* vframe_array); | |
208 | |
209 //** Performs an uncommon trap for compiled code. | |
210 // The top most compiler frame is converted into interpreter frames | |
211 static UnrollBlock* uncommon_trap(JavaThread* thread, jint unloaded_class_index); | |
212 // Helper routine that enters the VM and may block | |
213 static void uncommon_trap_inner(JavaThread* thread, jint unloaded_class_index); | |
214 | |
215 //** Deoptimizes the frame identified by id. | |
216 // Only called from VMDeoptimizeFrame | |
217 // @argument thread. Thread where stub_frame resides. | |
218 // @argument id. id of frame that should be deoptimized. | |
219 static void deoptimize_frame(JavaThread* thread, intptr_t* id); | |
220 | |
221 // Statistics | |
222 static void gather_statistics(DeoptReason reason, DeoptAction action, | |
223 Bytecodes::Code bc = Bytecodes::_illegal); | |
224 static void print_statistics(); | |
225 | |
226 // How much room to adjust the last frame's SP by, to make space for | |
227 // the callee's interpreter frame (which expects locals to be next to | |
228 // incoming arguments) | |
229 static int last_frame_adjust(int callee_parameters, int callee_locals); | |
230 | |
231 // trap_request codes | |
232 static DeoptReason trap_request_reason(int trap_request) { | |
233 if (trap_request < 0) | |
234 return (DeoptReason) | |
235 ((~(trap_request) >> _reason_shift) & right_n_bits(_reason_bits)); | |
236 else | |
237 // standard reason for unloaded CP entry | |
238 return Reason_unloaded; | |
239 } | |
240 static DeoptAction trap_request_action(int trap_request) { | |
241 if (trap_request < 0) | |
242 return (DeoptAction) | |
243 ((~(trap_request) >> _action_shift) & right_n_bits(_action_bits)); | |
244 else | |
245 // standard action for unloaded CP entry | |
246 return _unloaded_action; | |
247 } | |
248 static int trap_request_index(int trap_request) { | |
249 if (trap_request < 0) | |
250 return -1; | |
251 else | |
252 return trap_request; | |
253 } | |
254 static int make_trap_request(DeoptReason reason, DeoptAction action, | |
255 int index = -1) { | |
256 assert((1 << _reason_bits) >= Reason_LIMIT, "enough bits"); | |
257 assert((1 << _action_bits) >= Action_LIMIT, "enough bits"); | |
258 int trap_request; | |
259 if (index != -1) | |
260 trap_request = index; | |
261 else | |
262 trap_request = (~(((reason) << _reason_shift) | |
263 + ((action) << _action_shift))); | |
264 assert(reason == trap_request_reason(trap_request), "valid reason"); | |
265 assert(action == trap_request_action(trap_request), "valid action"); | |
266 assert(index == trap_request_index(trap_request), "valid index"); | |
267 return trap_request; | |
268 } | |
269 | |
270 // The trap_state stored in a MDO is decoded here. | |
271 // It records two items of information. | |
272 // reason: If a deoptimization happened here, what its reason was, | |
273 // or if there were multiple deopts with differing reasons. | |
274 // recompiled: If a deoptimization here triggered a recompilation. | |
275 // Note that not all reasons are recorded per-bci. | |
276 static DeoptReason trap_state_reason(int trap_state); | |
277 static int trap_state_has_reason(int trap_state, int reason); | |
278 static int trap_state_add_reason(int trap_state, int reason); | |
279 static bool trap_state_is_recompiled(int trap_state); | |
280 static int trap_state_set_recompiled(int trap_state, bool z); | |
281 static const char* format_trap_state(char* buf, size_t buflen, | |
282 int trap_state); | |
283 | |
284 static bool reason_is_recorded_per_bytecode(DeoptReason reason) { | |
1206
87684f1a88b5
6614597: Performance variability in jvm2008 xml.validation
kvn
parents:
1172
diff
changeset
|
285 return reason > Reason_none && reason <= Reason_RECORDED_LIMIT; |
0 | 286 } |
287 | |
288 static DeoptReason reason_recorded_per_bytecode_if_any(DeoptReason reason) { | |
289 if (reason_is_recorded_per_bytecode(reason)) | |
290 return reason; | |
291 else if (reason == Reason_div0_check) // null check due to divide-by-zero? | |
292 return Reason_null_check; // recorded per BCI as a null check | |
293 else | |
294 return Reason_none; | |
295 } | |
296 | |
297 static const char* trap_reason_name(int reason); | |
298 static const char* trap_action_name(int action); | |
299 // Format like reason='foo' action='bar' index='123'. | |
300 // This is suitable both for XML and for tty output. | |
301 static const char* format_trap_request(char* buf, size_t buflen, | |
302 int trap_request); | |
303 | |
304 static jint total_deoptimization_count(); | |
305 static jint deoptimization_count(DeoptReason reason); | |
306 | |
307 // JVMTI PopFrame support | |
308 | |
309 // Preserves incoming arguments to the popped frame when it is | |
310 // returning to a deoptimized caller | |
311 static void popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address); | |
312 | |
313 private: | |
314 enum { | |
315 _no_count = -1 | |
316 }; | |
317 | |
318 static void reset_invocation_counter(ScopeDesc* trap_scope, jint count = _no_count); | |
319 | |
320 static methodDataOop get_method_data(JavaThread* thread, methodHandle m, bool create_if_missing); | |
321 // Update the mdo's count and per-BCI reason bits, returning previous state: | |
322 static ProfileData* query_update_method_data(methodDataHandle trap_mdo, | |
323 int trap_bci, | |
324 DeoptReason reason, | |
325 //outputs: | |
326 uint& ret_this_trap_count, | |
327 bool& ret_maybe_prior_trap, | |
328 bool& ret_maybe_prior_recompile); | |
329 // class loading support for uncommon trap | |
330 static void load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS); | |
331 static void load_class_by_index(constantPoolHandle constant_pool, int index); | |
332 | |
333 static UnrollBlock* fetch_unroll_info_helper(JavaThread* thread); | |
334 | |
335 static DeoptAction _unloaded_action; // == Action_reinterpret; | |
336 static const char* _trap_reason_name[Reason_LIMIT]; | |
337 static const char* _trap_action_name[Action_LIMIT]; | |
338 | |
339 static juint _deoptimization_hist[Reason_LIMIT][1+Action_LIMIT][BC_CASE_LIMIT]; | |
340 // Note: Histogram array size is 1-2 Kb. | |
341 | |
342 public: | |
343 static void update_method_data_from_interpreter(methodDataHandle trap_mdo, int trap_bci, int reason); | |
344 }; | |
345 | |
346 class DeoptimizationMarker : StackObj { // for profiling | |
347 static bool _is_active; | |
348 public: | |
349 DeoptimizationMarker() { _is_active = true; } | |
350 ~DeoptimizationMarker() { _is_active = false; } | |
351 static bool is_active() { return _is_active; } | |
352 }; |