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

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

Issue 10877011: Do not clear the spill slots in optimized code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 __ jmp(&all_arguments_processed, Assembler::kNearJump); 763 __ jmp(&all_arguments_processed, Assembler::kNearJump);
764 } 764 }
765 765
766 __ Bind(&wrong_num_arguments); 766 __ Bind(&wrong_num_arguments);
767 if (StackSize() != 0) { 767 if (StackSize() != 0) {
768 // We need to unwind the space we reserved for locals and copied parameters. 768 // We need to unwind the space we reserved for locals and copied parameters.
769 // The NoSuchMethodFunction stub does not expect to see that area on the 769 // The NoSuchMethodFunction stub does not expect to see that area on the
770 // stack. 770 // stack.
771 __ addq(RSP, Immediate(StackSize() * kWordSize)); 771 __ addq(RSP, Immediate(StackSize() * kWordSize));
772 } 772 }
773 // The calls immediately below have empty stackmaps because we have just
774 // dropped the spill slots.
775 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
773 if (function.IsClosureFunction()) { 776 if (function.IsClosureFunction()) {
774 GenerateCallRuntime(Isolate::kNoDeoptId, 777 GenerateCallRuntime(Isolate::kNoDeoptId,
775 0, 778 0,
776 CatchClauseNode::kInvalidTryIndex, 779 CatchClauseNode::kInvalidTryIndex,
777 kClosureArgumentMismatchRuntimeEntry, 780 kClosureArgumentMismatchRuntimeEntry,
778 NULL); 781 empty_stack_bitmap);
779 } else { 782 } else {
780 ASSERT(!IsLeaf()); 783 ASSERT(!IsLeaf());
781 // Invoke noSuchMethod function. 784 // Invoke noSuchMethod function.
782 const int kNumArgsChecked = 1; 785 const int kNumArgsChecked = 1;
783 ICData& ic_data = ICData::ZoneHandle(); 786 ICData& ic_data = ICData::ZoneHandle();
784 ic_data = ICData::New(function, 787 ic_data = ICData::New(function,
785 String::Handle(function.name()), 788 String::Handle(function.name()),
786 Isolate::kNoDeoptId, 789 Isolate::kNoDeoptId,
787 kNumArgsChecked); 790 kNumArgsChecked);
788 __ LoadObject(RBX, ic_data); 791 __ LoadObject(RBX, ic_data);
789 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj. 792 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj.
790 // RBP : points to previous frame pointer. 793 // RBP : points to previous frame pointer.
791 // RBP + 8 : points to return address. 794 // RBP + 8 : points to return address.
792 // RBP + 16 : address of last argument (arg n-1). 795 // RBP + 16 : address of last argument (arg n-1).
793 // RSP + 16 + 8*(n-1) : address of first argument (arg 0). 796 // RSP + 16 + 8*(n-1) : address of first argument (arg 0).
794 // RBX : ic-data. 797 // RBX : ic-data.
795 // R10 : arguments descriptor array. 798 // R10 : arguments descriptor array.
796 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); 799 __ call(&StubCode::CallNoSuchMethodFunctionLabel());
800 if (is_optimizing()) {
801 stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
802 empty_stack_bitmap);
803 }
797 } 804 }
798 805
799 if (FLAG_trace_functions) { 806 if (FLAG_trace_functions) {
800 __ pushq(RAX); // Preserve result. 807 __ pushq(RAX); // Preserve result.
801 __ PushObject(Function::ZoneHandle(function.raw())); 808 __ PushObject(Function::ZoneHandle(function.raw()));
802 GenerateCallRuntime(Isolate::kNoDeoptId, 809 GenerateCallRuntime(Isolate::kNoDeoptId,
803 0, 810 0,
804 CatchClauseNode::kInvalidTryIndex, 811 CatchClauseNode::kInvalidTryIndex,
805 kTraceFunctionExitRuntimeEntry, 812 kTraceFunctionExitRuntimeEntry,
806 NULL); 813 empty_stack_bitmap);
807 __ popq(RAX); // Remove argument. 814 __ popq(RAX); // Remove argument.
808 __ popq(RAX); // Restore result. 815 __ popq(RAX); // Restore result.
809 } 816 }
810 __ LeaveFrame(); 817 __ LeaveFrame();
811 __ ret(); 818 __ ret();
812 819
813 __ Bind(&all_arguments_processed); 820 __ Bind(&all_arguments_processed);
814 // Nullify originally passed arguments only after they have been copied and 821 // Nullify originally passed arguments only after they have been copied and
815 // checked, otherwise noSuchMethod would not see their original values. 822 // checked, otherwise noSuchMethod would not see their original values.
816 // This step can be skipped in case we decide that formal parameters are 823 // This step can be skipped in case we decide that formal parameters are
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 905
899 const int parameter_count = function.num_fixed_parameters(); 906 const int parameter_count = function.num_fixed_parameters();
900 const int copied_parameter_count = parsed_function().copied_parameter_count(); 907 const int copied_parameter_count = parsed_function().copied_parameter_count();
901 const int local_count = parsed_function().stack_local_count(); 908 const int local_count = parsed_function().stack_local_count();
902 __ Comment("Enter frame"); 909 __ Comment("Enter frame");
903 if (IsLeaf()) { 910 if (IsLeaf()) {
904 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize)); 911 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
905 } else { 912 } else {
906 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); 913 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
907 } 914 }
915
916 // For optimized code, keep a bitmap of the frame in order to build
917 // stackmaps for GC safepoints in the prologue.
918 BitmapBuilder* stack_bitmap = NULL;
919 if (is_optimizing()) {
920 // Spill slots are allocated but not initialized.
921 stack_bitmap = new BitmapBuilder();
922 stack_bitmap->SetLength(StackSize());
923 }
924
908 // We check the number of passed arguments when we have to copy them due to 925 // We check the number of passed arguments when we have to copy them due to
909 // the presence of optional named parameters. 926 // the presence of optional named parameters.
910 // No such checking code is generated if only fixed parameters are declared, 927 // No such checking code is generated if only fixed parameters are declared,
911 // unless we are debug mode or unless we are compiling a closure. 928 // unless we are debug mode or unless we are compiling a closure.
912 if (copied_parameter_count == 0) { 929 if (copied_parameter_count == 0) {
913 #ifdef DEBUG 930 #ifdef DEBUG
914 const bool check_arguments = true; 931 const bool check_arguments = true;
915 #else 932 #else
916 const bool check_arguments = function.IsClosureFunction(); 933 const bool check_arguments = function.IsClosureFunction();
917 #endif 934 #endif
918 if (check_arguments) { 935 if (check_arguments) {
919 __ Comment("Check argument count"); 936 __ Comment("Check argument count");
920 // Check that num_fixed <= argc <= num_params. 937 // Check that num_fixed <= argc <= num_params.
921 Label argc_in_range; 938 Label argc_in_range;
922 // Total number of args is the first Smi in args descriptor array (R10). 939 // Total number of args is the first Smi in args descriptor array (R10).
923 __ movq(RAX, FieldAddress(R10, Array::data_offset())); 940 __ movq(RAX, FieldAddress(R10, Array::data_offset()));
924 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count))); 941 __ cmpq(RAX, Immediate(Smi::RawValue(parameter_count)));
925 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 942 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
926 if (function.IsClosureFunction()) { 943 if (function.IsClosureFunction()) {
927 GenerateCallRuntime(Isolate::kNoDeoptId, 944 GenerateCallRuntime(Isolate::kNoDeoptId,
928 function.token_pos(), 945 function.token_pos(),
929 CatchClauseNode::kInvalidTryIndex, 946 CatchClauseNode::kInvalidTryIndex,
930 kClosureArgumentMismatchRuntimeEntry, 947 kClosureArgumentMismatchRuntimeEntry,
931 NULL); 948 stack_bitmap);
932 } else { 949 } else {
933 __ Stop("Wrong number of arguments"); 950 __ Stop("Wrong number of arguments");
934 } 951 }
935 __ Bind(&argc_in_range); 952 __ Bind(&argc_in_range);
936 } 953 }
937 } else { 954 } else {
938 CopyParameters(); 955 CopyParameters();
939 } 956 }
940 957
941 // Initialize (non-argument) stack allocated slots to null. 958 // In unoptimized code, initialize (non-argument) stack allocated slots to
942 // 959 // null.
943 // TODO(vegorov): introduce stack maps and stop initializing all spill slots 960 if (!is_optimizing() && (local_count > 0)) {
944 // with null.
945 intptr_t uninitialized_slot_count;
946 if (is_optimizing()) {
947 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry();
948 uninitialized_slot_count =
949 entry->spill_slot_count() - copied_parameter_count;
950 } else {
951 uninitialized_slot_count = local_count;
952 }
953 const intptr_t slot_base = parsed_function().first_stack_local_index();
954
955 if (uninitialized_slot_count > 0) {
956 __ Comment("Initialize spill slots"); 961 __ Comment("Initialize spill slots");
Vyacheslav Egorov (Google) 2012/08/22 13:22:08 Initialize locals
962 const intptr_t slot_base = parsed_function().first_stack_local_index();
957 const Immediate raw_null = 963 const Immediate raw_null =
958 Immediate(reinterpret_cast<intptr_t>(Object::null())); 964 Immediate(reinterpret_cast<intptr_t>(Object::null()));
959 __ movq(RAX, raw_null); 965 __ movq(RAX, raw_null);
960 for (intptr_t i = 0; i < uninitialized_slot_count; ++i) { 966 for (intptr_t i = 0; i < local_count; ++i) {
961 // Subtract index i (locals lie at lower addresses than RBP). 967 // Subtract index i (locals lie at lower addresses than RBP).
962 __ movq(Address(RBP, (slot_base - i) * kWordSize), RAX); 968 __ movq(Address(RBP, (slot_base - i) * kWordSize), RAX);
963 } 969 }
964 } 970 }
965 971
966 if (FLAG_print_scopes) { 972 if (FLAG_print_scopes) {
967 // Print the function scope (again) after generating the prologue in order 973 // Print the function scope (again) after generating the prologue in order
968 // to see annotations such as allocation indices of locals. 974 // to see annotations such as allocation indices of locals.
969 if (FLAG_print_ast) { 975 if (FLAG_print_ast) {
970 // Second printing. 976 // Second printing.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index); 1008 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index);
1003 } 1009 }
1004 1010
1005 1011
1006 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id, 1012 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id,
1007 intptr_t token_pos, 1013 intptr_t token_pos,
1008 intptr_t try_index, 1014 intptr_t try_index,
1009 const RuntimeEntry& entry, 1015 const RuntimeEntry& entry,
1010 BitmapBuilder* stack_bitmap) { 1016 BitmapBuilder* stack_bitmap) {
1011 ASSERT(!IsLeaf()); 1017 ASSERT(!IsLeaf());
1018 ASSERT(!is_optimizing() || (stack_bitmap != NULL));
1012 __ CallRuntime(entry); 1019 __ CallRuntime(entry);
1013 if (is_optimizing() && (stack_bitmap != NULL)) { 1020 if (is_optimizing()) {
1014 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), stack_bitmap); 1021 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), stack_bitmap);
1015 } 1022 }
1016 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index); 1023 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index);
1017 } 1024 }
1018 1025
1019 1026
1020 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, 1027 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
1021 const ICData& ic_data, 1028 const ICData& ic_data,
1022 const Array& arguments_descriptor, 1029 const Array& arguments_descriptor,
1023 intptr_t argument_count) { 1030 intptr_t argument_count) {
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { 1207 void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) {
1201 __ Exchange(mem1, mem2); 1208 __ Exchange(mem1, mem2);
1202 } 1209 }
1203 1210
1204 1211
1205 #undef __ 1212 #undef __
1206 1213
1207 } // namespace dart 1214 } // namespace dart
1208 1215
1209 #endif // defined TARGET_ARCH_X64 1216 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/flow_graph_compiler_ia32.cc ('K') | « runtime/vm/flow_graph_compiler_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698