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 |