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 <set> | 5 #include <set> |
6 | 6 |
7 #include "vm/kernel_to_il.h" | 7 #include "vm/kernel_to_il.h" |
8 | 8 |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/intermediate_language.h" | 10 #include "vm/intermediate_language.h" |
(...skipping 1995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2006 H.ReportError(Error::Cast(result), "error evaluating constant constructor"); | 2006 H.ReportError(Error::Cast(result), "error evaluating constant constructor"); |
2007 } | 2007 } |
2008 return result; | 2008 return result; |
2009 } | 2009 } |
2010 | 2010 |
2011 | 2011 |
2012 FlowGraphBuilder::FlowGraphBuilder( | 2012 FlowGraphBuilder::FlowGraphBuilder( |
2013 TreeNode* node, | 2013 TreeNode* node, |
2014 ParsedFunction* parsed_function, | 2014 ParsedFunction* parsed_function, |
2015 const ZoneGrowableArray<const ICData*>& ic_data_array, | 2015 const ZoneGrowableArray<const ICData*>& ic_data_array, |
| 2016 ZoneGrowableArray<intptr_t>* context_level_array, |
2016 InlineExitCollector* exit_collector, | 2017 InlineExitCollector* exit_collector, |
2017 intptr_t osr_id, | 2018 intptr_t osr_id, |
2018 intptr_t first_block_id) | 2019 intptr_t first_block_id) |
2019 : translation_helper_(Thread::Current()), | 2020 : translation_helper_(Thread::Current()), |
2020 thread_(translation_helper_.thread()), | 2021 thread_(translation_helper_.thread()), |
2021 zone_(translation_helper_.zone()), | 2022 zone_(translation_helper_.zone()), |
2022 node_(node), | 2023 node_(node), |
2023 parsed_function_(parsed_function), | 2024 parsed_function_(parsed_function), |
2024 osr_id_(osr_id), | 2025 osr_id_(osr_id), |
2025 ic_data_array_(ic_data_array), | 2026 ic_data_array_(ic_data_array), |
| 2027 context_level_array_(context_level_array), |
2026 exit_collector_(exit_collector), | 2028 exit_collector_(exit_collector), |
2027 next_block_id_(first_block_id), | 2029 next_block_id_(first_block_id), |
2028 next_function_id_(0), | 2030 next_function_id_(0), |
2029 context_depth_(0), | 2031 context_depth_(0), |
2030 loop_depth_(0), | 2032 loop_depth_(0), |
2031 try_depth_(0), | 2033 try_depth_(0), |
2032 catch_depth_(0), | 2034 catch_depth_(0), |
2033 for_in_depth_(0), | 2035 for_in_depth_(0), |
2034 stack_(NULL), | 2036 stack_(NULL), |
2035 pending_argument_count_(0), | 2037 pending_argument_count_(0), |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2411 bool needs_stacktrace) { | 2413 bool needs_stacktrace) { |
2412 ASSERT(CurrentException()->is_captured() == | 2414 ASSERT(CurrentException()->is_captured() == |
2413 CurrentStackTrace()->is_captured()); | 2415 CurrentStackTrace()->is_captured()); |
2414 const bool should_restore_closure_context = | 2416 const bool should_restore_closure_context = |
2415 CurrentException()->is_captured() || CurrentCatchContext()->is_captured(); | 2417 CurrentException()->is_captured() || CurrentCatchContext()->is_captured(); |
2416 CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr( | 2418 CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr( |
2417 TokenPosition::kNoSource, // Token position of catch block. | 2419 TokenPosition::kNoSource, // Token position of catch block. |
2418 false, // Not an artifact of compilation. | 2420 false, // Not an artifact of compilation. |
2419 AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types, | 2421 AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types, |
2420 handler_index, *CurrentException(), *CurrentStackTrace(), | 2422 handler_index, *CurrentException(), *CurrentStackTrace(), |
2421 needs_stacktrace, H.thread()->GetNextDeoptId(), | 2423 needs_stacktrace, GetNextDeoptId(), should_restore_closure_context); |
2422 should_restore_closure_context); | |
2423 graph_entry_->AddCatchEntry(entry); | 2424 graph_entry_->AddCatchEntry(entry); |
2424 Fragment instructions(entry); | 2425 Fragment instructions(entry); |
2425 | 2426 |
2426 // :saved_try_context_var can be captured in the context of | 2427 // :saved_try_context_var can be captured in the context of |
2427 // of the closure, in this case CatchBlockEntryInstr restores | 2428 // of the closure, in this case CatchBlockEntryInstr restores |
2428 // :current_context_var to point to closure context in the | 2429 // :current_context_var to point to closure context in the |
2429 // same way as normal function prologue does. | 2430 // same way as normal function prologue does. |
2430 // Update current context depth to reflect that. | 2431 // Update current context depth to reflect that. |
2431 const intptr_t saved_context_depth = context_depth_; | 2432 const intptr_t saved_context_depth = context_depth_; |
2432 ASSERT(!CurrentCatchContext()->is_captured() || | 2433 ASSERT(!CurrentCatchContext()->is_captured() || |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2828 | 2829 |
2829 | 2830 |
2830 Fragment FlowGraphBuilder::StoreInstanceFieldGuarded( | 2831 Fragment FlowGraphBuilder::StoreInstanceFieldGuarded( |
2831 const dart::Field& field, | 2832 const dart::Field& field, |
2832 bool is_initialization_store) { | 2833 bool is_initialization_store) { |
2833 Fragment instructions; | 2834 Fragment instructions; |
2834 const dart::Field& field_clone = MayCloneField(Z, field); | 2835 const dart::Field& field_clone = MayCloneField(Z, field); |
2835 if (I->use_field_guards()) { | 2836 if (I->use_field_guards()) { |
2836 LocalVariable* store_expression = MakeTemporary(); | 2837 LocalVariable* store_expression = MakeTemporary(); |
2837 instructions += LoadLocal(store_expression); | 2838 instructions += LoadLocal(store_expression); |
2838 instructions += GuardFieldClass(field_clone, H.thread()->GetNextDeoptId()); | 2839 instructions += GuardFieldClass(field_clone, GetNextDeoptId()); |
2839 instructions += LoadLocal(store_expression); | 2840 instructions += LoadLocal(store_expression); |
2840 instructions += GuardFieldLength(field_clone, H.thread()->GetNextDeoptId()); | 2841 instructions += GuardFieldLength(field_clone, GetNextDeoptId()); |
2841 } | 2842 } |
2842 instructions += StoreInstanceField(field_clone, is_initialization_store); | 2843 instructions += StoreInstanceField(field_clone, is_initialization_store); |
2843 return instructions; | 2844 return instructions; |
2844 } | 2845 } |
2845 | 2846 |
2846 | 2847 |
2847 Fragment FlowGraphBuilder::StoreInstanceField( | 2848 Fragment FlowGraphBuilder::StoreInstanceField( |
2848 TokenPosition position, | 2849 TokenPosition position, |
2849 intptr_t offset, | 2850 intptr_t offset, |
2850 StoreBarrierType emit_store_barrier) { | 2851 StoreBarrierType emit_store_barrier) { |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3504 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); | 3505 scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); |
3505 ASSERT((async_stack_trace_var != NULL) && | 3506 ASSERT((async_stack_trace_var != NULL) && |
3506 async_stack_trace_var->is_captured()); | 3507 async_stack_trace_var->is_captured()); |
3507 instructions += LoadLocal(async_stack_trace_var); | 3508 instructions += LoadLocal(async_stack_trace_var); |
3508 instructions += PushArgument(); | 3509 instructions += PushArgument(); |
3509 | 3510 |
3510 // Call _asyncSetThreadStackTrace | 3511 // Call _asyncSetThreadStackTrace |
3511 instructions += StaticCall(TokenPosition::kNoSource, target, 1); | 3512 instructions += StaticCall(TokenPosition::kNoSource, target, 1); |
3512 instructions += Drop(); | 3513 instructions += Drop(); |
3513 | 3514 |
| 3515 // TODO(29737): This sequence should be generated in order. |
3514 body = instructions + body; | 3516 body = instructions + body; |
3515 context_depth_ = current_context_depth; | 3517 context_depth_ = current_context_depth; |
3516 } | 3518 } |
3517 | 3519 |
3518 if (NeedsDebugStepCheck(dart_function, function->position())) { | 3520 if (NeedsDebugStepCheck(dart_function, function->position())) { |
| 3521 const intptr_t current_context_depth = context_depth_; |
| 3522 context_depth_ = 0; |
| 3523 |
3519 // If a switch was added above: Start the switch by injecting a debuggable | 3524 // If a switch was added above: Start the switch by injecting a debuggable |
3520 // safepoint so stepping over an await works. | 3525 // safepoint so stepping over an await works. |
3521 // If not, still start the body with a debuggable safepoint to ensure | 3526 // If not, still start the body with a debuggable safepoint to ensure |
3522 // breaking on a method always happens, even if there are no | 3527 // breaking on a method always happens, even if there are no |
3523 // assignments/calls/runtimecalls in the first basic block. | 3528 // assignments/calls/runtimecalls in the first basic block. |
3524 // Place this check at the last parameter to ensure parameters | 3529 // Place this check at the last parameter to ensure parameters |
3525 // are in scope in the debugger at method entry. | 3530 // are in scope in the debugger at method entry. |
3526 const int num_params = dart_function.NumParameters(); | 3531 const int num_params = dart_function.NumParameters(); |
3527 TokenPosition check_pos = TokenPosition::kNoSource; | 3532 TokenPosition check_pos = TokenPosition::kNoSource; |
3528 if (num_params > 0) { | 3533 if (num_params > 0) { |
3529 LocalScope* scope = parsed_function_->node_sequence()->scope(); | 3534 LocalScope* scope = parsed_function_->node_sequence()->scope(); |
3530 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 3535 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
3531 check_pos = parameter.token_pos(); | 3536 check_pos = parameter.token_pos(); |
3532 } | 3537 } |
3533 if (!check_pos.IsDebugPause()) { | 3538 if (!check_pos.IsDebugPause()) { |
3534 // No parameters or synthetic parameters. | 3539 // No parameters or synthetic parameters. |
3535 check_pos = function->position(); | 3540 check_pos = function->position(); |
3536 ASSERT(check_pos.IsDebugPause()); | 3541 ASSERT(check_pos.IsDebugPause()); |
3537 } | 3542 } |
| 3543 |
| 3544 // TODO(29737): This sequence should be generated in order. |
3538 body = DebugStepCheck(check_pos) + body; | 3545 body = DebugStepCheck(check_pos) + body; |
| 3546 context_depth_ = current_context_depth; |
3539 } | 3547 } |
3540 | 3548 |
3541 normal_entry->LinkTo(body.entry); | 3549 normal_entry->LinkTo(body.entry); |
3542 | 3550 |
3543 // When compiling for OSR, use a depth first search to prune instructions | 3551 // When compiling for OSR, use a depth first search to prune instructions |
3544 // unreachable from the OSR entry. Catch entries are always considered | 3552 // unreachable from the OSR entry. Catch entries are always considered |
3545 // reachable, even if they become unreachable after OSR. | 3553 // reachable, even if they become unreachable after OSR. |
3546 if (osr_id_ != Compiler::kNoOSRDeoptId) { | 3554 if (osr_id_ != Compiler::kNoOSRDeoptId) { |
3547 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); | 3555 BitVector* block_marks = new (Z) BitVector(Z, next_block_id_); |
3548 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, | 3556 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3875 Definition* definition = value->definition(); | 3883 Definition* definition = value->definition(); |
3876 if (definition->IsConstant() || definition->IsLoadStaticField()) return true; | 3884 if (definition->IsConstant() || definition->IsLoadStaticField()) return true; |
3877 if (definition->IsAllocateObject()) { | 3885 if (definition->IsAllocateObject()) { |
3878 return !definition->AsAllocateObject()->closure_function().IsNull(); | 3886 return !definition->AsAllocateObject()->closure_function().IsNull(); |
3879 } | 3887 } |
3880 return definition->IsLoadLocal() && | 3888 return definition->IsLoadLocal() && |
3881 !definition->AsLoadLocal()->local().IsInternal(); | 3889 !definition->AsLoadLocal()->local().IsInternal(); |
3882 } | 3890 } |
3883 | 3891 |
3884 Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) { | 3892 Fragment FlowGraphBuilder::DebugStepCheck(TokenPosition position) { |
3885 return Fragment( | 3893 return Fragment(new (Z) DebugStepCheckInstr( |
3886 new (Z) DebugStepCheckInstr(position, RawPcDescriptors::kRuntimeCall)); | 3894 position, RawPcDescriptors::kRuntimeCall, GetNextDeoptId())); |
3887 } | 3895 } |
3888 | 3896 |
3889 | 3897 |
3890 Fragment FlowGraphBuilder::EvaluateAssertion() { | 3898 Fragment FlowGraphBuilder::EvaluateAssertion() { |
3891 const dart::Class& klass = dart::Class::ZoneHandle( | 3899 const dart::Class& klass = dart::Class::ZoneHandle( |
3892 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); | 3900 Z, dart::Library::LookupCoreClass(Symbols::AssertionError())); |
3893 ASSERT(!klass.IsNull()); | 3901 ASSERT(!klass.IsNull()); |
3894 const Function& target = | 3902 const Function& target = |
3895 Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( | 3903 Function::ZoneHandle(Z, klass.LookupStaticFunctionAllowPrivate( |
3896 H.DartSymbol("_evaluateAssertion"))); | 3904 H.DartSymbol("_evaluateAssertion"))); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3959 | 3967 |
3960 if (!dst_type.IsInstantiated(kFunctions)) { | 3968 if (!dst_type.IsInstantiated(kFunctions)) { |
3961 instructions += LoadFunctionTypeArguments(); | 3969 instructions += LoadFunctionTypeArguments(); |
3962 } else { | 3970 } else { |
3963 instructions += NullConstant(); | 3971 instructions += NullConstant(); |
3964 } | 3972 } |
3965 Value* function_type_args = Pop(); | 3973 Value* function_type_args = Pop(); |
3966 | 3974 |
3967 AssertAssignableInstr* instr = new (Z) AssertAssignableInstr( | 3975 AssertAssignableInstr* instr = new (Z) AssertAssignableInstr( |
3968 TokenPosition::kNoSource, value, instantiator_type_args, | 3976 TokenPosition::kNoSource, value, instantiator_type_args, |
3969 function_type_args, dst_type, dst_name, H.thread()->GetNextDeoptId()); | 3977 function_type_args, dst_type, dst_name, GetNextDeoptId()); |
3970 Push(instr); | 3978 Push(instr); |
3971 | 3979 |
3972 instructions += Fragment(instr); | 3980 instructions += Fragment(instr); |
3973 | 3981 |
3974 return instructions; | 3982 return instructions; |
3975 } | 3983 } |
3976 | 3984 |
3977 | 3985 |
3978 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( | 3986 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( |
3979 const Function& method) { | 3987 const Function& method) { |
(...skipping 2859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6839 thread->clear_sticky_error(); | 6847 thread->clear_sticky_error(); |
6840 return error.raw(); | 6848 return error.raw(); |
6841 } | 6849 } |
6842 } | 6850 } |
6843 | 6851 |
6844 | 6852 |
6845 } // namespace kernel | 6853 } // namespace kernel |
6846 } // namespace dart | 6854 } // namespace dart |
6847 | 6855 |
6848 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6856 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |