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

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

Issue 2891053003: Add support for converted closures with explicit contexts to VM (Closed)
Patch Set: Return statement-to-block conversion for procedure bodies Created 3 years, 6 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
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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 scope_->AddVariable(context_var); 114 scope_->AddVariable(context_var);
115 115
116 parsed_function->SetNodeSequence( 116 parsed_function->SetNodeSequence(
117 new SequenceNode(TokenPosition::kNoSource, scope_)); 117 new SequenceNode(TokenPosition::kNoSource, scope_));
118 118
119 intptr_t parent_offset = -1; 119 intptr_t parent_offset = -1;
120 builder_->SetOffset(kernel_offset_); 120 builder_->SetOffset(kernel_offset_);
121 121
122 switch (function.kind()) { 122 switch (function.kind()) {
123 case RawFunction::kClosureFunction: 123 case RawFunction::kClosureFunction:
124 case RawFunction::kConvertedClosureFunction:
124 case RawFunction::kRegularFunction: 125 case RawFunction::kRegularFunction:
125 case RawFunction::kGetterFunction: 126 case RawFunction::kGetterFunction:
126 case RawFunction::kSetterFunction: 127 case RawFunction::kSetterFunction:
127 case RawFunction::kConstructor: { 128 case RawFunction::kConstructor: {
128 const Tag tag = builder_->PeekTag(); 129 const Tag tag = builder_->PeekTag();
129 parent_offset = builder_->ReadUntilFunctionNode(); 130 parent_offset = builder_->ReadUntilFunctionNode();
130 word async_marker_word; 131 word async_marker_word;
131 builder_->ReadFunctionNodeUntilTypeParameters( 132 builder_->ReadFunctionNodeUntilTypeParameters(
132 &unused_tokenposition, &unused_tokenposition, &async_marker_word, 133 &unused_tokenposition, &unused_tokenposition, &async_marker_word,
133 &unused_word); // read first part of function node. 134 &unused_word); // read first part of function node.
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 Tag function_node = builder_->ReadProcedureUntilFunctionNode( 353 Tag function_node = builder_->ReadProcedureUntilFunctionNode(
353 &unused_word, &unused_intptr); // read first part of procedure. 354 &unused_word, &unused_intptr); // read first part of procedure.
354 if (function_node == kSomething) { 355 if (function_node == kSomething) {
355 VisitFunctionNode(); 356 VisitFunctionNode();
356 } 357 }
357 } 358 }
358 359
359 void StreamingScopeBuilder::VisitField() { 360 void StreamingScopeBuilder::VisitField() {
360 builder_->ReadFieldUntilAnnotation( 361 builder_->ReadFieldUntilAnnotation(
361 &unused_nameindex, &unused_tokenposition, &unused_tokenposition, 362 &unused_nameindex, &unused_tokenposition, &unused_tokenposition,
362 &unused_intptr, &unused_word); // read first part of field. 363 &unused_intptr, &unused_word); // read first part of field.
363 builder_->SkipListOfExpressions(); // read annotations. 364 builder_->SkipListOfExpressions(); // read annotations.
364 VisitDartType(); // read type. 365 VisitDartType(); // read type.
365 Tag tag = builder_->ReadTag(); // read initializer (part 1). 366 Tag tag = builder_->ReadTag(); // read initializer (part 1).
366 if (tag == kSomething) { 367 if (tag == kSomething) {
367 VisitExpression(); // read initializer (part 2). 368 VisitExpression(); // read initializer (part 2).
368 } 369 }
369 } 370 }
370 371
371 void StreamingScopeBuilder::VisitFunctionNode() { 372 void StreamingScopeBuilder::VisitFunctionNode() {
372 word async_marker_word; 373 word async_marker_word;
373 word dart_async_marker_word; 374 word dart_async_marker_word;
374 builder_->ReadFunctionNodeUntilTypeParameters( 375 builder_->ReadFunctionNodeUntilTypeParameters(
375 &unused_tokenposition, &unused_tokenposition, &async_marker_word, 376 &unused_tokenposition, &unused_tokenposition, &async_marker_word,
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 return; 687 return;
687 case kDoubleLiteral: 688 case kDoubleLiteral:
688 builder_->SkipStringReference(); // read index into string table. 689 builder_->SkipStringReference(); // read index into string table.
689 return; 690 return;
690 case kTrueLiteral: 691 case kTrueLiteral:
691 return; 692 return;
692 case kFalseLiteral: 693 case kFalseLiteral:
693 return; 694 return;
694 case kNullLiteral: 695 case kNullLiteral:
695 return; 696 return;
697 case kVectorCreation:
698 builder_->ReadUInt(); // read size.
699 return;
700 case kVectorGet:
701 VisitExpression(); // read expression.
702 builder_->ReadUInt(); // read index.
703 return;
704 case kVectorSet:
705 VisitExpression(); // read vector expression.
706 builder_->ReadUInt(); // read index.
707 VisitExpression(); // read value.
708 return;
709 case kVectorCopy:
710 VisitExpression(); // read vector expression.
711 return;
712 case kClosureCreation:
713 builder_->SkipCanonicalNameReference(); // read function reference.
714 VisitExpression(); // read context vector.
715 VisitDartType(); // read function type of the closure.
716 return;
696 default: 717 default:
697 UNREACHABLE(); 718 UNREACHABLE();
698 } 719 }
699 } 720 }
700 721
701 void StreamingScopeBuilder::VisitStatement() { 722 void StreamingScopeBuilder::VisitStatement() {
702 Tag tag = builder_->ReadTag(); // read tag. 723 Tag tag = builder_->ReadTag(); // read tag.
703 switch (tag) { 724 switch (tag) {
704 case kInvalidStatement: 725 case kInvalidStatement:
705 return; 726 return;
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 result_->locals.Insert(kernel_offset_no_tag, variable); 1046 result_->locals.Insert(kernel_offset_no_tag, variable);
1026 } 1047 }
1027 1048
1028 void StreamingScopeBuilder::VisitDartType() { 1049 void StreamingScopeBuilder::VisitDartType() {
1029 Tag tag = builder_->ReadTag(); 1050 Tag tag = builder_->ReadTag();
1030 switch (tag) { 1051 switch (tag) {
1031 case kInvalidType: 1052 case kInvalidType:
1032 case kDynamicType: 1053 case kDynamicType:
1033 case kVoidType: 1054 case kVoidType:
1034 case kBottomType: 1055 case kBottomType:
1056 case kVectorType:
1035 // those contain nothing. 1057 // those contain nothing.
1036 return; 1058 return;
1037 case kInterfaceType: 1059 case kInterfaceType:
1038 VisitInterfaceType(false); 1060 VisitInterfaceType(false);
1039 return; 1061 return;
1040 case kSimpleInterfaceType: 1062 case kSimpleInterfaceType:
1041 VisitInterfaceType(true); 1063 VisitInterfaceType(true);
1042 return; 1064 return;
1043 case kFunctionType: 1065 case kFunctionType:
1044 VisitFunctionType(false); 1066 VisitFunctionType(false);
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 Error::Handle(Z), // No previous error. 1458 Error::Handle(Z), // No previous error.
1437 dart::Script::Handle(Z, dart::Script::null()), 1459 dart::Script::Handle(Z, dart::Script::null()),
1438 TokenPosition::kNoSource, "[InvalidType] in Kernel IR."); 1460 TokenPosition::kNoSource, "[InvalidType] in Kernel IR.");
1439 break; 1461 break;
1440 case kDynamicType: 1462 case kDynamicType:
1441 result_ = Object::dynamic_type().raw(); 1463 result_ = Object::dynamic_type().raw();
1442 break; 1464 break;
1443 case kVoidType: 1465 case kVoidType:
1444 result_ = Object::void_type().raw(); 1466 result_ = Object::void_type().raw();
1445 break; 1467 break;
1468 case kVectorType:
1469 result_ = Object::vector_type().raw();
1470 break;
1446 case kBottomType: 1471 case kBottomType:
1447 result_ = dart::Class::Handle(Z, I->object_store()->null_class()) 1472 result_ = dart::Class::Handle(Z, I->object_store()->null_class())
1448 .CanonicalType(); 1473 .CanonicalType();
1449 break; 1474 break;
1450 case kInterfaceType: 1475 case kInterfaceType:
1451 BuildInterfaceType(false); 1476 BuildInterfaceType(false);
1452 break; 1477 break;
1453 case kSimpleInterfaceType: 1478 case kSimpleInterfaceType:
1454 BuildInterfaceType(true); 1479 BuildInterfaceType(true);
1455 break; 1480 break;
(...skipping 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after
3134 argument_names); 3159 argument_names);
3135 3160
3136 // Return the result. 3161 // Return the result.
3137 body += Return(end_position); 3162 body += Return(end_position);
3138 3163
3139 return new (Z) 3164 return new (Z)
3140 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, 3165 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
3141 flow_graph_builder_->next_block_id_ - 1); 3166 flow_graph_builder_->next_block_id_ - 1);
3142 } 3167 }
3143 3168
3169
3170 // This method follows the logic similar to that of
kustermann 2017/06/20 12:13:14 s/follows the logic .... of/follows the logic of/
Dmitry Stefantsov 2017/06/22 14:12:52 Agreed. It reads better. Thanks!
3171 // StreamingFlowGraphBuilder::BuildGraphOfImplicitClosureFunction. For
3172 // additional details on converted closure functions, please, see the comment on
3173 // the method Function::ConvertedClosureFunction.
3174 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfConvertedClosureFunction(
3175 const Function& function) {
kustermann 2017/06/20 12:13:13 Given the significant duplication of code, maybe c
Dmitry Stefantsov 2017/06/22 14:12:52 I agree, we may benefit from the parametrization.
kustermann 2017/06/26 10:32:36 Just keep it then.
3176 const Function& target = Function::ZoneHandle(Z, function.parent_function());
3177
3178 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry();
3179 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr(
3180 *parsed_function(), normal_entry, Compiler::kNoOSRDeoptId);
3181 SetupDefaultParameterValues();
3182
3183 Fragment body(normal_entry);
3184 body += flow_graph_builder_->CheckStackOverflowInPrologue();
3185
3186 // Load all the arguments.
3187 ASSERT(target.is_static());
3188
3189 TokenPosition end_position;
3190 ReadFunctionNodeUntilTypeParameters(
3191 &unused_tokenposition, &end_position, &unused_word,
3192 &unused_word); // read first part of function node.
3193 SkipTypeParametersList(); // read type parameter list.
3194 ReadUInt(); // read total parameter count.
3195 ReadUInt(); // read required_parameter_count.
3196
3197 // Positional.
3198 intptr_t positional_argument_count = ReadListLength();
kustermann 2017/06/20 12:13:14 Usually we try to use "const" where possible. (als
Dmitry Stefantsov 2017/06/22 14:12:52 Do you mean something like `const intptr_t positio
kustermann 2017/06/26 10:32:36 It's fine to just change your code. The benefit of
3199
3200 // The first argument is the instance of the closure class. For converted
3201 // closures its context field contains the context vector that is used by the
3202 // converted top-level function (target) explicitly and that should be passed
3203 // to that function as the first parameter.
3204 body += LoadLocal(LookupVariable(ReaderOffset())); // 0th variable offset.
3205 body += flow_graph_builder_->LoadField(Closure::context_offset());
3206 body += PushArgument();
3207 SkipVariableDeclaration(); // read 0th variable.
3208
3209 // The rest of the parameters are the same for the method of the Closure class
3210 // being invoked and the top-level function (target).
3211 for (intptr_t i = 1; i < positional_argument_count; i++) {
3212 body += LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3213 body += PushArgument();
3214 SkipVariableDeclaration(); // read ith variable.
3215 }
3216
3217 // Named.
3218 intptr_t named_argument_count = ReadListLength();
3219 Array& argument_names = Array::ZoneHandle(Z);
3220 if (named_argument_count > 0) {
3221 argument_names = Array::New(named_argument_count);
3222 for (intptr_t i = 0; i < named_argument_count; i++) {
3223 body +=
3224 LoadLocal(LookupVariable(ReaderOffset())); // ith variable offset.
3225 body += PushArgument();
3226 argument_names.SetAt(
3227 i, H.DartSymbol(GetNameFromVariableDeclaration(ReaderOffset())));
3228 SkipVariableDeclaration(); // read ith variable.
3229 }
3230 }
3231
3232 // Forward them to the target.
3233 intptr_t argument_count = positional_argument_count + named_argument_count;
3234 body += StaticCall(TokenPosition::kNoSource, target, argument_count,
3235 argument_names);
3236
3237 // Return the result.
3238 body += Return(end_position);
3239
3240 return new (Z)
3241 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_,
3242 flow_graph_builder_->next_block_id_ - 1);
3243 }
3244
3245
3144 static bool IsGetMainClosure(const String& name) { 3246 static bool IsGetMainClosure(const String& name) {
3145 if (name.Length() < 16) return false; 3247 if (name.Length() < 16) return false;
3146 const char* cstr = "_getMainClosure@"; 3248 const char* cstr = "_getMainClosure@";
3147 for (intptr_t i = 0; i < 16; ++i) { 3249 for (intptr_t i = 0; i < 16; ++i) {
3148 if (name.CharAt(i) != cstr[i]) return false; 3250 if (name.CharAt(i) != cstr[i]) return false;
3149 } 3251 }
3150 return true; 3252 return true;
3151 } 3253 }
3152 3254
3153 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction( 3255 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction(
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
3557 // will not need an AST. The code generator will assume that there is a 3659 // will not need an AST. The code generator will assume that there is a
3558 // local variable stack slot allocated for the current context and (I 3660 // local variable stack slot allocated for the current context and (I
3559 // think) that the runtime will expect it to be at a fixed offset which 3661 // think) that the runtime will expect it to be at a fixed offset which
3560 // requires allocating an unused expression temporary variable. 3662 // requires allocating an unused expression temporary variable.
3561 set_scopes(parsed_function()->EnsureKernelScopes()); 3663 set_scopes(parsed_function()->EnsureKernelScopes());
3562 3664
3563 SetOffset(kernel_offset); 3665 SetOffset(kernel_offset);
3564 3666
3565 switch (function.kind()) { 3667 switch (function.kind()) {
3566 case RawFunction::kClosureFunction: 3668 case RawFunction::kClosureFunction:
3669 case RawFunction::kConvertedClosureFunction:
3567 case RawFunction::kRegularFunction: 3670 case RawFunction::kRegularFunction:
3568 case RawFunction::kGetterFunction: 3671 case RawFunction::kGetterFunction:
3569 case RawFunction::kSetterFunction: { 3672 case RawFunction::kSetterFunction: {
3570 ReadUntilFunctionNode(); // read until function node. 3673 ReadUntilFunctionNode(); // read until function node.
3571 return function.IsImplicitClosureFunction() 3674 if (function.IsImplicitClosureFunction()) {
3572 ? BuildGraphOfImplicitClosureFunction(function) 3675 return BuildGraphOfImplicitClosureFunction(function);
3573 : BuildGraphOfFunction(is_in_builtin_library_toplevel); 3676 } else if (function.IsConvertedClosureFunction()) {
3677 return BuildGraphOfConvertedClosureFunction(function);
3678 }
3679 return BuildGraphOfFunction(is_in_builtin_library_toplevel);
3574 } 3680 }
3575 case RawFunction::kConstructor: { 3681 case RawFunction::kConstructor: {
3576 bool is_factory = function.IsFactory(); 3682 bool is_factory = function.IsFactory();
3577 if (is_factory) { 3683 if (is_factory) {
3578 ReadUntilFunctionNode(); // read until function node. 3684 ReadUntilFunctionNode(); // read until function node.
3579 return BuildGraphOfFunction(is_in_builtin_library_toplevel); 3685 return BuildGraphOfFunction(is_in_builtin_library_toplevel);
3580 } else { 3686 } else {
3581 // Constructor: Pass offset to parent class. 3687 // Constructor: Pass offset to parent class.
3582 return BuildGraphOfFunction( 3688 return BuildGraphOfFunction(
3583 is_in_builtin_library_toplevel, 3689 is_in_builtin_library_toplevel,
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
3694 case kPositiveIntLiteral: 3800 case kPositiveIntLiteral:
3695 return BuildIntLiteral(false, position); 3801 return BuildIntLiteral(false, position);
3696 case kDoubleLiteral: 3802 case kDoubleLiteral:
3697 return BuildDoubleLiteral(position); 3803 return BuildDoubleLiteral(position);
3698 case kTrueLiteral: 3804 case kTrueLiteral:
3699 return BuildBoolLiteral(true, position); 3805 return BuildBoolLiteral(true, position);
3700 case kFalseLiteral: 3806 case kFalseLiteral:
3701 return BuildBoolLiteral(false, position); 3807 return BuildBoolLiteral(false, position);
3702 case kNullLiteral: 3808 case kNullLiteral:
3703 return BuildNullLiteral(position); 3809 return BuildNullLiteral(position);
3810 case kVectorCreation:
3811 return BuildVectorCreation(position);
3812 case kVectorGet:
3813 return BuildVectorGet(position);
3814 case kVectorSet:
3815 return BuildVectorSet(position);
3816 case kVectorCopy:
3817 return BuildVectorCopy(position);
3818 case kClosureCreation:
3819 return BuildClosureCreation(position);
3704 default: 3820 default:
3705 UNREACHABLE(); 3821 UNREACHABLE();
3706 } 3822 }
3707 3823
3708 return Fragment(); 3824 return Fragment();
3709 } 3825 }
3710 3826
3711 Fragment StreamingFlowGraphBuilder::BuildStatement() { 3827 Fragment StreamingFlowGraphBuilder::BuildStatement() {
3712 Tag tag = ReadTag(); // read tag. 3828 Tag tag = ReadTag(); // read tag.
3713 switch (tag) { 3829 switch (tag) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
3849 ReadUInt(); 3965 ReadUInt();
3850 } 3966 }
3851 3967
3852 void StreamingFlowGraphBuilder::SkipDartType() { 3968 void StreamingFlowGraphBuilder::SkipDartType() {
3853 Tag tag = ReadTag(); 3969 Tag tag = ReadTag();
3854 switch (tag) { 3970 switch (tag) {
3855 case kInvalidType: 3971 case kInvalidType:
3856 case kDynamicType: 3972 case kDynamicType:
3857 case kVoidType: 3973 case kVoidType:
3858 case kBottomType: 3974 case kBottomType:
3975 case kVectorType:
3859 // those contain nothing. 3976 // those contain nothing.
3860 return; 3977 return;
3861 case kInterfaceType: 3978 case kInterfaceType:
3862 SkipInterfaceType(false); 3979 SkipInterfaceType(false);
3863 return; 3980 return;
3864 case kSimpleInterfaceType: 3981 case kSimpleInterfaceType:
3865 SkipInterfaceType(true); 3982 SkipInterfaceType(true);
3866 return; 3983 return;
3867 case kFunctionType: 3984 case kFunctionType:
3868 SkipFunctionType(false); 3985 SkipFunctionType(false);
(...skipping 24 matching lines...) Expand all
3893 void StreamingFlowGraphBuilder::SkipInterfaceType(bool simple) { 4010 void StreamingFlowGraphBuilder::SkipInterfaceType(bool simple) {
3894 ReadUInt(); // read klass_name. 4011 ReadUInt(); // read klass_name.
3895 if (!simple) { 4012 if (!simple) {
3896 SkipListOfDartTypes(); // read list of types. 4013 SkipListOfDartTypes(); // read list of types.
3897 } 4014 }
3898 } 4015 }
3899 4016
3900 void StreamingFlowGraphBuilder::SkipFunctionType(bool simple) { 4017 void StreamingFlowGraphBuilder::SkipFunctionType(bool simple) {
3901 if (!simple) { 4018 if (!simple) {
3902 SkipTypeParametersList(); // read type_parameters. 4019 SkipTypeParametersList(); // read type_parameters.
3903 ReadUInt(); // read required parameter count. 4020 ReadUInt(); // read required parameter count.
3904 ReadUInt(); // read total parameter count. 4021 ReadUInt(); // read total parameter count.
3905 } 4022 }
3906 4023
3907 SkipListOfDartTypes(); // read positional_parameters types. 4024 SkipListOfDartTypes(); // read positional_parameters types.
3908 4025
3909 if (!simple) { 4026 if (!simple) {
3910 const intptr_t named_count = 4027 const intptr_t named_count =
3911 ReadListLength(); // read named_parameters list length. 4028 ReadListLength(); // read named_parameters list length.
3912 for (intptr_t i = 0; i < named_count; ++i) { 4029 for (intptr_t i = 0; i < named_count; ++i) {
3913 // read string reference (i.e. named_parameters[i].name). 4030 // read string reference (i.e. named_parameters[i].name).
3914 SkipStringReference(); 4031 SkipStringReference();
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
4043 SkipBytes(1); // read operator. 4160 SkipBytes(1); // read operator.
4044 SkipExpression(); // read right. 4161 SkipExpression(); // read right.
4045 return; 4162 return;
4046 case kConditionalExpression: 4163 case kConditionalExpression:
4047 SkipExpression(); // read condition. 4164 SkipExpression(); // read condition.
4048 SkipExpression(); // read then. 4165 SkipExpression(); // read then.
4049 SkipExpression(); // read otherwise. 4166 SkipExpression(); // read otherwise.
4050 SkipOptionalDartType(); // read unused static type. 4167 SkipOptionalDartType(); // read unused static type.
4051 return; 4168 return;
4052 case kStringConcatenation: 4169 case kStringConcatenation:
4053 ReadPosition(); // read position. 4170 ReadPosition(); // read position.
4054 SkipListOfExpressions(); // read list of expressions. 4171 SkipListOfExpressions(); // read list of expressions.
4055 return; 4172 return;
4056 case kIsExpression: 4173 case kIsExpression:
4057 ReadPosition(); // read position. 4174 ReadPosition(); // read position.
4058 SkipExpression(); // read operand. 4175 SkipExpression(); // read operand.
4059 SkipDartType(); // read type. 4176 SkipDartType(); // read type.
4060 return; 4177 return;
4061 case kAsExpression: 4178 case kAsExpression:
4062 ReadPosition(); // read position. 4179 ReadPosition(); // read position.
4063 SkipExpression(); // read operand. 4180 SkipExpression(); // read operand.
4064 SkipDartType(); // read type. 4181 SkipDartType(); // read type.
4065 return; 4182 return;
4066 case kSymbolLiteral: 4183 case kSymbolLiteral:
4067 SkipStringReference(); // read index into string table. 4184 SkipStringReference(); // read index into string table.
4068 return; 4185 return;
4069 case kTypeLiteral: 4186 case kTypeLiteral:
4070 SkipDartType(); // read type. 4187 SkipDartType(); // read type.
4071 return; 4188 return;
4072 case kThisExpression: 4189 case kThisExpression:
4073 return; 4190 return;
4074 case kRethrow: 4191 case kRethrow:
4075 ReadPosition(); // read position. 4192 ReadPosition(); // read position.
4076 return; 4193 return;
4077 case kThrow: 4194 case kThrow:
4078 ReadPosition(); // read position. 4195 ReadPosition(); // read position.
4079 SkipExpression(); // read expression. 4196 SkipExpression(); // read expression.
4080 return; 4197 return;
4081 case kListLiteral: 4198 case kListLiteral:
4082 case kConstListLiteral: 4199 case kConstListLiteral:
4083 ReadPosition(); // read position. 4200 ReadPosition(); // read position.
4084 SkipDartType(); // read type. 4201 SkipDartType(); // read type.
4085 SkipListOfExpressions(); // read list of expressions. 4202 SkipListOfExpressions(); // read list of expressions.
4086 return; 4203 return;
4087 case kMapLiteral: 4204 case kMapLiteral:
4088 case kConstMapLiteral: { 4205 case kConstMapLiteral: {
4089 ReadPosition(); // read position. 4206 ReadPosition(); // read position.
4090 SkipDartType(); // read key type. 4207 SkipDartType(); // read key type.
4091 SkipDartType(); // read value type. 4208 SkipDartType(); // read value type.
4092 intptr_t list_length = ReadListLength(); // read list length. 4209 intptr_t list_length = ReadListLength(); // read list length.
4093 for (intptr_t i = 0; i < list_length; ++i) { 4210 for (intptr_t i = 0; i < list_length; ++i) {
4094 SkipExpression(); // read ith key. 4211 SkipExpression(); // read ith key.
4095 SkipExpression(); // read ith value. 4212 SkipExpression(); // read ith value.
4096 } 4213 }
4097 return; 4214 return;
4098 } 4215 }
4099 case kFunctionExpression: 4216 case kFunctionExpression:
4100 SkipFunctionNode(); // read function node. 4217 SkipFunctionNode(); // read function node.
4101 return; 4218 return;
4102 case kLet: 4219 case kLet:
4103 SkipVariableDeclaration(); // read variable declaration. 4220 SkipVariableDeclaration(); // read variable declaration.
4104 SkipExpression(); // read expression. 4221 SkipExpression(); // read expression.
4105 return; 4222 return;
4223 case kVectorCreation:
4224 ReadUInt(); // read value.
4225 return;
4226 case kVectorGet:
4227 SkipExpression(); // read vector expression.
4228 ReadUInt(); // read index.
4229 return;
4230 case kVectorSet:
4231 SkipExpression(); // read vector expression.
4232 ReadUInt(); // read index.
4233 SkipExpression(); // read value.
4234 return;
4235 case kVectorCopy:
4236 SkipExpression(); // read vector expression.
4237 return;
4238 case kClosureCreation:
4239 SkipCanonicalNameReference(); // read top-level function reference.
4240 SkipExpression(); // read context vector.
4241 SkipDartType(); // read function type.
4242 return;
4106 case kBigIntLiteral: 4243 case kBigIntLiteral:
4107 SkipStringReference(); // read string reference. 4244 SkipStringReference(); // read string reference.
4108 return; 4245 return;
4109 case kStringLiteral: 4246 case kStringLiteral:
4110 SkipStringReference(); // read string reference. 4247 SkipStringReference(); // read string reference.
4111 return; 4248 return;
4112 case kSpecialIntLiteral: 4249 case kSpecialIntLiteral:
4113 return; 4250 return;
4114 case kNegativeIntLiteral: 4251 case kNegativeIntLiteral:
4115 ReadUInt(); // read value. 4252 ReadUInt(); // read value.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4168 case kWhileStatement: 4305 case kWhileStatement:
4169 SkipExpression(); // read condition. 4306 SkipExpression(); // read condition.
4170 SkipStatement(); // read body. 4307 SkipStatement(); // read body.
4171 return; 4308 return;
4172 case kDoStatement: 4309 case kDoStatement:
4173 SkipStatement(); // read body. 4310 SkipStatement(); // read body.
4174 SkipExpression(); // read condition. 4311 SkipExpression(); // read condition.
4175 return; 4312 return;
4176 case kForStatement: { 4313 case kForStatement: {
4177 SkipListOfVariableDeclarations(); // read variables. 4314 SkipListOfVariableDeclarations(); // read variables.
4178 Tag tag = ReadTag(); // Read first part of condition. 4315 Tag tag = ReadTag(); // Read first part of condition.
4179 if (tag == kSomething) { 4316 if (tag == kSomething) {
4180 SkipExpression(); // read rest of condition. 4317 SkipExpression(); // read rest of condition.
4181 } 4318 }
4182 SkipListOfExpressions(); // read updates. 4319 SkipListOfExpressions(); // read updates.
4183 SkipStatement(); // read body. 4320 SkipStatement(); // read body.
4184 return; 4321 return;
4185 } 4322 }
4186 case kForInStatement: 4323 case kForInStatement:
4187 case kAsyncForInStatement: 4324 case kAsyncForInStatement:
4188 ReadPosition(); // read position. 4325 ReadPosition(); // read position.
4189 SkipVariableDeclaration(); // read variable. 4326 SkipVariableDeclaration(); // read variable.
4190 SkipExpression(); // read iterable. 4327 SkipExpression(); // read iterable.
4191 SkipStatement(); // read body. 4328 SkipStatement(); // read body.
4192 return; 4329 return;
4193 case kSwitchStatement: { 4330 case kSwitchStatement: {
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
4416 4553
4417 GrowableArray<YieldContinuation>& 4554 GrowableArray<YieldContinuation>&
4418 StreamingFlowGraphBuilder::yield_continuations() { 4555 StreamingFlowGraphBuilder::yield_continuations() {
4419 return flow_graph_builder_->yield_continuations_; 4556 return flow_graph_builder_->yield_continuations_;
4420 } 4557 }
4421 4558
4422 Value* StreamingFlowGraphBuilder::stack() { 4559 Value* StreamingFlowGraphBuilder::stack() {
4423 return flow_graph_builder_->stack_; 4560 return flow_graph_builder_->stack_;
4424 } 4561 }
4425 4562
4563 void StreamingFlowGraphBuilder::Push(Definition* definition) {
4564 flow_graph_builder_->Push(definition);
4565 }
4566
4426 Value* StreamingFlowGraphBuilder::Pop() { 4567 Value* StreamingFlowGraphBuilder::Pop() {
4427 return flow_graph_builder_->Pop(); 4568 return flow_graph_builder_->Pop();
4428 } 4569 }
4429 4570
4430 Tag StreamingFlowGraphBuilder::PeekArgumentsFirstPositionalTag() { 4571 Tag StreamingFlowGraphBuilder::PeekArgumentsFirstPositionalTag() {
4431 // read parts of arguments, then go back to before doing so. 4572 // read parts of arguments, then go back to before doing so.
4432 AlternativeReadingScope alt(reader_); 4573 AlternativeReadingScope alt(reader_);
4433 ReadUInt(); // read number of arguments. 4574 ReadUInt(); // read number of arguments.
4434 4575
4435 SkipListOfDartTypes(); // Read list of types. 4576 SkipListOfDartTypes(); // Read list of types.
(...skipping 16 matching lines...) Expand all
4452 intptr_t list_length = ReadListLength(); // read types list length. 4593 intptr_t list_length = ReadListLength(); // read types list length.
4453 return T.BuildInstantiatedTypeArguments(klass, list_length); // read types. 4594 return T.BuildInstantiatedTypeArguments(klass, list_length); // read types.
4454 } 4595 }
4455 4596
4456 intptr_t StreamingFlowGraphBuilder::PeekArgumentsCount() { 4597 intptr_t StreamingFlowGraphBuilder::PeekArgumentsCount() {
4457 return PeekUInt(); 4598 return PeekUInt();
4458 } 4599 }
4459 4600
4460 intptr_t StreamingFlowGraphBuilder::PeekArgumentsTypeCount() { 4601 intptr_t StreamingFlowGraphBuilder::PeekArgumentsTypeCount() {
4461 AlternativeReadingScope alt(reader_); 4602 AlternativeReadingScope alt(reader_);
4462 ReadUInt(); // read arguments count. 4603 ReadUInt(); // read arguments count.
4463 return ReadListLength(); // read length of types list. 4604 return ReadListLength(); // read length of types list.
4464 } 4605 }
4465 4606
4466 void StreamingFlowGraphBuilder::SkipArgumentsBeforeActualArguments() { 4607 void StreamingFlowGraphBuilder::SkipArgumentsBeforeActualArguments() {
4467 ReadUInt(); // read arguments count. 4608 ReadUInt(); // read arguments count.
4468 SkipListOfDartTypes(); // read list of types. 4609 SkipListOfDartTypes(); // read list of types.
4469 } 4610 }
4470 4611
4471 LocalVariable* StreamingFlowGraphBuilder::LookupVariable( 4612 LocalVariable* StreamingFlowGraphBuilder::LookupVariable(
4472 intptr_t kernel_offset) { 4613 intptr_t kernel_offset) {
4473 return flow_graph_builder_->LookupVariable(kernel_offset); 4614 return flow_graph_builder_->LookupVariable(kernel_offset);
4474 } 4615 }
4475 4616
4476 LocalVariable* StreamingFlowGraphBuilder::MakeTemporary() { 4617 LocalVariable* StreamingFlowGraphBuilder::MakeTemporary() {
4477 return flow_graph_builder_->MakeTemporary(); 4618 return flow_graph_builder_->MakeTemporary();
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4582 Fragment StreamingFlowGraphBuilder::StrictCompare(Token::Kind kind, 4723 Fragment StreamingFlowGraphBuilder::StrictCompare(Token::Kind kind,
4583 bool number_check) { 4724 bool number_check) {
4584 return flow_graph_builder_->StrictCompare(kind, number_check); 4725 return flow_graph_builder_->StrictCompare(kind, number_check);
4585 } 4726 }
4586 4727
4587 Fragment StreamingFlowGraphBuilder::AllocateObject(const dart::Class& klass, 4728 Fragment StreamingFlowGraphBuilder::AllocateObject(const dart::Class& klass,
4588 intptr_t argument_count) { 4729 intptr_t argument_count) {
4589 return flow_graph_builder_->AllocateObject(klass, argument_count); 4730 return flow_graph_builder_->AllocateObject(klass, argument_count);
4590 } 4731 }
4591 4732
4733 Fragment StreamingFlowGraphBuilder::AllocateObject(
4734 const dart::Class& klass,
4735 const Function& closure_function) {
4736 return flow_graph_builder_->AllocateObject(klass, closure_function);
4737 }
4738
4739 Fragment StreamingFlowGraphBuilder::AllocateContext(int size) {
4740 return flow_graph_builder_->AllocateContext(size);
4741 }
4742
4743 Fragment StreamingFlowGraphBuilder::LoadField(intptr_t offset) {
4744 return flow_graph_builder_->LoadField(offset);
4745 }
4746
4592 Fragment StreamingFlowGraphBuilder::InstanceCall(TokenPosition position, 4747 Fragment StreamingFlowGraphBuilder::InstanceCall(TokenPosition position,
4593 const dart::String& name, 4748 const dart::String& name,
4594 Token::Kind kind, 4749 Token::Kind kind,
4595 intptr_t argument_count, 4750 intptr_t argument_count,
4596 const Array& argument_names, 4751 const Array& argument_names,
4597 intptr_t num_args_checked) { 4752 intptr_t num_args_checked) {
4598 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, 4753 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count,
4599 argument_names, num_args_checked); 4754 argument_names, num_args_checked);
4600 } 4755 }
4601 4756
4602 Fragment StreamingFlowGraphBuilder::StoreLocal(TokenPosition position, 4757 Fragment StreamingFlowGraphBuilder::StoreLocal(TokenPosition position,
4603 LocalVariable* variable) { 4758 LocalVariable* variable) {
4604 return flow_graph_builder_->StoreLocal(position, variable); 4759 return flow_graph_builder_->StoreLocal(position, variable);
4605 } 4760 }
4606 4761
4607 Fragment StreamingFlowGraphBuilder::StoreStaticField(TokenPosition position, 4762 Fragment StreamingFlowGraphBuilder::StoreStaticField(TokenPosition position,
4608 const dart::Field& field) { 4763 const dart::Field& field) {
4609 return flow_graph_builder_->StoreStaticField(position, field); 4764 return flow_graph_builder_->StoreStaticField(position, field);
4610 } 4765 }
4611 4766
4767 Fragment StreamingFlowGraphBuilder::StoreInstanceField(TokenPosition position,
4768 intptr_t offset) {
4769 return flow_graph_builder_->StoreInstanceField(position, offset);
4770 }
4771
4612 Fragment StreamingFlowGraphBuilder::StringInterpolate(TokenPosition position) { 4772 Fragment StreamingFlowGraphBuilder::StringInterpolate(TokenPosition position) {
4613 return flow_graph_builder_->StringInterpolate(position); 4773 return flow_graph_builder_->StringInterpolate(position);
4614 } 4774 }
4615 4775
4616 Fragment StreamingFlowGraphBuilder::StringInterpolateSingle( 4776 Fragment StreamingFlowGraphBuilder::StringInterpolateSingle(
4617 TokenPosition position) { 4777 TokenPosition position) {
4618 return flow_graph_builder_->StringInterpolateSingle(position); 4778 return flow_graph_builder_->StringInterpolateSingle(position);
4619 } 4779 }
4620 4780
4621 Fragment StreamingFlowGraphBuilder::ThrowTypeError() { 4781 Fragment StreamingFlowGraphBuilder::ThrowTypeError() {
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after
5512 5672
5513 // Let condition be always true. 5673 // Let condition be always true.
5514 instructions += Constant(Bool::True()); 5674 instructions += Constant(Bool::True());
5515 } else { 5675 } else {
5516 instructions += PushArgument(); 5676 instructions += PushArgument();
5517 5677
5518 // See if simple instanceOf is applicable. 5678 // See if simple instanceOf is applicable.
5519 if (dart::FlowGraphBuilder::SimpleInstanceOfType(type)) { 5679 if (dart::FlowGraphBuilder::SimpleInstanceOfType(type)) {
5520 instructions += Constant(type); 5680 instructions += Constant(type);
5521 instructions += PushArgument(); // Type. 5681 instructions += PushArgument(); // Type.
5522 instructions += InstanceCall(position, dart::Library::PrivateCoreLibName( 5682 instructions += InstanceCall(
5523 Symbols::_simpleInstanceOf()), 5683 position,
5524 Token::kIS, 2, 2); // 2 checked arguments. 5684 dart::Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()),
5685 Token::kIS, 2, 2); // 2 checked arguments.
5525 return instructions; 5686 return instructions;
5526 } 5687 }
5527 5688
5528 if (!type.IsInstantiated(kCurrentClass)) { 5689 if (!type.IsInstantiated(kCurrentClass)) {
5529 instructions += LoadInstantiatorTypeArguments(); 5690 instructions += LoadInstantiatorTypeArguments();
5530 } else { 5691 } else {
5531 instructions += NullConstant(); 5692 instructions += NullConstant();
5532 } 5693 }
5533 instructions += PushArgument(); // Instantiator type arguments. 5694 instructions += PushArgument(); // Instantiator type arguments.
5534 5695
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
5782 } 5943 }
5783 5944
5784 Fragment StreamingFlowGraphBuilder::BuildFunctionExpression() { 5945 Fragment StreamingFlowGraphBuilder::BuildFunctionExpression() {
5785 intptr_t offset = ReaderOffset() - 1; // -1 to include tag byte. 5946 intptr_t offset = ReaderOffset() - 1; // -1 to include tag byte.
5786 return BuildFunctionNode(offset, TokenPosition::kNoSource, false, -1); 5947 return BuildFunctionNode(offset, TokenPosition::kNoSource, false, -1);
5787 } 5948 }
5788 5949
5789 Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) { 5950 Fragment StreamingFlowGraphBuilder::BuildLet(TokenPosition* position) {
5790 if (position != NULL) *position = TokenPosition::kNoSource; 5951 if (position != NULL) *position = TokenPosition::kNoSource;
5791 5952
5792 Fragment instructions = BuildVariableDeclaration(); // read variable. 5953 Fragment instructions = BuildVariableDeclaration(); // read variable.
5793 instructions += BuildExpression(); // read body. 5954 instructions += BuildExpression(); // read body.
5794 return instructions; 5955 return instructions;
5795 } 5956 }
5796 5957
5797 5958
5798 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral( 5959 Fragment StreamingFlowGraphBuilder::BuildBigIntLiteral(
5799 TokenPosition* position) { 5960 TokenPosition* position) {
5800 if (position != NULL) *position = TokenPosition::kNoSource; 5961 if (position != NULL) *position = TokenPosition::kNoSource;
5801 5962
5802 const dart::String& value = 5963 const dart::String& value =
5803 H.DartString(ReadStringReference()); // read index into string table. 5964 H.DartString(ReadStringReference()); // read index into string table.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
5844 6005
5845 return Constant(Bool::Get(value)); 6006 return Constant(Bool::Get(value));
5846 } 6007 }
5847 6008
5848 Fragment StreamingFlowGraphBuilder::BuildNullLiteral(TokenPosition* position) { 6009 Fragment StreamingFlowGraphBuilder::BuildNullLiteral(TokenPosition* position) {
5849 if (position != NULL) *position = TokenPosition::kNoSource; 6010 if (position != NULL) *position = TokenPosition::kNoSource;
5850 6011
5851 return Constant(Instance::ZoneHandle(Z, Instance::null())); 6012 return Constant(Instance::ZoneHandle(Z, Instance::null()));
5852 } 6013 }
5853 6014
6015 Fragment StreamingFlowGraphBuilder::BuildVectorCreation(
6016 TokenPosition* position) {
6017 if (position != NULL) *position = TokenPosition::kNoSource;
6018
6019 intptr_t size = ReadUInt(); // read size.
6020 return AllocateContext(size);
6021 }
6022
6023 Fragment StreamingFlowGraphBuilder::BuildVectorGet(TokenPosition* position) {
6024 if (position != NULL) *position = TokenPosition::kNoSource;
6025
6026 Fragment instructions = BuildExpression(); // read expression.
6027 intptr_t index = ReadUInt(); // read index.
6028 instructions += LoadField(Context::variable_offset(index));
6029 return instructions;
6030 }
6031
6032 Fragment StreamingFlowGraphBuilder::BuildVectorSet(TokenPosition* position) {
6033 if (position != NULL) *position = TokenPosition::kNoSource;
6034
6035 Fragment instructions = BuildExpression(); // read vector expression.
6036 intptr_t index = ReadUInt(); // read index.
6037 instructions += BuildExpression(); // read value expression.
6038
6039 // The assigned value is the result of the expression.
6040 LocalVariable* result = MakeTemporary();
kustermann 2017/06/20 12:13:14 I suspect this is unsafe: The MakeTemporary() mak
Dmitry Stefantsov 2017/06/22 14:12:52 Thank you so much for pointing me to that! Indeed
6041
6042 Value* value = Pop();
6043 StoreInstanceFieldInstr* store = new (Z)
6044 StoreInstanceFieldInstr(Context::variable_offset(index), Pop(), value,
6045 kNoStoreBarrier, TokenPosition::kNoSource);
6046 instructions <<= store;
6047
6048 // Load the result that is stored in the temporary variable.
6049 instructions += LoadLocal(result);
6050
6051 return instructions;
6052 }
6053
6054 Fragment StreamingFlowGraphBuilder::BuildVectorCopy(TokenPosition* position) {
6055 if (position != NULL) *position = TokenPosition::kNoSource;
6056
6057 Fragment instructions = BuildExpression(); // read vector expression.
6058 CloneContextInstr* clone_instruction = new (Z) CloneContextInstr(
6059 TokenPosition::kNoSource, Pop(), Thread::Current()->GetNextDeoptId());
kustermann 2017/06/20 12:13:13 Maybe introduce local variables, so one knows what
Dmitry Stefantsov 2017/06/22 14:12:52 Thanks! That would read better indeed. Done.
6060 instructions <<= clone_instruction;
6061 Push(clone_instruction);
6062
6063 return instructions;
6064 }
6065
6066 Fragment StreamingFlowGraphBuilder::BuildClosureCreation(
6067 TokenPosition* position) {
6068 if (position != NULL) *position = TokenPosition::kNoSource;
6069
6070 NameIndex function_reference =
6071 ReadCanonicalNameReference(); // read function reference.
6072 Function& function = Function::ZoneHandle(
6073 Z, H.LookupStaticMethodByKernelProcedure(function_reference));
6074 function = function.ConvertedClosureFunction();
6075 ASSERT(!function.IsNull());
6076
6077 const dart::Class& closure_class =
6078 dart::Class::ZoneHandle(Z, I->object_store()->closure_class());
6079 Fragment instructions = AllocateObject(closure_class, function);
6080 LocalVariable* closure = MakeTemporary();
kustermann 2017/06/20 12:13:14 Here for example (as opposed to above), the [closu
Dmitry Stefantsov 2017/06/22 14:12:52 Yep. Now I see it. Thanks!
6081
6082 instructions += BuildExpression(); // read context vector.
6083 LocalVariable* context = MakeTemporary();
6084
6085 instructions += LoadLocal(closure);
6086 instructions += Constant(function);
6087 instructions +=
6088 StoreInstanceField(TokenPosition::kNoSource, Closure::function_offset());
6089
6090 instructions += LoadLocal(closure);
6091 instructions += LoadLocal(context);
6092 instructions +=
6093 StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset());
6094
6095 instructions += Drop();
6096
6097 SkipDartType(); // skip function type of the closure.
6098
6099 return instructions;
6100 }
6101
5854 Fragment StreamingFlowGraphBuilder::BuildInvalidStatement() { 6102 Fragment StreamingFlowGraphBuilder::BuildInvalidStatement() {
5855 H.ReportError("Invalid statements not implemented yet!"); 6103 H.ReportError("Invalid statements not implemented yet!");
5856 return Fragment(); 6104 return Fragment();
5857 } 6105 }
5858 6106
5859 Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() { 6107 Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() {
5860 Fragment instructions = BuildExpression(); // read expression. 6108 Fragment instructions = BuildExpression(); // read expression.
5861 instructions += Drop(); 6109 instructions += Drop();
5862 return instructions; 6110 return instructions;
5863 } 6111 }
(...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after
7136 metadata_values.SetAt(i, value); 7384 metadata_values.SetAt(i, value);
7137 } 7385 }
7138 7386
7139 return metadata_values.raw(); 7387 return metadata_values.raw();
7140 } 7388 }
7141 7389
7142 } // namespace kernel 7390 } // namespace kernel
7143 } // namespace dart 7391 } // namespace dart
7144 7392
7145 #endif // !defined(DART_PRECOMPILED_RUNTIME) 7393 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698