Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: runtime/vm/kernel_binary_flowgraph.cc

Issue 2931773005: [kernel] Delete most of the AST (Closed)
Patch Set: Review Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_reader.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "vm/kernel_binary_flowgraph.h" 5 #include "vm/kernel_binary_flowgraph.h"
6 6
7 #include "vm/compiler.h" 7 #include "vm/compiler.h"
8 #include "vm/longjump.h" 8 #include "vm/longjump.h"
9 #include "vm/object_store.h" 9 #include "vm/object_store.h"
10 10
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 // TODO(jensj): From kernel_binary.cc 811 // TODO(jensj): From kernel_binary.cc
812 // forinstmt->variable_->set_end_position(forinstmt->position_); 812 // forinstmt->variable_->set_end_position(forinstmt->position_);
813 ExitScope(position, builder_->reader_->max_position()); 813 ExitScope(position, builder_->reader_->max_position());
814 --depth_.loop_; 814 --depth_.loop_;
815 --depth_.for_in_; 815 --depth_.for_in_;
816 return; 816 return;
817 } 817 }
818 case kSwitchStatement: { 818 case kSwitchStatement: {
819 AddSwitchVariable(); 819 AddSwitchVariable();
820 VisitExpression(); // read condition. 820 VisitExpression(); // read condition.
821 int num_cases = builder_->ReadListLength(); // read number of cases. 821 int case_count = builder_->ReadListLength(); // read number of cases.
822 for (intptr_t i = 0; i < num_cases; ++i) { 822 for (intptr_t i = 0; i < case_count; ++i) {
823 int num_expressions = 823 int expression_count =
824 builder_->ReadListLength(); // read number of expressions. 824 builder_->ReadListLength(); // read number of expressions.
825 for (intptr_t j = 0; j < num_expressions; ++j) { 825 for (intptr_t j = 0; j < expression_count; ++j) {
826 builder_->ReadPosition(); // read jth position. 826 builder_->ReadPosition(); // read jth position.
827 VisitExpression(); // read jth expression. 827 VisitExpression(); // read jth expression.
828 } 828 }
829 builder_->ReadBool(); // read is_default. 829 builder_->ReadBool(); // read is_default.
830 VisitStatement(); // read body. 830 VisitStatement(); // read body.
831 } 831 }
832 return; 832 return;
833 } 833 }
834 case kContinueSwitchStatement: 834 case kContinueSwitchStatement:
835 builder_->ReadUInt(); // read target_index. 835 builder_->ReadUInt(); // read target_index.
(...skipping 24 matching lines...) Expand all
860 case kTryCatch: { 860 case kTryCatch: {
861 ++depth_.try_; 861 ++depth_.try_;
862 AddTryVariables(); 862 AddTryVariables();
863 VisitStatement(); // read body. 863 VisitStatement(); // read body.
864 --depth_.try_; 864 --depth_.try_;
865 865
866 ++depth_.catch_; 866 ++depth_.catch_;
867 AddCatchVariables(); 867 AddCatchVariables();
868 868
869 builder_->ReadBool(); // read any_catch_needs_stack_trace. 869 builder_->ReadBool(); // read any_catch_needs_stack_trace.
870 intptr_t num_catches = 870 intptr_t catch_count =
871 builder_->ReadListLength(); // read number of catches. 871 builder_->ReadListLength(); // read number of catches.
872 for (intptr_t i = 0; i < num_catches; ++i) { 872 for (intptr_t i = 0; i < catch_count; ++i) {
873 PositionScope scope(builder_->reader_); 873 PositionScope scope(builder_->reader_);
874 intptr_t offset = builder_->ReaderOffset(); // Catch has no tag. 874 intptr_t offset = builder_->ReaderOffset(); // Catch has no tag.
875 875
876 EnterScope(offset); 876 EnterScope(offset);
877 877
878 VisitDartType(); // Read the guard. 878 VisitDartType(); // Read the guard.
879 tag = builder_->ReadTag(); // read first part of exception. 879 tag = builder_->ReadTag(); // read first part of exception.
880 if (tag == kSomething) { 880 if (tag == kSomething) {
881 VisitVariableDeclaration(); // read exception. 881 VisitVariableDeclaration(); // read exception.
882 } 882 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 VisitVariableDeclaration(); // read variable declaration. 937 VisitVariableDeclaration(); // read variable declaration.
938 HandleLocalFunction(offset); // read function node. 938 HandleLocalFunction(offset); // read function node.
939 return; 939 return;
940 } 940 }
941 default: 941 default:
942 UNREACHABLE(); 942 UNREACHABLE();
943 } 943 }
944 } 944 }
945 945
946 void StreamingScopeBuilder::VisitArguments() { 946 void StreamingScopeBuilder::VisitArguments() {
947 builder_->ReadUInt(); // read num_arguments. 947 builder_->ReadUInt(); // read argument_count.
948 948
949 // Types 949 // Types
950 intptr_t list_length = builder_->ReadListLength(); // read list length. 950 intptr_t list_length = builder_->ReadListLength(); // read list length.
951 for (intptr_t i = 0; i < list_length; ++i) { 951 for (intptr_t i = 0; i < list_length; ++i) {
952 VisitDartType(); // read ith type. 952 VisitDartType(); // read ith type.
953 } 953 }
954 954
955 // Positional. 955 // Positional.
956 list_length = builder_->ReadListLength(); // read list length. 956 list_length = builder_->ReadListLength(); // read list length.
957 for (intptr_t i = 0; i < list_length; ++i) { 957 for (intptr_t i = 0; i < list_length; ++i) {
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after
2346 RawObject* StreamingConstantEvaluator::EvaluateConstConstructorCall( 2346 RawObject* StreamingConstantEvaluator::EvaluateConstConstructorCall(
2347 const dart::Class& type_class, 2347 const dart::Class& type_class,
2348 const TypeArguments& type_arguments, 2348 const TypeArguments& type_arguments,
2349 const Function& constructor, 2349 const Function& constructor,
2350 const Object& argument) { 2350 const Object& argument) {
2351 // Factories have one extra argument: the type arguments. 2351 // Factories have one extra argument: the type arguments.
2352 // Constructors have 1 extra arguments: receiver. 2352 // Constructors have 1 extra arguments: receiver.
2353 const int kTypeArgsLen = 0; 2353 const int kTypeArgsLen = 0;
2354 const int kNumArgs = 1; 2354 const int kNumArgs = 1;
2355 const int kNumExtraArgs = 1; 2355 const int kNumExtraArgs = 1;
2356 const int num_arguments = kNumArgs + kNumExtraArgs; 2356 const int argument_count = kNumArgs + kNumExtraArgs;
2357 const Array& arg_values = 2357 const Array& arg_values =
2358 Array::Handle(Z, Array::New(num_arguments, Heap::kOld)); 2358 Array::Handle(Z, Array::New(argument_count, Heap::kOld));
2359 Instance& instance = Instance::Handle(Z); 2359 Instance& instance = Instance::Handle(Z);
2360 if (!constructor.IsFactory()) { 2360 if (!constructor.IsFactory()) {
2361 instance = Instance::New(type_class, Heap::kOld); 2361 instance = Instance::New(type_class, Heap::kOld);
2362 if (!type_arguments.IsNull()) { 2362 if (!type_arguments.IsNull()) {
2363 ASSERT(type_arguments.IsInstantiated()); 2363 ASSERT(type_arguments.IsInstantiated());
2364 instance.SetTypeArguments( 2364 instance.SetTypeArguments(
2365 TypeArguments::Handle(Z, type_arguments.Canonicalize())); 2365 TypeArguments::Handle(Z, type_arguments.Canonicalize()));
2366 } 2366 }
2367 arg_values.SetAt(0, instance); 2367 arg_values.SetAt(0, instance);
2368 } else { 2368 } else {
2369 // Prepend type_arguments to list of arguments to factory. 2369 // Prepend type_arguments to list of arguments to factory.
2370 ASSERT(type_arguments.IsZoneHandle()); 2370 ASSERT(type_arguments.IsZoneHandle());
2371 arg_values.SetAt(0, type_arguments); 2371 arg_values.SetAt(0, type_arguments);
2372 } 2372 }
2373 arg_values.SetAt((0 + kNumExtraArgs), argument); 2373 arg_values.SetAt((0 + kNumExtraArgs), argument);
2374 const Array& args_descriptor = 2374 const Array& args_descriptor =
2375 Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, num_arguments, 2375 Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, argument_count,
2376 Object::empty_array())); 2376 Object::empty_array()));
2377 const Object& result = Object::Handle( 2377 const Object& result = Object::Handle(
2378 Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor)); 2378 Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor));
2379 ASSERT(!result.IsError()); 2379 ASSERT(!result.IsError());
2380 if (constructor.IsFactory()) { 2380 if (constructor.IsFactory()) {
2381 // The factory method returns the allocated object. 2381 // The factory method returns the allocated object.
2382 instance ^= result.raw(); 2382 instance ^= result.raw();
2383 } 2383 }
2384 return H.Canonicalize(instance); 2384 return H.Canonicalize(instance);
2385 } 2385 }
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
2671 body += LoadStaticField(); 2671 body += LoadStaticField();
2672 } 2672 }
2673 body += Return(TokenPosition::kNoSource); 2673 body += Return(TokenPosition::kNoSource);
2674 2674
2675 return new (Z) 2675 return new (Z)
2676 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, 2676 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
2677 flow_graph_builder_->next_block_id_ - 1); 2677 flow_graph_builder_->next_block_id_ - 1);
2678 } 2678 }
2679 2679
2680 void StreamingFlowGraphBuilder::SetupDefaultParameterValues() { 2680 void StreamingFlowGraphBuilder::SetupDefaultParameterValues() {
2681 intptr_t num_optional_parameters = 2681 intptr_t optional_parameter_count =
2682 parsed_function()->function().NumOptionalParameters(); 2682 parsed_function()->function().NumOptionalParameters();
2683 if (num_optional_parameters > 0) { 2683 if (optional_parameter_count > 0) {
2684 ZoneGrowableArray<const Instance*>* default_values = 2684 ZoneGrowableArray<const Instance*>* default_values =
2685 new ZoneGrowableArray<const Instance*>(Z, num_optional_parameters); 2685 new ZoneGrowableArray<const Instance*>(Z, optional_parameter_count);
2686 2686
2687 AlternativeReadingScope alt(reader_); 2687 AlternativeReadingScope alt(reader_);
2688 FunctionNodeHelper function_node_helper(this); 2688 FunctionNodeHelper function_node_helper(this);
2689 function_node_helper.ReadUntilExcluding( 2689 function_node_helper.ReadUntilExcluding(
2690 FunctionNodeHelper::kPositionalParameters); 2690 FunctionNodeHelper::kPositionalParameters);
2691 2691
2692 if (parsed_function()->function().HasOptionalNamedParameters()) { 2692 if (parsed_function()->function().HasOptionalNamedParameters()) {
2693 // List of positional. 2693 // List of positional.
2694 intptr_t list_length = ReadListLength(); // read list length. 2694 intptr_t list_length = ReadListLength(); // read list length.
2695 for (intptr_t i = 0; i < list_length; ++i) { 2695 for (intptr_t i = 0; i < list_length; ++i) {
2696 SkipVariableDeclaration(); // read ith variable declaration. 2696 SkipVariableDeclaration(); // read ith variable declaration.
2697 } 2697 }
2698 2698
2699 // List of named. 2699 // List of named.
2700 list_length = ReadListLength(); // read list length. 2700 list_length = ReadListLength(); // read list length.
2701 ASSERT(num_optional_parameters == list_length); 2701 ASSERT(optional_parameter_count == list_length);
2702 ASSERT(!parsed_function()->function().HasOptionalPositionalParameters()); 2702 ASSERT(!parsed_function()->function().HasOptionalPositionalParameters());
2703 for (intptr_t i = 0; i < list_length; ++i) { 2703 for (intptr_t i = 0; i < list_length; ++i) {
2704 Instance* default_value; 2704 Instance* default_value;
2705 2705
2706 // Read ith variable declaration 2706 // Read ith variable declaration
2707 VariableDeclarationHelper helper(this); 2707 VariableDeclarationHelper helper(this);
2708 helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); 2708 helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer);
2709 Tag tag = ReadTag(); // read (first part of) initializer. 2709 Tag tag = ReadTag(); // read (first part of) initializer.
2710 if (tag == kSomething) { 2710 if (tag == kSomething) {
2711 // this will (potentially) read the initializer, 2711 // this will (potentially) read the initializer,
2712 // but reset the position. 2712 // but reset the position.
2713 default_value = 2713 default_value =
2714 &constant_evaluator_.EvaluateExpression(ReaderOffset()); 2714 &constant_evaluator_.EvaluateExpression(ReaderOffset());
2715 SkipExpression(); // read (actual) initializer. 2715 SkipExpression(); // read (actual) initializer.
2716 } else { 2716 } else {
2717 default_value = &Instance::ZoneHandle(Z, Instance::null()); 2717 default_value = &Instance::ZoneHandle(Z, Instance::null());
2718 } 2718 }
2719 default_values->Add(default_value); 2719 default_values->Add(default_value);
2720 } 2720 }
2721 } else { 2721 } else {
2722 // List of positional. 2722 // List of positional.
2723 intptr_t list_length = ReadListLength(); // read list length. 2723 intptr_t list_length = ReadListLength(); // read list length.
2724 ASSERT(list_length == function_node_helper.required_parameter_count_ + 2724 ASSERT(list_length == function_node_helper.required_parameter_count_ +
2725 num_optional_parameters); 2725 optional_parameter_count);
2726 ASSERT(parsed_function()->function().HasOptionalPositionalParameters()); 2726 ASSERT(parsed_function()->function().HasOptionalPositionalParameters());
2727 for (intptr_t i = 0; i < function_node_helper.required_parameter_count_; 2727 for (intptr_t i = 0; i < function_node_helper.required_parameter_count_;
2728 ++i) { 2728 ++i) {
2729 SkipVariableDeclaration(); // read ith variable declaration. 2729 SkipVariableDeclaration(); // read ith variable declaration.
2730 } 2730 }
2731 for (intptr_t i = 0; i < num_optional_parameters; ++i) { 2731 for (intptr_t i = 0; i < optional_parameter_count; ++i) {
2732 Instance* default_value; 2732 Instance* default_value;
2733 2733
2734 // Read ith variable declaration 2734 // Read ith variable declaration
2735 VariableDeclarationHelper helper(this); 2735 VariableDeclarationHelper helper(this);
2736 helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); 2736 helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer);
2737 Tag tag = ReadTag(); // read (first part of) initializer. 2737 Tag tag = ReadTag(); // read (first part of) initializer.
2738 if (tag == kSomething) { 2738 if (tag == kSomething) {
2739 // this will (potentially) read the initializer, 2739 // this will (potentially) read the initializer,
2740 // but reset the position. 2740 // but reset the position.
2741 default_value = 2741 default_value =
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
2987 argument_names); 2987 argument_names);
2988 2988
2989 // Return the result. 2989 // Return the result.
2990 body += Return(function_node_helper.end_position_); 2990 body += Return(function_node_helper.end_position_);
2991 2991
2992 return new (Z) 2992 return new (Z)
2993 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, 2993 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
2994 flow_graph_builder_->next_block_id_ - 1); 2994 flow_graph_builder_->next_block_id_ - 1);
2995 } 2995 }
2996 2996
2997 static bool IsGetMainClosure(const String& name) {
2998 if (name.Length() < 16) return false;
2999 const char* cstr = "_getMainClosure@";
3000 for (intptr_t i = 0; i < 16; ++i) {
3001 if (name.CharAt(i) != cstr[i]) return false;
3002 }
3003 return true;
3004 }
3005
3006 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction( 2997 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(
3007 bool is_in_builtin_library_toplevel,
3008 intptr_t constructor_class_parent_offset) { 2998 intptr_t constructor_class_parent_offset) {
3009 const Function& dart_function = parsed_function()->function(); 2999 const Function& dart_function = parsed_function()->function();
3010 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); 3000 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
3011 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( 3001 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
3012 *parsed_function(), normal_entry, flow_graph_builder_->osr_id_); 3002 *parsed_function(), normal_entry, flow_graph_builder_->osr_id_);
3013 3003
3014 SetupDefaultParameterValues(); 3004 SetupDefaultParameterValues();
3015 3005
3016 Fragment body; 3006 Fragment body;
3017 if (!dart_function.is_native()) 3007 if (!dart_function.is_native())
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
3159 body += StoreLocal(TokenPosition::kNoSource, async_stack_trace_var); 3149 body += StoreLocal(TokenPosition::kNoSource, async_stack_trace_var);
3160 body += Drop(); 3150 body += Drop();
3161 } 3151 }
3162 3152
3163 bool has_body = ReadTag() == kSomething; // read first part of body. 3153 bool has_body = ReadTag() == kSomething; // read first part of body.
3164 3154
3165 if (dart_function.is_native()) { 3155 if (dart_function.is_native()) {
3166 body += flow_graph_builder_->NativeFunctionBody(first_parameter_offset, 3156 body += flow_graph_builder_->NativeFunctionBody(first_parameter_offset,
3167 dart_function); 3157 dart_function);
3168 } else if (has_body) { 3158 } else if (has_body) {
3169 if (is_in_builtin_library_toplevel && 3159 body += BuildStatement(); // read body.
3170 IsGetMainClosure(dart::String::Handle(Z, dart_function.name()))) {
3171 body += BuildGetMainClosure();
3172 } else {
3173 body += BuildStatement(); // read body.
3174 }
3175 } 3160 }
3176 if (body.is_open()) { 3161 if (body.is_open()) {
3177 body += NullConstant(); 3162 body += NullConstant();
3178 body += Return(dart_function.end_token_pos()); 3163 body += Return(dart_function.end_token_pos());
3179 } 3164 }
3180 3165
3181 // If functions body contains any yield points build switch statement that 3166 // If functions body contains any yield points build switch statement that
3182 // selects a continuation point based on the value of :await_jump_var. 3167 // selects a continuation point based on the value of :await_jump_var.
3183 if (!yield_continuations().is_empty()) { 3168 if (!yield_continuations().is_empty()) {
3184 // The code we are building will be executed right after we enter 3169 // The code we are building will be executed right after we enter
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3286 if (NeedsDebugStepCheck(dart_function, function_node_helper.position_)) { 3271 if (NeedsDebugStepCheck(dart_function, function_node_helper.position_)) {
3287 const intptr_t current_context_depth = flow_graph_builder_->context_depth_; 3272 const intptr_t current_context_depth = flow_graph_builder_->context_depth_;
3288 flow_graph_builder_->context_depth_ = 0; 3273 flow_graph_builder_->context_depth_ = 0;
3289 // If a switch was added above: Start the switch by injecting a debuggable 3274 // If a switch was added above: Start the switch by injecting a debuggable
3290 // safepoint so stepping over an await works. 3275 // safepoint so stepping over an await works.
3291 // If not, still start the body with a debuggable safepoint to ensure 3276 // If not, still start the body with a debuggable safepoint to ensure
3292 // breaking on a method always happens, even if there are no 3277 // breaking on a method always happens, even if there are no
3293 // assignments/calls/runtimecalls in the first basic block. 3278 // assignments/calls/runtimecalls in the first basic block.
3294 // Place this check at the last parameter to ensure parameters 3279 // Place this check at the last parameter to ensure parameters
3295 // are in scope in the debugger at method entry. 3280 // are in scope in the debugger at method entry.
3296 const int num_params = dart_function.NumParameters(); 3281 const int parameter_count = dart_function.NumParameters();
3297 TokenPosition check_pos = TokenPosition::kNoSource; 3282 TokenPosition check_pos = TokenPosition::kNoSource;
3298 if (num_params > 0) { 3283 if (parameter_count > 0) {
3299 LocalScope* scope = parsed_function()->node_sequence()->scope(); 3284 LocalScope* scope = parsed_function()->node_sequence()->scope();
3300 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); 3285 const LocalVariable& parameter = *scope->VariableAt(parameter_count - 1);
3301 check_pos = parameter.token_pos(); 3286 check_pos = parameter.token_pos();
3302 } 3287 }
3303 if (!check_pos.IsDebugPause()) { 3288 if (!check_pos.IsDebugPause()) {
3304 // No parameters or synthetic parameters. 3289 // No parameters or synthetic parameters.
3305 check_pos = function_node_helper.position_; 3290 check_pos = function_node_helper.position_;
3306 ASSERT(check_pos.IsDebugPause()); 3291 ASSERT(check_pos.IsDebugPause());
3307 } 3292 }
3308 3293
3309 // TODO(29737): This sequence should be generated in order. 3294 // TODO(29737): This sequence should be generated in order.
3310 body = DebugStepCheck(check_pos) + body; 3295 body = DebugStepCheck(check_pos) + body;
3311 flow_graph_builder_->context_depth_ = current_context_depth; 3296 flow_graph_builder_->context_depth_ = current_context_depth;
3312 } 3297 }
3313 3298
3314 normal_entry->LinkTo(body.entry); 3299 normal_entry->LinkTo(body.entry);
3315 3300
3316 GraphEntryInstr* graph_entry = flow_graph_builder_->graph_entry_; 3301 GraphEntryInstr* graph_entry = flow_graph_builder_->graph_entry_;
3317 // When compiling for OSR, use a depth first search to find the OSR 3302 // When compiling for OSR, use a depth first search to find the OSR
3318 // entry and make graph entry jump to it instead of normal entry. 3303 // entry and make graph entry jump to it instead of normal entry.
3319 // Catch entries are always considered reachable, even if they 3304 // Catch entries are always considered reachable, even if they
3320 // become unreachable after OSR. 3305 // become unreachable after OSR.
3321 if (flow_graph_builder_->osr_id_ != Compiler::kNoOSRDeoptId) { 3306 if (flow_graph_builder_->osr_id_ != Compiler::kNoOSRDeoptId) {
3322 graph_entry->RelinkToOsrEntry(Z, flow_graph_builder_->next_block_id_); 3307 graph_entry->RelinkToOsrEntry(Z, flow_graph_builder_->next_block_id_);
3323 } 3308 }
3324 return new (Z) FlowGraph(*parsed_function(), graph_entry, 3309 return new (Z) FlowGraph(*parsed_function(), graph_entry,
3325 flow_graph_builder_->next_block_id_ - 1); 3310 flow_graph_builder_->next_block_id_ - 1);
3326 } 3311 }
3327 3312
3328 Fragment StreamingFlowGraphBuilder::BuildGetMainClosure() {
3329 // _getMainClosure in dart:_builtin. Compile that one specially here.
3330 const dart::Library& builtin =
3331 dart::Library::Handle(Z, I->object_store()->builtin_library());
3332 const Object& main =
3333 Object::Handle(Z, builtin.LookupObjectAllowPrivate(dart::String::Handle(
3334 Z, dart::String::New("main"))));
3335 if (main.IsField()) {
3336 UNIMPLEMENTED();
3337 } else if (main.IsFunction()) {
3338 const Function& function = Function::Cast(main);
3339 if (function.kind() == RawFunction::kRegularFunction) {
3340 const Function& closure_function =
3341 Function::Handle(Z, function.ImplicitClosureFunction());
3342 const Instance& closure =
3343 Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure());
3344 Fragment instructions = Constant(closure);
3345 instructions += Return(TokenPosition::kNoSource);
3346 return instructions;
3347 } else {
3348 UNIMPLEMENTED();
3349 }
3350 } else {
3351 UNIMPLEMENTED();
3352 }
3353 return Fragment();
3354 }
3355
3356 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) { 3313 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) {
3357 const Function& function = parsed_function()->function(); 3314 const Function& function = parsed_function()->function();
3358 3315
3359 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used 3316 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used
3360 // e.g. for type translation. 3317 // e.g. for type translation.
3361 const dart::Class& klass = 3318 const dart::Class& klass =
3362 dart::Class::Handle(zone_, parsed_function()->function().Owner()); 3319 dart::Class::Handle(zone_, parsed_function()->function().Owner());
3363 bool is_in_builtin_library_toplevel =
3364 klass.library() == I->object_store()->builtin_library() &&
3365 klass.IsTopLevel();
3366 3320
3367 Function& outermost_function = Function::Handle(Z); 3321 Function& outermost_function = Function::Handle(Z);
3368 intptr_t outermost_kernel_offset = -1; 3322 intptr_t outermost_kernel_offset = -1;
3369 intptr_t parent_class_offset = -1; 3323 intptr_t parent_class_offset = -1;
3370 DiscoverEnclosingElements(Z, function, &outermost_function, 3324 DiscoverEnclosingElements(Z, function, &outermost_function,
3371 &outermost_kernel_offset, &parent_class_offset); 3325 &outermost_kernel_offset, &parent_class_offset);
3372 // Use [klass]/[kernel_class] as active class. Type parameters will get 3326 // Use [klass]/[kernel_class] as active class. Type parameters will get
3373 // resolved via [kernel_class] unless we are nested inside a static factory 3327 // resolved via [kernel_class] unless we are nested inside a static factory
3374 // in which case we will use [member]. 3328 // in which case we will use [member].
3375 intptr_t class_type_parameters = 0; 3329 intptr_t class_type_parameters = 0;
(...skipping 29 matching lines...) Expand all
3405 SetOffset(kernel_offset); 3359 SetOffset(kernel_offset);
3406 3360
3407 switch (function.kind()) { 3361 switch (function.kind()) {
3408 case RawFunction::kClosureFunction: 3362 case RawFunction::kClosureFunction:
3409 case RawFunction::kRegularFunction: 3363 case RawFunction::kRegularFunction:
3410 case RawFunction::kGetterFunction: 3364 case RawFunction::kGetterFunction:
3411 case RawFunction::kSetterFunction: { 3365 case RawFunction::kSetterFunction: {
3412 ReadUntilFunctionNode(); // read until function node. 3366 ReadUntilFunctionNode(); // read until function node.
3413 return function.IsImplicitClosureFunction() 3367 return function.IsImplicitClosureFunction()
3414 ? BuildGraphOfImplicitClosureFunction(function) 3368 ? BuildGraphOfImplicitClosureFunction(function)
3415 : BuildGraphOfFunction(is_in_builtin_library_toplevel); 3369 : BuildGraphOfFunction();
3416 } 3370 }
3417 case RawFunction::kConstructor: { 3371 case RawFunction::kConstructor: {
3418 bool is_factory = function.IsFactory(); 3372 bool is_factory = function.IsFactory();
3419 if (is_factory) { 3373 if (is_factory) {
3420 ReadUntilFunctionNode(); // read until function node. 3374 ReadUntilFunctionNode(); // read until function node.
3421 return BuildGraphOfFunction(is_in_builtin_library_toplevel); 3375 return BuildGraphOfFunction();
3422 } else { 3376 } else {
3423 // Constructor: Pass offset to parent class. 3377 // Constructor: Pass offset to parent class.
3424 return BuildGraphOfFunction( 3378 return BuildGraphOfFunction(
3425 is_in_builtin_library_toplevel,
3426 ReadUntilFunctionNode()); // read until function node. 3379 ReadUntilFunctionNode()); // read until function node.
3427 } 3380 }
3428 } 3381 }
3429 case RawFunction::kImplicitGetter: 3382 case RawFunction::kImplicitGetter:
3430 case RawFunction::kImplicitStaticFinalGetter: 3383 case RawFunction::kImplicitStaticFinalGetter:
3431 case RawFunction::kImplicitSetter: { 3384 case RawFunction::kImplicitSetter: {
3432 return IsStaticInitializer(function, Z) 3385 return IsStaticInitializer(function, Z)
3433 ? BuildGraphOfStaticFieldInitializer() 3386 ? BuildGraphOfStaticFieldInitializer()
3434 : BuildGraphOfFieldAccessor(scopes()->setter_value); 3387 : BuildGraphOfFieldAccessor(scopes()->setter_value);
3435 } 3388 }
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after
4039 } 3992 }
4040 case kForInStatement: 3993 case kForInStatement:
4041 case kAsyncForInStatement: 3994 case kAsyncForInStatement:
4042 ReadPosition(); // read position. 3995 ReadPosition(); // read position.
4043 SkipVariableDeclaration(); // read variable. 3996 SkipVariableDeclaration(); // read variable.
4044 SkipExpression(); // read iterable. 3997 SkipExpression(); // read iterable.
4045 SkipStatement(); // read body. 3998 SkipStatement(); // read body.
4046 return; 3999 return;
4047 case kSwitchStatement: { 4000 case kSwitchStatement: {
4048 SkipExpression(); // read condition. 4001 SkipExpression(); // read condition.
4049 int num_cases = ReadListLength(); // read number of cases. 4002 int case_count = ReadListLength(); // read number of cases.
4050 for (intptr_t i = 0; i < num_cases; ++i) { 4003 for (intptr_t i = 0; i < case_count; ++i) {
4051 int num_expressions = ReadListLength(); // read number of expressions. 4004 int expression_count = ReadListLength(); // read number of expressions.
4052 for (intptr_t j = 0; j < num_expressions; ++j) { 4005 for (intptr_t j = 0; j < expression_count; ++j) {
4053 ReadPosition(); // read jth position. 4006 ReadPosition(); // read jth position.
4054 SkipExpression(); // read jth expression. 4007 SkipExpression(); // read jth expression.
4055 } 4008 }
4056 ReadBool(); // read is_default. 4009 ReadBool(); // read is_default.
4057 SkipStatement(); // read body. 4010 SkipStatement(); // read body.
4058 } 4011 }
4059 return; 4012 return;
4060 } 4013 }
4061 case kContinueSwitchStatement: 4014 case kContinueSwitchStatement:
4062 ReadUInt(); // read target_index. 4015 ReadUInt(); // read target_index.
4063 return; 4016 return;
4064 case kIfStatement: 4017 case kIfStatement:
4065 SkipExpression(); // read condition. 4018 SkipExpression(); // read condition.
4066 SkipStatement(); // read then. 4019 SkipStatement(); // read then.
4067 SkipStatement(); // read otherwise. 4020 SkipStatement(); // read otherwise.
4068 return; 4021 return;
4069 case kReturnStatement: { 4022 case kReturnStatement: {
4070 ReadPosition(); // read position 4023 ReadPosition(); // read position
4071 Tag tag = ReadTag(); // read (first part of) expression. 4024 Tag tag = ReadTag(); // read (first part of) expression.
4072 if (tag == kSomething) { 4025 if (tag == kSomething) {
4073 SkipExpression(); // read (rest of) expression. 4026 SkipExpression(); // read (rest of) expression.
4074 } 4027 }
4075 return; 4028 return;
4076 } 4029 }
4077 case kTryCatch: { 4030 case kTryCatch: {
4078 SkipStatement(); // read body. 4031 SkipStatement(); // read body.
4079 ReadBool(); // read any_catch_needs_stack_trace. 4032 ReadBool(); // read any_catch_needs_stack_trace.
4080 intptr_t num_catches = ReadListLength(); // read number of catches. 4033 intptr_t catch_count = ReadListLength(); // read number of catches.
4081 for (intptr_t i = 0; i < num_catches; ++i) { 4034 for (intptr_t i = 0; i < catch_count; ++i) {
4082 SkipDartType(); // read guard. 4035 SkipDartType(); // read guard.
4083 tag = ReadTag(); // read first part of exception. 4036 tag = ReadTag(); // read first part of exception.
4084 if (tag == kSomething) { 4037 if (tag == kSomething) {
4085 SkipVariableDeclaration(); // read exception. 4038 SkipVariableDeclaration(); // read exception.
4086 } 4039 }
4087 tag = ReadTag(); // read first part of stack trace. 4040 tag = ReadTag(); // read first part of stack trace.
4088 if (tag == kSomething) { 4041 if (tag == kSomething) {
4089 SkipVariableDeclaration(); // read stack trace. 4042 SkipVariableDeclaration(); // read stack trace.
4090 } 4043 }
4091 SkipStatement(); // read body. 4044 SkipStatement(); // read body.
4092 } 4045 }
4093 return; 4046 return;
4094 } 4047 }
4095 case kTryFinally: 4048 case kTryFinally:
4096 SkipStatement(); // read body. 4049 SkipStatement(); // read body.
4097 SkipStatement(); // read finalizer. 4050 SkipStatement(); // read finalizer.
4098 return; 4051 return;
4099 case kYieldStatement: 4052 case kYieldStatement: {
4100 ReadPosition(); // read position. 4053 TokenPosition position = ReadPosition(); // read position.
4054 record_yield_position(position);
4101 ReadByte(); // read flags. 4055 ReadByte(); // read flags.
4102 SkipExpression(); // read expression. 4056 SkipExpression(); // read expression.
4103 return; 4057 return;
4058 }
4104 case kVariableDeclaration: 4059 case kVariableDeclaration:
4105 SkipVariableDeclaration(); // read variable declaration. 4060 SkipVariableDeclaration(); // read variable declaration.
4106 return; 4061 return;
4107 case kFunctionDeclaration: 4062 case kFunctionDeclaration:
4108 ReadPosition(); // read position. 4063 ReadPosition(); // read position.
4109 SkipVariableDeclaration(); // read variable. 4064 SkipVariableDeclaration(); // read variable.
4110 SkipFunctionNode(); // read function node. 4065 SkipFunctionNode(); // read function node.
4111 return; 4066 return;
4112 default: 4067 default:
4113 UNREACHABLE(); 4068 UNREACHABLE();
(...skipping 24 matching lines...) Expand all
4138 SkipStringReference(); // read ith name index. 4093 SkipStringReference(); // read ith name index.
4139 SkipExpression(); // read ith expression. 4094 SkipExpression(); // read ith expression.
4140 } 4095 }
4141 } 4096 }
4142 4097
4143 void StreamingFlowGraphBuilder::SkipVariableDeclaration() { 4098 void StreamingFlowGraphBuilder::SkipVariableDeclaration() {
4144 VariableDeclarationHelper helper(this); 4099 VariableDeclarationHelper helper(this);
4145 helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); 4100 helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd);
4146 } 4101 }
4147 4102
4103 void StreamingFlowGraphBuilder::SkipLibraryCombinator() {
4104 ReadBool(); // read is_show.
4105 intptr_t name_count = ReadUInt(); // read list length.
4106 for (intptr_t j = 0; j < name_count; ++j) {
4107 ReadUInt(); // read ith entry of name_indices.
4108 }
4109 }
4110
4111 void StreamingFlowGraphBuilder::SkipLibraryDependency() {
4112 ReadFlags(); // read flags.
4113 SkipListOfExpressions(); // Read annotations.
4114 ReadCanonicalNameReference(); // read target_reference.
4115 ReadStringReference(); // read name_index.
4116 intptr_t combinator_count = ReadListLength(); // read list length.
4117 for (intptr_t i = 0; i < combinator_count; ++i) {
4118 SkipLibraryCombinator();
4119 }
4120 }
4121
4122 void StreamingFlowGraphBuilder::SkipLibraryTypedef() {
4123 SkipCanonicalNameReference(); // read canonical name.
4124 ReadPosition(); // read position.
4125 SkipStringReference(); // read name index.
4126 ReadUInt(); // read source_uri_index.
4127 SkipListOfDartTypes(); // read type parameters.
4128 SkipDartType(); // read type.
4129 }
4130
4148 TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) { 4131 TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) {
4149 return reader_->ReadPosition(record); 4132 TokenPosition position = reader_->ReadPosition();
4133 if (record) {
4134 record_token_position(position);
4135 }
4136 return position;
4137 }
4138
4139 void StreamingFlowGraphBuilder::record_token_position(TokenPosition position) {
4140 if (record_for_script_id_ == current_script_id_ &&
4141 record_token_positions_into_ != NULL) {
4142 record_token_positions_into_->Add(position.value());
4143 }
4144 }
4145
4146 void StreamingFlowGraphBuilder::record_yield_position(TokenPosition position) {
4147 if (record_for_script_id_ == current_script_id_ &&
4148 record_yield_positions_into_ != NULL) {
4149 record_yield_positions_into_->Add(position.value());
4150 }
4150 } 4151 }
4151 4152
4152 Tag StreamingFlowGraphBuilder::ReadTag(uint8_t* payload) { 4153 Tag StreamingFlowGraphBuilder::ReadTag(uint8_t* payload) {
4153 return reader_->ReadTag(payload); 4154 return reader_->ReadTag(payload);
4154 } 4155 }
4155 4156
4156 Tag StreamingFlowGraphBuilder::PeekTag(uint8_t* payload) { 4157 Tag StreamingFlowGraphBuilder::PeekTag(uint8_t* payload) {
4157 return reader_->PeekTag(payload); 4158 return reader_->PeekTag(payload);
4158 } 4159 }
4159 4160
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
4380 } 4381 }
4381 4382
4382 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, 4383 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
4383 const Function& target, 4384 const Function& target,
4384 intptr_t argument_count, 4385 intptr_t argument_count,
4385 const Array& argument_names) { 4386 const Array& argument_names) {
4386 return flow_graph_builder_->StaticCall(position, target, argument_count, 4387 return flow_graph_builder_->StaticCall(position, target, argument_count,
4387 argument_names); 4388 argument_names);
4388 } 4389 }
4389 4390
4390 Fragment StreamingFlowGraphBuilder::InstanceCall(TokenPosition position, 4391 Fragment StreamingFlowGraphBuilder::InstanceCall(
4391 const dart::String& name, 4392 TokenPosition position,
4392 Token::Kind kind, 4393 const dart::String& name,
4393 intptr_t argument_count, 4394 Token::Kind kind,
4394 intptr_t num_args_checked) { 4395 intptr_t argument_count,
4396 intptr_t checked_argument_count) {
4395 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, 4397 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count,
4396 num_args_checked); 4398 checked_argument_count);
4397 } 4399 }
4398 4400
4399 Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) { 4401 Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) {
4400 return flow_graph_builder_->ThrowException(position); 4402 return flow_graph_builder_->ThrowException(position);
4401 } 4403 }
4402 4404
4403 Fragment StreamingFlowGraphBuilder::BooleanNegate() { 4405 Fragment StreamingFlowGraphBuilder::BooleanNegate() {
4404 return flow_graph_builder_->BooleanNegate(); 4406 return flow_graph_builder_->BooleanNegate();
4405 } 4407 }
4406 4408
4407 Fragment StreamingFlowGraphBuilder::TranslateInstantiatedTypeArguments( 4409 Fragment StreamingFlowGraphBuilder::TranslateInstantiatedTypeArguments(
4408 const TypeArguments& type_arguments) { 4410 const TypeArguments& type_arguments) {
4409 return flow_graph_builder_->TranslateInstantiatedTypeArguments( 4411 return flow_graph_builder_->TranslateInstantiatedTypeArguments(
4410 type_arguments); 4412 type_arguments);
4411 } 4413 }
4412 4414
4413 Fragment StreamingFlowGraphBuilder::StrictCompare(Token::Kind kind, 4415 Fragment StreamingFlowGraphBuilder::StrictCompare(Token::Kind kind,
4414 bool number_check) { 4416 bool number_check) {
4415 return flow_graph_builder_->StrictCompare(kind, number_check); 4417 return flow_graph_builder_->StrictCompare(kind, number_check);
4416 } 4418 }
4417 4419
4418 Fragment StreamingFlowGraphBuilder::AllocateObject(TokenPosition position, 4420 Fragment StreamingFlowGraphBuilder::AllocateObject(TokenPosition position,
4419 const dart::Class& klass, 4421 const dart::Class& klass,
4420 intptr_t argument_count) { 4422 intptr_t argument_count) {
4421 return flow_graph_builder_->AllocateObject(position, klass, argument_count); 4423 return flow_graph_builder_->AllocateObject(position, klass, argument_count);
4422 } 4424 }
4423 4425
4424 Fragment StreamingFlowGraphBuilder::InstanceCall(TokenPosition position, 4426 Fragment StreamingFlowGraphBuilder::InstanceCall(
4425 const dart::String& name, 4427 TokenPosition position,
4426 Token::Kind kind, 4428 const dart::String& name,
4427 intptr_t argument_count, 4429 Token::Kind kind,
4428 const Array& argument_names, 4430 intptr_t argument_count,
4429 intptr_t num_args_checked) { 4431 const Array& argument_names,
4432 intptr_t checked_argument_count) {
4430 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, 4433 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count,
4431 argument_names, num_args_checked); 4434 argument_names,
4435 checked_argument_count);
4432 } 4436 }
4433 4437
4434 Fragment StreamingFlowGraphBuilder::StoreLocal(TokenPosition position, 4438 Fragment StreamingFlowGraphBuilder::StoreLocal(TokenPosition position,
4435 LocalVariable* variable) { 4439 LocalVariable* variable) {
4436 return flow_graph_builder_->StoreLocal(position, variable); 4440 return flow_graph_builder_->StoreLocal(position, variable);
4437 } 4441 }
4438 4442
4439 Fragment StreamingFlowGraphBuilder::StoreStaticField(TokenPosition position, 4443 Fragment StreamingFlowGraphBuilder::StoreStaticField(TokenPosition position,
4440 const dart::Field& field) { 4444 const dart::Field& field) {
4441 return flow_graph_builder_->StoreStaticField(position, field); 4445 return flow_graph_builder_->StoreStaticField(position, field);
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
4951 4955
4952 instructions += PushArgument(); // push receiver as argument. 4956 instructions += PushArgument(); // push receiver as argument.
4953 4957
4954 // TODO(28109) Support generic methods in the VM or reify them away. 4958 // TODO(28109) Support generic methods in the VM or reify them away.
4955 Array& argument_names = Array::ZoneHandle(Z); 4959 Array& argument_names = Array::ZoneHandle(Z);
4956 intptr_t argument_count; 4960 intptr_t argument_count;
4957 instructions += 4961 instructions +=
4958 BuildArguments(&argument_names, &argument_count); // read arguments. 4962 BuildArguments(&argument_names, &argument_count); // read arguments.
4959 ++argument_count; 4963 ++argument_count;
4960 4964
4961 intptr_t num_args_checked = 1; 4965 intptr_t checked_argument_count = 1;
4962 // If we have a special operation (e.g. +/-/==) we mark both arguments as 4966 // If we have a special operation (e.g. +/-/==) we mark both arguments as
4963 // to be checked. 4967 // to be checked.
4964 if (token_kind != Token::kILLEGAL) { 4968 if (token_kind != Token::kILLEGAL) {
4965 ASSERT(argument_count <= 2); 4969 ASSERT(argument_count <= 2);
4966 num_args_checked = argument_count; 4970 checked_argument_count = argument_count;
4967 } 4971 }
4968 4972
4969 instructions += InstanceCall(position, name, token_kind, argument_count, 4973 instructions += InstanceCall(position, name, token_kind, argument_count,
4970 argument_names, num_args_checked); 4974 argument_names, checked_argument_count);
4971 // Later optimization passes assume that result of a x.[]=(...) call is not 4975 // Later optimization passes assume that result of a x.[]=(...) call is not
4972 // used. We must guarantee this invariant because violation will lead to an 4976 // used. We must guarantee this invariant because violation will lead to an
4973 // illegal IL once we replace x.[]=(...) with a sequence that does not 4977 // illegal IL once we replace x.[]=(...) with a sequence that does not
4974 // actually produce any value. See http://dartbug.com/29135 for more details. 4978 // actually produce any value. See http://dartbug.com/29135 for more details.
4975 if (name.raw() == Symbols::AssignIndexToken().raw()) { 4979 if (name.raw() == Symbols::AssignIndexToken().raw()) {
4976 instructions += Drop(); 4980 instructions += Drop();
4977 instructions += NullConstant(); 4981 instructions += NullConstant();
4978 } 4982 }
4979 4983
4980 SkipCanonicalNameReference(); // read unused "interface_target_reference". 4984 SkipCanonicalNameReference(); // read unused "interface_target_reference".
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after
6006 6010
6007 loop_depth_dec(); 6011 loop_depth_dec();
6008 for_in_depth_dec(); 6012 for_in_depth_dec();
6009 return Fragment(instructions.entry, loop_exit); 6013 return Fragment(instructions.entry, loop_exit);
6010 } 6014 }
6011 6015
6012 Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() { 6016 Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() {
6013 // We need the number of cases. So start by getting that, then go back. 6017 // We need the number of cases. So start by getting that, then go back.
6014 intptr_t offset = ReaderOffset(); 6018 intptr_t offset = ReaderOffset();
6015 SkipExpression(); // temporarily skip condition 6019 SkipExpression(); // temporarily skip condition
6016 int num_cases = ReadListLength(); // read number of cases. 6020 int case_count = ReadListLength(); // read number of cases.
6017 SetOffset(offset); 6021 SetOffset(offset);
6018 6022
6019 SwitchBlock block(flow_graph_builder_, num_cases); 6023 SwitchBlock block(flow_graph_builder_, case_count);
6020 6024
6021 // Instead of using a variable we should reuse the expression on the stack, 6025 // Instead of using a variable we should reuse the expression on the stack,
6022 // since it won't be assigned again, we don't need phi nodes. 6026 // since it won't be assigned again, we don't need phi nodes.
6023 Fragment head_instructions = BuildExpression(); // read condition. 6027 Fragment head_instructions = BuildExpression(); // read condition.
6024 head_instructions += 6028 head_instructions +=
6025 StoreLocal(TokenPosition::kNoSource, scopes()->switch_variable); 6029 StoreLocal(TokenPosition::kNoSource, scopes()->switch_variable);
6026 head_instructions += Drop(); 6030 head_instructions += Drop();
6027 6031
6028 num_cases = ReadListLength(); // read number of cases. 6032 case_count = ReadListLength(); // read number of cases.
6029 6033
6030 // Phase 1: Generate bodies and try to find out whether a body will be target 6034 // Phase 1: Generate bodies and try to find out whether a body will be target
6031 // of a jump due to: 6035 // of a jump due to:
6032 // * `continue case_label` 6036 // * `continue case_label`
6033 // * `case e1: case e2: body` 6037 // * `case e1: case e2: body`
6034 Fragment* body_fragments = new Fragment[num_cases]; 6038 Fragment* body_fragments = new Fragment[case_count];
6035 intptr_t* case_expression_offsets = new intptr_t[num_cases]; 6039 intptr_t* case_expression_offsets = new intptr_t[case_count];
6036 int default_case = -1; 6040 int default_case = -1;
6037 6041
6038 for (intptr_t i = 0; i < num_cases; ++i) { 6042 for (intptr_t i = 0; i < case_count; ++i) {
6039 case_expression_offsets[i] = ReaderOffset(); 6043 case_expression_offsets[i] = ReaderOffset();
6040 int num_expressions = ReadListLength(); // read number of expressions. 6044 int expression_count = ReadListLength(); // read number of expressions.
6041 for (intptr_t j = 0; j < num_expressions; ++j) { 6045 for (intptr_t j = 0; j < expression_count; ++j) {
6042 ReadPosition(); // read jth position. 6046 ReadPosition(); // read jth position.
6043 SkipExpression(); // read jth expression. 6047 SkipExpression(); // read jth expression.
6044 } 6048 }
6045 bool is_default = ReadBool(); // read is_default. 6049 bool is_default = ReadBool(); // read is_default.
6046 if (is_default) default_case = i; 6050 if (is_default) default_case = i;
6047 Fragment& body_fragment = body_fragments[i] = 6051 Fragment& body_fragment = body_fragments[i] =
6048 BuildStatement(); // read body. 6052 BuildStatement(); // read body.
6049 6053
6050 if (body_fragment.entry == NULL) { 6054 if (body_fragment.entry == NULL) {
6051 // Make a NOP in order to ensure linking works properly. 6055 // Make a NOP in order to ensure linking works properly.
6052 body_fragment = NullConstant(); 6056 body_fragment = NullConstant();
6053 body_fragment += Drop(); 6057 body_fragment += Drop();
6054 } 6058 }
6055 6059
6056 // The Dart language specification mandates fall-throughs in [SwitchCase]es 6060 // The Dart language specification mandates fall-throughs in [SwitchCase]es
6057 // to be runtime errors. 6061 // to be runtime errors.
6058 if (!is_default && body_fragment.is_open() && (i < (num_cases - 1))) { 6062 if (!is_default && body_fragment.is_open() && (i < (case_count - 1))) {
6059 const dart::Class& klass = dart::Class::ZoneHandle( 6063 const dart::Class& klass = dart::Class::ZoneHandle(
6060 Z, dart::Library::LookupCoreClass(Symbols::FallThroughError())); 6064 Z, dart::Library::LookupCoreClass(Symbols::FallThroughError()));
6061 ASSERT(!klass.IsNull()); 6065 ASSERT(!klass.IsNull());
6062 const dart::Function& constructor = dart::Function::ZoneHandle( 6066 const dart::Function& constructor = dart::Function::ZoneHandle(
6063 Z, klass.LookupConstructorAllowPrivate( 6067 Z, klass.LookupConstructorAllowPrivate(
6064 H.DartSymbol("FallThroughError._create"))); 6068 H.DartSymbol("FallThroughError._create")));
6065 ASSERT(!constructor.IsNull()); 6069 ASSERT(!constructor.IsNull());
6066 const dart::String& url = H.DartString( 6070 const dart::String& url = H.DartString(
6067 parsed_function()->function().ToLibNamePrefixedQualifiedCString(), 6071 parsed_function()->function().ToLibNamePrefixedQualifiedCString(),
6068 Heap::kOld); 6072 Heap::kOld);
(...skipping 26 matching lines...) Expand all
6095 // 6099 //
6096 // switch(expr) { 6100 // switch(expr) {
6097 // case a: 6101 // case a:
6098 // case b: 6102 // case b:
6099 // <stmt-body> 6103 // <stmt-body>
6100 // } 6104 // }
6101 // 6105 //
6102 // This means that the <stmt-body> will have more than 1 incoming edge (one 6106 // This means that the <stmt-body> will have more than 1 incoming edge (one
6103 // from `a == expr` and one from `a != expr && b == expr`). The 6107 // from `a == expr` and one from `a != expr && b == expr`). The
6104 // `block.Destination()` records the additional jump. 6108 // `block.Destination()` records the additional jump.
6105 if (num_expressions > 1) { 6109 if (expression_count > 1) {
6106 block.DestinationDirect(i); 6110 block.DestinationDirect(i);
6107 } 6111 }
6108 } 6112 }
6109 6113
6110 intptr_t end_offset = ReaderOffset(); 6114 intptr_t end_offset = ReaderOffset();
6111 6115
6112 // Phase 2: Generate everything except the real bodies: 6116 // Phase 2: Generate everything except the real bodies:
6113 // * jump directly to a body (if there is no jumper) 6117 // * jump directly to a body (if there is no jumper)
6114 // * jump to a wrapper block which jumps to the body (if there is a jumper) 6118 // * jump to a wrapper block which jumps to the body (if there is a jumper)
6115 Fragment current_instructions = head_instructions; 6119 Fragment current_instructions = head_instructions;
6116 for (intptr_t i = 0; i < num_cases; ++i) { 6120 for (intptr_t i = 0; i < case_count; ++i) {
6117 SetOffset(case_expression_offsets[i]); 6121 SetOffset(case_expression_offsets[i]);
6118 int num_expressions = ReadListLength(); // read length of expressions. 6122 int expression_count = ReadListLength(); // read length of expressions.
6119 6123
6120 if (i == default_case) { 6124 if (i == default_case) {
6121 ASSERT(i == (num_cases - 1)); 6125 ASSERT(i == (case_count - 1));
6122 6126
6123 // Evaluate the conditions for the default [SwitchCase] just for the 6127 // Evaluate the conditions for the default [SwitchCase] just for the
6124 // purpose of potentially triggering a compile-time error. 6128 // purpose of potentially triggering a compile-time error.
6125 6129
6126 for (intptr_t j = 0; j < num_expressions; ++j) { 6130 for (intptr_t j = 0; j < expression_count; ++j) {
6127 ReadPosition(); // read jth position. 6131 ReadPosition(); // read jth position.
6128 // this reads the expression, but doesn't skip past it. 6132 // this reads the expression, but doesn't skip past it.
6129 constant_evaluator_.EvaluateExpression(ReaderOffset()); 6133 constant_evaluator_.EvaluateExpression(ReaderOffset());
6130 SkipExpression(); // read jth expression. 6134 SkipExpression(); // read jth expression.
6131 } 6135 }
6132 6136
6133 if (block.HadJumper(i)) { 6137 if (block.HadJumper(i)) {
6134 // There are several branches to the body, so we will make a goto to 6138 // There are several branches to the body, so we will make a goto to
6135 // the join block (and prepend a join instruction to the real body). 6139 // the join block (and prepend a join instruction to the real body).
6136 JoinEntryInstr* join = block.DestinationDirect(i); 6140 JoinEntryInstr* join = block.DestinationDirect(i);
6137 current_instructions += Goto(join); 6141 current_instructions += Goto(join);
6138 6142
6139 current_instructions = Fragment(current_instructions.entry, join); 6143 current_instructions = Fragment(current_instructions.entry, join);
6140 current_instructions += body_fragments[i]; 6144 current_instructions += body_fragments[i];
6141 } else { 6145 } else {
6142 current_instructions += body_fragments[i]; 6146 current_instructions += body_fragments[i];
6143 } 6147 }
6144 } else { 6148 } else {
6145 JoinEntryInstr* body_join = NULL; 6149 JoinEntryInstr* body_join = NULL;
6146 if (block.HadJumper(i)) { 6150 if (block.HadJumper(i)) {
6147 body_join = block.DestinationDirect(i); 6151 body_join = block.DestinationDirect(i);
6148 body_fragments[i] = Fragment(body_join) + body_fragments[i]; 6152 body_fragments[i] = Fragment(body_join) + body_fragments[i];
6149 } 6153 }
6150 6154
6151 for (intptr_t j = 0; j < num_expressions; ++j) { 6155 for (intptr_t j = 0; j < expression_count; ++j) {
6152 TargetEntryInstr* then; 6156 TargetEntryInstr* then;
6153 TargetEntryInstr* otherwise; 6157 TargetEntryInstr* otherwise;
6154 6158
6155 TokenPosition position = ReadPosition(); // read jth position. 6159 TokenPosition position = ReadPosition(); // read jth position.
6156 current_instructions += 6160 current_instructions +=
6157 Constant(constant_evaluator_.EvaluateExpression(ReaderOffset())); 6161 Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
6158 SkipExpression(); // read jth expression. 6162 SkipExpression(); // read jth expression.
6159 current_instructions += PushArgument(); 6163 current_instructions += PushArgument();
6160 current_instructions += LoadLocal(scopes()->switch_variable); 6164 current_instructions += LoadLocal(scopes()->switch_variable);
6161 current_instructions += PushArgument(); 6165 current_instructions += PushArgument();
6162 current_instructions += 6166 current_instructions +=
6163 InstanceCall(position, Symbols::EqualOperator(), Token::kEQ, 6167 InstanceCall(position, Symbols::EqualOperator(), Token::kEQ,
6164 /*argument_count=*/2, 6168 /*argument_count=*/2,
6165 /*num_args_checked=*/2); 6169 /*checked_argument_count=*/2);
6166 current_instructions += BranchIfTrue(&then, &otherwise, false); 6170 current_instructions += BranchIfTrue(&then, &otherwise, false);
6167 6171
6168 Fragment then_fragment(then); 6172 Fragment then_fragment(then);
6169 6173
6170 if (body_join != NULL) { 6174 if (body_join != NULL) {
6171 // There are several branches to the body, so we will make a goto to 6175 // There are several branches to the body, so we will make a goto to
6172 // the join block (the real body has already been prepended with a 6176 // the join block (the real body has already been prepended with a
6173 // join instruction). 6177 // join instruction).
6174 then_fragment += Goto(body_join); 6178 then_fragment += Goto(body_join);
6175 } else { 6179 } else {
6176 // There is only a signle branch to the body, so we will just append 6180 // There is only a signle branch to the body, so we will just append
6177 // the body fragment. 6181 // the body fragment.
6178 then_fragment += body_fragments[i]; 6182 then_fragment += body_fragments[i];
6179 } 6183 }
6180 6184
6181 current_instructions = Fragment(otherwise); 6185 current_instructions = Fragment(otherwise);
6182 } 6186 }
6183 } 6187 }
6184 } 6188 }
6185 6189
6186 if (num_cases > 0 && default_case < 0) { 6190 if (case_count > 0 && default_case < 0) {
6187 // There is no default, which means we have an open [current_instructions] 6191 // There is no default, which means we have an open [current_instructions]
6188 // (which is a [TargetEntryInstruction] for the last "otherwise" branch). 6192 // (which is a [TargetEntryInstruction] for the last "otherwise" branch).
6189 // 6193 //
6190 // Furthermore the last [SwitchCase] can be open as well. If so, we need 6194 // Furthermore the last [SwitchCase] can be open as well. If so, we need
6191 // to join these two. 6195 // to join these two.
6192 Fragment& last_body = body_fragments[num_cases - 1]; 6196 Fragment& last_body = body_fragments[case_count - 1];
6193 if (last_body.is_open()) { 6197 if (last_body.is_open()) {
6194 ASSERT(current_instructions.is_open()); 6198 ASSERT(current_instructions.is_open());
6195 ASSERT(current_instructions.current->IsTargetEntry()); 6199 ASSERT(current_instructions.current->IsTargetEntry());
6196 6200
6197 // Join the last "otherwise" branch and the last [SwitchCase] fragment. 6201 // Join the last "otherwise" branch and the last [SwitchCase] fragment.
6198 JoinEntryInstr* join = BuildJoinEntry(); 6202 JoinEntryInstr* join = BuildJoinEntry();
6199 current_instructions += Goto(join); 6203 current_instructions += Goto(join);
6200 last_body += Goto(join); 6204 last_body += Goto(join);
6201 6205
6202 current_instructions = Fragment(join); 6206 current_instructions = Fragment(join);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
6306 { 6310 {
6307 TryCatchBlock block(flow_graph_builder_, try_handler_index); 6311 TryCatchBlock block(flow_graph_builder_, try_handler_index);
6308 try_body += BuildStatement(); // read body. 6312 try_body += BuildStatement(); // read body.
6309 try_body += Goto(after_try); 6313 try_body += Goto(after_try);
6310 } 6314 }
6311 try_depth_dec(); 6315 try_depth_dec();
6312 6316
6313 bool needs_stacktrace = ReadBool(); // read any_catch_needs_stack_trace 6317 bool needs_stacktrace = ReadBool(); // read any_catch_needs_stack_trace
6314 6318
6315 catch_depth_inc(); 6319 catch_depth_inc();
6316 intptr_t num_catches = ReadListLength(); // read number of catches. 6320 intptr_t catch_count = ReadListLength(); // read number of catches.
6317 const Array& handler_types = 6321 const Array& handler_types =
6318 Array::ZoneHandle(Z, Array::New(num_catches, Heap::kOld)); 6322 Array::ZoneHandle(Z, Array::New(catch_count, Heap::kOld));
6319 Fragment catch_body = 6323 Fragment catch_body =
6320 CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace); 6324 CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace);
6321 // Fill in the body of the catch. 6325 // Fill in the body of the catch.
6322 for (intptr_t i = 0; i < num_catches; ++i) { 6326 for (intptr_t i = 0; i < catch_count; ++i) {
6323 intptr_t catch_offset = ReaderOffset(); // Catch has no tag. 6327 intptr_t catch_offset = ReaderOffset(); // Catch has no tag.
6324 Tag tag = PeekTag(); // peek guard type. 6328 Tag tag = PeekTag(); // peek guard type.
6325 AbstractType* type_guard = NULL; 6329 AbstractType* type_guard = NULL;
6326 if (tag != kDynamicType) { 6330 if (tag != kDynamicType) {
6327 type_guard = &T.BuildType(); // read guard. 6331 type_guard = &T.BuildType(); // read guard.
6328 handler_types.SetAt(i, *type_guard); 6332 handler_types.SetAt(i, *type_guard);
6329 } else { 6333 } else {
6330 SkipDartType(); // read guard. 6334 SkipDartType(); // read guard.
6331 handler_types.SetAt(i, Object::dynamic_type()); 6335 handler_types.SetAt(i, Object::dynamic_type());
6332 } 6336 }
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
6785 total_parameter_count - positional_parameters_count; 6789 total_parameter_count - positional_parameters_count;
6786 6790
6787 function.set_num_fixed_parameters(extra_parameters + 6791 function.set_num_fixed_parameters(extra_parameters +
6788 required_parameter_count); 6792 required_parameter_count);
6789 if (named_parameters_count > 0) { 6793 if (named_parameters_count > 0) {
6790 function.SetNumOptionalParameters(named_parameters_count, false); 6794 function.SetNumOptionalParameters(named_parameters_count, false);
6791 } else { 6795 } else {
6792 function.SetNumOptionalParameters( 6796 function.SetNumOptionalParameters(
6793 positional_parameters_count - required_parameter_count, true); 6797 positional_parameters_count - required_parameter_count, true);
6794 } 6798 }
6795 intptr_t num_parameters = extra_parameters + total_parameter_count; 6799 intptr_t parameter_count = extra_parameters + total_parameter_count;
6796 function.set_parameter_types( 6800 function.set_parameter_types(
6797 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); 6801 Array::Handle(Z, Array::New(parameter_count, Heap::kOld)));
6798 function.set_parameter_names( 6802 function.set_parameter_names(
6799 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); 6803 Array::Handle(Z, Array::New(parameter_count, Heap::kOld)));
6800 intptr_t pos = 0; 6804 intptr_t pos = 0;
6801 if (is_method) { 6805 if (is_method) {
6802 ASSERT(!klass.IsNull()); 6806 ASSERT(!klass.IsNull());
6803 function.SetParameterTypeAt(pos, H.GetCanonicalType(klass)); 6807 function.SetParameterTypeAt(pos, H.GetCanonicalType(klass));
6804 function.SetParameterNameAt(pos, Symbols::This()); 6808 function.SetParameterNameAt(pos, Symbols::This());
6805 pos++; 6809 pos++;
6806 } else if (is_closure) { 6810 } else if (is_closure) {
6807 function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); 6811 function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
6808 function.SetParameterNameAt(pos, Symbols::ClosureParameter()); 6812 function.SetParameterNameAt(pos, Symbols::ClosureParameter());
6809 pos++; 6813 pos++;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
6931 for (intptr_t i = 0; i < list_length; ++i) { 6935 for (intptr_t i = 0; i < list_length; ++i) {
6932 // this will (potentially) read the expression, but reset the position. 6936 // this will (potentially) read the expression, but reset the position.
6933 Instance& value = constant_evaluator_.EvaluateExpression(ReaderOffset()); 6937 Instance& value = constant_evaluator_.EvaluateExpression(ReaderOffset());
6934 SkipExpression(); // read (actual) initializer. 6938 SkipExpression(); // read (actual) initializer.
6935 metadata_values.SetAt(i, value); 6939 metadata_values.SetAt(i, value);
6936 } 6940 }
6937 6941
6938 return metadata_values.raw(); 6942 return metadata_values.raw();
6939 } 6943 }
6940 6944
6945 void StreamingFlowGraphBuilder::CollectTokenPositionsFor(
6946 intptr_t script_index,
6947 GrowableArray<intptr_t>* record_token_positions_in,
6948 GrowableArray<intptr_t>* record_yield_positions_in) {
6949 record_token_positions_into_ = record_token_positions_in;
6950 record_yield_positions_into_ = record_yield_positions_in;
6951 record_for_script_id_ = script_index;
6952
6953 // Get offset for 1st library.
6954 SetOffset(reader_->size() - 4);
6955 intptr_t library_count = reader_->ReadUInt32();
6956
6957 SetOffset(reader_->size() - 4 - 4 * library_count);
6958 intptr_t offset = reader_->ReadUInt32();
6959
6960 SetOffset(offset);
6961 for (intptr_t i = 0; i < library_count; ++i) {
6962 LibraryHelper library_helper(this);
6963 library_helper.ReadUntilExcluding(LibraryHelper::kEnd);
6964 }
6965
6966 record_token_positions_into_ = NULL;
6967 record_yield_positions_into_ = NULL;
6968 record_for_script_id_ = -1;
6969 }
6970
6971 intptr_t StreamingFlowGraphBuilder::SourceTableSize() {
6972 AlternativeReadingScope alt(reader_);
6973 SetOffset(reader_->size() - 4);
6974 intptr_t library_count = reader_->ReadUInt32();
6975 SetOffset(reader_->size() - 4 - 4 * library_count - 3 * 4);
6976 SetOffset(reader_->ReadUInt32()); // read source table offset.
6977 return ReadUInt(); // read source table size.
6978 }
6979
6980 String& StreamingFlowGraphBuilder::SourceTableUriFor(intptr_t index) {
6981 AlternativeReadingScope alt(reader_);
6982 SetOffset(reader_->size() - 4);
6983 intptr_t library_count = reader_->ReadUInt32();
6984 SetOffset(reader_->size() - 4 - 4 * library_count - 3 * 4);
6985 SetOffset(reader_->ReadUInt32()); // read source table offset.
6986 intptr_t size = ReadUInt(); // read source table size.
6987 intptr_t start = 0;
6988 intptr_t end = -1;
6989 for (intptr_t i = 0; i < size; ++i) {
6990 intptr_t offset = ReadUInt();
6991 if (i == index - 1) {
6992 start = offset;
6993 } else if (i == index) {
6994 end = offset;
6995 }
6996 }
6997 intptr_t end_offset = ReaderOffset();
6998 return H.DartString(reader_->buffer() + end_offset + start, end - start,
6999 Heap::kOld);
7000 }
7001
7002 String& StreamingFlowGraphBuilder::GetSourceFor(intptr_t index) {
7003 AlternativeReadingScope alt(reader_);
7004 SetOffset(reader_->size() - 4);
7005 intptr_t library_count = reader_->ReadUInt32();
7006 SetOffset(reader_->size() - 4 - 4 * library_count - 3 * 4);
7007 SetOffset(reader_->ReadUInt32()); // read source table offset.
7008 intptr_t size = ReadUInt(); // read source table size.
7009 intptr_t uris_size = 0;
7010 for (intptr_t i = 0; i < size; ++i) {
7011 uris_size = ReadUInt();
7012 }
7013 SkipBytes(uris_size);
7014
7015 // Read the source code strings and line starts.
7016 for (intptr_t i = 0; i < size; ++i) {
7017 intptr_t length = ReadUInt();
7018 if (index == i) {
7019 return H.DartString(reader_->buffer() + ReaderOffset(), length,
7020 Heap::kOld);
7021 }
7022 SkipBytes(length);
7023 intptr_t line_count = ReadUInt();
7024 for (intptr_t j = 0; j < line_count; ++j) {
7025 ReadUInt();
7026 }
7027 }
7028
7029 return String::Handle(String::null());
7030 }
7031
7032 Array& StreamingFlowGraphBuilder::GetLineStartsFor(intptr_t index) {
7033 AlternativeReadingScope alt(reader_);
7034 SetOffset(reader_->size() - 4);
7035 intptr_t library_count = reader_->ReadUInt32();
7036 SetOffset(reader_->size() - 4 - 4 * library_count - 3 * 4);
7037 SetOffset(reader_->ReadUInt32()); // read source table offset.
7038 intptr_t size = ReadUInt(); // read source table size.
7039 intptr_t uris_size = 0;
7040 for (intptr_t i = 0; i < size; ++i) {
7041 uris_size = ReadUInt();
7042 }
7043 SkipBytes(uris_size);
7044
7045 // Read the source code strings and line starts.
7046 for (intptr_t i = 0; i < size; ++i) {
7047 intptr_t length = ReadUInt();
7048 SkipBytes(length);
7049 intptr_t line_count = ReadUInt();
7050 if (i == index) {
7051 Array& array_object =
7052 Array::Handle(Z, Array::New(line_count, Heap::kOld));
7053 Smi& value = Smi::Handle(Z);
7054 intptr_t previous_line_start = 0;
7055 for (intptr_t j = 0; j < line_count; ++j) {
7056 intptr_t line_start = ReadUInt() + previous_line_start;
7057 value = Smi::New(line_start);
7058 array_object.SetAt(j, value);
7059 previous_line_start = line_start;
7060 }
7061 return array_object;
7062 } else {
7063 for (intptr_t j = 0; j < line_count; ++j) {
7064 ReadUInt();
7065 }
7066 }
7067 }
7068
7069 return Array::Handle(Array::null());
7070 }
7071
6941 } // namespace kernel 7072 } // namespace kernel
6942 } // namespace dart 7073 } // namespace dart
6943 7074
6944 #endif // !defined(DART_PRECOMPILED_RUNTIME) 7075 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.h ('k') | runtime/vm/kernel_reader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698