| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 2255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 Value* type_arguments = NULL; | 2266 Value* type_arguments = NULL; |
| 2267 if (requires_type_arguments) { | 2267 if (requires_type_arguments) { |
| 2268 ASSERT(cls.type_arguments_field_offset() == | 2268 ASSERT(cls.type_arguments_field_offset() == |
| 2269 Closure::type_arguments_offset()); | 2269 Closure::type_arguments_offset()); |
| 2270 const Class& instantiator_class = Class::Handle( | 2270 const Class& instantiator_class = Class::Handle( |
| 2271 owner()->parsed_function()->function().Owner()); | 2271 owner()->parsed_function()->function().Owner()); |
| 2272 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), | 2272 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| 2273 instantiator_class, | 2273 instantiator_class, |
| 2274 NULL); | 2274 NULL); |
| 2275 arguments->Add(PushArgument(type_arguments)); | 2275 arguments->Add(PushArgument(type_arguments)); |
| 2276 | |
| 2277 Value* instantiator_val = Bind(new ConstantInstr( | |
| 2278 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | |
| 2279 arguments->Add(PushArgument(instantiator_val)); | |
| 2280 } | 2276 } |
| 2281 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(), | 2277 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(), |
| 2282 cls, | 2278 cls, |
| 2283 arguments); | 2279 arguments); |
| 2284 alloc->set_closure_function(function); | 2280 alloc->set_closure_function(function); |
| 2285 | 2281 |
| 2286 // Create fake fields for function and context. Only the context field is | 2282 // Create fake fields for function and context. Only the context field is |
| 2287 // stored at the allocation to be used later when inlining a closure call. | 2283 // stored at the allocation to be used later when inlining a closure call. |
| 2288 const Field& function_field = | 2284 const Field& function_field = |
| 2289 Field::ZoneHandle( | 2285 Field::ZoneHandle( |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2484 | 2480 |
| 2485 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 2481 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 2486 Value* context = Bind(new CurrentContextInstr()); | 2482 Value* context = Bind(new CurrentContextInstr()); |
| 2487 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 2483 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); |
| 2488 AddInstruction(new StoreContextInstr(clone)); | 2484 AddInstruction(new StoreContextInstr(clone)); |
| 2489 } | 2485 } |
| 2490 | 2486 |
| 2491 | 2487 |
| 2492 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { | 2488 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { |
| 2493 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 2489 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 2494 const bool requires_type_arguments = cls.NumTypeArguments() > 0; | 2490 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; |
| 2495 | 2491 |
| 2496 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 2492 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 2497 new ZoneGrowableArray<PushArgumentInstr*>(); | 2493 new ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0); |
| 2498 if (requires_type_arguments) { | 2494 if (cls_is_parameterized) { |
| 2499 BuildConstructorTypeArguments(node, allocate_arguments); | 2495 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(), |
| 2496 node->type_arguments()); |
| 2497 allocate_arguments->Add(PushArgument(type_args)); |
| 2500 } | 2498 } |
| 2501 | 2499 |
| 2502 Definition* allocation = new AllocateObjectInstr( | 2500 Definition* allocation = new AllocateObjectInstr( |
| 2503 node->token_pos(), | 2501 node->token_pos(), |
| 2504 Class::ZoneHandle(node->constructor().Owner()), | 2502 Class::ZoneHandle(node->constructor().Owner()), |
| 2505 allocate_arguments); | 2503 allocate_arguments); |
| 2506 | 2504 |
| 2507 return Bind(allocation); | 2505 return Bind(allocation); |
| 2508 } | 2506 } |
| 2509 | 2507 |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2674 return Bind(new ConstantInstr(type_arguments)); | 2672 return Bind(new ConstantInstr(type_arguments)); |
| 2675 } | 2673 } |
| 2676 // The type arguments are uninstantiated. | 2674 // The type arguments are uninstantiated. |
| 2677 const Class& instantiator_class = Class::ZoneHandle( | 2675 const Class& instantiator_class = Class::ZoneHandle( |
| 2678 owner()->parsed_function()->function().Owner()); | 2676 owner()->parsed_function()->function().Owner()); |
| 2679 Value* instantiator_value = | 2677 Value* instantiator_value = |
| 2680 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 2678 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 2681 const bool use_instantiator_type_args = | 2679 const bool use_instantiator_type_args = |
| 2682 type_arguments.IsUninstantiatedIdentity() || | 2680 type_arguments.IsUninstantiatedIdentity() || |
| 2683 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); | 2681 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); |
| 2684 return use_instantiator_type_args | 2682 if (use_instantiator_type_args) { |
| 2685 ? instantiator_value | 2683 return instantiator_value; |
| 2686 : Bind(new InstantiateTypeArgumentsInstr(token_pos, | 2684 } else { |
| 2687 type_arguments, | 2685 return Bind(new InstantiateTypeArgumentsInstr(token_pos, |
| 2688 instantiator_class, | 2686 type_arguments, |
| 2689 instantiator_value)); | 2687 instantiator_class, |
| 2688 instantiator_value)); |
| 2689 } |
| 2690 } | 2690 } |
| 2691 | 2691 |
| 2692 | 2692 |
| 2693 void EffectGraphVisitor::BuildConstructorTypeArguments( | |
| 2694 ConstructorCallNode* node, | |
| 2695 ZoneGrowableArray<PushArgumentInstr*>* call_arguments) { | |
| 2696 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | |
| 2697 ASSERT((cls.NumTypeArguments() > 0) && !node->constructor().IsFactory()); | |
| 2698 if (node->type_arguments().IsNull() || | |
| 2699 node->type_arguments().IsInstantiated()) { | |
| 2700 Value* type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); | |
| 2701 call_arguments->Add(PushArgument(type_arguments_val)); | |
| 2702 | |
| 2703 // No instantiator required. | |
| 2704 Value* instantiator_val = Bind(new ConstantInstr( | |
| 2705 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | |
| 2706 call_arguments->Add(PushArgument(instantiator_val)); | |
| 2707 return; | |
| 2708 } | |
| 2709 | |
| 2710 // The type arguments are uninstantiated. We use expression_temp_var to save | |
| 2711 // the instantiator type arguments because they have two uses. | |
| 2712 ASSERT(owner()->parsed_function()->expression_temp_var() != NULL); | |
| 2713 const Class& instantiator_class = Class::Handle( | |
| 2714 owner()->parsed_function()->function().Owner()); | |
| 2715 Value* type_arguments_val = BuildInstantiatorTypeArguments( | |
| 2716 node->token_pos(), instantiator_class, NULL); | |
| 2717 | |
| 2718 const bool use_instantiator_type_args = | |
| 2719 node->type_arguments().IsUninstantiatedIdentity() || | |
| 2720 node->type_arguments().CanShareInstantiatorTypeArguments( | |
| 2721 instantiator_class); | |
| 2722 | |
| 2723 if (!use_instantiator_type_args) { | |
| 2724 const intptr_t len = node->type_arguments().Length(); | |
| 2725 if (node->type_arguments().IsRawInstantiatedRaw(len)) { | |
| 2726 type_arguments_val = | |
| 2727 Bind(BuildStoreExprTemp(type_arguments_val)); | |
| 2728 type_arguments_val = Bind( | |
| 2729 new ExtractConstructorTypeArgumentsInstr( | |
| 2730 node->token_pos(), | |
| 2731 node->type_arguments(), | |
| 2732 instantiator_class, | |
| 2733 type_arguments_val)); | |
| 2734 } else { | |
| 2735 Do(BuildStoreExprTemp(type_arguments_val)); | |
| 2736 type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); | |
| 2737 } | |
| 2738 } | |
| 2739 call_arguments->Add(PushArgument(type_arguments_val)); | |
| 2740 | |
| 2741 Value* instantiator_val = NULL; | |
| 2742 if (!use_instantiator_type_args) { | |
| 2743 instantiator_val = Bind(BuildLoadExprTemp()); | |
| 2744 const intptr_t len = node->type_arguments().Length(); | |
| 2745 if (node->type_arguments().IsRawInstantiatedRaw(len)) { | |
| 2746 instantiator_val = | |
| 2747 Bind(new ExtractConstructorInstantiatorInstr(node, | |
| 2748 instantiator_class, | |
| 2749 instantiator_val)); | |
| 2750 } | |
| 2751 } else { | |
| 2752 // No instantiator required. | |
| 2753 instantiator_val = Bind(new ConstantInstr( | |
| 2754 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | |
| 2755 } | |
| 2756 call_arguments->Add(PushArgument(instantiator_val)); | |
| 2757 } | |
| 2758 | |
| 2759 | |
| 2760 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { | 2693 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { |
| 2761 if (node->constructor().IsFactory()) { | 2694 if (node->constructor().IsFactory()) { |
| 2762 EffectGraphVisitor::VisitConstructorCallNode(node); | 2695 EffectGraphVisitor::VisitConstructorCallNode(node); |
| 2763 return; | 2696 return; |
| 2764 } | 2697 } |
| 2765 | 2698 |
| 2766 // t_n contains the allocated and initialized object. | 2699 // t_n contains the allocated and initialized object. |
| 2767 // t_n <- AllocateObject(class) | 2700 // t_n <- AllocateObject(class) |
| 2768 // t_n <- StoreLocal(temp, t_n); | 2701 // t_n <- StoreLocal(temp, t_n); |
| 2769 // t_n+1 <- ctor-arg | 2702 // t_n+1 <- ctor-arg |
| (...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4005 LanguageError::kError, | 3938 LanguageError::kError, |
| 4006 Heap::kNew, | 3939 Heap::kNew, |
| 4007 "FlowGraphBuilder Bailout: %s %s", | 3940 "FlowGraphBuilder Bailout: %s %s", |
| 4008 String::Handle(function.name()).ToCString(), | 3941 String::Handle(function.name()).ToCString(), |
| 4009 reason)); | 3942 reason)); |
| 4010 Isolate::Current()->long_jump_base()->Jump(1, error); | 3943 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 4011 } | 3944 } |
| 4012 | 3945 |
| 4013 | 3946 |
| 4014 } // namespace dart | 3947 } // namespace dart |
| OLD | NEW |