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 |