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, &reg_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;