comparison src/share/vm/runtime/deoptimization.hpp @ 5110:0ebca2e35ca5

more preparations for disabling runtime feedback selectively based on deoptimization history
author Christian Haeubl <christian.haeubl@oracle.com>
date Thu, 15 Mar 2012 15:31:34 -0700
parents 04b9a2566eec
children dad1ac9dba7d
comparison
equal deleted inserted replaced
5109:6766253384bf 5110:0ebca2e35ca5
35 35
36 class Deoptimization : AllStatic { 36 class Deoptimization : AllStatic {
37 friend class VMStructs; 37 friend class VMStructs;
38 38
39 public: 39 public:
40 // What condition caused the deoptimization? 40 // What condition caused the deoptimization
41 enum DeoptReason { 41 enum DeoptReason {
42 #ifdef GRAAL
43 Reason_many = -1, // indicates presence of several reasons
44 Reason_none = 0, // indicates absence of a relevant deopt.
45 // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits
46 Reason_null_check,
47 Reason_range_check,
48 Reason_class_check,
49 Reason_array_check,
50 Reason_unreached,
51 Reason_type_checked_inlining,
52 Reason_optimized_type_check,
53
54 // recorded per method
55 Reason_not_compiled_exception_handler,
56 Reason_unresolved,
57 Reason_jsr_mismatch,
58 Reason_div0_check,
59 Reason_constraint,
60 Reason_LIMIT,
61 Reason_RECORDED_LIMIT = Reason_optimized_type_check
62 #else
42 Reason_many = -1, // indicates presence of several reasons 63 Reason_many = -1, // indicates presence of several reasons
43 Reason_none = 0, // indicates absence of a relevant deopt. 64 Reason_none = 0, // indicates absence of a relevant deopt.
44 // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits 65 // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits
45 Reason_null_check, // saw unexpected null or zero divisor (@bci) 66 Reason_null_check, // saw unexpected null or zero divisor (@bci)
46 Reason_null_assert, // saw unexpected non-null or non-zero (@bci) 67 Reason_null_assert, // saw unexpected non-null or non-zero (@bci)
48 Reason_class_check, // saw unexpected object class (@bci) 69 Reason_class_check, // saw unexpected object class (@bci)
49 Reason_array_check, // saw unexpected array class (aastore @bci) 70 Reason_array_check, // saw unexpected array class (aastore @bci)
50 Reason_intrinsic, // saw unexpected operand to intrinsic (@bci) 71 Reason_intrinsic, // saw unexpected operand to intrinsic (@bci)
51 Reason_bimorphic, // saw unexpected object class in bimorphic inlining (@bci) 72 Reason_bimorphic, // saw unexpected object class in bimorphic inlining (@bci)
52 73
53 Reason_unloaded, // unloaded class or constant pool entry 74 Reason_unloaded, // unloaded or class constant pool entry
54 Reason_uninitialized, // bad class state (uninitialized) 75 Reason_uninitialized, // bad class state (uninitialized)
55 Reason_unreached, // code is not reached, compiler 76 Reason_unreached, // code is not reached, compiler
56 Reason_unhandled, // arbitrary compiler limitation 77 Reason_unhandled, // arbitrary compiler limitation
57 Reason_constraint, // arbitrary runtime constraint violated 78 Reason_constraint, // arbitrary runtime constraint violated
58 Reason_div0_check, // a null_check due to division by zero 79 Reason_div0_check, // a null_check due to division by zero
60 Reason_predicate, // compiler generated predicate failed 81 Reason_predicate, // compiler generated predicate failed
61 Reason_loop_limit_check, // compiler generated loop limits check failed 82 Reason_loop_limit_check, // compiler generated loop limits check failed
62 Reason_LIMIT, 83 Reason_LIMIT,
63 // Note: Keep this enum in sync. with _trap_reason_name. 84 // Note: Keep this enum in sync. with _trap_reason_name.
64 Reason_RECORDED_LIMIT = Reason_bimorphic // some are not recorded per bc 85 Reason_RECORDED_LIMIT = Reason_bimorphic // some are not recorded per bc
86 #endif
65 // Note: Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of 87 // Note: Reason_RECORDED_LIMIT should be < 8 to fit into 3 bits of
66 // DataLayout::trap_bits. This dependency is enforced indirectly 88 // DataLayout::trap_bits. This dependency is enforced indirectly
67 // via asserts, to avoid excessive direct header-to-header dependencies. 89 // via asserts, to avoid excessive direct header-to-header dependencies.
68 // See Deoptimization::trap_state_reason and class DataLayout. 90 // See Deoptimization::trap_state_reason and class DataLayout
69 }; 91 };
70 92
71 // What action must be taken by the runtime? 93 // What action must be taken by the runtime?
72 enum DeoptAction { 94 enum DeoptAction {
73 Action_none, // just interpret, do not invalidate nmethod 95 Action_none, // just interpret, do not invalidate nmethod
97 // Checks all compiled methods. Invalid methods are deleted and 119 // Checks all compiled methods. Invalid methods are deleted and
98 // corresponding activations are deoptimized. 120 // corresponding activations are deoptimized.
99 static int deoptimize_dependents(); 121 static int deoptimize_dependents();
100 122
101 // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame 123 // Deoptimizes a frame lazily. nmethod gets patched deopt happens on return to the frame
102 static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map); 124 static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason);
103 125
104 private: 126 private:
105 // Does the actual work for deoptimizing a single frame 127 // Does the actual work for deoptimizing a single frame
106 static void deoptimize_single_frame(JavaThread* thread, frame fr); 128 static void deoptimize_single_frame(JavaThread* thread, frame fr, DeoptReason reason);
107 129
108 // Helper function to revoke biases of all monitors in frame if UseBiasedLocking 130 // Helper function to revoke biases of all monitors in frame if UseBiasedLocking
109 // is enabled 131 // is enabled
110 static void revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map); 132 static void revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map);
111 // Helper function to revoke biases of all monitors in frames 133 // Helper function to revoke biases of all monitors in frames
231 253
232 //** Deoptimizes the frame identified by id. 254 //** Deoptimizes the frame identified by id.
233 // Only called from VMDeoptimizeFrame 255 // Only called from VMDeoptimizeFrame
234 // @argument thread. Thread where stub_frame resides. 256 // @argument thread. Thread where stub_frame resides.
235 // @argument id. id of frame that should be deoptimized. 257 // @argument id. id of frame that should be deoptimized.
236 static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id); 258 static void deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason);
237 259
238 // If thread is not the current thread then execute 260 // if thread is not the current thread then execute
239 // VM_DeoptimizeFrame otherwise deoptimize directly. 261 // VM_DeoptimizeFrame otherwise deoptimize directly.
240 static void deoptimize_frame(JavaThread* thread, intptr_t* id); 262 static void deoptimize_frame(JavaThread* thread, intptr_t* id, DeoptReason reason);
241 263
242 // Statistics 264 // Statistics
243 static void gather_statistics(DeoptReason reason, DeoptAction action, 265 static void gather_statistics(DeoptReason reason, DeoptAction action,
244 Bytecodes::Code bc = Bytecodes::_illegal); 266 Bytecodes::Code bc = Bytecodes::_illegal);
245 static void print_statistics(); 267 static void print_statistics();
249 // incoming arguments) 271 // incoming arguments)
250 static int last_frame_adjust(int callee_parameters, int callee_locals); 272 static int last_frame_adjust(int callee_parameters, int callee_locals);
251 273
252 // trap_request codes 274 // trap_request codes
253 static DeoptReason trap_request_reason(int trap_request) { 275 static DeoptReason trap_request_reason(int trap_request) {
254 if (trap_request < 0) 276 if (trap_request < 0) {
255 return (DeoptReason) 277 return (DeoptReason)
256 ((~(trap_request) >> _reason_shift) & right_n_bits(_reason_bits)); 278 ((~(trap_request) >> _reason_shift) & right_n_bits(_reason_bits));
257 else 279 } else {
280 #ifdef GRAAL
281 ShouldNotReachHere();
282 return Reason_none;
283 #else
258 // standard reason for unloaded CP entry 284 // standard reason for unloaded CP entry
259 return Reason_unloaded; 285 return Reason_unloaded;
286 #endif // GRAAL
287 }
260 } 288 }
261 static DeoptAction trap_request_action(int trap_request) { 289 static DeoptAction trap_request_action(int trap_request) {
262 if (trap_request < 0) 290 if (trap_request < 0) {
263 return (DeoptAction) 291 return (DeoptAction)
264 ((~(trap_request) >> _action_shift) & right_n_bits(_action_bits)); 292 ((~(trap_request) >> _action_shift) & right_n_bits(_action_bits));
265 else 293 } else {
294 #ifdef GRAAL
295 ShouldNotReachHere();
296 return Action_make_not_compilable;
297 #else
266 // standard action for unloaded CP entry 298 // standard action for unloaded CP entry
267 return _unloaded_action; 299 return _unloaded_action;
300 #endif // GRAAL
301 }
268 } 302 }
269 static int trap_request_index(int trap_request) { 303 static int trap_request_index(int trap_request) {
270 if (trap_request < 0) 304 if (trap_request < 0) {
271 return -1; 305 return -1;
272 else 306 } else {
307 #ifdef GRAAL
308 ShouldNotReachHere();
309 return -1;
310 #else
273 return trap_request; 311 return trap_request;
312 #endif // GRAAL
313 }
274 } 314 }
275 static int make_trap_request(DeoptReason reason, DeoptAction action, 315 static int make_trap_request(DeoptReason reason, DeoptAction action,
276 int index = -1) { 316 int index = -1) {
317 #ifdef GRAAL
318 assert(index == -1, "Graal does not use index");
319 #endif
320
277 assert((1 << _reason_bits) >= Reason_LIMIT, "enough bits"); 321 assert((1 << _reason_bits) >= Reason_LIMIT, "enough bits");
278 assert((1 << _action_bits) >= Action_LIMIT, "enough bits"); 322 assert((1 << _action_bits) >= Action_LIMIT, "enough bits");
279 int trap_request; 323 int trap_request;
280 if (index != -1) 324 if (index != -1) {
281 trap_request = index; 325 trap_request = index;
282 else 326 } else {
283 trap_request = (~(((reason) << _reason_shift) 327 trap_request = (~(((reason) << _reason_shift)
284 + ((action) << _action_shift))); 328 + ((action) << _action_shift)));
329 }
285 assert(reason == trap_request_reason(trap_request), "valid reason"); 330 assert(reason == trap_request_reason(trap_request), "valid reason");
286 assert(action == trap_request_action(trap_request), "valid action"); 331 assert(action == trap_request_action(trap_request), "valid action");
287 assert(index == trap_request_index(trap_request), "valid index"); 332 assert(index == trap_request_index(trap_request), "valid index");
288 return trap_request; 333 return trap_request;
289 } 334 }