| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 // ------------------------------------------------------------------------- | 39 // ------------------------------------------------------------------------- |
| 40 // VirtualFrame implementation. | 40 // VirtualFrame implementation. |
| 41 | 41 |
| 42 // On entry to a function, the virtual frame already contains the receiver, | 42 // On entry to a function, the virtual frame already contains the receiver, |
| 43 // the parameters, and a return address. All frame elements are in memory. | 43 // the parameters, and a return address. All frame elements are in memory. |
| 44 VirtualFrame::VirtualFrame() | 44 VirtualFrame::VirtualFrame() |
| 45 : elements_(parameter_count() + local_count() + kPreallocatedElements), | 45 : elements_(parameter_count() + local_count() + kPreallocatedElements), |
| 46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS. | 46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS. |
| 47 for (int i = 0; i <= stack_pointer_; i++) { | 47 for (int i = 0; i <= stack_pointer_; i++) { |
| 48 elements_.Add(FrameElement::MemoryElement()); | 48 elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown)); |
| 49 } | 49 } |
| 50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { | 50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { |
| 51 register_locations_[i] = kIllegalIndex; | 51 register_locations_[i] = kIllegalIndex; |
| 52 } | 52 } |
| 53 } | 53 } |
| 54 | 54 |
| 55 | 55 |
| 56 void VirtualFrame::SyncElementBelowStackPointer(int index) { | 56 void VirtualFrame::SyncElementBelowStackPointer(int index) { |
| 57 // Emit code to write elements below the stack pointer to their | 57 // Emit code to write elements below the stack pointer to their |
| 58 // (already allocated) stack address. | 58 // (already allocated) stack address. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 void VirtualFrame::MakeMergable() { | 172 void VirtualFrame::MakeMergable() { |
| 173 for (int i = 0; i < element_count(); i++) { | 173 for (int i = 0; i < element_count(); i++) { |
| 174 FrameElement element = elements_[i]; | 174 FrameElement element = elements_[i]; |
| 175 | 175 |
| 176 // All number type information is reset to unknown for a mergable frame |
| 177 // because of incoming back edges. |
| 176 if (element.is_constant() || element.is_copy()) { | 178 if (element.is_constant() || element.is_copy()) { |
| 177 if (element.is_synced()) { | 179 if (element.is_synced()) { |
| 178 // Just spill. | 180 // Just spill. |
| 179 elements_[i] = FrameElement::MemoryElement(); | 181 elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown); |
| 180 } else { | 182 } else { |
| 181 // Allocate to a register. | 183 // Allocate to a register. |
| 182 FrameElement backing_element; // Invalid if not a copy. | 184 FrameElement backing_element; // Invalid if not a copy. |
| 183 if (element.is_copy()) { | 185 if (element.is_copy()) { |
| 184 backing_element = elements_[element.index()]; | 186 backing_element = elements_[element.index()]; |
| 185 } | 187 } |
| 186 Result fresh = cgen()->allocator()->Allocate(); | 188 Result fresh = cgen()->allocator()->Allocate(); |
| 187 ASSERT(fresh.is_valid()); // A register was spilled if all were in use. | 189 ASSERT(fresh.is_valid()); // A register was spilled if all were in use. |
| 188 elements_[i] = | 190 elements_[i] = |
| 189 FrameElement::RegisterElement(fresh.reg(), | 191 FrameElement::RegisterElement(fresh.reg(), |
| 190 FrameElement::NOT_SYNCED); | 192 FrameElement::NOT_SYNCED, |
| 193 NumberInfo::kUnknown); |
| 191 Use(fresh.reg(), i); | 194 Use(fresh.reg(), i); |
| 192 | 195 |
| 193 // Emit a move. | 196 // Emit a move. |
| 194 if (element.is_constant()) { | 197 if (element.is_constant()) { |
| 195 if (cgen()->IsUnsafeSmi(element.handle())) { | 198 if (cgen()->IsUnsafeSmi(element.handle())) { |
| 196 cgen()->MoveUnsafeSmi(fresh.reg(), element.handle()); | 199 cgen()->MoveUnsafeSmi(fresh.reg(), element.handle()); |
| 197 } else { | 200 } else { |
| 198 __ Set(fresh.reg(), Immediate(element.handle())); | 201 __ Set(fresh.reg(), Immediate(element.handle())); |
| 199 } | 202 } |
| 200 } else { | 203 } else { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 213 } | 216 } |
| 214 } | 217 } |
| 215 } | 218 } |
| 216 // No need to set the copied flag --- there are no copies. | 219 // No need to set the copied flag --- there are no copies. |
| 217 } else { | 220 } else { |
| 218 // Clear the copy flag of non-constant, non-copy elements. | 221 // Clear the copy flag of non-constant, non-copy elements. |
| 219 // They cannot be copied because copies are not allowed. | 222 // They cannot be copied because copies are not allowed. |
| 220 // The copy flag is not relied on before the end of this loop, | 223 // The copy flag is not relied on before the end of this loop, |
| 221 // including when registers are spilled. | 224 // including when registers are spilled. |
| 222 elements_[i].clear_copied(); | 225 elements_[i].clear_copied(); |
| 226 elements_[i].set_number_info(NumberInfo::kUnknown); |
| 223 } | 227 } |
| 224 } | 228 } |
| 225 } | 229 } |
| 226 | 230 |
| 227 | 231 |
| 228 void VirtualFrame::MergeTo(VirtualFrame* expected) { | 232 void VirtualFrame::MergeTo(VirtualFrame* expected) { |
| 229 Comment cmnt(masm(), "[ Merge frame"); | 233 Comment cmnt(masm(), "[ Merge frame"); |
| 230 // We should always be merging the code generator's current frame to an | 234 // We should always be merging the code generator's current frame to an |
| 231 // expected frame. | 235 // expected frame. |
| 232 ASSERT(cgen()->frame() == this); | 236 ASSERT(cgen()->frame() == this); |
| (...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 600 } else { | 604 } else { |
| 601 // The original was in a register. | 605 // The original was in a register. |
| 602 backing_reg = original.reg(); | 606 backing_reg = original.reg(); |
| 603 set_register_location(backing_reg, new_backing_index); | 607 set_register_location(backing_reg, new_backing_index); |
| 604 } | 608 } |
| 605 // Invalidate the element at index. | 609 // Invalidate the element at index. |
| 606 elements_[index] = FrameElement::InvalidElement(); | 610 elements_[index] = FrameElement::InvalidElement(); |
| 607 // Set the new backing element. | 611 // Set the new backing element. |
| 608 if (elements_[new_backing_index].is_synced()) { | 612 if (elements_[new_backing_index].is_synced()) { |
| 609 elements_[new_backing_index] = | 613 elements_[new_backing_index] = |
| 610 FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED); | 614 FrameElement::RegisterElement(backing_reg, |
| 615 FrameElement::SYNCED, |
| 616 original.number_info()); |
| 611 } else { | 617 } else { |
| 612 elements_[new_backing_index] = | 618 elements_[new_backing_index] = |
| 613 FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED); | 619 FrameElement::RegisterElement(backing_reg, |
| 620 FrameElement::NOT_SYNCED, |
| 621 original.number_info()); |
| 614 } | 622 } |
| 615 // Update the other copies. | 623 // Update the other copies. |
| 616 for (int i = new_backing_index + 1; i < element_count(); i++) { | 624 for (int i = new_backing_index + 1; i < element_count(); i++) { |
| 617 if (elements_[i].is_copy() && elements_[i].index() == index) { | 625 if (elements_[i].is_copy() && elements_[i].index() == index) { |
| 618 elements_[i].set_index(new_backing_index); | 626 elements_[i].set_index(new_backing_index); |
| 619 elements_[new_backing_index].set_copied(); | 627 elements_[new_backing_index].set_copied(); |
| 620 } | 628 } |
| 621 } | 629 } |
| 622 return new_backing_index; | 630 return new_backing_index; |
| 623 } | 631 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 634 } | 642 } |
| 635 | 643 |
| 636 switch (original.type()) { | 644 switch (original.type()) { |
| 637 case FrameElement::MEMORY: { | 645 case FrameElement::MEMORY: { |
| 638 // Emit code to load the original element's data into a register. | 646 // Emit code to load the original element's data into a register. |
| 639 // Push that register as a FrameElement on top of the frame. | 647 // Push that register as a FrameElement on top of the frame. |
| 640 Result fresh = cgen()->allocator()->Allocate(); | 648 Result fresh = cgen()->allocator()->Allocate(); |
| 641 ASSERT(fresh.is_valid()); | 649 ASSERT(fresh.is_valid()); |
| 642 FrameElement new_element = | 650 FrameElement new_element = |
| 643 FrameElement::RegisterElement(fresh.reg(), | 651 FrameElement::RegisterElement(fresh.reg(), |
| 644 FrameElement::NOT_SYNCED); | 652 FrameElement::NOT_SYNCED, |
| 653 original.number_info()); |
| 645 Use(fresh.reg(), element_count()); | 654 Use(fresh.reg(), element_count()); |
| 646 elements_.Add(new_element); | 655 elements_.Add(new_element); |
| 647 __ mov(fresh.reg(), Operand(ebp, fp_relative(index))); | 656 __ mov(fresh.reg(), Operand(ebp, fp_relative(index))); |
| 648 break; | 657 break; |
| 649 } | 658 } |
| 650 case FrameElement::REGISTER: | 659 case FrameElement::REGISTER: |
| 651 Use(original.reg(), element_count()); | 660 Use(original.reg(), element_count()); |
| 652 // Fall through. | 661 // Fall through. |
| 653 case FrameElement::CONSTANT: | 662 case FrameElement::CONSTANT: |
| 654 case FrameElement::COPY: | 663 case FrameElement::COPY: |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { | 855 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { |
| 847 PrepareForCall(arg_count, arg_count); | 856 PrepareForCall(arg_count, arg_count); |
| 848 ASSERT(cgen()->HasValidEntryRegisters()); | 857 ASSERT(cgen()->HasValidEntryRegisters()); |
| 849 __ CallRuntime(id, arg_count); | 858 __ CallRuntime(id, arg_count); |
| 850 Result result = cgen()->allocator()->Allocate(eax); | 859 Result result = cgen()->allocator()->Allocate(eax); |
| 851 ASSERT(result.is_valid()); | 860 ASSERT(result.is_valid()); |
| 852 return result; | 861 return result; |
| 853 } | 862 } |
| 854 | 863 |
| 855 | 864 |
| 865 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 866 void VirtualFrame::DebugBreak() { |
| 867 PrepareForCall(0, 0); |
| 868 ASSERT(cgen()->HasValidEntryRegisters()); |
| 869 __ DebugBreak(); |
| 870 Result result = cgen()->allocator()->Allocate(eax); |
| 871 ASSERT(result.is_valid()); |
| 872 } |
| 873 #endif |
| 874 |
| 875 |
| 856 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, | 876 Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, |
| 857 InvokeFlag flag, | 877 InvokeFlag flag, |
| 858 int arg_count) { | 878 int arg_count) { |
| 859 PrepareForCall(arg_count, arg_count); | 879 PrepareForCall(arg_count, arg_count); |
| 860 ASSERT(cgen()->HasValidEntryRegisters()); | 880 ASSERT(cgen()->HasValidEntryRegisters()); |
| 861 __ InvokeBuiltin(id, flag); | 881 __ InvokeBuiltin(id, flag); |
| 862 Result result = cgen()->allocator()->Allocate(eax); | 882 Result result = cgen()->allocator()->Allocate(eax); |
| 863 ASSERT(result.is_valid()); | 883 ASSERT(result.is_valid()); |
| 864 return result; | 884 return result; |
| 865 } | 885 } |
| 866 | 886 |
| 867 | 887 |
| 868 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, | 888 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, |
| 869 RelocInfo::Mode rmode) { | 889 RelocInfo::Mode rmode) { |
| 870 ASSERT(cgen()->HasValidEntryRegisters()); | 890 ASSERT(cgen()->HasValidEntryRegisters()); |
| 871 __ call(code, rmode); | 891 __ call(code, rmode); |
| 872 Result result = cgen()->allocator()->Allocate(eax); | 892 Result result = cgen()->allocator()->Allocate(eax); |
| 873 ASSERT(result.is_valid()); | 893 ASSERT(result.is_valid()); |
| 874 return result; | 894 return result; |
| 875 } | 895 } |
| 876 | 896 |
| 877 | 897 |
| 878 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { | 898 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { |
| 879 // Name and receiver are on the top of the frame. The IC expects | 899 // Name and receiver are on the top of the frame. The IC expects |
| 880 // name in ecx and receiver on the stack. It does not drop the | 900 // name in ecx and receiver in eax. |
| 881 // receiver. | |
| 882 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 901 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 883 Result name = Pop(); | 902 Result name = Pop(); |
| 884 PrepareForCall(1, 0); // One stack arg, not callee-dropped. | 903 Result receiver = Pop(); |
| 885 name.ToRegister(ecx); | 904 PrepareForCall(0, 0); // No stack arguments. |
| 905 // Move results to the right registers: |
| 906 if (name.is_register() && name.reg().is(eax)) { |
| 907 if (receiver.is_register() && receiver.reg().is(ecx)) { |
| 908 // Wrong registers. |
| 909 __ xchg(eax, ecx); |
| 910 } else { |
| 911 // Register ecx is free for name, which frees eax for receiver. |
| 912 name.ToRegister(ecx); |
| 913 receiver.ToRegister(eax); |
| 914 } |
| 915 } else { |
| 916 // Register eax is free for receiver, which frees ecx for name. |
| 917 receiver.ToRegister(eax); |
| 918 name.ToRegister(ecx); |
| 919 } |
| 886 name.Unuse(); | 920 name.Unuse(); |
| 921 receiver.Unuse(); |
| 887 return RawCallCodeObject(ic, mode); | 922 return RawCallCodeObject(ic, mode); |
| 888 } | 923 } |
| 889 | 924 |
| 890 | 925 |
| 891 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { | 926 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { |
| 892 // Key and receiver are on top of the frame. The IC expects them on | 927 // Key and receiver are on top of the frame. Put them in eax and edx. |
| 893 // the stack. It does not drop them. | 928 Result key = Pop(); |
| 929 Result receiver = Pop(); |
| 930 PrepareForCall(0, 0); |
| 931 |
| 932 if (!key.is_register() || !key.reg().is(edx)) { |
| 933 // Register edx is available for receiver. |
| 934 receiver.ToRegister(edx); |
| 935 key.ToRegister(eax); |
| 936 } else if (!receiver.is_register() || !receiver.reg().is(eax)) { |
| 937 // Register eax is available for key. |
| 938 key.ToRegister(eax); |
| 939 receiver.ToRegister(edx); |
| 940 } else { |
| 941 __ xchg(edx, eax); |
| 942 } |
| 943 key.Unuse(); |
| 944 receiver.Unuse(); |
| 945 |
| 894 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); | 946 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
| 895 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. | |
| 896 return RawCallCodeObject(ic, mode); | 947 return RawCallCodeObject(ic, mode); |
| 897 } | 948 } |
| 898 | 949 |
| 899 | 950 |
| 900 Result VirtualFrame::CallStoreIC() { | 951 Result VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) { |
| 901 // Name, value, and receiver are on top of the frame. The IC | 952 // Value and (if not contextual) receiver are on top of the frame. |
| 902 // expects name in ecx, value in eax, and receiver in edx. | 953 // The IC expects name in ecx, value in eax, and receiver in edx. |
| 903 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 954 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 904 Result name = Pop(); | |
| 905 Result value = Pop(); | 955 Result value = Pop(); |
| 906 Result receiver = Pop(); | 956 if (is_contextual) { |
| 907 PrepareForCall(0, 0); | 957 PrepareForCall(0, 0); |
| 958 value.ToRegister(eax); |
| 959 __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 960 __ mov(ecx, name); |
| 961 } else { |
| 962 Result receiver = Pop(); |
| 963 PrepareForCall(0, 0); |
| 908 | 964 |
| 909 // Optimized for case in which name is a constant value. | 965 if (value.is_register() && value.reg().is(edx)) { |
| 910 if (name.is_register() && (name.reg().is(edx) || name.reg().is(eax))) { | 966 if (receiver.is_register() && receiver.reg().is(eax)) { |
| 911 if (!is_used(ecx)) { | 967 // Wrong registers. |
| 912 name.ToRegister(ecx); | 968 __ xchg(eax, edx); |
| 913 } else if (!is_used(ebx)) { | 969 } else { |
| 914 name.ToRegister(ebx); | 970 // Register eax is free for value, which frees edx for receiver. |
| 971 value.ToRegister(eax); |
| 972 receiver.ToRegister(edx); |
| 973 } |
| 915 } else { | 974 } else { |
| 916 ASSERT(!is_used(edi)); // Only three results are live, so edi is free. | 975 // Register edx is free for receiver, which guarantees eax is free for |
| 917 name.ToRegister(edi); | 976 // value. |
| 977 receiver.ToRegister(edx); |
| 978 value.ToRegister(eax); |
| 918 } | 979 } |
| 919 } | 980 } |
| 920 // Now name is not in edx or eax, so we can fix them, then move name to ecx. | 981 __ mov(ecx, name); |
| 921 if (value.is_register() && value.reg().is(edx)) { | |
| 922 if (receiver.is_register() && receiver.reg().is(eax)) { | |
| 923 // Wrong registers. | |
| 924 __ xchg(eax, edx); | |
| 925 } else { | |
| 926 // Register eax is free for value, which frees edx for receiver. | |
| 927 value.ToRegister(eax); | |
| 928 receiver.ToRegister(edx); | |
| 929 } | |
| 930 } else { | |
| 931 // Register edx is free for receiver, which guarantees eax is free for | |
| 932 // value. | |
| 933 receiver.ToRegister(edx); | |
| 934 value.ToRegister(eax); | |
| 935 } | |
| 936 // Receiver and value are in the right place, so ecx is free for name. | |
| 937 name.ToRegister(ecx); | |
| 938 name.Unuse(); | |
| 939 value.Unuse(); | 982 value.Unuse(); |
| 940 receiver.Unuse(); | |
| 941 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); | 983 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); |
| 942 } | 984 } |
| 943 | 985 |
| 944 | 986 |
| 945 Result VirtualFrame::CallKeyedStoreIC() { | 987 Result VirtualFrame::CallKeyedStoreIC() { |
| 946 // Value, key, and receiver are on the top of the frame. The IC | 988 // Value, key, and receiver are on the top of the frame. The IC |
| 947 // expects value in eax and key and receiver on the stack. It does | 989 // expects value in eax and key and receiver on the stack. It does |
| 948 // not drop the key and receiver. | 990 // not drop the key and receiver. |
| 949 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 991 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 950 // TODO(1222589): Make the IC grab the values from the stack. | |
| 951 Result value = Pop(); | 992 Result value = Pop(); |
| 952 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. | 993 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. |
| 953 value.ToRegister(eax); | 994 value.ToRegister(eax); |
| 954 value.Unuse(); | 995 value.Unuse(); |
| 955 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); | 996 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); |
| 956 } | 997 } |
| 957 | 998 |
| 958 | 999 |
| 959 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, | 1000 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, |
| 960 int arg_count, | 1001 int arg_count, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1018 } | 1059 } |
| 1019 } | 1060 } |
| 1020 } | 1061 } |
| 1021 | 1062 |
| 1022 | 1063 |
| 1023 Result VirtualFrame::Pop() { | 1064 Result VirtualFrame::Pop() { |
| 1024 FrameElement element = elements_.RemoveLast(); | 1065 FrameElement element = elements_.RemoveLast(); |
| 1025 int index = element_count(); | 1066 int index = element_count(); |
| 1026 ASSERT(element.is_valid()); | 1067 ASSERT(element.is_valid()); |
| 1027 | 1068 |
| 1069 // Get number type information of the result. |
| 1070 NumberInfo::Type info; |
| 1071 if (!element.is_copy()) { |
| 1072 info = element.number_info(); |
| 1073 } else { |
| 1074 info = elements_[element.index()].number_info(); |
| 1075 } |
| 1076 |
| 1028 bool pop_needed = (stack_pointer_ == index); | 1077 bool pop_needed = (stack_pointer_ == index); |
| 1029 if (pop_needed) { | 1078 if (pop_needed) { |
| 1030 stack_pointer_--; | 1079 stack_pointer_--; |
| 1031 if (element.is_memory()) { | 1080 if (element.is_memory()) { |
| 1032 Result temp = cgen()->allocator()->Allocate(); | 1081 Result temp = cgen()->allocator()->Allocate(); |
| 1033 ASSERT(temp.is_valid()); | 1082 ASSERT(temp.is_valid()); |
| 1034 __ pop(temp.reg()); | 1083 __ pop(temp.reg()); |
| 1084 temp.set_number_info(info); |
| 1035 return temp; | 1085 return temp; |
| 1036 } | 1086 } |
| 1037 | 1087 |
| 1038 __ add(Operand(esp), Immediate(kPointerSize)); | 1088 __ add(Operand(esp), Immediate(kPointerSize)); |
| 1039 } | 1089 } |
| 1040 ASSERT(!element.is_memory()); | 1090 ASSERT(!element.is_memory()); |
| 1041 | 1091 |
| 1042 // The top element is a register, constant, or a copy. Unuse | 1092 // The top element is a register, constant, or a copy. Unuse |
| 1043 // registers and follow copies to their backing store. | 1093 // registers and follow copies to their backing store. |
| 1044 if (element.is_register()) { | 1094 if (element.is_register()) { |
| 1045 Unuse(element.reg()); | 1095 Unuse(element.reg()); |
| 1046 } else if (element.is_copy()) { | 1096 } else if (element.is_copy()) { |
| 1047 ASSERT(element.index() < index); | 1097 ASSERT(element.index() < index); |
| 1048 index = element.index(); | 1098 index = element.index(); |
| 1049 element = elements_[index]; | 1099 element = elements_[index]; |
| 1050 } | 1100 } |
| 1051 ASSERT(!element.is_copy()); | 1101 ASSERT(!element.is_copy()); |
| 1052 | 1102 |
| 1053 // The element is memory, a register, or a constant. | 1103 // The element is memory, a register, or a constant. |
| 1054 if (element.is_memory()) { | 1104 if (element.is_memory()) { |
| 1055 // Memory elements could only be the backing store of a copy. | 1105 // Memory elements could only be the backing store of a copy. |
| 1056 // Allocate the original to a register. | 1106 // Allocate the original to a register. |
| 1057 ASSERT(index <= stack_pointer_); | 1107 ASSERT(index <= stack_pointer_); |
| 1058 Result temp = cgen()->allocator()->Allocate(); | 1108 Result temp = cgen()->allocator()->Allocate(); |
| 1059 ASSERT(temp.is_valid()); | 1109 ASSERT(temp.is_valid()); |
| 1060 Use(temp.reg(), index); | 1110 Use(temp.reg(), index); |
| 1061 FrameElement new_element = | 1111 FrameElement new_element = |
| 1062 FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED); | 1112 FrameElement::RegisterElement(temp.reg(), |
| 1113 FrameElement::SYNCED, |
| 1114 element.number_info()); |
| 1063 // Preserve the copy flag on the element. | 1115 // Preserve the copy flag on the element. |
| 1064 if (element.is_copied()) new_element.set_copied(); | 1116 if (element.is_copied()) new_element.set_copied(); |
| 1065 elements_[index] = new_element; | 1117 elements_[index] = new_element; |
| 1066 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); | 1118 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); |
| 1067 return Result(temp.reg()); | 1119 return Result(temp.reg(), info); |
| 1068 } else if (element.is_register()) { | 1120 } else if (element.is_register()) { |
| 1069 return Result(element.reg()); | 1121 return Result(element.reg(), info); |
| 1070 } else { | 1122 } else { |
| 1071 ASSERT(element.is_constant()); | 1123 ASSERT(element.is_constant()); |
| 1072 return Result(element.handle()); | 1124 return Result(element.handle()); |
| 1073 } | 1125 } |
| 1074 } | 1126 } |
| 1075 | 1127 |
| 1076 | 1128 |
| 1077 void VirtualFrame::EmitPop(Register reg) { | 1129 void VirtualFrame::EmitPop(Register reg) { |
| 1078 ASSERT(stack_pointer_ == element_count() - 1); | 1130 ASSERT(stack_pointer_ == element_count() - 1); |
| 1079 stack_pointer_--; | 1131 stack_pointer_--; |
| 1080 elements_.RemoveLast(); | 1132 elements_.RemoveLast(); |
| 1081 __ pop(reg); | 1133 __ pop(reg); |
| 1082 } | 1134 } |
| 1083 | 1135 |
| 1084 | 1136 |
| 1085 void VirtualFrame::EmitPop(Operand operand) { | 1137 void VirtualFrame::EmitPop(Operand operand) { |
| 1086 ASSERT(stack_pointer_ == element_count() - 1); | 1138 ASSERT(stack_pointer_ == element_count() - 1); |
| 1087 stack_pointer_--; | 1139 stack_pointer_--; |
| 1088 elements_.RemoveLast(); | 1140 elements_.RemoveLast(); |
| 1089 __ pop(operand); | 1141 __ pop(operand); |
| 1090 } | 1142 } |
| 1091 | 1143 |
| 1092 | 1144 |
| 1093 void VirtualFrame::EmitPush(Register reg) { | 1145 void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) { |
| 1094 ASSERT(stack_pointer_ == element_count() - 1); | 1146 ASSERT(stack_pointer_ == element_count() - 1); |
| 1095 elements_.Add(FrameElement::MemoryElement()); | 1147 elements_.Add(FrameElement::MemoryElement(info)); |
| 1096 stack_pointer_++; | 1148 stack_pointer_++; |
| 1097 __ push(reg); | 1149 __ push(reg); |
| 1098 } | 1150 } |
| 1099 | 1151 |
| 1100 | 1152 |
| 1101 void VirtualFrame::EmitPush(Operand operand) { | 1153 void VirtualFrame::EmitPush(Operand operand, NumberInfo::Type info) { |
| 1102 ASSERT(stack_pointer_ == element_count() - 1); | 1154 ASSERT(stack_pointer_ == element_count() - 1); |
| 1103 elements_.Add(FrameElement::MemoryElement()); | 1155 elements_.Add(FrameElement::MemoryElement(info)); |
| 1104 stack_pointer_++; | 1156 stack_pointer_++; |
| 1105 __ push(operand); | 1157 __ push(operand); |
| 1106 } | 1158 } |
| 1107 | 1159 |
| 1108 | 1160 |
| 1109 void VirtualFrame::EmitPush(Immediate immediate) { | 1161 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) { |
| 1110 ASSERT(stack_pointer_ == element_count() - 1); | 1162 ASSERT(stack_pointer_ == element_count() - 1); |
| 1111 elements_.Add(FrameElement::MemoryElement()); | 1163 elements_.Add(FrameElement::MemoryElement(info)); |
| 1112 stack_pointer_++; | 1164 stack_pointer_++; |
| 1113 __ push(immediate); | 1165 __ push(immediate); |
| 1114 } | 1166 } |
| 1115 | 1167 |
| 1116 | 1168 |
| 1169 void VirtualFrame::Push(Expression* expr) { |
| 1170 ASSERT(expr->IsTrivial()); |
| 1171 |
| 1172 Literal* lit = expr->AsLiteral(); |
| 1173 if (lit != NULL) { |
| 1174 Push(lit->handle()); |
| 1175 return; |
| 1176 } |
| 1177 |
| 1178 VariableProxy* proxy = expr->AsVariableProxy(); |
| 1179 if (proxy != NULL && proxy->is_this()) { |
| 1180 PushParameterAt(-1); |
| 1181 return; |
| 1182 } |
| 1183 |
| 1184 UNREACHABLE(); |
| 1185 } |
| 1186 |
| 1187 |
| 1117 #undef __ | 1188 #undef __ |
| 1118 | 1189 |
| 1119 } } // namespace v8::internal | 1190 } } // namespace v8::internal |
| OLD | NEW |