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

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

Issue 154393003: Implement eager instantiation and canonicalization of type arguments at run (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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
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 2151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 if (num_temps > 0) { 2162 if (num_temps > 0) {
2163 owner()->DeallocateTemps(num_temps); 2163 owner()->DeallocateTemps(num_temps);
2164 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); 2164 ReturnDefinition(new DropTempsInstr(num_temps, result_value));
2165 } else { 2165 } else {
2166 ReturnValue(result_value); 2166 ReturnValue(result_value);
2167 } 2167 }
2168 } 2168 }
2169 2169
2170 2170
2171 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 2171 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
2172 const AbstractTypeArguments& type_args = 2172 const TypeArguments& type_args =
2173 AbstractTypeArguments::ZoneHandle(node->type().arguments()); 2173 TypeArguments::ZoneHandle(node->type().arguments());
2174 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), 2174 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
2175 type_args); 2175 type_args);
2176 Value* num_elements = 2176 Value* num_elements =
2177 Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(node->length())))); 2177 Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(node->length()))));
2178 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), 2178 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(),
2179 element_type, 2179 element_type,
2180 num_elements); 2180 num_elements);
2181 Value* array_val = Bind(create); 2181 Value* array_val = Bind(create);
2182 2182
2183 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); 2183 { LocalVariable* tmp_var = EnterTempLocalScope(array_val);
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2482 } 2482 }
2483 2483
2484 2484
2485 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 2485 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
2486 Value* context = Bind(new CurrentContextInstr()); 2486 Value* context = Bind(new CurrentContextInstr());
2487 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); 2487 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context));
2488 AddInstruction(new StoreContextInstr(clone)); 2488 AddInstruction(new StoreContextInstr(clone));
2489 } 2489 }
2490 2490
2491 2491
2492 Value* EffectGraphVisitor::BuildObjectAllocation( 2492 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) {
2493 ConstructorCallNode* node) {
2494 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); 2493 const Class& cls = Class::ZoneHandle(node->constructor().Owner());
2495 const bool requires_type_arguments = cls.NumTypeArguments() > 0; 2494 const bool requires_type_arguments = cls.NumTypeArguments() > 0;
2496 2495
2497 // In checked mode, if the type arguments are uninstantiated, they may need to 2496 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
2498 // be checked against declared bounds at run time. 2497 new ZoneGrowableArray<PushArgumentInstr*>();
2499 Definition* allocation = NULL; 2498 if (requires_type_arguments) {
2500 if (FLAG_enable_type_checks &&
2501 requires_type_arguments &&
2502 !node->type_arguments().IsNull() &&
2503 !node->type_arguments().IsInstantiated() &&
2504 node->type_arguments().IsBounded()) {
2505 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
2506 new ZoneGrowableArray<PushArgumentInstr*>(4);
2507 // Argument 1: Empty argument slot for return value.
2508 Value* null_val = Bind(new ConstantInstr(Object::ZoneHandle()));
2509 allocate_arguments->Add(PushArgument(null_val));
2510 // Argument 2: Class.
2511 Value* cls_val =
2512 Bind(new ConstantInstr(Class::ZoneHandle(node->constructor().Owner())));
2513 allocate_arguments->Add(PushArgument(cls_val));
2514 // Build arguments 3 and 4.
2515 BuildConstructorTypeArguments(node, allocate_arguments); 2499 BuildConstructorTypeArguments(node, allocate_arguments);
2500 }
2516 2501
2517 // The uninstantiated type arguments cannot be verified to be within their 2502 Definition* allocation = new AllocateObjectInstr(
2518 // bounds at compile time, so verify them at runtime. 2503 node->token_pos(),
2519 allocation = new AllocateObjectWithBoundsCheckInstr(node); 2504 Class::ZoneHandle(node->constructor().Owner()),
2520 } else { 2505 allocate_arguments);
2521 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
2522 new ZoneGrowableArray<PushArgumentInstr*>();
2523 if (requires_type_arguments) {
2524 BuildConstructorTypeArguments(node, allocate_arguments);
2525 }
2526 2506
2527 allocation = new AllocateObjectInstr(
2528 node->token_pos(),
2529 Class::ZoneHandle(node->constructor().Owner()),
2530 allocate_arguments);
2531 }
2532 return Bind(allocation); 2507 return Bind(allocation);
2533 } 2508 }
2534 2509
2535 2510
2536 void EffectGraphVisitor::BuildConstructorCall( 2511 void EffectGraphVisitor::BuildConstructorCall(
2537 ConstructorCallNode* node, 2512 ConstructorCallNode* node,
2538 PushArgumentInstr* push_alloc_value) { 2513 PushArgumentInstr* push_alloc_value) {
2539 Value* ctor_arg = Bind( 2514 Value* ctor_arg = Bind(
2540 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); 2515 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))));
2541 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); 2516 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 2617
2643 2618
2644 // 'expression_temp_var' may not be used inside this method if 'instantiator' 2619 // 'expression_temp_var' may not be used inside this method if 'instantiator'
2645 // is not NULL. 2620 // is not NULL.
2646 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 2621 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
2647 intptr_t token_pos, 2622 intptr_t token_pos,
2648 const Class& instantiator_class, 2623 const Class& instantiator_class,
2649 Value* instantiator) { 2624 Value* instantiator) {
2650 if (instantiator_class.NumTypeParameters() == 0) { 2625 if (instantiator_class.NumTypeParameters() == 0) {
2651 // The type arguments are compile time constants. 2626 // The type arguments are compile time constants.
2652 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); 2627 TypeArguments& type_arguments = TypeArguments::ZoneHandle();
2653 // Type is temporary. Only its type arguments are preserved. 2628 // Type is temporary. Only its type arguments are preserved.
2654 Type& type = Type::Handle( 2629 Type& type = Type::Handle(
2655 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); 2630 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
2656 type ^= ClassFinalizer::FinalizeType( 2631 type ^= ClassFinalizer::FinalizeType(
2657 instantiator_class, type, ClassFinalizer::kFinalize); 2632 instantiator_class, type, ClassFinalizer::kFinalize);
2658 ASSERT(!type.IsMalformedOrMalbounded()); 2633 ASSERT(!type.IsMalformedOrMalbounded());
2659 type_arguments = type.arguments(); 2634 type_arguments = type.arguments();
2660 type_arguments = type_arguments.Canonicalize(); 2635 type_arguments = type_arguments.Canonicalize();
2661 return Bind(new ConstantInstr(type_arguments)); 2636 return Bind(new ConstantInstr(type_arguments));
2662 } 2637 }
2663 Function& outer_function = 2638 Function& outer_function =
2664 Function::Handle(owner()->parsed_function()->function().raw()); 2639 Function::Handle(owner()->parsed_function()->function().raw());
2665 while (outer_function.IsLocalFunction()) { 2640 while (outer_function.IsLocalFunction()) {
2666 outer_function = outer_function.parent_function(); 2641 outer_function = outer_function.parent_function();
2667 } 2642 }
2668 if (outer_function.IsFactory()) { 2643 if (outer_function.IsFactory()) {
2669 // No instantiator for factories. 2644 // No instantiator for factories.
2670 ASSERT(instantiator == NULL); 2645 ASSERT(instantiator == NULL);
2671 ASSERT(owner()->parsed_function()->instantiator() != NULL); 2646 ASSERT(owner()->parsed_function()->instantiator() != NULL);
2672 ValueGraphVisitor for_instantiator(owner()); 2647 ValueGraphVisitor for_instantiator(owner());
2673 owner()->parsed_function()->instantiator()->Visit(&for_instantiator); 2648 owner()->parsed_function()->instantiator()->Visit(&for_instantiator);
2674 Append(for_instantiator); 2649 Append(for_instantiator);
2675 return for_instantiator.value(); 2650 return for_instantiator.value();
2676 } 2651 }
2677 if (instantiator == NULL) { 2652 if (instantiator == NULL) {
2678 instantiator = BuildInstantiator(); 2653 instantiator = BuildInstantiator();
2679 } 2654 }
2680 // The instantiator is the receiver of the caller, which is not a factory. 2655 // The instantiator is the receiver of the caller, which is not a factory.
2681 // The receiver cannot be null; extract its AbstractTypeArguments object. 2656 // The receiver cannot be null; extract its TypeArguments object.
2682 // Note that in the factory case, the instantiator is the first parameter 2657 // Note that in the factory case, the instantiator is the first parameter
2683 // of the factory, i.e. already an AbstractTypeArguments object. 2658 // of the factory, i.e. already a TypeArguments object.
2684 intptr_t type_arguments_field_offset = 2659 intptr_t type_arguments_field_offset =
2685 instantiator_class.type_arguments_field_offset(); 2660 instantiator_class.type_arguments_field_offset();
2686 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); 2661 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
2687 2662
2688 return Bind(new LoadFieldInstr( 2663 return Bind(new LoadFieldInstr(
2689 instantiator, 2664 instantiator,
2690 type_arguments_field_offset, 2665 type_arguments_field_offset,
2691 Type::ZoneHandle())); // Not an instance, no type. 2666 Type::ZoneHandle())); // Not an instance, no type.
2692 } 2667 }
2693 2668
2694 2669
2695 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 2670 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
2696 intptr_t token_pos, 2671 intptr_t token_pos,
2697 const AbstractTypeArguments& type_arguments) { 2672 const TypeArguments& type_arguments) {
2698 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2673 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2699 return Bind(new ConstantInstr(type_arguments)); 2674 return Bind(new ConstantInstr(type_arguments));
2700 } 2675 }
2701 // The type arguments are uninstantiated. 2676 // The type arguments are uninstantiated.
2702 const Class& instantiator_class = Class::ZoneHandle( 2677 const Class& instantiator_class = Class::ZoneHandle(
2703 owner()->parsed_function()->function().Owner()); 2678 owner()->parsed_function()->function().Owner());
2704 Value* instantiator_value = 2679 Value* instantiator_value =
2705 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 2680 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
2706 const bool use_instantiator_type_args = 2681 const bool use_instantiator_type_args =
2707 type_arguments.IsUninstantiatedIdentity() || 2682 type_arguments.IsUninstantiatedIdentity() ||
(...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after
4030 LanguageError::kError, 4005 LanguageError::kError,
4031 Heap::kNew, 4006 Heap::kNew,
4032 "FlowGraphBuilder Bailout: %s %s", 4007 "FlowGraphBuilder Bailout: %s %s",
4033 String::Handle(function.name()).ToCString(), 4008 String::Handle(function.name()).ToCString(),
4034 reason)); 4009 reason));
4035 Isolate::Current()->long_jump_base()->Jump(1, error); 4010 Isolate::Current()->long_jump_base()->Jump(1, error);
4036 } 4011 }
4037 4012
4038 4013
4039 } // namespace dart 4014 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698