OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include <map> | 5 #include <map> |
6 #include <set> | 6 #include <set> |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "vm/kernel_to_il.h" | 9 #include "vm/kernel_to_il.h" |
10 | 10 |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
359 Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type()); | 359 Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type()); |
360 scope_->InsertParameterAt(pos++, variable); | 360 scope_->InsertParameterAt(pos++, variable); |
361 result_->type_arguments_variable = variable; | 361 result_->type_arguments_variable = variable; |
362 } | 362 } |
363 AddParameters(node, pos); | 363 AddParameters(node, pos); |
364 | 364 |
365 // We generate a syntethic body for implicit closure functions - which | 365 // We generate a syntethic body for implicit closure functions - which |
366 // will forward the call to the real function. | 366 // will forward the call to the real function. |
367 // -> see BuildGraphOfImplicitClosureFunction | 367 // -> see BuildGraphOfImplicitClosureFunction |
368 if (!function.IsImplicitClosureFunction()) { | 368 if (!function.IsImplicitClosureFunction()) { |
369 // TODO(jensj): HACK: Push the begin token to after any parameters to | |
370 // avoid crash when breaking on definition line of async method in | |
371 // debugger. It seems that another scope needs to be added | |
372 // in which captures are made, but I can't make that work. | |
373 // This 'solution' doesn't crash, but I cannot see the parameters at | |
374 // that particular breakpoint either. | |
375 // Also push the end token to after the "}" to avoid crashing on | |
376 // stepping past the last line (to the "}" character). | |
377 if (node->body() != NULL && node->body()->position().IsReal()) { | |
378 scope_->set_begin_token_pos(node->body()->position()); | |
379 } | |
380 if (scope_->end_token_pos().IsReal()) { | |
381 scope_->set_end_token_pos(scope_->end_token_pos().Next()); | |
382 } | |
369 node_->AcceptVisitor(this); | 383 node_->AcceptVisitor(this); |
370 } | 384 } |
371 break; | 385 break; |
372 } | 386 } |
373 case RawFunction::kImplicitGetter: | 387 case RawFunction::kImplicitGetter: |
374 case RawFunction::kImplicitStaticFinalGetter: | 388 case RawFunction::kImplicitStaticFinalGetter: |
375 case RawFunction::kImplicitSetter: { | 389 case RawFunction::kImplicitSetter: { |
376 ASSERT(node_->IsField()); | 390 ASSERT(node_->IsField()); |
377 if (IsStaticInitializer(function, Z)) { | 391 if (IsStaticInitializer(function, Z)) { |
378 node_->AcceptVisitor(this); | 392 node_->AcceptVisitor(this); |
(...skipping 2139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2518 argument->set_temp_index(argument->temp_index() - 1); | 2532 argument->set_temp_index(argument->temp_index() - 1); |
2519 ++pending_argument_count_; | 2533 ++pending_argument_count_; |
2520 | 2534 |
2521 return Fragment(argument); | 2535 return Fragment(argument); |
2522 } | 2536 } |
2523 | 2537 |
2524 | 2538 |
2525 Fragment FlowGraphBuilder::Return(TokenPosition position) { | 2539 Fragment FlowGraphBuilder::Return(TokenPosition position) { |
2526 Value* value = Pop(); | 2540 Value* value = Pop(); |
2527 ASSERT(stack_ == NULL); | 2541 ASSERT(stack_ == NULL); |
2528 ReturnInstr* return_instr = | 2542 |
2529 new (Z) ReturnInstr(TokenPosition::kNoSource, value); | 2543 Fragment fragment; |
2544 | |
2545 // Doing what's done in EffectGraphVisitor::VisitReturnNode. | |
Kevin Millikin (Google)
2017/01/24 13:44:13
This kind of comment isn't useful.
It won't even
jensj
2017/01/25 12:52:22
I will remove the comment.
| |
2546 | |
2547 // Call to stub that checks whether the debugger is in single | |
2548 // step mode. This call must happen before the contexts are | |
2549 // unchained so that captured variables can be inspected. | |
2550 // No debugger check is done in native functions or for return | |
2551 // statements for which there is no associated source position. | |
2552 const Function& function = parsed_function_->function(); | |
Kevin Millikin (Google)
2017/01/24 13:44:13
Note that we are not doing the same thing as the c
jensj
2017/01/25 12:52:22
I don't think that's the issue (in regards to the
| |
2553 if (FLAG_support_debugger && position.IsDebugPause() && | |
2554 !function.is_native()) { | |
2555 fragment <<= | |
2556 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); | |
2557 } | |
2558 | |
2559 ReturnInstr* return_instr = new (Z) ReturnInstr(position, value); | |
2530 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); | 2560 if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr); |
2531 return Fragment(return_instr).closed(); | 2561 fragment <<= return_instr; |
2562 return fragment.closed(); | |
2532 } | 2563 } |
2533 | 2564 |
2534 | 2565 |
2535 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, | 2566 Fragment FlowGraphBuilder::StaticCall(TokenPosition position, |
2536 const Function& target, | 2567 const Function& target, |
2537 intptr_t argument_count) { | 2568 intptr_t argument_count) { |
2538 return StaticCall(position, target, argument_count, Array::null_array()); | 2569 return StaticCall(position, target, argument_count, Array::null_array()); |
2539 } | 2570 } |
2540 | 2571 |
2541 | 2572 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2641 LocalVariable* variable) { | 2672 LocalVariable* variable) { |
2642 Fragment instructions; | 2673 Fragment instructions; |
2643 if (variable->is_captured()) { | 2674 if (variable->is_captured()) { |
2644 LocalVariable* value = MakeTemporary(); | 2675 LocalVariable* value = MakeTemporary(); |
2645 instructions += LoadContextAt(variable->owner()->context_level()); | 2676 instructions += LoadContextAt(variable->owner()->context_level()); |
2646 instructions += LoadLocal(value); | 2677 instructions += LoadLocal(value); |
2647 instructions += | 2678 instructions += |
2648 StoreInstanceField(Context::variable_offset(variable->index())); | 2679 StoreInstanceField(Context::variable_offset(variable->index())); |
2649 } else { | 2680 } else { |
2650 Value* value = Pop(); | 2681 Value* value = Pop(); |
2682 // Do approximately as in EffectGraphVisitor::VisitStoreLocalNode. | |
Kevin Millikin (Google)
2017/01/24 13:44:13
Again, this comment isn't useful.
This seems some
jensj
2017/01/25 12:52:22
I will remove the comment.
I would suggest going
| |
2683 if (FLAG_support_debugger && position.IsDebugPause() && | |
2684 !variable->IsInternal()) { | |
2685 if (value->definition()->IsConstant() || | |
2686 value->definition()->IsAllocateObject() || | |
2687 (value->definition()->IsLoadLocal() && | |
2688 !value->definition()->AsLoadLocal()->local().IsInternal())) { | |
2689 instructions <<= new (Z) | |
2690 DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall); | |
2691 } | |
2692 } | |
2693 | |
2651 StoreLocalInstr* store = | 2694 StoreLocalInstr* store = |
2652 new (Z) StoreLocalInstr(*variable, value, position); | 2695 new (Z) StoreLocalInstr(*variable, value, position); |
2653 instructions <<= store; | 2696 instructions <<= store; |
2654 Push(store); | 2697 Push(store); |
2655 } | 2698 } |
2656 return instructions; | 2699 return instructions; |
2657 } | 2700 } |
2658 | 2701 |
2659 | 2702 |
2660 Fragment FlowGraphBuilder::StoreStaticField(const dart::Field& field) { | 2703 Fragment FlowGraphBuilder::StoreStaticField(const dart::Field& field) { |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3154 | 3197 |
3155 // False branch will contain the next comparison. | 3198 // False branch will contain the next comparison. |
3156 dispatch = Fragment(dispatch.entry, otherwise); | 3199 dispatch = Fragment(dispatch.entry, otherwise); |
3157 block = otherwise; | 3200 block = otherwise; |
3158 } | 3201 } |
3159 body = dispatch; | 3202 body = dispatch; |
3160 | 3203 |
3161 context_depth_ = current_context_depth; | 3204 context_depth_ = current_context_depth; |
3162 } | 3205 } |
3163 | 3206 |
3207 if (FLAG_support_debugger && function->position().IsDebugPause() && | |
3208 !dart_function.is_native() && dart_function.is_debuggable()) { | |
3209 // If a switch was added above: Start the switch by injecting a debugable | |
3210 // safepoint so stepping over an await works. | |
3211 // If not, still start the body with a debugable safepoint to ensure | |
3212 // breaking on a method always happens, even if there are no | |
3213 // assignments/calls/runtimecalls in the first basic block. | |
3214 // Place this check at the last parameter to ensure parameters | |
3215 // are in scope in the debugger at method entry. | |
3216 // Basically copied from EffectGraphVisitor::VisitSequenceNode. | |
3217 Fragment dispatch; | |
3218 const int num_params = dart_function.NumParameters(); | |
3219 TokenPosition check_pos = TokenPosition::kNoSource; | |
3220 if (num_params > 0) { | |
3221 LocalScope* scope = parsed_function_->node_sequence()->scope(); | |
3222 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | |
3223 check_pos = parameter.token_pos(); | |
3224 } | |
3225 if (!check_pos.IsDebugPause()) { | |
3226 // No parameters or synthetic parameters. | |
3227 check_pos = function->position(); | |
3228 ASSERT(check_pos.IsDebugPause()); | |
3229 } | |
3230 dispatch <<= | |
Kevin Millikin (Google)
2017/01/24 13:44:13
I'm not sure why this is called dispatch. I don't
jensj
2017/01/25 12:52:22
Done.
| |
3231 new (Z) DebugStepCheckInstr(check_pos, RawPcDescriptors::kRuntimeCall); | |
3232 dispatch.entry->LinkTo(body.entry); | |
3233 body = dispatch; | |
3234 } | |
3235 | |
3164 normal_entry->LinkTo(body.entry); | 3236 normal_entry->LinkTo(body.entry); |
3165 | 3237 |
3166 // When compiling for OSR, use a depth first search to prune instructions | 3238 // When compiling for OSR, use a depth first search to prune instructions |
3167 // unreachable from the OSR entry. Catch entries are always considered | 3239 // unreachable from the OSR entry. Catch entries are always considered |
3168 // reachable, even if they become unreachable after OSR. | 3240 // reachable, even if they become unreachable after OSR. |
3169 if (osr_id_ != Compiler::kNoOSRDeoptId) { | 3241 if (osr_id_ != Compiler::kNoOSRDeoptId) { |
3170 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); | 3242 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); |
3171 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, | 3243 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, |
3172 block_marks); | 3244 block_marks); |
3173 ASSERT(found); | 3245 ASSERT(found); |
(...skipping 2739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5913 instructions += LoadLocal(parsed_function_->current_context_var()); | 5985 instructions += LoadLocal(parsed_function_->current_context_var()); |
5914 instructions += StoreInstanceField(Closure::context_offset()); | 5986 instructions += StoreInstanceField(Closure::context_offset()); |
5915 | 5987 |
5916 return instructions; | 5988 return instructions; |
5917 } | 5989 } |
5918 | 5990 |
5919 | 5991 |
5920 } // namespace kernel | 5992 } // namespace kernel |
5921 } // namespace dart | 5993 } // namespace dart |
5922 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 5994 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |