| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 4061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4072 LocalScope* scope = node->scope(); | 4072 LocalScope* scope = node->scope(); |
| 4073 const Function& function = owner()->function(); | 4073 const Function& function = owner()->function(); |
| 4074 const intptr_t num_context_variables = | 4074 const intptr_t num_context_variables = |
| 4075 (scope != NULL) ? scope->num_context_variables() : 0; | 4075 (scope != NULL) ? scope->num_context_variables() : 0; |
| 4076 const bool is_top_level_sequence = | 4076 const bool is_top_level_sequence = |
| 4077 node == owner()->parsed_function().node_sequence(); | 4077 node == owner()->parsed_function().node_sequence(); |
| 4078 // The outermost function sequence cannot contain a label. | 4078 // The outermost function sequence cannot contain a label. |
| 4079 ASSERT((node->label() == NULL) || !is_top_level_sequence); | 4079 ASSERT((node->label() == NULL) || !is_top_level_sequence); |
| 4080 NestedBlock nested_block(owner(), node); | 4080 NestedBlock nested_block(owner(), node); |
| 4081 | 4081 |
| 4082 if (FLAG_support_debugger && is_top_level_sequence) { | |
| 4083 AddInstruction(new(Z) DebugStepCheckInstr(function.token_pos(), | |
| 4084 RawPcDescriptors::kRuntimeCall)); | |
| 4085 } | |
| 4086 | |
| 4087 if (num_context_variables > 0) { | 4082 if (num_context_variables > 0) { |
| 4088 // The local scope declares variables that are captured. | 4083 // The local scope declares variables that are captured. |
| 4089 // Allocate and chain a new context (Except don't chain when at the function | 4084 // Allocate and chain a new context (Except don't chain when at the function |
| 4090 // entry if the function does not capture any variables from outer scopes). | 4085 // entry if the function does not capture any variables from outer scopes). |
| 4091 Value* allocated_context = | 4086 Value* allocated_context = |
| 4092 Bind(new(Z) AllocateContextInstr(node->token_pos(), | 4087 Bind(new(Z) AllocateContextInstr(node->token_pos(), |
| 4093 num_context_variables)); | 4088 num_context_variables)); |
| 4094 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); | 4089 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); |
| 4095 if (!is_top_level_sequence || HasContextScope()) { | 4090 if (!is_top_level_sequence || HasContextScope()) { |
| 4096 ASSERT(is_top_level_sequence || | 4091 ASSERT(is_top_level_sequence || |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4139 // allow GC of passed value if it gets overwritten by a new value in | 4134 // allow GC of passed value if it gets overwritten by a new value in |
| 4140 // the function. | 4135 // the function. |
| 4141 Value* null_constant = Bind(new(Z) ConstantInstr( | 4136 Value* null_constant = Bind(new(Z) ConstantInstr( |
| 4142 Object::ZoneHandle(Z, Object::null()))); | 4137 Object::ZoneHandle(Z, Object::null()))); |
| 4143 Do(BuildStoreLocal(*temp_local, null_constant)); | 4138 Do(BuildStoreLocal(*temp_local, null_constant)); |
| 4144 } | 4139 } |
| 4145 } | 4140 } |
| 4146 } | 4141 } |
| 4147 } | 4142 } |
| 4148 | 4143 |
| 4144 if (FLAG_support_debugger && |
| 4145 is_top_level_sequence && |
| 4146 function.is_debuggable()) { |
| 4147 // Place a debug check at method entry to ensure breaking on a method always |
| 4148 // happens, even if there are no assignments/calls/runtimecalls in the first |
| 4149 // basic block. Place this check at the last parameter to ensure parameters |
| 4150 // are in scope in the debugger at method entry. |
| 4151 const int num_params = function.NumParameters(); |
| 4152 intptr_t check_pos = Scanner::kNoSourcePos; |
| 4153 if (num_params > 0) { |
| 4154 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
| 4155 check_pos = parameter.token_pos(); |
| 4156 } |
| 4157 if (check_pos == Scanner::kNoSourcePos) { |
| 4158 // No parameters or synthetic parameters. |
| 4159 check_pos = node->token_pos(); |
| 4160 } |
| 4161 AddInstruction(new(Z) DebugStepCheckInstr(check_pos, |
| 4162 RawPcDescriptors::kRuntimeCall)); |
| 4163 } |
| 4164 |
| 4149 // This check may be deleted if the generated code is leaf. | 4165 // This check may be deleted if the generated code is leaf. |
| 4150 // Native functions don't need a stack check at entry. | 4166 // Native functions don't need a stack check at entry. |
| 4151 if (is_top_level_sequence && !function.is_native()) { | 4167 if (is_top_level_sequence && !function.is_native()) { |
| 4152 // Always allocate CheckOverflowInstr so that deopt-ids match regardless | 4168 // Always allocate CheckOverflowInstr so that deopt-ids match regardless |
| 4153 // if we inline or not. | 4169 // if we inline or not. |
| 4154 if (!function.IsImplicitGetterFunction() && | 4170 if (!function.IsImplicitGetterFunction() && |
| 4155 !function.IsImplicitSetterFunction()) { | 4171 !function.IsImplicitSetterFunction()) { |
| 4156 CheckStackOverflowInstr* check = | 4172 CheckStackOverflowInstr* check = |
| 4157 new(Z) CheckStackOverflowInstr(function.token_pos(), 0); | 4173 new(Z) CheckStackOverflowInstr(function.token_pos(), 0); |
| 4158 // If we are inlining don't actually attach the stack check. We must still | 4174 // If we are inlining don't actually attach the stack check. We must still |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4678 Report::MessageF(Report::kBailout, | 4694 Report::MessageF(Report::kBailout, |
| 4679 Script::Handle(function.script()), | 4695 Script::Handle(function.script()), |
| 4680 function.token_pos(), | 4696 function.token_pos(), |
| 4681 "FlowGraphBuilder Bailout: %s %s", | 4697 "FlowGraphBuilder Bailout: %s %s", |
| 4682 String::Handle(function.name()).ToCString(), | 4698 String::Handle(function.name()).ToCString(), |
| 4683 reason); | 4699 reason); |
| 4684 UNREACHABLE(); | 4700 UNREACHABLE(); |
| 4685 } | 4701 } |
| 4686 | 4702 |
| 4687 } // namespace dart | 4703 } // namespace dart |
| OLD | NEW |