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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 // Modify the state of the virtual frame to match the actual frame by | 125 // Modify the state of the virtual frame to match the actual frame by |
126 // removing elements from the top of the virtual frame. The elements will | 126 // removing elements from the top of the virtual frame. The elements will |
127 // be externally popped from the actual frame (eg, by a runtime call). No | 127 // be externally popped from the actual frame (eg, by a runtime call). No |
128 // code is emitted. | 128 // code is emitted. |
129 void VirtualFrame::Forget(int count) { | 129 void VirtualFrame::Forget(int count) { |
130 ASSERT(count >= 0); | 130 ASSERT(count >= 0); |
131 ASSERT(stack_pointer_ == elements_.length() - 1); | 131 ASSERT(stack_pointer_ == elements_.length() - 1); |
| 132 |
| 133 stack_pointer_ -= count; |
| 134 ForgetElements(count); |
| 135 } |
| 136 |
| 137 |
| 138 void VirtualFrame::ForgetElements(int count) { |
| 139 ASSERT(count >= 0); |
132 ASSERT(elements_.length() >= count); | 140 ASSERT(elements_.length() >= count); |
133 | 141 |
134 stack_pointer_ -= count; | |
135 for (int i = 0; i < count; i++) { | 142 for (int i = 0; i < count; i++) { |
136 FrameElement last = elements_.RemoveLast(); | 143 FrameElement last = elements_.RemoveLast(); |
137 if (last.is_register()) { | 144 if (last.is_register()) { |
138 Unuse(last.reg()); | 145 // A hack to properly count register references for the code |
| 146 // generator's current frame and also for other frames. The |
| 147 // same code appears in PrepareMergeTo. |
| 148 if (cgen_->frame() == this) { |
| 149 Unuse(last.reg()); |
| 150 } else { |
| 151 frame_registers_.Unuse(last.reg()); |
| 152 } |
139 } | 153 } |
140 } | 154 } |
141 } | 155 } |
142 | 156 |
143 | 157 |
144 void VirtualFrame::Use(Register reg) { | 158 void VirtualFrame::Use(Register reg) { |
145 frame_registers_.Use(reg); | 159 frame_registers_.Use(reg); |
146 cgen_->allocator()->Use(reg); | 160 cgen_->allocator()->Use(reg); |
147 } | 161 } |
148 | 162 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 if (elements_[i].is_register()) { | 331 if (elements_[i].is_register()) { |
318 cgen_->allocator()->Use(elements_[i].reg()); | 332 cgen_->allocator()->Use(elements_[i].reg()); |
319 } | 333 } |
320 } | 334 } |
321 } | 335 } |
322 | 336 |
323 | 337 |
324 void VirtualFrame::PrepareForReturn() { | 338 void VirtualFrame::PrepareForReturn() { |
325 // Spill all locals. This is necessary to make sure all locals have | 339 // Spill all locals. This is necessary to make sure all locals have |
326 // the right value when breaking at the return site in the debugger. | 340 // the right value when breaking at the return site in the debugger. |
| 341 // |
| 342 // TODO(203): It is also necessary to ensure that merging at the |
| 343 // return site does not generate code to overwrite eax, where the |
| 344 // return value is kept in a non-refcounted register reference. |
327 for (int i = 0; i < expression_base_index(); i++) SpillElementAt(i); | 345 for (int i = 0; i < expression_base_index(); i++) SpillElementAt(i); |
328 | |
329 // Drop all non-local stack elements. | |
330 Drop(height()); | |
331 | |
332 // Validate state: The expression stack should be empty and the | |
333 // stack pointer should have been updated to reflect this. | |
334 ASSERT(height() == 0); | |
335 ASSERT(stack_pointer_ == expression_base_index() - 1); | |
336 } | 346 } |
337 | 347 |
338 | 348 |
339 void VirtualFrame::SetElementAt(int index, Result* value) { | 349 void VirtualFrame::SetElementAt(int index, Result* value) { |
340 int frame_index = elements_.length() - index - 1; | 350 int frame_index = elements_.length() - index - 1; |
341 ASSERT(frame_index >= 0); | 351 ASSERT(frame_index >= 0); |
342 ASSERT(frame_index < elements_.length()); | 352 ASSERT(frame_index < elements_.length()); |
343 ASSERT(value->is_valid()); | 353 ASSERT(value->is_valid()); |
344 FrameElement original = elements_[frame_index]; | 354 FrameElement original = elements_[frame_index]; |
345 | 355 |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 for (int i = 0; i < kNumRegisters; i++) { | 555 for (int i = 0; i < kNumRegisters; i++) { |
546 if (frame_registers_.count(i) != other->frame_registers_.count(i)) { | 556 if (frame_registers_.count(i) != other->frame_registers_.count(i)) { |
547 return false; | 557 return false; |
548 } | 558 } |
549 } | 559 } |
550 | 560 |
551 return true; | 561 return true; |
552 } | 562 } |
553 | 563 |
554 } } // namespace v8::internal | 564 } } // namespace v8::internal |
OLD | NEW |