| 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 frame_pointer_(kIllegalIndex) { | 50 frame_pointer_(kIllegalIndex) { |
| 51 for (int i = 0; i < parameter_count_ + 2; i++) { | 51 for (int i = 0; i < parameter_count_ + 2; i++) { |
| 52 elements_.Add(FrameElement::MemoryElement()); | 52 elements_.Add(FrameElement::MemoryElement()); |
| 53 } | 53 } |
| 54 for (int i = 0; i < kNumRegisters; i++) { | 54 for (int i = 0; i < kNumRegisters; i++) { |
| 55 register_locations_[i] = kIllegalIndex; | 55 register_locations_[i] = kIllegalIndex; |
| 56 } | 56 } |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 // Clear the dirty bit for the element at a given index if it is a | 60 void VirtualFrame::SyncElementBelowStackPointer(int index) { |
| 61 // valid element. The stack address corresponding to the element must | 61 // Emit code to write elements below the stack pointer to their |
| 62 // be allocated on the physical stack, or the first element above the | 62 // (already allocated) stack address. |
| 63 // stack pointer so it can be allocated by a single push instruction. | 63 ASSERT(index <= stack_pointer_); |
| 64 void VirtualFrame::RawSyncElementAt(int index) { | |
| 65 FrameElement element = elements_[index]; | 64 FrameElement element = elements_[index]; |
| 65 ASSERT(!element.is_synced()); |
| 66 switch (element.type()) { |
| 67 case FrameElement::INVALID: |
| 68 break; |
| 66 | 69 |
| 67 if (!element.is_valid() || element.is_synced()) return; | 70 case FrameElement::MEMORY: |
| 71 // This function should not be called with synced elements. |
| 72 // (memory elements are always synced). |
| 73 UNREACHABLE(); |
| 74 break; |
| 68 | 75 |
| 69 if (index <= stack_pointer_) { | 76 case FrameElement::REGISTER: |
| 70 // Emit code to write elements below the stack pointer to their | 77 __ mov(Operand(ebp, fp_relative(index)), element.reg()); |
| 71 // (already allocated) stack address. | 78 break; |
| 72 switch (element.type()) { | |
| 73 case FrameElement::INVALID: // Fall through. | |
| 74 case FrameElement::MEMORY: | |
| 75 // There was an early bailout for invalid and synced elements | |
| 76 // (memory elements are always synced). | |
| 77 UNREACHABLE(); | |
| 78 break; | |
| 79 | 79 |
| 80 case FrameElement::REGISTER: | 80 case FrameElement::CONSTANT: |
| 81 __ mov(Operand(ebp, fp_relative(index)), element.reg()); | 81 if (cgen_->IsUnsafeSmi(element.handle())) { |
| 82 break; | 82 Result temp = cgen_->allocator()->Allocate(); |
| 83 ASSERT(temp.is_valid()); |
| 84 cgen_->LoadUnsafeSmi(temp.reg(), element.handle()); |
| 85 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); |
| 86 } else { |
| 87 __ Set(Operand(ebp, fp_relative(index)), |
| 88 Immediate(element.handle())); |
| 89 } |
| 90 break; |
| 83 | 91 |
| 84 case FrameElement::CONSTANT: | 92 case FrameElement::COPY: { |
| 85 if (cgen_->IsUnsafeSmi(element.handle())) { | 93 int backing_index = element.index(); |
| 86 Result temp = cgen_->allocator()->Allocate(); | 94 FrameElement backing_element = elements_[backing_index]; |
| 87 ASSERT(temp.is_valid()); | 95 if (backing_element.is_memory()) { |
| 88 cgen_->LoadUnsafeSmi(temp.reg(), element.handle()); | 96 Result temp = cgen_->allocator()->Allocate(); |
| 89 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); | 97 ASSERT(temp.is_valid()); |
| 90 } else { | 98 __ mov(temp.reg(), Operand(ebp, fp_relative(backing_index))); |
| 91 __ Set(Operand(ebp, fp_relative(index)), | 99 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); |
| 92 Immediate(element.handle())); | 100 } else { |
| 93 } | 101 ASSERT(backing_element.is_register()); |
| 94 break; | 102 __ mov(Operand(ebp, fp_relative(index)), backing_element.reg()); |
| 95 | |
| 96 case FrameElement::COPY: { | |
| 97 int backing_index = element.index(); | |
| 98 FrameElement backing_element = elements_[backing_index]; | |
| 99 if (backing_element.is_memory()) { | |
| 100 Result temp = cgen_->allocator()->Allocate(); | |
| 101 ASSERT(temp.is_valid()); | |
| 102 __ mov(temp.reg(), Operand(ebp, fp_relative(backing_index))); | |
| 103 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); | |
| 104 } else { | |
| 105 ASSERT(backing_element.is_register()); | |
| 106 __ mov(Operand(ebp, fp_relative(index)), backing_element.reg()); | |
| 107 } | |
| 108 break; | |
| 109 } | 103 } |
| 110 } | 104 break; |
| 111 | |
| 112 } else { | |
| 113 // Push elements above the stack pointer to allocate space and | |
| 114 // sync them. Space should have already been allocated in the | |
| 115 // actual frame for all the elements below this one. | |
| 116 ASSERT(index == stack_pointer_ + 1); | |
| 117 stack_pointer_++; | |
| 118 switch (element.type()) { | |
| 119 case FrameElement::INVALID: // Fall through. | |
| 120 case FrameElement::MEMORY: | |
| 121 // There was an early bailout for invalid and synced elements | |
| 122 // (memory elements are always synced). | |
| 123 UNREACHABLE(); | |
| 124 break; | |
| 125 | |
| 126 case FrameElement::REGISTER: | |
| 127 __ push(element.reg()); | |
| 128 break; | |
| 129 | |
| 130 case FrameElement::CONSTANT: | |
| 131 if (cgen_->IsUnsafeSmi(element.handle())) { | |
| 132 Result temp = cgen_->allocator()->Allocate(); | |
| 133 ASSERT(temp.is_valid()); | |
| 134 cgen_->LoadUnsafeSmi(temp.reg(), element.handle()); | |
| 135 __ push(temp.reg()); | |
| 136 } else { | |
| 137 __ push(Immediate(element.handle())); | |
| 138 } | |
| 139 break; | |
| 140 | |
| 141 case FrameElement::COPY: { | |
| 142 int backing_index = element.index(); | |
| 143 FrameElement backing = elements_[backing_index]; | |
| 144 ASSERT(backing.is_memory() || backing.is_register()); | |
| 145 if (backing.is_memory()) { | |
| 146 __ push(Operand(ebp, fp_relative(backing_index))); | |
| 147 } else { | |
| 148 __ push(backing.reg()); | |
| 149 } | |
| 150 break; | |
| 151 } | |
| 152 } | 105 } |
| 153 } | 106 } |
| 154 | |
| 155 elements_[index].set_sync(); | 107 elements_[index].set_sync(); |
| 156 } | 108 } |
| 157 | 109 |
| 110 |
| 111 void VirtualFrame::SyncElementByPushing(int index) { |
| 112 // Sync an element of the frame that is just above the stack pointer |
| 113 // by pushing it. |
| 114 ASSERT(index == stack_pointer_ + 1); |
| 115 stack_pointer_++; |
| 116 FrameElement element = elements_[index]; |
| 117 |
| 118 switch (element.type()) { |
| 119 case FrameElement::INVALID: |
| 120 __ push(Immediate(Smi::FromInt(0))); |
| 121 break; |
| 122 |
| 123 case FrameElement::MEMORY: |
| 124 // No memory elements exist above the stack pointer. |
| 125 UNREACHABLE(); |
| 126 break; |
| 127 |
| 128 case FrameElement::REGISTER: |
| 129 __ push(element.reg()); |
| 130 break; |
| 131 |
| 132 case FrameElement::CONSTANT: |
| 133 if (cgen_->IsUnsafeSmi(element.handle())) { |
| 134 Result temp = cgen_->allocator()->Allocate(); |
| 135 ASSERT(temp.is_valid()); |
| 136 cgen_->LoadUnsafeSmi(temp.reg(), element.handle()); |
| 137 __ push(temp.reg()); |
| 138 } else { |
| 139 __ push(Immediate(element.handle())); |
| 140 } |
| 141 break; |
| 142 |
| 143 case FrameElement::COPY: { |
| 144 int backing_index = element.index(); |
| 145 FrameElement backing = elements_[backing_index]; |
| 146 ASSERT(backing.is_memory() || backing.is_register()); |
| 147 if (backing.is_memory()) { |
| 148 __ push(Operand(ebp, fp_relative(backing_index))); |
| 149 } else { |
| 150 __ push(backing.reg()); |
| 151 } |
| 152 break; |
| 153 } |
| 154 } |
| 155 elements_[index].set_sync(); |
| 156 } |
| 157 |
| 158 | 158 |
| 159 void VirtualFrame::MergeTo(VirtualFrame* expected) { | 159 void VirtualFrame::MergeTo(VirtualFrame* expected) { |
| 160 Comment cmnt(masm_, "[ Merge frame"); | 160 Comment cmnt(masm_, "[ Merge frame"); |
| 161 // We should always be merging the code generator's current frame to an | 161 // We should always be merging the code generator's current frame to an |
| 162 // expected frame. | 162 // expected frame. |
| 163 ASSERT(cgen_->frame() == this); | 163 ASSERT(cgen_->frame() == this); |
| 164 | 164 |
| 165 // Adjust the stack pointer upward (toward the top of the virtual | 165 // Adjust the stack pointer upward (toward the top of the virtual |
| 166 // frame) if necessary. | 166 // frame) if necessary. |
| 167 if (stack_pointer_ < expected->stack_pointer_) { | 167 if (stack_pointer_ < expected->stack_pointer_) { |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 ASSERT(stack_pointer_ == elements_.length() - 1); | 980 ASSERT(stack_pointer_ == elements_.length() - 1); |
| 981 elements_.Add(FrameElement::MemoryElement()); | 981 elements_.Add(FrameElement::MemoryElement()); |
| 982 stack_pointer_++; | 982 stack_pointer_++; |
| 983 __ push(immediate); | 983 __ push(immediate); |
| 984 } | 984 } |
| 985 | 985 |
| 986 | 986 |
| 987 #undef __ | 987 #undef __ |
| 988 | 988 |
| 989 } } // namespace v8::internal | 989 } } // namespace v8::internal |
| OLD | NEW |