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

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

Issue 9939003: Use null type argument vector instead of vector of Dynamic for a generic raw (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 478
479 const Class& type_class = Class::ZoneHandle(type.type_class()); 479 const Class& type_class = Class::ZoneHandle(type.type_class());
480 const bool requires_type_arguments = type_class.HasTypeArguments(); 480 const bool requires_type_arguments = type_class.HasTypeArguments();
481 // A Smi object cannot be the instance of a parameterized class. 481 // A Smi object cannot be the instance of a parameterized class.
482 // A class equality check is only applicable with a dst type of a 482 // A class equality check is only applicable with a dst type of a
483 // non-parameterized class or with a raw dst type of a parameterized class. 483 // non-parameterized class or with a raw dst type of a parameterized class.
484 if (requires_type_arguments) { 484 if (requires_type_arguments) {
485 const AbstractTypeArguments& type_arguments = 485 const AbstractTypeArguments& type_arguments =
486 AbstractTypeArguments::Handle(type.arguments()); 486 AbstractTypeArguments::Handle(type.arguments());
487 const bool is_raw_type = type_arguments.IsNull() || 487 const bool is_raw_type = type_arguments.IsNull() ||
488 type_arguments.IsDynamicTypes(type_arguments.Length()); 488 type_arguments.IsRaw(type_arguments.Length());
489 Label runtime_call; 489 Label runtime_call;
490 __ testq(RAX, Immediate(kSmiTagMask)); 490 __ testq(RAX, Immediate(kSmiTagMask));
491 __ j(ZERO, &runtime_call, Assembler::kNearJump); 491 __ j(ZERO, &runtime_call, Assembler::kNearJump);
492 // Object not Smi. 492 // Object not Smi.
493 if (is_raw_type) { 493 if (is_raw_type) {
494 if (type.IsListInterface()) { 494 if (type.IsListInterface()) {
495 Label push_result; 495 Label push_result;
496 // TODO(srdjan) also accept List<Object>. 496 // TODO(srdjan) also accept List<Object>.
497 __ movq(RCX, FieldAddress(RAX, Object::class_offset())); 497 __ movq(RCX, FieldAddress(RAX, Object::class_offset()));
498 __ CompareObject(RCX, *CoreClass("ObjectArray")); 498 __ CompareObject(RCX, *CoreClass("ObjectArray"));
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 628
629 void FlowGraphCompiler::VisitCreateClosure(CreateClosureComp* comp) { 629 void FlowGraphCompiler::VisitCreateClosure(CreateClosureComp* comp) {
630 const Function& function = comp->function(); 630 const Function& function = comp->function();
631 const Code& stub = Code::Handle( 631 const Code& stub = Code::Handle(
632 StubCode::GetAllocationStubForClosure(function)); 632 StubCode::GetAllocationStubForClosure(function));
633 const ExternalLabel label(function.ToCString(), stub.EntryPoint()); 633 const ExternalLabel label(function.ToCString(), stub.EntryPoint());
634 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther); 634 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther);
635 635
636 const Class& cls = Class::Handle(function.signature_class()); 636 const Class& cls = Class::Handle(function.signature_class());
637 if (cls.HasTypeArguments()) { 637 if (cls.HasTypeArguments()) {
638 UNIMPLEMENTED(); // We should have bailed out.
638 __ popq(RCX); // Discard type arguments. 639 __ popq(RCX); // Discard type arguments.
639 } 640 }
640 if (function.IsImplicitInstanceClosureFunction()) { 641 if (function.IsImplicitInstanceClosureFunction()) {
641 __ popq(RCX); // Discard receiver. 642 __ popq(RCX); // Discard receiver.
642 } 643 }
643 } 644 }
644 645
645 646
646 void FlowGraphCompiler::VisitNativeLoadField(NativeLoadFieldComp* comp) { 647 void FlowGraphCompiler::VisitNativeLoadField(NativeLoadFieldComp* comp) {
647 __ popq(RAX); 648 __ popq(RAX);
648 __ movq(RAX, FieldAddress(RAX, comp->offset_in_bytes())); 649 __ movq(RAX, FieldAddress(RAX, comp->offset_in_bytes()));
649 } 650 }
650 651
651 652
652 void FlowGraphCompiler::VisitExtractFactoryTypeArguments( 653 void FlowGraphCompiler::VisitExtractFactoryTypeArguments(
653 ExtractFactoryTypeArgumentsComp* comp) { 654 ExtractFactoryTypeArgumentsComp* comp) {
654 __ popq(RAX); // Instantiator. 655 __ popq(RAX); // Instantiator.
655 656
656 // RAX is the instantiator AbstractTypeArguments object (or null). 657 // RAX is the instantiator AbstractTypeArguments object (or null).
657 // If RAX is null, no need to instantiate the type arguments, use null, and 658 // If the instantiator is null and if the type argument vector
658 // allocate an object of a raw type. 659 // instantiated from null becomes a vector of Dynamic, then use null as
659 const Immediate raw_null = 660 // the type arguments.
660 Immediate(reinterpret_cast<intptr_t>(Object::null())); 661 Label type_arguments_instantiated;
661 Label type_arguments_instantiated, type_arguments_uninstantiated; 662 const intptr_t len = comp->type_arguments().Length();
662 __ cmpq(RAX, raw_null); 663 if (comp->type_arguments().IsRawInstantiatedRaw(len)) {
663 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 664 const Immediate raw_null =
664 665 Immediate(reinterpret_cast<intptr_t>(Object::null()));
666 __ cmpq(RAX, raw_null);
667 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
668 }
665 // Instantiate non-null type arguments. 669 // Instantiate non-null type arguments.
666 if (comp->type_arguments().IsUninstantiatedIdentity()) { 670 if (comp->type_arguments().IsUninstantiatedIdentity()) {
671 Label type_arguments_uninstantiated;
667 // Check if the instantiator type argument vector is a TypeArguments of a 672 // Check if the instantiator type argument vector is a TypeArguments of a
668 // matching length and, if so, use it as the instantiated type_arguments. 673 // matching length and, if so, use it as the instantiated type_arguments.
674 // No need to check the instantiator (RAX) for null here, because a null
675 // instantiator will have the wrong class (Null instead of TypeArguments).
669 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 676 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class()));
670 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 677 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset()));
671 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 678 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
672 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>( 679 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>(
673 Smi::New(comp->type_arguments().Length()))); 680 Smi::New(comp->type_arguments().Length())));
674 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 681 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
675 arguments_length); 682 arguments_length);
676 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 683 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
684 __ Bind(&type_arguments_uninstantiated);
677 } 685 }
678 __ Bind(&type_arguments_uninstantiated);
679 // A runtime call to instantiate the type arguments is required before 686 // A runtime call to instantiate the type arguments is required before
680 // calling the factory. 687 // calling the factory.
681 __ PushObject(Object::ZoneHandle()); // Make room for the result. 688 __ PushObject(Object::ZoneHandle()); // Make room for the result.
682 __ PushObject(comp->type_arguments()); 689 __ PushObject(comp->type_arguments());
683 __ pushq(RAX); // Push instantiator type arguments. 690 __ pushq(RAX); // Push instantiator type arguments.
684 GenerateCallRuntime(comp->node_id(), 691 GenerateCallRuntime(comp->node_id(),
685 comp->token_index(), 692 comp->token_index(),
686 kInstantiateTypeArgumentsRuntimeEntry); 693 kInstantiateTypeArgumentsRuntimeEntry);
687 __ popq(RAX); // Pop instantiator type arguments. 694 __ popq(RAX); // Pop instantiator type arguments.
688 __ popq(RAX); // Pop uninstantiated type arguments. 695 __ popq(RAX); // Pop uninstantiated type arguments.
689 __ popq(RAX); // Pop instantiated type arguments. 696 __ popq(RAX); // Pop instantiated type arguments.
690 __ Bind(&type_arguments_instantiated); 697 __ Bind(&type_arguments_instantiated);
691 // RAX: Instantiated type arguments. 698 // RAX: Instantiated type arguments.
692 } 699 }
693 700
694 701
695 void FlowGraphCompiler::VisitExtractConstructorTypeArguments( 702 void FlowGraphCompiler::VisitExtractConstructorTypeArguments(
696 ExtractConstructorTypeArgumentsComp* comp) { 703 ExtractConstructorTypeArgumentsComp* comp) {
697 __ popq(RAX); // Instantiator. 704 __ popq(RAX); // Instantiator.
698 705
699 // RAX is the instantiator AbstractTypeArguments object (or null). 706 // RAX is the instantiator AbstractTypeArguments object (or null).
700 // If RAX is null, no need to instantiate the type arguments, use null, and 707 // If the instantiator is null and if the type argument vector
701 // allocate an object of a raw type. 708 // instantiated from null becomes a vector of Dynamic, then use null as
702 // TODO(regis): The above sentence is actually not correct. If the type 709 // the type arguments.
703 // arguments are only partially uninstantiated, we are losing type information 710 Label type_arguments_instantiated;
704 // by allocating a raw type. The code needs to be fixed here and in the 711 const intptr_t len = comp->type_arguments().Length();
705 // unoptimized version (both ia32 and x64). 712 if (comp->type_arguments().IsRawInstantiatedRaw(len)) {
706 const Immediate raw_null = 713 const Immediate raw_null =
707 Immediate(reinterpret_cast<intptr_t>(Object::null())); 714 Immediate(reinterpret_cast<intptr_t>(Object::null()));
708 Label type_arguments_instantiated, type_arguments_uninstantiated; 715 __ cmpq(RAX, raw_null);
709 __ cmpq(RAX, raw_null); 716 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
710 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 717 }
711 718 // Instantiate non-null type arguments.
712 // Check if type arguments represent the uninstantiated identity vector.
713 if (comp->type_arguments().IsUninstantiatedIdentity()) { 719 if (comp->type_arguments().IsUninstantiatedIdentity()) {
714 // Check if the instantiator type argument vector is a TypeArguments of a 720 // Check if the instantiator type argument vector is a TypeArguments of a
715 // matching length and, if so, use it as the instantiated type_arguments. 721 // matching length and, if so, use it as the instantiated type_arguments.
722 // No need to check the instantiator (RAX) for null here, because a null
723 // instantiator will have the wrong class (Null instead of TypeArguments).
724 Label type_arguments_uninstantiated;
716 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 725 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class()));
717 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 726 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset()));
718 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 727 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
719 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>( 728 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>(
720 Smi::New(comp->type_arguments().Length()))); 729 Smi::New(comp->type_arguments().Length())));
721 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 730 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
722 arguments_length); 731 arguments_length);
723 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 732 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
733 __ Bind(&type_arguments_uninstantiated);
724 } 734 }
725 __ Bind(&type_arguments_uninstantiated);
726 // In the non-factory case, we rely on the allocation stub to 735 // In the non-factory case, we rely on the allocation stub to
727 // instantiate the type arguments. 736 // instantiate the type arguments.
728 __ LoadObject(RAX, comp->type_arguments()); 737 __ LoadObject(RAX, comp->type_arguments());
729 // RAX: uninstantiated type arguments. 738 // RAX: uninstantiated type arguments.
730 __ Bind(&type_arguments_instantiated); 739 __ Bind(&type_arguments_instantiated);
731 // RAX: uninstantiated or instantiated type arguments. 740 // RAX: uninstantiated or instantiated type arguments.
732 } 741 }
733 742
734 743
735 void FlowGraphCompiler::VisitExtractConstructorInstantiator( 744 void FlowGraphCompiler::VisitExtractConstructorInstantiator(
736 ExtractConstructorInstantiatorComp* comp) { 745 ExtractConstructorInstantiatorComp* comp) {
737 __ popq(RCX); // Discard value. 746 __ popq(RCX); // Discard value.
738 __ popq(RAX); // Instantiator. 747 __ popq(RAX); // Instantiator.
739 748
740 // RAX is the instantiator AbstractTypeArguments object (or null). 749 // RAX is the instantiator AbstractTypeArguments object (or null).
741 // If RAX is null, no need to instantiate the type arguments, use null, and 750 // If the instantiator is null and if the type argument vector
742 // allocate an object of a raw type. 751 // instantiated from null becomes a vector of Dynamic, then use null as
743 // TODO(regis): The above sentence is actually not correct. If the type 752 // the type arguments and do not pass the instantiator.
744 // arguments are only partially uninstantiated, we are losing type information 753 Label done;
745 // by allocating a raw type. The code needs to be fixed here and in the 754 const intptr_t len = comp->type_arguments().Length();
746 // unoptimized version (both ia32 and x64). 755 if (comp->type_arguments().IsRawInstantiatedRaw(len)) {
747 756 const Immediate raw_null =
748 // If type arguments represent the uninstantiated identity vector and if the 757 Immediate(reinterpret_cast<intptr_t>(Object::null()));
749 // instantiator is not null, the instantiator was used as type arguments, 758 Label instantiator_not_null;
750 // therefore, the instantiator must be reset to null here to indicate to the 759 __ cmpq(RAX, raw_null);
751 // allocator that the type arguments are instantiated. 760 __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump);
761 // Null was used in VisitExtractConstructorTypeArguments as the
762 // instantiated type arguments, no proper instantiator needed.
763 __ movq(RAX, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
764 __ jmp(&done);
765 __ Bind(&instantiator_not_null);
766 }
767 // Instantiate non-null type arguments.
752 if (comp->type_arguments().IsUninstantiatedIdentity()) { 768 if (comp->type_arguments().IsUninstantiatedIdentity()) {
753 // TODO(regis): The following emitted code is duplicated in 769 // TODO(regis): The following emitted code is duplicated in
754 // VisitExtractConstructorTypeArguments above. The reason is that the code 770 // VisitExtractConstructorTypeArguments above. The reason is that the code
755 // is split between two computations, so that each one produces a 771 // is split between two computations, so that each one produces a
756 // single value, rather than producing a pair of values. 772 // single value, rather than producing a pair of values.
757 // If this becomes an issue, we should expose these tests at the IL level. 773 // If this becomes an issue, we should expose these tests at the IL level.
758 // Note that this code will still change, because bounds checking is not 774 // TODO(regis): This code will still change, because bounds checking is not
759 // implemented yet. 775 // implemented yet.
760 const Immediate raw_null =
761 Immediate(reinterpret_cast<intptr_t>(Object::null()));
762 Label use_instantiator;
763 __ cmpq(RAX, raw_null);
764 __ j(EQUAL, &use_instantiator, Assembler::kNearJump); // Already null.
765 776
766 // Check if the instantiator type argument vector is a TypeArguments of a 777 // Check if the instantiator type argument vector is a TypeArguments of a
767 // matching length and, if so, use it as the instantiated type_arguments. 778 // matching length and, if so, use it as the instantiated type_arguments.
779 // No need to check the instantiator (RAX) for null here, because a null
780 // instantiator will have the wrong class (Null instead of TypeArguments).
768 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class())); 781 __ LoadObject(RCX, Class::ZoneHandle(Object::type_arguments_class()));
769 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset())); 782 __ cmpq(RCX, FieldAddress(RAX, Object::class_offset()));
770 __ j(NOT_EQUAL, &use_instantiator, Assembler::kNearJump); 783 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
771 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>( 784 Immediate arguments_length = Immediate(reinterpret_cast<int64_t>(
772 Smi::New(comp->type_arguments().Length()))); 785 Smi::New(comp->type_arguments().Length())));
773 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()), 786 __ cmpq(FieldAddress(RAX, TypeArguments::length_offset()),
774 arguments_length); 787 arguments_length);
775 __ j(NOT_EQUAL, &use_instantiator, Assembler::kNearJump); 788 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
776 // The instantiator was used in VisitExtractConstructorTypeArguments as the 789 // The instantiator was used in VisitExtractConstructorTypeArguments as the
777 // instantiated type arguments, reset instantiator to null. 790 // instantiated type arguments, no proper instantiator needed.
778 __ movq(RAX, raw_null); // Null instantiator. 791 __ movq(RAX, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
779 __ Bind(&use_instantiator); // Use instantiator in RAX.
780 } 792 }
781 // In the non-factory case, we rely on the allocation stub to 793 __ Bind(&done);
782 // instantiate the type arguments. 794 // RAX: instantiator or kNoInstantiator.
783 // RAX: instantiator or null.
784 } 795 }
785 796
786 797
787 void FlowGraphCompiler::VisitAllocateContext(AllocateContextComp* comp) { 798 void FlowGraphCompiler::VisitAllocateContext(AllocateContextComp* comp) {
788 __ movq(R10, Immediate(comp->num_context_variables())); 799 __ movq(R10, Immediate(comp->num_context_variables()));
789 const ExternalLabel label("alloc_context", 800 const ExternalLabel label("alloc_context",
790 StubCode::AllocateContextEntryPoint()); 801 StubCode::AllocateContextEntryPoint());
791 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther); 802 GenerateCall(comp->token_index(), &label, PcDescriptors::kOther);
792 } 803 }
793 804
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { 1281 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
1271 // We don't compile exception handlers yet. 1282 // We don't compile exception handlers yet.
1272 code.set_exception_handlers( 1283 code.set_exception_handlers(
1273 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); 1284 ExceptionHandlers::Handle(ExceptionHandlers::New(0)));
1274 } 1285 }
1275 1286
1276 1287
1277 } // namespace dart 1288 } // namespace dart
1278 1289
1279 #endif // defined TARGET_ARCH_X64 1290 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698