| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 | 240 |
| 241 | 241 |
| 242 // Make the type of all elements be MEMORY. | 242 // Make the type of all elements be MEMORY. |
| 243 void VirtualFrame::SpillAll() { | 243 void VirtualFrame::SpillAll() { |
| 244 for (int i = 0; i < elements_.length(); i++) { | 244 for (int i = 0; i < elements_.length(); i++) { |
| 245 SpillElementAt(i); | 245 SpillElementAt(i); |
| 246 } | 246 } |
| 247 } | 247 } |
| 248 | 248 |
| 249 | 249 |
| 250 void VirtualFrame::PrepareForCall(int frame_arg_count) { | 250 void VirtualFrame::PrepareForCall(int spilled_args, int dropped_args) { |
| 251 ASSERT(height() >= frame_arg_count); | 251 ASSERT(height() >= dropped_args); |
| 252 ASSERT(height() >= spilled_args); |
| 253 ASSERT(dropped_args <= spilled_args); |
| 252 | 254 |
| 253 // Below the arguments to the function being called, spill all registers and | 255 // Below the arguments to the function being called, spill all registers and |
| 254 // make sure that locals have the right values by synching them. The synching | 256 // make sure that locals have the right values by synching them. The synching |
| 255 // is necessary to give the debugger a consistent view of the values of | 257 // is necessary to give the debugger a consistent view of the values of |
| 256 // locals in the frame. Spill the arguments to the function being called. | 258 // locals in the frame. Spill the arguments to the function being called. |
| 257 int arg_base_index = elements_.length() - frame_arg_count; | 259 int arg_base_index = elements_.length() - spilled_args; |
| 258 for (int i = 0; i < arg_base_index; i++) { | 260 for (int i = 0; i < arg_base_index; i++) { |
| 259 FrameElement element = elements_[i]; | 261 FrameElement element = elements_[i]; |
| 260 if (element.is_register()) { | 262 if (element.is_register()) { |
| 261 SpillElementAt(i); | 263 SpillElementAt(i); |
| 262 } else if (element.is_valid()) { | 264 } else if (element.is_valid()) { |
| 263 SyncElementAt(i); | 265 SyncElementAt(i); |
| 264 } | 266 } |
| 265 } | 267 } |
| 266 // The arguments are spilled. | 268 // The arguments are spilled. |
| 267 for (int i = arg_base_index; i < elements_.length(); i++) { | 269 for (int i = arg_base_index; i < elements_.length(); i++) { |
| 268 SpillElementAt(i); | 270 SpillElementAt(i); |
| 269 } | 271 } |
| 270 | 272 |
| 271 // Forget the frame elements that will be popped by the call. | 273 // Forget the frame elements that will be popped by the call. |
| 272 Forget(frame_arg_count); | 274 Forget(dropped_args); |
| 273 } | 275 } |
| 274 | 276 |
| 275 | 277 |
| 276 void VirtualFrame::MakeMergable() { | 278 void VirtualFrame::MakeMergable() { |
| 277 Comment cmnt(masm_, "[ Make frame mergable"); | 279 Comment cmnt(masm_, "[ Make frame mergable"); |
| 278 // We should always be merging the code generator's current frame to an | 280 // We should always be merging the code generator's current frame to an |
| 279 // expected frame. | 281 // expected frame. |
| 280 ASSERT(cgen_->frame() == this); | 282 ASSERT(cgen_->frame() == this); |
| 281 ASSERT(cgen_->HasValidEntryRegisters()); | 283 ASSERT(cgen_->HasValidEntryRegisters()); |
| 282 | 284 |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 // pushed separately). | 819 // pushed separately). |
| 818 Adjust(kHandlerSize - 2); | 820 Adjust(kHandlerSize - 2); |
| 819 __ PushTryHandler(IN_JAVASCRIPT, type); | 821 __ PushTryHandler(IN_JAVASCRIPT, type); |
| 820 // TODO(1222589): remove the reliance of PushTryHandler on a cached TOS | 822 // TODO(1222589): remove the reliance of PushTryHandler on a cached TOS |
| 821 EmitPush(eax); | 823 EmitPush(eax); |
| 822 } | 824 } |
| 823 | 825 |
| 824 | 826 |
| 825 Result VirtualFrame::CallStub(CodeStub* stub, int frame_arg_count) { | 827 Result VirtualFrame::CallStub(CodeStub* stub, int frame_arg_count) { |
| 826 ASSERT(cgen_->HasValidEntryRegisters()); | 828 ASSERT(cgen_->HasValidEntryRegisters()); |
| 827 PrepareForCall(frame_arg_count); | 829 PrepareForCall(frame_arg_count, frame_arg_count); |
| 828 __ CallStub(stub); | 830 __ CallStub(stub); |
| 829 Result result = cgen_->allocator()->Allocate(eax); | 831 Result result = cgen_->allocator()->Allocate(eax); |
| 830 ASSERT(result.is_valid()); | 832 ASSERT(result.is_valid()); |
| 831 return result; | 833 return result; |
| 832 } | 834 } |
| 833 | 835 |
| 834 | 836 |
| 835 Result VirtualFrame::CallStub(CodeStub* stub, | 837 Result VirtualFrame::CallStub(CodeStub* stub, |
| 836 Result* arg, | 838 Result* arg, |
| 837 int frame_arg_count) { | 839 int frame_arg_count) { |
| 838 arg->Unuse(); | 840 arg->Unuse(); |
| 839 return CallStub(stub, frame_arg_count); | 841 return CallStub(stub, frame_arg_count); |
| 840 } | 842 } |
| 841 | 843 |
| 842 | 844 |
| 843 Result VirtualFrame::CallStub(CodeStub* stub, | 845 Result VirtualFrame::CallStub(CodeStub* stub, |
| 844 Result* arg0, | 846 Result* arg0, |
| 845 Result* arg1, | 847 Result* arg1, |
| 846 int frame_arg_count) { | 848 int frame_arg_count) { |
| 847 arg0->Unuse(); | 849 arg0->Unuse(); |
| 848 arg1->Unuse(); | 850 arg1->Unuse(); |
| 849 return CallStub(stub, frame_arg_count); | 851 return CallStub(stub, frame_arg_count); |
| 850 } | 852 } |
| 851 | 853 |
| 852 | 854 |
| 853 Result VirtualFrame::CallRuntime(Runtime::Function* f, | 855 Result VirtualFrame::CallRuntime(Runtime::Function* f, |
| 854 int frame_arg_count) { | 856 int frame_arg_count) { |
| 855 ASSERT(cgen_->HasValidEntryRegisters()); | 857 ASSERT(cgen_->HasValidEntryRegisters()); |
| 856 PrepareForCall(frame_arg_count); | 858 PrepareForCall(frame_arg_count, frame_arg_count); |
| 857 __ CallRuntime(f, frame_arg_count); | 859 __ CallRuntime(f, frame_arg_count); |
| 858 Result result = cgen_->allocator()->Allocate(eax); | 860 Result result = cgen_->allocator()->Allocate(eax); |
| 859 ASSERT(result.is_valid()); | 861 ASSERT(result.is_valid()); |
| 860 return result; | 862 return result; |
| 861 } | 863 } |
| 862 | 864 |
| 863 | 865 |
| 864 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, | 866 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, |
| 865 int frame_arg_count) { | 867 int frame_arg_count) { |
| 866 ASSERT(cgen_->HasValidEntryRegisters()); | 868 ASSERT(cgen_->HasValidEntryRegisters()); |
| 867 PrepareForCall(frame_arg_count); | 869 PrepareForCall(frame_arg_count, frame_arg_count); |
| 868 __ CallRuntime(id, frame_arg_count); | 870 __ CallRuntime(id, frame_arg_count); |
| 869 Result result = cgen_->allocator()->Allocate(eax); | 871 Result result = cgen_->allocator()->Allocate(eax); |
| 870 ASSERT(result.is_valid()); | 872 ASSERT(result.is_valid()); |
| 871 return result; | 873 return result; |
| 872 } | 874 } |
| 873 | 875 |
| 874 | 876 |
| 875 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, | 877 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, |
| 876 InvokeFlag flag, | 878 InvokeFlag flag, |
| 877 int frame_arg_count) { | 879 int frame_arg_count) { |
| 878 ASSERT(cgen_->HasValidEntryRegisters()); | 880 ASSERT(cgen_->HasValidEntryRegisters()); |
| 879 PrepareForCall(frame_arg_count); | 881 PrepareForCall(frame_arg_count, frame_arg_count); |
| 880 __ InvokeBuiltin(id, flag); | 882 __ InvokeBuiltin(id, flag); |
| 881 Result result = cgen_->allocator()->Allocate(eax); | 883 Result result = cgen_->allocator()->Allocate(eax); |
| 882 ASSERT(result.is_valid()); | 884 ASSERT(result.is_valid()); |
| 883 return result; | 885 return result; |
| 884 } | 886 } |
| 885 | 887 |
| 886 | 888 |
| 887 Result VirtualFrame::CallCodeObject(Handle<Code> code, | 889 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, |
| 888 RelocInfo::Mode rmode, | 890 RelocInfo::Mode rmode, |
| 889 int frame_arg_count) { | 891 int spilled_args, |
| 892 int dropped_args) { |
| 890 ASSERT(cgen_->HasValidEntryRegisters()); | 893 ASSERT(cgen_->HasValidEntryRegisters()); |
| 891 PrepareForCall(frame_arg_count); | 894 PrepareForCall(spilled_args, dropped_args); |
| 892 __ call(code, rmode); | 895 __ call(code, rmode); |
| 893 Result result = cgen_->allocator()->Allocate(eax); | 896 Result result = cgen_->allocator()->Allocate(eax); |
| 894 ASSERT(result.is_valid()); | 897 ASSERT(result.is_valid()); |
| 895 return result; | 898 return result; |
| 896 } | 899 } |
| 897 | 900 |
| 898 | 901 |
| 902 Result VirtualFrame::CallCodeObject(Handle<Code> code, |
| 903 RelocInfo::Mode rmode, |
| 904 int dropped_args) { |
| 905 int spilled_args = 0; |
| 906 switch (code->kind()) { |
| 907 case Code::CALL_IC: |
| 908 spilled_args = dropped_args + 1; |
| 909 break; |
| 910 case Code::FUNCTION: |
| 911 spilled_args = dropped_args + 1; |
| 912 break; |
| 913 case Code::KEYED_LOAD_IC: |
| 914 ASSERT(dropped_args == 0); |
| 915 spilled_args = 2; |
| 916 break; |
| 917 default: |
| 918 // The other types of code objects are called with values |
| 919 // in specific registers, and are handled in functions with |
| 920 // a different signature. |
| 921 UNREACHABLE(); |
| 922 break; |
| 923 } |
| 924 return RawCallCodeObject(code, rmode, spilled_args, dropped_args); |
| 925 } |
| 926 |
| 927 |
| 928 Result VirtualFrame::CallCodeObject(Handle<Code> code, |
| 929 RelocInfo::Mode rmode, |
| 930 Result* arg, |
| 931 int dropped_args) { |
| 932 int spilled_args = 0; |
| 933 switch (code->kind()) { |
| 934 case Code::CALL_IC: |
| 935 ASSERT(arg->reg().is(eax)); |
| 936 spilled_args = dropped_args + 1; |
| 937 break; |
| 938 case Code::LOAD_IC: |
| 939 ASSERT(arg->reg().is(ecx)); |
| 940 ASSERT(dropped_args == 0); |
| 941 spilled_args = 1; |
| 942 break; |
| 943 case Code::KEYED_STORE_IC: |
| 944 ASSERT(arg->reg().is(eax)); |
| 945 ASSERT(dropped_args == 0); |
| 946 spilled_args = 2; |
| 947 break; |
| 948 default: |
| 949 // No other types of code objects are called with values |
| 950 // in exactly one register. |
| 951 UNREACHABLE(); |
| 952 break; |
| 953 } |
| 954 arg->Unuse(); |
| 955 return RawCallCodeObject(code, rmode, spilled_args, dropped_args); |
| 956 } |
| 957 |
| 958 |
| 959 Result VirtualFrame::CallCodeObject(Handle<Code> code, |
| 960 RelocInfo::Mode rmode, |
| 961 Result* arg0, |
| 962 Result* arg1, |
| 963 int dropped_args) { |
| 964 int spilled_args = 1; |
| 965 switch (code->kind()) { |
| 966 case Code::STORE_IC: |
| 967 ASSERT(arg0->reg().is(eax)); |
| 968 ASSERT(arg1->reg().is(ecx)); |
| 969 ASSERT(dropped_args == 0); |
| 970 spilled_args = 1; |
| 971 break; |
| 972 case Code::BUILTIN: |
| 973 ASSERT(*code == Builtins::builtin(Builtins::JSConstructCall)); |
| 974 ASSERT(arg0->reg().is(eax)); |
| 975 ASSERT(arg1->reg().is(edi)); |
| 976 spilled_args = dropped_args + 1; |
| 977 break; |
| 978 default: |
| 979 // No other types of code objects are called with values |
| 980 // in exactly two registers. |
| 981 UNREACHABLE(); |
| 982 break; |
| 983 } |
| 984 arg0->Unuse(); |
| 985 arg1->Unuse(); |
| 986 return RawCallCodeObject(code, rmode, spilled_args, dropped_args); |
| 987 } |
| 988 |
| 989 |
| 899 void VirtualFrame::Drop(int count) { | 990 void VirtualFrame::Drop(int count) { |
| 900 ASSERT(height() >= count); | 991 ASSERT(height() >= count); |
| 901 int num_virtual_elements = (elements_.length() - 1) - stack_pointer_; | 992 int num_virtual_elements = (elements_.length() - 1) - stack_pointer_; |
| 902 | 993 |
| 903 // Emit code to lower the stack pointer if necessary. | 994 // Emit code to lower the stack pointer if necessary. |
| 904 if (num_virtual_elements < count) { | 995 if (num_virtual_elements < count) { |
| 905 int num_dropped = count - num_virtual_elements; | 996 int num_dropped = count - num_virtual_elements; |
| 906 stack_pointer_ -= num_dropped; | 997 stack_pointer_ -= num_dropped; |
| 907 __ add(Operand(esp), Immediate(num_dropped * kPointerSize)); | 998 __ add(Operand(esp), Immediate(num_dropped * kPointerSize)); |
| 908 } | 999 } |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1028 return false; | 1119 return false; |
| 1029 } | 1120 } |
| 1030 } | 1121 } |
| 1031 return true; | 1122 return true; |
| 1032 } | 1123 } |
| 1033 #endif | 1124 #endif |
| 1034 | 1125 |
| 1035 #undef __ | 1126 #undef __ |
| 1036 | 1127 |
| 1037 } } // namespace v8::internal | 1128 } } // namespace v8::internal |
| OLD | NEW |