Mercurial > hg > graal-jvmci-8
comparison src/share/vm/runtime/deoptimization.cpp @ 22712:3c1edc9c60d8
Let fetch_unroll_info override the exec_mode and handle rethrowing scopes
Scopes with rethrow_exception set to true need to be handled
for all types of deoptimization, not just for uncommon traps.
This change moves their handling from uncommon_trap_inner to
fetch_unroll_info_helper and uses exception_oop and exec_mode
Unpack_exception rather than setting a pending execption.
fetch_unroll_info_helper can now override the exec_mode by
passing it through the UnrollBlock.
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Thu, 29 Oct 2015 16:11:45 +0100 |
parents | 6832e10a0b97 |
children | ba7846fcb814 |
comparison
equal
deleted
inserted
replaced
22711:316e768645c0 | 22712:3c1edc9c60d8 |
---|---|
104 int caller_adjustment, | 104 int caller_adjustment, |
105 int caller_actual_parameters, | 105 int caller_actual_parameters, |
106 int number_of_frames, | 106 int number_of_frames, |
107 intptr_t* frame_sizes, | 107 intptr_t* frame_sizes, |
108 address* frame_pcs, | 108 address* frame_pcs, |
109 BasicType return_type) { | 109 BasicType return_type, |
110 int exec_mode) { | |
110 _size_of_deoptimized_frame = size_of_deoptimized_frame; | 111 _size_of_deoptimized_frame = size_of_deoptimized_frame; |
111 _caller_adjustment = caller_adjustment; | 112 _caller_adjustment = caller_adjustment; |
112 _caller_actual_parameters = caller_actual_parameters; | 113 _caller_actual_parameters = caller_actual_parameters; |
113 _number_of_frames = number_of_frames; | 114 _number_of_frames = number_of_frames; |
114 _frame_sizes = frame_sizes; | 115 _frame_sizes = frame_sizes; |
120 _counter_temp = 0; | 121 _counter_temp = 0; |
121 _unpack_kind = 0; | 122 _unpack_kind = 0; |
122 _sender_sp_temp = 0; | 123 _sender_sp_temp = 0; |
123 | 124 |
124 _total_frame_sizes = size_of_frames(); | 125 _total_frame_sizes = size_of_frames(); |
126 assert(exec_mode >= 0 && exec_mode < Unpack_LIMIT, "Unexpected exec_mode"); | |
127 _exec_mode = exec_mode; | |
125 } | 128 } |
126 | 129 |
127 | 130 |
128 Deoptimization::UnrollBlock::~UnrollBlock() { | 131 Deoptimization::UnrollBlock::~UnrollBlock() { |
129 FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes, mtCompiler); | 132 FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes, mtCompiler); |
164 // In order to make fetch_unroll_info work properly with escape | 167 // In order to make fetch_unroll_info work properly with escape |
165 // analysis, The method was changed from JRT_LEAF to JRT_BLOCK_ENTRY and | 168 // analysis, The method was changed from JRT_LEAF to JRT_BLOCK_ENTRY and |
166 // ResetNoHandleMark and HandleMark were removed from it. The actual reallocation | 169 // ResetNoHandleMark and HandleMark were removed from it. The actual reallocation |
167 // of previously eliminated objects occurs in realloc_objects, which is | 170 // of previously eliminated objects occurs in realloc_objects, which is |
168 // called from the method fetch_unroll_info_helper below. | 171 // called from the method fetch_unroll_info_helper below. |
169 JRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread)) | 172 JRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread, int exec_mode)) |
170 // It is actually ok to allocate handles in a leaf method. It causes no safepoints, | 173 // It is actually ok to allocate handles in a leaf method. It causes no safepoints, |
171 // but makes the entry a little slower. There is however a little dance we have to | 174 // but makes the entry a little slower. There is however a little dance we have to |
172 // do in debug mode to get around the NoHandleMark code in the JRT_LEAF macro | 175 // do in debug mode to get around the NoHandleMark code in the JRT_LEAF macro |
173 | 176 |
174 // fetch_unroll_info() is called at the beginning of the deoptimization | 177 // fetch_unroll_info() is called at the beginning of the deoptimization |
178 if (TraceDeoptimization) { | 181 if (TraceDeoptimization) { |
179 tty->print_cr("Deoptimizing thread " INTPTR_FORMAT, thread); | 182 tty->print_cr("Deoptimizing thread " INTPTR_FORMAT, thread); |
180 } | 183 } |
181 thread->inc_in_deopt_handler(); | 184 thread->inc_in_deopt_handler(); |
182 | 185 |
183 return fetch_unroll_info_helper(thread); | 186 return fetch_unroll_info_helper(thread, exec_mode); |
184 JRT_END | 187 JRT_END |
185 | 188 |
186 | 189 |
187 // This is factored, since it is both called from a JRT_LEAF (deoptimization) and a JRT_ENTRY (uncommon_trap) | 190 // This is factored, since it is both called from a JRT_LEAF (deoptimization) and a JRT_ENTRY (uncommon_trap) |
188 Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread* thread) { | 191 Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread* thread, int exec_mode) { |
189 | 192 |
190 // Note: there is a safepoint safety issue here. No matter whether we enter | 193 // Note: there is a safepoint safety issue here. No matter whether we enter |
191 // via vanilla deopt or uncommon trap we MUST NOT stop at a safepoint once | 194 // via vanilla deopt or uncommon trap we MUST NOT stop at a safepoint once |
192 // the vframeArray is created. | 195 // the vframeArray is created. |
193 // | 196 // |
221 chunk->push(compiledVFrame::cast(vf)); | 224 chunk->push(compiledVFrame::cast(vf)); |
222 vf = vf->sender(); | 225 vf = vf->sender(); |
223 } | 226 } |
224 assert(vf->is_compiled_frame(), "Wrong frame type"); | 227 assert(vf->is_compiled_frame(), "Wrong frame type"); |
225 chunk->push(compiledVFrame::cast(vf)); | 228 chunk->push(compiledVFrame::cast(vf)); |
229 | |
230 #ifdef INCLUDE_JVMCI | |
231 ScopeDesc* trap_scope = chunk->at(0)->scope(); | |
232 Handle exceptionObject; | |
233 if (trap_scope->rethrow_exception()) { | |
234 if (PrintDeoptimizationDetails) { | |
235 tty->print_cr("Exception to be rethrown in the interpreter for method %s::%s at bci %d", trap_scope->method()->method_holder()->name()->as_C_string(), trap_scope->method()->name()->as_C_string(), trap_scope->bci()); | |
236 } | |
237 GrowableArray<ScopeValue*>* expressions = trap_scope->expressions(); | |
238 guarantee(expressions != NULL && expressions->length() > 0, "must have exception to throw"); | |
239 ScopeValue* topOfStack = expressions->top(); | |
240 exceptionObject = StackValue::create_stack_value(&deoptee, &map, topOfStack)->get_obj(); | |
241 assert(exceptionObject() != NULL, "exception oop can not be null"); | |
242 } | |
243 #endif | |
226 | 244 |
227 bool realloc_failures = false; | 245 bool realloc_failures = false; |
228 | 246 |
229 #if defined(COMPILER2) || INCLUDE_JVMCI | 247 #if defined(COMPILER2) || INCLUDE_JVMCI |
230 // Reallocate the non-escaping objects and restore their fields. Then | 248 // Reallocate the non-escaping objects and restore their fields. Then |
510 | 528 |
511 #ifndef SHARK | 529 #ifndef SHARK |
512 assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc"); | 530 assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc"); |
513 #endif // SHARK | 531 #endif // SHARK |
514 | 532 |
533 #ifdef INCLUDE_JVMCI | |
534 if (exceptionObject() != NULL) { | |
535 thread->set_exception_oop(exceptionObject()); | |
536 exec_mode = Unpack_exception; | |
537 } | |
538 #endif | |
539 | |
515 UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, | 540 UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, |
516 caller_adjustment * BytesPerWord, | 541 caller_adjustment * BytesPerWord, |
517 caller_was_method_handle ? 0 : callee_parameters, | 542 caller_was_method_handle ? 0 : callee_parameters, |
518 number_of_frames, | 543 number_of_frames, |
519 frame_sizes, | 544 frame_sizes, |
520 frame_pcs, | 545 frame_pcs, |
521 return_type); | 546 return_type, |
547 exec_mode); | |
522 // On some platforms, we need a way to pass some platform dependent | 548 // On some platforms, we need a way to pass some platform dependent |
523 // information to the unpacking code so the skeletal frames come out | 549 // information to the unpacking code so the skeletal frames come out |
524 // correct (initial fp value, unextended sp, ...) | 550 // correct (initial fp value, unextended sp, ...) |
525 info->set_initial_info((intptr_t) array->sender().initial_deoptimization_info()); | 551 info->set_initial_info((intptr_t) array->sender().initial_deoptimization_info()); |
526 | 552 |
1512 } | 1538 } |
1513 #endif | 1539 #endif |
1514 | 1540 |
1515 Bytecodes::Code trap_bc = trap_method->java_code_at(trap_bci); | 1541 Bytecodes::Code trap_bc = trap_method->java_code_at(trap_bci); |
1516 | 1542 |
1517 if (trap_scope->rethrow_exception()) { | |
1518 if (PrintDeoptimizationDetails) { | |
1519 tty->print_cr("Exception to be rethrown in the interpreter for method %s::%s at bci %d", trap_method->method_holder()->name()->as_C_string(), trap_method->name()->as_C_string(), trap_bci); | |
1520 } | |
1521 GrowableArray<ScopeValue*>* expressions = trap_scope->expressions(); | |
1522 guarantee(expressions != NULL, "must have exception to throw"); | |
1523 ScopeValue* topOfStack = expressions->top(); | |
1524 Handle topOfStackObj = StackValue::create_stack_value(&fr, ®_map, topOfStack)->get_obj(); | |
1525 THREAD->set_pending_exception(topOfStackObj(), NULL, 0); | |
1526 } | |
1527 | |
1528 // Record this event in the histogram. | 1543 // Record this event in the histogram. |
1529 gather_statistics(reason, action, trap_bc); | 1544 gather_statistics(reason, action, trap_bc); |
1530 | 1545 |
1531 // Ensure that we can record deopt. history: | 1546 // Ensure that we can record deopt. history: |
1532 // Need MDO to record RTM code generation state. | 1547 // Need MDO to record RTM code generation state. |
2011 ignore_this_trap_count, | 2026 ignore_this_trap_count, |
2012 ignore_maybe_prior_trap, | 2027 ignore_maybe_prior_trap, |
2013 ignore_maybe_prior_recompile); | 2028 ignore_maybe_prior_recompile); |
2014 } | 2029 } |
2015 | 2030 |
2016 Deoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, jint trap_request) { | 2031 Deoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, jint trap_request, jint exec_mode) { |
2017 if (TraceDeoptimization) { | 2032 if (TraceDeoptimization) { |
2018 tty->print("Uncommon trap "); | 2033 tty->print("Uncommon trap "); |
2019 } | 2034 } |
2020 // Still in Java no safepoints | 2035 // Still in Java no safepoints |
2021 { | 2036 { |
2022 // This enters VM and may safepoint | 2037 // This enters VM and may safepoint |
2023 uncommon_trap_inner(thread, trap_request); | 2038 uncommon_trap_inner(thread, trap_request); |
2024 } | 2039 } |
2025 return fetch_unroll_info_helper(thread); | 2040 return fetch_unroll_info_helper(thread, exec_mode); |
2026 } | 2041 } |
2027 | 2042 |
2028 // Local derived constants. | 2043 // Local derived constants. |
2029 // Further breakdown of DataLayout::trap_state, as promised by DataLayout. | 2044 // Further breakdown of DataLayout::trap_state, as promised by DataLayout. |
2030 const int DS_REASON_MASK = DataLayout::trap_mask >> 1; | 2045 const int DS_REASON_MASK = DataLayout::trap_mask >> 1; |