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

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

Issue 10458031: In generated code for x64 don't load object's class directly from class_ field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Eliminate CoreClass helpers on ia32/x64 and use class ids for array classes. Created 8 years, 6 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_compiler_x64.cc ('k') | runtime/vm/intrinsifier_ia32.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/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 "lib/error.h" 8 #include "lib/error.h"
9 #include "vm/flow_graph_compiler.h" 9 #include "vm/flow_graph_compiler.h"
10 #include "vm/locations.h" 10 #include "vm/locations.h"
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 Register dest_reg = locs()->in(1).reg(); 670 Register dest_reg = locs()->in(1).reg();
671 ASSERT(value_reg == locs()->out().reg()); 671 ASSERT(value_reg == locs()->out().reg());
672 672
673 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()), 673 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
674 value_reg); 674 value_reg);
675 } 675 }
676 676
677 677
678 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { 678 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
679 const intptr_t kNumInputs = 1; 679 const intptr_t kNumInputs = 1;
680 const intptr_t kNumTemps = 1; 680 const intptr_t kNumTemps = 0;
681 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 681 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
682 locs->set_in(0, Location::RequiresRegister()); 682 locs->set_in(0, Location::RequiresRegister());
683 locs->set_temp(0, Location::RequiresRegister());
684 locs->set_out(Location::SameAsFirstInput()); 683 locs->set_out(Location::SameAsFirstInput());
685 return locs; 684 return locs;
686 } 685 }
687 686
688 687
689 void InstantiateTypeArgumentsComp::EmitNativeCode(FlowGraphCompiler* compiler) { 688 void InstantiateTypeArgumentsComp::EmitNativeCode(FlowGraphCompiler* compiler) {
690 Register instantiator_reg = locs()->in(0).reg(); 689 Register instantiator_reg = locs()->in(0).reg();
691 Register temp_reg = locs()->temp(0).reg();
692 Register result_reg = locs()->out().reg(); 690 Register result_reg = locs()->out().reg();
693 691
694 // 'instantiator_reg' is the instantiator AbstractTypeArguments object 692 // 'instantiator_reg' is the instantiator AbstractTypeArguments object
695 // (or null). 693 // (or null).
696 // If the instantiator is null and if the type argument vector 694 // If the instantiator is null and if the type argument vector
697 // instantiated from null becomes a vector of Dynamic, then use null as 695 // instantiated from null becomes a vector of Dynamic, then use null as
698 // the type arguments. 696 // the type arguments.
699 Label type_arguments_instantiated; 697 Label type_arguments_instantiated;
700 const intptr_t len = type_arguments().Length(); 698 const intptr_t len = type_arguments().Length();
701 if (type_arguments().IsRawInstantiatedRaw(len)) { 699 if (type_arguments().IsRawInstantiatedRaw(len)) {
702 const Immediate raw_null = 700 const Immediate raw_null =
703 Immediate(reinterpret_cast<intptr_t>(Object::null())); 701 Immediate(reinterpret_cast<intptr_t>(Object::null()));
704 __ cmpq(instantiator_reg, raw_null); 702 __ cmpq(instantiator_reg, raw_null);
705 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 703 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
706 } 704 }
707 // Instantiate non-null type arguments. 705 // Instantiate non-null type arguments.
708 if (type_arguments().IsUninstantiatedIdentity()) { 706 if (type_arguments().IsUninstantiatedIdentity()) {
709 Label type_arguments_uninstantiated; 707 Label type_arguments_uninstantiated;
710 // Check if the instantiator type argument vector is a TypeArguments of a 708 // Check if the instantiator type argument vector is a TypeArguments of a
711 // matching length and, if so, use it as the instantiated type_arguments. 709 // matching length and, if so, use it as the instantiated type_arguments.
712 // No need to check the instantiator ('instantiator_reg') for null here, 710 // No need to check the instantiator ('instantiator_reg') for null here,
713 // because a null instantiator will have the wrong class (Null instead of 711 // because a null instantiator will have the wrong class (Null instead of
714 // TypeArguments). 712 // TypeArguments).
715 __ LoadObject(temp_reg, Class::ZoneHandle(Object::type_arguments_class())); 713 __ CompareClassId(instantiator_reg, kTypeArguments);
716 __ cmpq(temp_reg, FieldAddress(instantiator_reg, Object::class_offset()));
717 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 714 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
718 Immediate arguments_length = 715 Immediate arguments_length =
719 Immediate(Smi::RawValue(type_arguments().Length())); 716 Immediate(Smi::RawValue(type_arguments().Length()));
720 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 717 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
721 arguments_length); 718 arguments_length);
722 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 719 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
723 __ Bind(&type_arguments_uninstantiated); 720 __ Bind(&type_arguments_uninstantiated);
724 } 721 }
725 // A runtime call to instantiate the type arguments is required. 722 // A runtime call to instantiate the type arguments is required.
726 __ PushObject(Object::ZoneHandle()); // Make room for the result. 723 __ PushObject(Object::ZoneHandle()); // Make room for the result.
727 __ PushObject(type_arguments()); 724 __ PushObject(type_arguments());
728 __ pushq(instantiator_reg); // Push instantiator type arguments. 725 __ pushq(instantiator_reg); // Push instantiator type arguments.
729 compiler->GenerateCallRuntime(cid(), 726 compiler->GenerateCallRuntime(cid(),
730 token_index(), 727 token_index(),
731 try_index(), 728 try_index(),
732 kInstantiateTypeArgumentsRuntimeEntry); 729 kInstantiateTypeArgumentsRuntimeEntry);
733 __ popq(temp_reg); // Pop instantiator type arguments. 730 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
734 __ popq(temp_reg); // Pop uninstantiated type arguments.
735 __ popq(result_reg); // Pop instantiated type arguments. 731 __ popq(result_reg); // Pop instantiated type arguments.
736 __ Bind(&type_arguments_instantiated); 732 __ Bind(&type_arguments_instantiated);
737 ASSERT(instantiator_reg == result_reg); 733 ASSERT(instantiator_reg == result_reg);
738 // 'result_reg': Instantiated type arguments. 734 // 'result_reg': Instantiated type arguments.
739 } 735 }
740 736
741 737
742 LocationSummary* ExtractConstructorTypeArgumentsComp:: 738 LocationSummary* ExtractConstructorTypeArgumentsComp::
743 MakeLocationSummary() const { 739 MakeLocationSummary() const {
744 return NULL; 740 return NULL;
745 } 741 }
746 742
747 743
748 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( 744 void ExtractConstructorTypeArgumentsComp::EmitNativeCode(
749 FlowGraphCompiler* compiler) { 745 FlowGraphCompiler* compiler) {
750 UNIMPLEMENTED(); 746 UNIMPLEMENTED();
751 } 747 }
752 748
753 749
754 LocationSummary* ExtractConstructorInstantiatorComp:: 750 LocationSummary* ExtractConstructorInstantiatorComp::
755 MakeLocationSummary() const { 751 MakeLocationSummary() const {
756 const intptr_t kNumInputs = 1; 752 const intptr_t kNumInputs = 1;
757 const intptr_t kNumTemps = 1; 753 const intptr_t kNumTemps = 0;
758 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 754 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
759 locs->set_in(0, Location::RequiresRegister()); 755 locs->set_in(0, Location::RequiresRegister());
760 locs->set_temp(0, Location::RequiresRegister());
761 locs->set_out(Location::SameAsFirstInput()); 756 locs->set_out(Location::SameAsFirstInput());
762 return locs; 757 return locs;
763 } 758 }
764 759
765 760
766 void ExtractConstructorInstantiatorComp::EmitNativeCode( 761 void ExtractConstructorInstantiatorComp::EmitNativeCode(
767 FlowGraphCompiler* compiler) { 762 FlowGraphCompiler* compiler) {
768 ASSERT(instantiator()->IsUse()); 763 ASSERT(instantiator()->IsUse());
769 Register instantiator_reg = locs()->in(0).reg(); 764 Register instantiator_reg = locs()->in(0).reg();
770 Register temp_reg = locs()->temp(0).reg();
771 ASSERT(locs()->out().reg() == instantiator_reg); 765 ASSERT(locs()->out().reg() == instantiator_reg);
772 766
773 // instantiator_reg is the instantiator AbstractTypeArguments object 767 // instantiator_reg is the instantiator AbstractTypeArguments object
774 // (or null). If the instantiator is null and if the type argument vector 768 // (or null). If the instantiator is null and if the type argument vector
775 // instantiated from null becomes a vector of Dynamic, then use null as 769 // instantiated from null becomes a vector of Dynamic, then use null as
776 // the type arguments and do not pass the instantiator. 770 // the type arguments and do not pass the instantiator.
777 Label done; 771 Label done;
778 const intptr_t len = type_arguments().Length(); 772 const intptr_t len = type_arguments().Length();
779 if (type_arguments().IsRawInstantiatedRaw(len)) { 773 if (type_arguments().IsRawInstantiatedRaw(len)) {
780 const Immediate raw_null = 774 const Immediate raw_null =
(...skipping 13 matching lines...) Expand all
794 // TODO(regis): The following emitted code is duplicated in 788 // TODO(regis): The following emitted code is duplicated in
795 // VisitExtractConstructorTypeArguments above. The reason is that the code 789 // VisitExtractConstructorTypeArguments above. The reason is that the code
796 // is split between two computations, so that each one produces a 790 // is split between two computations, so that each one produces a
797 // single value, rather than producing a pair of values. 791 // single value, rather than producing a pair of values.
798 // If this becomes an issue, we should expose these tests at the IL level. 792 // If this becomes an issue, we should expose these tests at the IL level.
799 793
800 // Check if the instantiator type argument vector is a TypeArguments of a 794 // Check if the instantiator type argument vector is a TypeArguments of a
801 // matching length and, if so, use it as the instantiated type_arguments. 795 // matching length and, if so, use it as the instantiated type_arguments.
802 // No need to check the instantiator (RAX) for null here, because a null 796 // No need to check the instantiator (RAX) for null here, because a null
803 // instantiator will have the wrong class (Null instead of TypeArguments). 797 // instantiator will have the wrong class (Null instead of TypeArguments).
804 __ LoadObject(temp_reg, Class::ZoneHandle(Object::type_arguments_class())); 798 __ CompareClassId(instantiator_reg, kTypeArguments);
805 __ cmpq(temp_reg, FieldAddress(instantiator_reg, Object::class_offset()));
806 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 799 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
807 Immediate arguments_length = 800 Immediate arguments_length =
808 Immediate(Smi::RawValue(type_arguments().Length())); 801 Immediate(Smi::RawValue(type_arguments().Length()));
809 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 802 __ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
810 arguments_length); 803 arguments_length);
811 __ j(NOT_EQUAL, &done, Assembler::kNearJump); 804 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
812 // The instantiator was used in VisitExtractConstructorTypeArguments as the 805 // The instantiator was used in VisitExtractConstructorTypeArguments as the
813 // instantiated type arguments, no proper instantiator needed. 806 // instantiated type arguments, no proper instantiator needed.
814 __ movq(instantiator_reg, 807 __ movq(instantiator_reg,
815 Immediate(Smi::RawValue(StubCode::kNoInstantiator))); 808 Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 if (locs()->out().reg() != RAX) { 958 if (locs()->out().reg() != RAX) {
966 __ movq(locs()->out().reg(), RAX); 959 __ movq(locs()->out().reg(), RAX);
967 } 960 }
968 } 961 }
969 962
970 } // namespace dart 963 } // namespace dart
971 964
972 #undef __ 965 #undef __
973 966
974 #endif // defined TARGET_ARCH_X64 967 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.cc ('k') | runtime/vm/intrinsifier_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698