| 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 19 matching lines...) Expand all Loading... |
| 30 #include "codegen-inl.h" | 30 #include "codegen-inl.h" |
| 31 #include "register-allocator-inl.h" | 31 #include "register-allocator-inl.h" |
| 32 | 32 |
| 33 namespace v8 { namespace internal { | 33 namespace v8 { namespace internal { |
| 34 | 34 |
| 35 // ------------------------------------------------------------------------- | 35 // ------------------------------------------------------------------------- |
| 36 // VirtualFrame implementation. | 36 // VirtualFrame implementation. |
| 37 | 37 |
| 38 // When cloned, a frame is a deep copy of the original. | 38 // When cloned, a frame is a deep copy of the original. |
| 39 VirtualFrame::VirtualFrame(VirtualFrame* original) | 39 VirtualFrame::VirtualFrame(VirtualFrame* original) |
| 40 : cgen_(original->cgen_), | 40 : elements_(original->elements_), |
| 41 masm_(original->masm_), | 41 stack_pointer_(original->stack_pointer_) { |
| 42 elements_(original->elements_), | |
| 43 parameter_count_(original->parameter_count_), | |
| 44 local_count_(original->local_count_), | |
| 45 stack_pointer_(original->stack_pointer_), | |
| 46 frame_pointer_(original->frame_pointer_) { | |
| 47 // Copy register locations from original. | 42 // Copy register locations from original. |
| 48 memcpy(®ister_locations_, | 43 memcpy(®ister_locations_, |
| 49 original->register_locations_, | 44 original->register_locations_, |
| 50 sizeof(register_locations_)); | 45 sizeof(register_locations_)); |
| 51 } | 46 } |
| 52 | 47 |
| 53 | 48 |
| 54 FrameElement VirtualFrame::CopyElementAt(int index) { | 49 FrameElement VirtualFrame::CopyElementAt(int index) { |
| 55 ASSERT(index >= 0); | 50 ASSERT(index >= 0); |
| 56 ASSERT(index < elements_.length()); | 51 ASSERT(index < elements_.length()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 void VirtualFrame::ForgetElements(int count) { | 106 void VirtualFrame::ForgetElements(int count) { |
| 112 ASSERT(count >= 0); | 107 ASSERT(count >= 0); |
| 113 ASSERT(elements_.length() >= count); | 108 ASSERT(elements_.length() >= count); |
| 114 | 109 |
| 115 for (int i = 0; i < count; i++) { | 110 for (int i = 0; i < count; i++) { |
| 116 FrameElement last = elements_.RemoveLast(); | 111 FrameElement last = elements_.RemoveLast(); |
| 117 if (last.is_register()) { | 112 if (last.is_register()) { |
| 118 // A hack to properly count register references for the code | 113 // A hack to properly count register references for the code |
| 119 // generator's current frame and also for other frames. The | 114 // generator's current frame and also for other frames. The |
| 120 // same code appears in PrepareMergeTo. | 115 // same code appears in PrepareMergeTo. |
| 121 if (cgen_->frame() == this) { | 116 if (cgen()->frame() == this) { |
| 122 Unuse(last.reg()); | 117 Unuse(last.reg()); |
| 123 } else { | 118 } else { |
| 124 register_locations_[last.reg().code()] = kIllegalIndex; | 119 register_locations_[last.reg().code()] = kIllegalIndex; |
| 125 } | 120 } |
| 126 } | 121 } |
| 127 } | 122 } |
| 128 } | 123 } |
| 129 | 124 |
| 130 | 125 |
| 131 // If there are any registers referenced only by the frame, spill one. | 126 // If there are any registers referenced only by the frame, spill one. |
| 132 Register VirtualFrame::SpillAnyRegister() { | 127 Register VirtualFrame::SpillAnyRegister() { |
| 133 // Find the leftmost (ordered by register code) register whose only | 128 // Find the leftmost (ordered by register code) register whose only |
| 134 // reference is in the frame. | 129 // reference is in the frame. |
| 135 for (int i = 0; i < kNumRegisters; i++) { | 130 for (int i = 0; i < kNumRegisters; i++) { |
| 136 if (is_used(i) && cgen_->allocator()->count(i) == 1) { | 131 if (is_used(i) && cgen()->allocator()->count(i) == 1) { |
| 137 Register result = { i }; | 132 Register result = { i }; |
| 138 Spill(result); | 133 Spill(result); |
| 139 ASSERT(!cgen_->allocator()->is_used(result)); | 134 ASSERT(!cgen()->allocator()->is_used(result)); |
| 140 return result; | 135 return result; |
| 141 } | 136 } |
| 142 } | 137 } |
| 143 return no_reg; | 138 return no_reg; |
| 144 } | 139 } |
| 145 | 140 |
| 146 | 141 |
| 147 // Make the type of the element at a given index be MEMORY. | 142 // Make the type of the element at a given index be MEMORY. |
| 148 void VirtualFrame::SpillElementAt(int index) { | 143 void VirtualFrame::SpillElementAt(int index) { |
| 149 if (!elements_[index].is_valid()) return; | 144 if (!elements_[index].is_valid()) return; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 if (!target.is_valid() || | 188 if (!target.is_valid() || |
| 194 (target.is_memory() && !source.is_memory() && source.is_synced())) { | 189 (target.is_memory() && !source.is_memory() && source.is_synced())) { |
| 195 // No code needs to be generated to invalidate valid elements. | 190 // No code needs to be generated to invalidate valid elements. |
| 196 // No code needs to be generated to move values to memory if | 191 // No code needs to be generated to move values to memory if |
| 197 // they are already synced. We perform those moves here, before | 192 // they are already synced. We perform those moves here, before |
| 198 // merging. | 193 // merging. |
| 199 if (source.is_register()) { | 194 if (source.is_register()) { |
| 200 // If the frame is the code generator's current frame, we have | 195 // If the frame is the code generator's current frame, we have |
| 201 // to decrement both the frame-internal and global register | 196 // to decrement both the frame-internal and global register |
| 202 // counts. | 197 // counts. |
| 203 if (cgen_->frame() == this) { | 198 if (cgen()->frame() == this) { |
| 204 Unuse(source.reg()); | 199 Unuse(source.reg()); |
| 205 } else { | 200 } else { |
| 206 register_locations_[source.reg().code()] = kIllegalIndex; | 201 register_locations_[source.reg().code()] = kIllegalIndex; |
| 207 } | 202 } |
| 208 } | 203 } |
| 209 elements_[i] = target; | 204 elements_[i] = target; |
| 210 } else if (target.is_register() && !target.is_synced() && | 205 } else if (target.is_register() && !target.is_synced() && |
| 211 !source.is_memory()) { | 206 !source.is_memory()) { |
| 212 // If an element's target is a register that doesn't need to be | 207 // If an element's target is a register that doesn't need to be |
| 213 // synced, and the element is not in memory, then the sync state | 208 // synced, and the element is not in memory, then the sync state |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 Result tos = Pop(); | 357 Result tos = Pop(); |
| 363 if (num_dropped > 1) { | 358 if (num_dropped > 1) { |
| 364 Drop(num_dropped - 1); | 359 Drop(num_dropped - 1); |
| 365 } | 360 } |
| 366 SetElementAt(0, &tos); | 361 SetElementAt(0, &tos); |
| 367 } | 362 } |
| 368 | 363 |
| 369 | 364 |
| 370 bool VirtualFrame::Equals(VirtualFrame* other) { | 365 bool VirtualFrame::Equals(VirtualFrame* other) { |
| 371 #ifdef DEBUG | 366 #ifdef DEBUG |
| 372 // These are sanity checks in debug builds, but we do not need to | |
| 373 // use them to distinguish frames at merge points. | |
| 374 if (cgen_ != other->cgen_) return false; | |
| 375 if (masm_ != other->masm_) return false; | |
| 376 if (parameter_count_ != other->parameter_count_) return false; | |
| 377 if (local_count_ != other->local_count_) return false; | |
| 378 if (frame_pointer_ != other->frame_pointer_) return false; | |
| 379 | |
| 380 for (int i = 0; i < kNumRegisters; i++) { | 367 for (int i = 0; i < kNumRegisters; i++) { |
| 381 if (register_locations_[i] != other->register_locations_[i]) { | 368 if (register_locations_[i] != other->register_locations_[i]) { |
| 382 return false; | 369 return false; |
| 383 } | 370 } |
| 384 } | 371 } |
| 385 if (elements_.length() != other->elements_.length()) return false; | 372 if (elements_.length() != other->elements_.length()) return false; |
| 386 #endif | 373 #endif |
| 387 if (stack_pointer_ != other->stack_pointer_) return false; | 374 if (stack_pointer_ != other->stack_pointer_) return false; |
| 388 for (int i = 0; i < elements_.length(); i++) { | 375 for (int i = 0; i < elements_.length(); i++) { |
| 389 if (!elements_[i].Equals(other->elements_[i])) return false; | 376 if (!elements_[i].Equals(other->elements_[i])) return false; |
| 390 } | 377 } |
| 391 | 378 |
| 392 return true; | 379 return true; |
| 393 } | 380 } |
| 394 | 381 |
| 395 | 382 |
| 396 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. | 383 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. |
| 397 // The function ResizeAdd becomes a real function, whose implementation is the | 384 // The function ResizeAdd becomes a real function, whose implementation is the |
| 398 // inlined ResizeAddInternal. | 385 // inlined ResizeAddInternal. |
| 399 template <> | 386 template <> |
| 400 void List<FrameElement, | 387 void List<FrameElement, |
| 401 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { | 388 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { |
| 402 ResizeAddInternal(element); | 389 ResizeAddInternal(element); |
| 403 } | 390 } |
| 404 | 391 |
| 405 } } // namespace v8::internal | 392 } } // namespace v8::internal |
| OLD | NEW |