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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 746 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 __ jmp(&all_arguments_processed, Assembler::kNearJump); 757 __ jmp(&all_arguments_processed, Assembler::kNearJump);
758 } 758 }
759 759
760 __ Bind(&wrong_num_arguments); 760 __ Bind(&wrong_num_arguments);
761 if (StackSize() != 0) { 761 if (StackSize() != 0) {
762 // We need to unwind the space we reserved for locals and copied parameters. 762 // We need to unwind the space we reserved for locals and copied parameters.
763 // The NoSuchMethodFunction stub does not expect to see that area on the 763 // The NoSuchMethodFunction stub does not expect to see that area on the
764 // stack. 764 // stack.
765 __ addl(ESP, Immediate(StackSize() * kWordSize)); 765 __ addl(ESP, Immediate(StackSize() * kWordSize));
766 } 766 }
767 // The calls below have empty stackmaps because we have just dropped the
768 // spill slots.
769 BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
767 if (function.IsClosureFunction()) { 770 if (function.IsClosureFunction()) {
768 GenerateCallRuntime(Isolate::kNoDeoptId, 771 GenerateCallRuntime(Isolate::kNoDeoptId,
769 0, 772 0,
770 CatchClauseNode::kInvalidTryIndex, 773 CatchClauseNode::kInvalidTryIndex,
771 kClosureArgumentMismatchRuntimeEntry, 774 kClosureArgumentMismatchRuntimeEntry,
772 NULL); 775 empty_stack_bitmap);
773 } else { 776 } else {
774 ASSERT(!IsLeaf()); 777 ASSERT(!IsLeaf());
775 // Invoke noSuchMethod function. 778 // Invoke noSuchMethod function.
776 const int kNumArgsChecked = 1; 779 const int kNumArgsChecked = 1;
777 ICData& ic_data = ICData::ZoneHandle(); 780 ICData& ic_data = ICData::ZoneHandle();
778 ic_data = ICData::New(function, 781 ic_data = ICData::New(function,
779 String::Handle(function.name()), 782 String::Handle(function.name()),
780 Isolate::kNoDeoptId, 783 Isolate::kNoDeoptId,
781 kNumArgsChecked); 784 kNumArgsChecked);
782 __ LoadObject(ECX, ic_data); 785 __ LoadObject(ECX, ic_data);
783 // EBP - 4 : PC marker, allows easy identification of RawInstruction obj. 786 // EBP - 4 : PC marker, allows easy identification of RawInstruction obj.
784 // EBP : points to previous frame pointer. 787 // EBP : points to previous frame pointer.
785 // EBP + 4 : points to return address. 788 // EBP + 4 : points to return address.
786 // EBP + 8 : address of last argument (arg n-1). 789 // EBP + 8 : address of last argument (arg n-1).
787 // ESP + 8 + 4*(n-1) : address of first argument (arg 0). 790 // ESP + 8 + 4*(n-1) : address of first argument (arg 0).
788 // ECX : ic-data. 791 // ECX : ic-data.
789 // EDX : arguments descriptor array. 792 // EDX : arguments descriptor array.
790 __ call(&StubCode::CallNoSuchMethodFunctionLabel()); 793 __ call(&StubCode::CallNoSuchMethodFunctionLabel());
794 if (is_optimizing()) {
795 stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
796 empty_stack_bitmap);
797 }
791 } 798 }
792 799
793 if (FLAG_trace_functions) { 800 if (FLAG_trace_functions) {
794 __ pushl(EAX); // Preserve result. 801 __ pushl(EAX); // Preserve result.
795 __ PushObject(Function::ZoneHandle(function.raw())); 802 __ PushObject(Function::ZoneHandle(function.raw()));
796 GenerateCallRuntime(Isolate::kNoDeoptId, 803 GenerateCallRuntime(Isolate::kNoDeoptId,
797 0, 804 0,
798 CatchClauseNode::kInvalidTryIndex, 805 CatchClauseNode::kInvalidTryIndex,
799 kTraceFunctionExitRuntimeEntry, 806 kTraceFunctionExitRuntimeEntry,
800 NULL); 807 empty_stack_bitmap);
801 __ popl(EAX); // Remove argument. 808 __ popl(EAX); // Remove argument.
802 __ popl(EAX); // Restore result. 809 __ popl(EAX); // Restore result.
803 } 810 }
804 __ LeaveFrame(); 811 __ LeaveFrame();
805 __ ret(); 812 __ ret();
806 813
807 __ Bind(&all_arguments_processed); 814 __ Bind(&all_arguments_processed);
808 // Nullify originally passed arguments only after they have been copied and 815 // Nullify originally passed arguments only after they have been copied and
809 // checked, otherwise noSuchMethod would not see their original values. 816 // checked, otherwise noSuchMethod would not see their original values.
810 // This step can be skipped in case we decide that formal parameters are 817 // This step can be skipped in case we decide that formal parameters are
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 898
892 const int parameter_count = function.num_fixed_parameters(); 899 const int parameter_count = function.num_fixed_parameters();
893 const int copied_parameter_count = parsed_function().copied_parameter_count(); 900 const int copied_parameter_count = parsed_function().copied_parameter_count();
894 const int local_count = parsed_function().stack_local_count(); 901 const int local_count = parsed_function().stack_local_count();
895 __ Comment("Enter frame"); 902 __ Comment("Enter frame");
896 if (IsLeaf()) { 903 if (IsLeaf()) {
897 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize)); 904 AssemblerMacros::EnterDartLeafFrame(assembler(), (StackSize() * kWordSize));
898 } else { 905 } else {
899 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize)); 906 AssemblerMacros::EnterDartFrame(assembler(), (StackSize() * kWordSize));
900 } 907 }
908
909 // For optimized code, keep a bitmap of the frame in order to build
910 // stackmaps for GC safepoints in the prologue.
911 BitmapBuilder* stack_bitmap = NULL;
912 if (is_optimizing()) {
913 // Spill slots are allocated but not initialized.
914 stack_bitmap = new BitmapBuilder();
915 stack_bitmap->SetLength(StackSize());
916 }
917
901 // We check the number of passed arguments when we have to copy them due to 918 // We check the number of passed arguments when we have to copy them due to
902 // the presence of optional named parameters. 919 // the presence of optional named parameters.
903 // No such checking code is generated if only fixed parameters are declared, 920 // No such checking code is generated if only fixed parameters are declared,
904 // unless we are debug mode or unless we are compiling a closure. 921 // unless we are debug mode or unless we are compiling a closure.
905 if (copied_parameter_count == 0) { 922 if (copied_parameter_count == 0) {
906 #ifdef DEBUG 923 #ifdef DEBUG
907 const bool check_arguments = true; 924 const bool check_arguments = true;
908 #else 925 #else
909 const bool check_arguments = function.IsClosureFunction(); 926 const bool check_arguments = function.IsClosureFunction();
910 #endif 927 #endif
911 if (check_arguments) { 928 if (check_arguments) {
912 __ Comment("Check argument count"); 929 __ Comment("Check argument count");
913 // Check that num_fixed <= argc <= num_params. 930 // Check that num_fixed <= argc <= num_params.
914 Label argc_in_range; 931 Label argc_in_range;
915 // Total number of args is the first Smi in args descriptor array (EDX). 932 // Total number of args is the first Smi in args descriptor array (EDX).
916 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 933 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
917 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count))); 934 __ cmpl(EAX, Immediate(Smi::RawValue(parameter_count)));
918 __ j(EQUAL, &argc_in_range, Assembler::kNearJump); 935 __ j(EQUAL, &argc_in_range, Assembler::kNearJump);
919 if (function.IsClosureFunction()) { 936 if (function.IsClosureFunction()) {
920 GenerateCallRuntime(Isolate::kNoDeoptId, 937 GenerateCallRuntime(Isolate::kNoDeoptId,
921 function.token_pos(), 938 function.token_pos(),
922 CatchClauseNode::kInvalidTryIndex, 939 CatchClauseNode::kInvalidTryIndex,
923 kClosureArgumentMismatchRuntimeEntry, 940 kClosureArgumentMismatchRuntimeEntry,
924 NULL); 941 stack_bitmap);
925 } else { 942 } else {
926 __ Stop("Wrong number of arguments"); 943 __ Stop("Wrong number of arguments");
927 } 944 }
928 __ Bind(&argc_in_range); 945 __ Bind(&argc_in_range);
929 } 946 }
930 } else { 947 } else {
931 CopyParameters(); 948 CopyParameters();
932 } 949 }
933 950
934 // Initialize (non-argument) stack allocated slots to null. 951 // In unoptimized code, initialize (non-argument) stack allocated slots to
935 // 952 // null.
936 // TODO(vegorov): introduce stack maps and stop initializing all spill slots 953 if (!is_optimizing() && (local_count > 0)) {
937 // with null.
938 intptr_t uninitialized_slot_count;
939 if (is_optimizing()) {
940 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry();
941 uninitialized_slot_count =
942 entry->spill_slot_count() - copied_parameter_count;
943 } else {
944 uninitialized_slot_count = local_count;
945 }
946 const intptr_t slot_base = parsed_function().first_stack_local_index();
947
948 if (uninitialized_slot_count > 0) {
949 __ Comment("Initialize spill slots"); 954 __ Comment("Initialize spill slots");
Vyacheslav Egorov (Google) 2012/08/22 13:22:08 "Initialize locals"
955 const intptr_t slot_base = parsed_function().first_stack_local_index();
950 const Immediate raw_null = 956 const Immediate raw_null =
951 Immediate(reinterpret_cast<intptr_t>(Object::null())); 957 Immediate(reinterpret_cast<intptr_t>(Object::null()));
952 __ movl(EAX, raw_null); 958 __ movl(EAX, raw_null);
953 for (intptr_t i = 0; i < uninitialized_slot_count; ++i) { 959 for (intptr_t i = 0; i < local_count; ++i) {
954 // Subtract index i (locals lie at lower addresses than EBP). 960 // Subtract index i (locals lie at lower addresses than EBP).
955 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX); 961 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX);
956 } 962 }
957 } 963 }
958 964
959 if (FLAG_print_scopes) { 965 if (FLAG_print_scopes) {
960 // Print the function scope (again) after generating the prologue in order 966 // Print the function scope (again) after generating the prologue in order
961 // to see annotations such as allocation indices of locals. 967 // to see annotations such as allocation indices of locals.
962 if (FLAG_print_ast) { 968 if (FLAG_print_ast) {
963 // Second printing. 969 // Second printing.
(...skipping 30 matching lines...) Expand all
994 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index); 1000 AddCurrentDescriptor(kind, Isolate::kNoDeoptId, token_pos, try_index);
995 } 1001 }
996 1002
997 1003
998 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id, 1004 void FlowGraphCompiler::GenerateCallRuntime(intptr_t deopt_id,
999 intptr_t token_pos, 1005 intptr_t token_pos,
1000 intptr_t try_index, 1006 intptr_t try_index,
1001 const RuntimeEntry& entry, 1007 const RuntimeEntry& entry,
1002 BitmapBuilder* stack_bitmap) { 1008 BitmapBuilder* stack_bitmap) {
1003 ASSERT(!IsLeaf()); 1009 ASSERT(!IsLeaf());
1010 ASSERT(!is_optimizing() || (stack_bitmap != NULL));
1004 __ CallRuntime(entry); 1011 __ CallRuntime(entry);
1005 if (is_optimizing() && (stack_bitmap != NULL)) { 1012 if (is_optimizing()) {
1006 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), stack_bitmap); 1013 stackmap_table_builder_->AddEntry(assembler()->CodeSize(), stack_bitmap);
1007 } 1014 }
1008 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index); 1015 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos, try_index);
1009 } 1016 }
1010 1017
1011 1018
1012 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label, 1019 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
1013 const ICData& ic_data, 1020 const ICData& ic_data,
1014 const Array& arguments_descriptor, 1021 const Array& arguments_descriptor,
1015 intptr_t argument_count) { 1022 intptr_t argument_count) {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 __ popl(ECX); 1221 __ popl(ECX);
1215 __ popl(EAX); 1222 __ popl(EAX);
1216 } 1223 }
1217 1224
1218 1225
1219 #undef __ 1226 #undef __
1220 1227
1221 } // namespace dart 1228 } // namespace dart
1222 1229
1223 #endif // defined TARGET_ARCH_IA32 1230 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_compiler_x64.cc » ('j') | runtime/vm/flow_graph_compiler_x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698