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

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

Issue 881063003: Cleanups: parsed_function()->function() => function() (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.cc » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 ValueGraphVisitor::VisitBinaryOpNode(node); 998 ValueGraphVisitor::VisitBinaryOpNode(node);
999 } 999 }
1000 1000
1001 1001
1002 void EffectGraphVisitor::Bailout(const char* reason) const { 1002 void EffectGraphVisitor::Bailout(const char* reason) const {
1003 owner()->Bailout(reason); 1003 owner()->Bailout(reason);
1004 } 1004 }
1005 1005
1006 1006
1007 void EffectGraphVisitor::InlineBailout(const char* reason) const { 1007 void EffectGraphVisitor::InlineBailout(const char* reason) const {
1008 owner()->parsed_function()->function().set_is_inlinable(false); 1008 owner()->function().set_is_inlinable(false);
1009 if (owner()->IsInlining()) owner()->Bailout(reason); 1009 if (owner()->IsInlining()) owner()->Bailout(reason);
1010 } 1010 }
1011 1011
1012 1012
1013 // <Statement> ::= Return { value: <Expression> 1013 // <Statement> ::= Return { value: <Expression>
1014 // inlined_finally_list: <InlinedFinally>* } 1014 // inlined_finally_list: <InlinedFinally>* }
1015 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { 1015 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
1016 ValueGraphVisitor for_value(owner()); 1016 ValueGraphVisitor for_value(owner());
1017 node->value()->Visit(&for_value); 1017 node->value()->Visit(&for_value);
1018 Append(for_value); 1018 Append(for_value);
(...skipping 13 matching lines...) Expand all
1032 } 1032 }
1033 } 1033 }
1034 return_value = Bind(BuildLoadLocal(*temp)); 1034 return_value = Bind(BuildLoadLocal(*temp));
1035 } 1035 }
1036 1036
1037 // Call to stub that checks whether the debugger is in single 1037 // Call to stub that checks whether the debugger is in single
1038 // step mode. This call must happen before the contexts are 1038 // step mode. This call must happen before the contexts are
1039 // unchained so that captured variables can be inspected. 1039 // unchained so that captured variables can be inspected.
1040 // No debugger check is done in native functions or for return 1040 // No debugger check is done in native functions or for return
1041 // statements for which there is no associated source position. 1041 // statements for which there is no associated source position.
1042 const Function& function = owner()->parsed_function()->function(); 1042 const Function& function = owner()->function();
1043 if ((node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) { 1043 if ((node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) {
1044 AddInstruction(new(I) DebugStepCheckInstr(node->token_pos(), 1044 AddInstruction(new(I) DebugStepCheckInstr(node->token_pos(),
1045 RawPcDescriptors::kRuntimeCall)); 1045 RawPcDescriptors::kRuntimeCall));
1046 } 1046 }
1047 1047
1048 if (FLAG_enable_type_checks) { 1048 if (FLAG_enable_type_checks) {
1049 const bool is_implicit_dynamic_getter = 1049 const bool is_implicit_dynamic_getter =
1050 (!function.is_static() && 1050 (!function.is_static() &&
1051 ((function.kind() == RawFunction::kImplicitGetter) || 1051 ((function.kind() == RawFunction::kImplicitGetter) ||
1052 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); 1052 (function.kind() == RawFunction::kImplicitStaticFinalGetter)));
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 1136
1137 1137
1138 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { 1138 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
1139 const AbstractType& type = node->type(); 1139 const AbstractType& type = node->type();
1140 // Type may be malbounded, but not malformed. 1140 // Type may be malbounded, but not malformed.
1141 ASSERT(type.IsFinalized() && !type.IsMalformed()); 1141 ASSERT(type.IsFinalized() && !type.IsMalformed());
1142 if (type.IsInstantiated()) { 1142 if (type.IsInstantiated()) {
1143 ReturnDefinition(new(I) ConstantInstr(type)); 1143 ReturnDefinition(new(I) ConstantInstr(type));
1144 } else { 1144 } else {
1145 const Class& instantiator_class = Class::ZoneHandle( 1145 const Class& instantiator_class = Class::ZoneHandle(
1146 I, owner()->parsed_function()->function().Owner()); 1146 I, owner()->function().Owner());
1147 Value* instantiator_value = BuildInstantiatorTypeArguments( 1147 Value* instantiator_value = BuildInstantiatorTypeArguments(
1148 node->token_pos(), instantiator_class, NULL); 1148 node->token_pos(), instantiator_class, NULL);
1149 ReturnDefinition(new(I) InstantiateTypeInstr( 1149 ReturnDefinition(new(I) InstantiateTypeInstr(
1150 node->token_pos(), type, instantiator_class, instantiator_value)); 1150 node->token_pos(), type, instantiator_class, instantiator_value));
1151 } 1151 }
1152 } 1152 }
1153 1153
1154 1154
1155 // Returns true if the type check can be skipped, for example, if the 1155 // Returns true if the type check can be skipped, for example, if the
1156 // destination type is dynamic or if the compile type of the value is a subtype 1156 // destination type is dynamic or if the compile type of the value is a subtype
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 owner()->ic_data_array()); 1389 owner()->ic_data_array());
1390 ReturnDefinition(call); 1390 ReturnDefinition(call);
1391 } 1391 }
1392 1392
1393 1393
1394 void EffectGraphVisitor::BuildTypecheckPushArguments( 1394 void EffectGraphVisitor::BuildTypecheckPushArguments(
1395 intptr_t token_pos, 1395 intptr_t token_pos,
1396 PushArgumentInstr** push_instantiator_result, 1396 PushArgumentInstr** push_instantiator_result,
1397 PushArgumentInstr** push_instantiator_type_arguments_result) { 1397 PushArgumentInstr** push_instantiator_type_arguments_result) {
1398 const Class& instantiator_class = Class::Handle( 1398 const Class& instantiator_class = Class::Handle(
1399 I, owner()->parsed_function()->function().Owner()); 1399 I, owner()->function().Owner());
1400 // Since called only when type tested against is not instantiated. 1400 // Since called only when type tested against is not instantiated.
1401 ASSERT(instantiator_class.NumTypeParameters() > 0); 1401 ASSERT(instantiator_class.NumTypeParameters() > 0);
1402 Value* instantiator_type_arguments = NULL; 1402 Value* instantiator_type_arguments = NULL;
1403 Value* instantiator = BuildInstantiator(instantiator_class); 1403 Value* instantiator = BuildInstantiator(instantiator_class);
1404 if (instantiator == NULL) { 1404 if (instantiator == NULL) {
1405 // No instantiator when inside factory. 1405 // No instantiator when inside factory.
1406 *push_instantiator_result = PushArgument(BuildNullValue()); 1406 *push_instantiator_result = PushArgument(BuildNullValue());
1407 instantiator_type_arguments = 1407 instantiator_type_arguments =
1408 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1408 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1409 } else { 1409 } else {
1410 instantiator = Bind(BuildStoreExprTemp(instantiator)); 1410 instantiator = Bind(BuildStoreExprTemp(instantiator));
1411 *push_instantiator_result = PushArgument(instantiator); 1411 *push_instantiator_result = PushArgument(instantiator);
1412 Value* loaded = Bind(BuildLoadExprTemp()); 1412 Value* loaded = Bind(BuildLoadExprTemp());
1413 instantiator_type_arguments = 1413 instantiator_type_arguments =
1414 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); 1414 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded);
1415 } 1415 }
1416 *push_instantiator_type_arguments_result = 1416 *push_instantiator_type_arguments_result =
1417 PushArgument(instantiator_type_arguments); 1417 PushArgument(instantiator_type_arguments);
1418 } 1418 }
1419 1419
1420 1420
1421 1421
1422 void EffectGraphVisitor::BuildTypecheckArguments( 1422 void EffectGraphVisitor::BuildTypecheckArguments(
1423 intptr_t token_pos, 1423 intptr_t token_pos,
1424 Value** instantiator_result, 1424 Value** instantiator_result,
1425 Value** instantiator_type_arguments_result) { 1425 Value** instantiator_type_arguments_result) {
1426 Value* instantiator = NULL; 1426 Value* instantiator = NULL;
1427 Value* instantiator_type_arguments = NULL; 1427 Value* instantiator_type_arguments = NULL;
1428 const Class& instantiator_class = Class::Handle( 1428 const Class& instantiator_class = Class::Handle(
1429 I, owner()->parsed_function()->function().Owner()); 1429 I, owner()->function().Owner());
1430 // Since called only when type tested against is not instantiated. 1430 // Since called only when type tested against is not instantiated.
1431 ASSERT(instantiator_class.NumTypeParameters() > 0); 1431 ASSERT(instantiator_class.NumTypeParameters() > 0);
1432 instantiator = BuildInstantiator(instantiator_class); 1432 instantiator = BuildInstantiator(instantiator_class);
1433 if (instantiator == NULL) { 1433 if (instantiator == NULL) {
1434 // No instantiator when inside factory. 1434 // No instantiator when inside factory.
1435 instantiator = BuildNullValue(); 1435 instantiator = BuildNullValue();
1436 instantiator_type_arguments = 1436 instantiator_type_arguments =
1437 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1437 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1438 } else { 1438 } else {
1439 // Preserve instantiator. 1439 // Preserve instantiator.
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 // The context scope may have already been set by the non-optimizing 2442 // The context scope may have already been set by the non-optimizing
2443 // compiler. If it was not, set it here. 2443 // compiler. If it was not, set it here.
2444 if (function.context_scope() == ContextScope::null()) { 2444 if (function.context_scope() == ContextScope::null()) {
2445 ASSERT(!is_implicit); 2445 ASSERT(!is_implicit);
2446 const ContextScope& context_scope = ContextScope::ZoneHandle( 2446 const ContextScope& context_scope = ContextScope::ZoneHandle(
2447 I, node->scope()->PreserveOuterScope(owner()->context_level())); 2447 I, node->scope()->PreserveOuterScope(owner()->context_level()));
2448 ASSERT(!function.HasCode()); 2448 ASSERT(!function.HasCode());
2449 ASSERT(function.context_scope() == ContextScope::null()); 2449 ASSERT(function.context_scope() == ContextScope::null());
2450 function.set_context_scope(context_scope); 2450 function.set_context_scope(context_scope);
2451 const Class& cls = Class::Handle( 2451 const Class& cls = Class::Handle(
2452 I, owner()->parsed_function()->function().Owner()); 2452 I, owner()->function().Owner());
2453 // The closure is now properly setup, add it to the lookup table. 2453 // The closure is now properly setup, add it to the lookup table.
2454 // It is possible that the compiler creates more than one function 2454 // It is possible that the compiler creates more than one function
2455 // object for the same closure, e.g. when inlining nodes from 2455 // object for the same closure, e.g. when inlining nodes from
2456 // finally clauses. If we already have a function object for the 2456 // finally clauses. If we already have a function object for the
2457 // same closure, do not add a second one. We compare the origin 2457 // same closure, do not add a second one. We compare the origin
2458 // class, token position, and parent function to detect duplicates. 2458 // class, token position, and parent function to detect duplicates.
2459 // Note that we can have two different closure object for the same 2459 // Note that we can have two different closure object for the same
2460 // source text representation of the closure: one with a non-closurized 2460 // source text representation of the closure: one with a non-closurized
2461 // parent, and one with a closurized parent function. 2461 // parent, and one with a closurized parent function.
2462 2462
(...skipping 15 matching lines...) Expand all
2478 // pass the type arguments of the instantiator. 2478 // pass the type arguments of the instantiator.
2479 const Class& cls = Class::ZoneHandle(I, function.signature_class()); 2479 const Class& cls = Class::ZoneHandle(I, function.signature_class());
2480 ASSERT(!cls.IsNull()); 2480 ASSERT(!cls.IsNull());
2481 const bool requires_type_arguments = cls.NumTypeArguments() > 0; 2481 const bool requires_type_arguments = cls.NumTypeArguments() > 0;
2482 Value* type_arguments = NULL; 2482 Value* type_arguments = NULL;
2483 if (requires_type_arguments) { 2483 if (requires_type_arguments) {
2484 ASSERT(cls.type_arguments_field_offset() == 2484 ASSERT(cls.type_arguments_field_offset() ==
2485 Closure::type_arguments_offset()); 2485 Closure::type_arguments_offset());
2486 ASSERT(cls.instance_size() == Closure::InstanceSize()); 2486 ASSERT(cls.instance_size() == Closure::InstanceSize());
2487 const Class& instantiator_class = Class::Handle( 2487 const Class& instantiator_class = Class::Handle(
2488 I, owner()->parsed_function()->function().Owner()); 2488 I, owner()->function().Owner());
2489 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), 2489 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2490 instantiator_class, 2490 instantiator_class,
2491 NULL); 2491 NULL);
2492 arguments->Add(PushArgument(type_arguments)); 2492 arguments->Add(PushArgument(type_arguments));
2493 } 2493 }
2494 AllocateObjectInstr* alloc = new(I) AllocateObjectInstr(node->token_pos(), 2494 AllocateObjectInstr* alloc = new(I) AllocateObjectInstr(node->token_pos(),
2495 cls, 2495 cls,
2496 arguments); 2496 arguments);
2497 alloc->set_closure_function(function); 2497 alloc->set_closure_function(function);
2498 2498
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
2800 // StaticCall(constructor, t_n+1, t_n+2, ...) 2800 // StaticCall(constructor, t_n+1, t_n+2, ...)
2801 // No need to preserve allocated value (simpler than in ValueGraphVisitor). 2801 // No need to preserve allocated value (simpler than in ValueGraphVisitor).
2802 Value* allocated_value = BuildObjectAllocation(node); 2802 Value* allocated_value = BuildObjectAllocation(node);
2803 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); 2803 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value);
2804 BuildConstructorCall(node, push_allocated_value); 2804 BuildConstructorCall(node, push_allocated_value);
2805 } 2805 }
2806 2806
2807 2807
2808 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) { 2808 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) {
2809 ASSERT(instantiator_class.NumTypeParameters() > 0); 2809 ASSERT(instantiator_class.NumTypeParameters() > 0);
2810 Function& outer_function = 2810 Function& outer_function = Function::Handle(I, owner()->function().raw());
2811 Function::Handle(I, owner()->parsed_function()->function().raw());
2812 while (outer_function.IsLocalFunction()) { 2811 while (outer_function.IsLocalFunction()) {
2813 outer_function = outer_function.parent_function(); 2812 outer_function = outer_function.parent_function();
2814 } 2813 }
2815 if (outer_function.IsFactory()) { 2814 if (outer_function.IsFactory()) {
2816 return NULL; 2815 return NULL;
2817 } 2816 }
2818 2817
2819 LocalVariable* instantiator = owner()->parsed_function()->instantiator(); 2818 LocalVariable* instantiator = owner()->parsed_function()->instantiator();
2820 ASSERT(instantiator != NULL); 2819 ASSERT(instantiator != NULL);
2821 Value* result = Bind(BuildLoadLocal(*instantiator)); 2820 Value* result = Bind(BuildLoadLocal(*instantiator));
(...skipping 15 matching lines...) Expand all
2837 Type& type = Type::Handle( 2836 Type& type = Type::Handle(
2838 I, 2837 I,
2839 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); 2838 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
2840 type ^= ClassFinalizer::FinalizeType( 2839 type ^= ClassFinalizer::FinalizeType(
2841 instantiator_class, type, ClassFinalizer::kFinalize); 2840 instantiator_class, type, ClassFinalizer::kFinalize);
2842 ASSERT(!type.IsMalformedOrMalbounded()); 2841 ASSERT(!type.IsMalformedOrMalbounded());
2843 type_arguments = type.arguments(); 2842 type_arguments = type.arguments();
2844 type_arguments = type_arguments.Canonicalize(); 2843 type_arguments = type_arguments.Canonicalize();
2845 return Bind(new(I) ConstantInstr(type_arguments)); 2844 return Bind(new(I) ConstantInstr(type_arguments));
2846 } 2845 }
2847 Function& outer_function = 2846 Function& outer_function = Function::Handle(I, owner()->function().raw());
2848 Function::Handle(I, owner()->parsed_function()->function().raw());
2849 while (outer_function.IsLocalFunction()) { 2847 while (outer_function.IsLocalFunction()) {
2850 outer_function = outer_function.parent_function(); 2848 outer_function = outer_function.parent_function();
2851 } 2849 }
2852 if (outer_function.IsFactory()) { 2850 if (outer_function.IsFactory()) {
2853 // No instantiator for factories. 2851 // No instantiator for factories.
2854 ASSERT(instantiator == NULL); 2852 ASSERT(instantiator == NULL);
2855 LocalVariable* instantiator_var = 2853 LocalVariable* instantiator_var =
2856 owner()->parsed_function()->instantiator(); 2854 owner()->parsed_function()->instantiator();
2857 ASSERT(instantiator_var != NULL); 2855 ASSERT(instantiator_var != NULL);
2858 return Bind(BuildLoadLocal(*instantiator_var)); 2856 return Bind(BuildLoadLocal(*instantiator_var));
(...skipping 18 matching lines...) Expand all
2877 2875
2878 2876
2879 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 2877 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
2880 intptr_t token_pos, 2878 intptr_t token_pos,
2881 const TypeArguments& type_arguments) { 2879 const TypeArguments& type_arguments) {
2882 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2880 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2883 return Bind(new(I) ConstantInstr(type_arguments)); 2881 return Bind(new(I) ConstantInstr(type_arguments));
2884 } 2882 }
2885 // The type arguments are uninstantiated. 2883 // The type arguments are uninstantiated.
2886 const Class& instantiator_class = Class::ZoneHandle( 2884 const Class& instantiator_class = Class::ZoneHandle(
2887 I, owner()->parsed_function()->function().Owner()); 2885 I, owner()->function().Owner());
2888 Value* instantiator_value = 2886 Value* instantiator_value =
2889 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 2887 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
2890 const bool use_instantiator_type_args = 2888 const bool use_instantiator_type_args =
2891 type_arguments.IsUninstantiatedIdentity() || 2889 type_arguments.IsUninstantiatedIdentity() ||
2892 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); 2890 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class);
2893 if (use_instantiator_type_args) { 2891 if (use_instantiator_type_args) {
2894 return instantiator_value; 2892 return instantiator_value;
2895 } else { 2893 } else {
2896 return Bind(new(I) InstantiateTypeArgumentsInstr(token_pos, 2894 return Bind(new(I) InstantiateTypeArgumentsInstr(token_pos,
2897 type_arguments, 2895 type_arguments,
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
3183 3181
3184 3182
3185 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) { 3183 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) {
3186 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), 3184 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(),
3187 true); // Test only. 3185 true); // Test only.
3188 return new(I) LoadLocalInstr(*receiver_var); 3186 return new(I) LoadLocalInstr(*receiver_var);
3189 } 3187 }
3190 3188
3191 3189
3192 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { 3190 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
3193 const Function& function = owner()->parsed_function()->function(); 3191 const Function& function = owner()->function();
3194 if (!function.IsClosureFunction()) { 3192 if (!function.IsClosureFunction()) {
3195 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 3193 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
3196 switch (kind) { 3194 switch (kind) {
3197 case MethodRecognizer::kObjectEquals: { 3195 case MethodRecognizer::kObjectEquals: {
3198 Value* receiver = Bind(BuildLoadThisVar(node->scope())); 3196 Value* receiver = Bind(BuildLoadThisVar(node->scope()));
3199 LocalVariable* other_var = 3197 LocalVariable* other_var =
3200 node->scope()->LookupVariable(Symbols::Other(), 3198 node->scope()->LookupVariable(Symbols::Other(),
3201 true); // Test only. 3199 true); // Test only.
3202 Value* other = Bind(new(I) LoadLocalInstr(*other_var)); 3200 Value* other = Bind(new(I) LoadLocalInstr(*other_var));
3203 // Receiver is not a number because numbers override equality. 3201 // Receiver is not a number because numbers override equality.
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
3704 } 3702 }
3705 3703
3706 3704
3707 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 3705 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
3708 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); 3706 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded));
3709 } 3707 }
3710 3708
3711 3709
3712 bool EffectGraphVisitor::HasContextScope() const { 3710 bool EffectGraphVisitor::HasContextScope() const {
3713 const ContextScope& context_scope = ContextScope::Handle( 3711 const ContextScope& context_scope = ContextScope::Handle(
3714 owner()->parsed_function()->function().context_scope()); 3712 owner()->function().context_scope());
3715 return !context_scope.IsNull() && (context_scope.num_variables() > 0); 3713 return !context_scope.IsNull() && (context_scope.num_variables() > 0);
3716 } 3714 }
3717 3715
3718 3716
3719 void EffectGraphVisitor::UnchainContexts(intptr_t n) { 3717 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
3720 if (n > 0) { 3718 if (n > 0) {
3721 Value* context = Bind(BuildCurrentContext()); 3719 Value* context = Bind(BuildCurrentContext());
3722 while (n-- > 0) { 3720 while (n-- > 0) {
3723 context = Bind( 3721 context = Bind(
3724 new(I) LoadFieldInstr(context, 3722 new(I) LoadFieldInstr(context,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3762 kEmitStoreBarrier, 3760 kEmitStoreBarrier,
3763 Scanner::kNoSourcePos)); 3761 Scanner::kNoSourcePos));
3764 } 3762 }
3765 Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var)))); 3763 Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var))));
3766 } 3764 }
3767 3765
3768 // If this node_sequence is the body of the function being compiled, copy 3766 // If this node_sequence is the body of the function being compiled, copy
3769 // the captured parameters from the frame into the context. 3767 // the captured parameters from the frame into the context.
3770 if (is_top_level_sequence) { 3768 if (is_top_level_sequence) {
3771 ASSERT(scope->context_level() == 1); 3769 ASSERT(scope->context_level() == 1);
3772 const Function& function = owner()->parsed_function()->function(); 3770 const Function& function = owner()->function();
3773 const int num_params = function.NumParameters(); 3771 const int num_params = function.NumParameters();
3774 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 3772 int param_frame_index = (num_params == function.num_fixed_parameters()) ?
3775 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; 3773 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp;
3776 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 3774 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
3777 const LocalVariable& parameter = *scope->VariableAt(pos); 3775 const LocalVariable& parameter = *scope->VariableAt(pos);
3778 ASSERT(parameter.owner() == scope); 3776 ASSERT(parameter.owner() == scope);
3779 if (parameter.is_captured()) { 3777 if (parameter.is_captured()) {
3780 // Create a temporary local describing the original position. 3778 // Create a temporary local describing the original position.
3781 const String& temp_name = Symbols::TempParam(); 3779 const String& temp_name = Symbols::TempParam();
3782 LocalVariable* temp_local = new(I) LocalVariable( 3780 LocalVariable* temp_local = new(I) LocalVariable(
(...skipping 17 matching lines...) Expand all
3800 Value* null_constant = Bind(new(I) ConstantInstr( 3798 Value* null_constant = Bind(new(I) ConstantInstr(
3801 Object::ZoneHandle(I, Object::null()))); 3799 Object::ZoneHandle(I, Object::null())));
3802 Do(BuildStoreLocal(*temp_local, null_constant)); 3800 Do(BuildStoreLocal(*temp_local, null_constant));
3803 } 3801 }
3804 } 3802 }
3805 } 3803 }
3806 } 3804 }
3807 3805
3808 // This check may be deleted if the generated code is leaf. 3806 // This check may be deleted if the generated code is leaf.
3809 // Native functions don't need a stack check at entry. 3807 // Native functions don't need a stack check at entry.
3810 const Function& function = owner()->parsed_function()->function(); 3808 const Function& function = owner()->function();
3811 if (is_top_level_sequence && !function.is_native()) { 3809 if (is_top_level_sequence && !function.is_native()) {
3812 // Always allocate CheckOverflowInstr so that deopt-ids match regardless 3810 // Always allocate CheckOverflowInstr so that deopt-ids match regardless
3813 // if we inline or not. 3811 // if we inline or not.
3814 if (!function.IsImplicitGetterFunction() && 3812 if (!function.IsImplicitGetterFunction() &&
3815 !function.IsImplicitSetterFunction()) { 3813 !function.IsImplicitSetterFunction()) {
3816 CheckStackOverflowInstr* check = 3814 CheckStackOverflowInstr* check =
3817 new(I) CheckStackOverflowInstr(function.token_pos(), 0); 3815 new(I) CheckStackOverflowInstr(function.token_pos(), 0);
3818 // If we are inlining don't actually attach the stack check. We must still 3816 // If we are inlining don't actually attach the stack check. We must still
3819 // create the stack check in order to allocate a deopt id. 3817 // create the stack check in order to allocate a deopt id.
3820 if (!owner()->IsInlining()) { 3818 if (!owner()->IsInlining()) {
3821 AddInstruction(check); 3819 AddInstruction(check);
3822 } 3820 }
3823 } 3821 }
3824 } 3822 }
3825 3823
3826 if (FLAG_enable_type_checks && is_top_level_sequence) { 3824 if (FLAG_enable_type_checks && is_top_level_sequence) {
3827 const Function& function = owner()->parsed_function()->function(); 3825 const Function& function = owner()->function();
3828 const int num_params = function.NumParameters(); 3826 const int num_params = function.NumParameters();
3829 int pos = 0; 3827 int pos = 0;
3830 if (function.IsConstructor()) { 3828 if (function.IsConstructor()) {
3831 // Skip type checking of receiver and phase for constructor functions. 3829 // Skip type checking of receiver and phase for constructor functions.
3832 pos = 2; 3830 pos = 2;
3833 } else if (function.IsFactory() || function.IsDynamicFunction()) { 3831 } else if (function.IsFactory() || function.IsDynamicFunction()) {
3834 // Skip type checking of type arguments for factory functions. 3832 // Skip type checking of type arguments for factory functions.
3835 // Skip type checking of receiver for instance functions. 3833 // Skip type checking of receiver for instance functions.
3836 pos = 1; 3834 pos = 1;
3837 } 3835 }
(...skipping 11 matching lines...) Expand all
3849 parameter.name())); 3847 parameter.name()));
3850 } 3848 }
3851 pos++; 3849 pos++;
3852 } 3850 }
3853 } 3851 }
3854 3852
3855 // Continuation part: 3853 // Continuation part:
3856 // If this node sequence is the body of an async closure leave room for a 3854 // If this node sequence is the body of an async closure leave room for a
3857 // preamble. The preamble is generated after visiting the body. 3855 // preamble. The preamble is generated after visiting the body.
3858 GotoInstr* preamble_start = NULL; 3856 GotoInstr* preamble_start = NULL;
3859 if (is_top_level_sequence && 3857 if (is_top_level_sequence && (owner()->function().is_async_closure())) {
3860 (owner()->parsed_function()->function().is_async_closure())) {
3861 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr( 3858 JoinEntryInstr* preamble_end = new(I) JoinEntryInstr(
3862 owner()->AllocateBlockId(), owner()->try_index()); 3859 owner()->AllocateBlockId(), owner()->try_index());
3863 ASSERT(exit() != NULL); 3860 ASSERT(exit() != NULL);
3864 exit()->Goto(preamble_end); 3861 exit()->Goto(preamble_end);
3865 ASSERT(exit()->next()->IsGoto()); 3862 ASSERT(exit()->next()->IsGoto());
3866 preamble_start = exit()->next()->AsGoto(); 3863 preamble_start = exit()->next()->AsGoto();
3867 ASSERT(preamble_start->IsGoto()); 3864 ASSERT(preamble_start->IsGoto());
3868 exit_ = preamble_end; 3865 exit_ = preamble_end;
3869 } 3866 }
3870 3867
3871 intptr_t i = 0; 3868 intptr_t i = 0;
3872 while (is_open() && (i < node->length())) { 3869 while (is_open() && (i < node->length())) {
3873 EffectGraphVisitor for_effect(owner()); 3870 EffectGraphVisitor for_effect(owner());
3874 node->NodeAt(i++)->Visit(&for_effect); 3871 node->NodeAt(i++)->Visit(&for_effect);
3875 Append(for_effect); 3872 Append(for_effect);
3876 if (!is_open()) { 3873 if (!is_open()) {
3877 // E.g., because of a JumpNode. 3874 // E.g., because of a JumpNode.
3878 break; 3875 break;
3879 } 3876 }
3880 } 3877 }
3881 3878
3882 // Continuation part: 3879 // Continuation part:
3883 // After generating the CFG for the body we can create the preamble because we 3880 // After generating the CFG for the body we can create the preamble because we
3884 // know exactly how many continuation states we need. 3881 // know exactly how many continuation states we need.
3885 if (is_top_level_sequence && 3882 if (is_top_level_sequence && (owner()->function().is_async_closure())) {
3886 (owner()->parsed_function()->function().is_async_closure())) {
3887 ASSERT(preamble_start != NULL); 3883 ASSERT(preamble_start != NULL);
3888 // We are at the top level. Fetch the corresponding scope. 3884 // We are at the top level. Fetch the corresponding scope.
3889 LocalScope* top_scope = node->scope(); 3885 LocalScope* top_scope = node->scope();
3890 LocalVariable* jump_var = top_scope->LookupVariable( 3886 LocalVariable* jump_var = top_scope->LookupVariable(
3891 Symbols::AwaitJumpVar(), false); 3887 Symbols::AwaitJumpVar(), false);
3892 ASSERT(jump_var != NULL && jump_var->is_captured()); 3888 ASSERT(jump_var != NULL && jump_var->is_captured());
3893 3889
3894 Instruction* saved_entry = entry_; 3890 Instruction* saved_entry = entry_;
3895 Instruction* saved_exit = exit_; 3891 Instruction* saved_exit = exit_;
3896 entry_ = NULL; 3892 entry_ = NULL;
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
4316 Report::MessageF(Report::kBailout, 4312 Report::MessageF(Report::kBailout,
4317 Script::Handle(function.script()), 4313 Script::Handle(function.script()),
4318 function.token_pos(), 4314 function.token_pos(),
4319 "FlowGraphBuilder Bailout: %s %s", 4315 "FlowGraphBuilder Bailout: %s %s",
4320 String::Handle(function.name()).ToCString(), 4316 String::Handle(function.name()).ToCString(),
4321 reason); 4317 reason);
4322 UNREACHABLE(); 4318 UNREACHABLE();
4323 } 4319 }
4324 4320
4325 } // namespace dart 4321 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698