| 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 30 matching lines...) Expand all Loading... |
| 41 : elements_(original->element_count()), | 41 : elements_(original->element_count()), |
| 42 stack_pointer_(original->stack_pointer_) { | 42 stack_pointer_(original->stack_pointer_) { |
| 43 elements_.AddAll(original->elements_); | 43 elements_.AddAll(original->elements_); |
| 44 // Copy register locations from original. | 44 // Copy register locations from original. |
| 45 memcpy(®ister_locations_, | 45 memcpy(®ister_locations_, |
| 46 original->register_locations_, | 46 original->register_locations_, |
| 47 sizeof(register_locations_)); | 47 sizeof(register_locations_)); |
| 48 } | 48 } |
| 49 | 49 |
| 50 | 50 |
| 51 FrameElement VirtualFrame::CopyElementAt(int index) { | 51 // Create a duplicate of an existing valid frame element. |
| 52 // We can pass an optional number type information that will override the |
| 53 // existing information about the backing element. The new information must |
| 54 // not conflict with the existing type information and must be equally or |
| 55 // more precise. The default parameter value kUninitialized means that there |
| 56 // is no additional information. |
| 57 FrameElement VirtualFrame::CopyElementAt(int index, NumberInfo::Type info) { |
| 52 ASSERT(index >= 0); | 58 ASSERT(index >= 0); |
| 53 ASSERT(index < element_count()); | 59 ASSERT(index < element_count()); |
| 54 | 60 |
| 55 FrameElement target = elements_[index]; | 61 FrameElement target = elements_[index]; |
| 56 FrameElement result; | 62 FrameElement result; |
| 57 | 63 |
| 58 switch (target.type()) { | 64 switch (target.type()) { |
| 59 case FrameElement::CONSTANT: | 65 case FrameElement::CONSTANT: |
| 60 // We do not copy constants and instead return a fresh unsynced | 66 // We do not copy constants and instead return a fresh unsynced |
| 61 // constant. | 67 // constant. |
| 62 result = FrameElement::ConstantElement(target.handle(), | 68 result = FrameElement::ConstantElement(target.handle(), |
| 63 FrameElement::NOT_SYNCED); | 69 FrameElement::NOT_SYNCED); |
| 64 break; | 70 break; |
| 65 | 71 |
| 66 case FrameElement::COPY: | 72 case FrameElement::COPY: |
| 67 // We do not allow copies of copies, so we follow one link to | 73 // We do not allow copies of copies, so we follow one link to |
| 68 // the actual backing store of a copy before making a copy. | 74 // the actual backing store of a copy before making a copy. |
| 69 index = target.index(); | 75 index = target.index(); |
| 70 ASSERT(elements_[index].is_memory() || elements_[index].is_register()); | 76 ASSERT(elements_[index].is_memory() || elements_[index].is_register()); |
| 71 // Fall through. | 77 // Fall through. |
| 72 | 78 |
| 73 case FrameElement::MEMORY: // Fall through. | 79 case FrameElement::MEMORY: // Fall through. |
| 74 case FrameElement::REGISTER: | 80 case FrameElement::REGISTER: { |
| 75 // All copies are backed by memory or register locations. | 81 // All copies are backed by memory or register locations. |
| 76 result.set_type(FrameElement::COPY); | 82 result.set_type(FrameElement::COPY); |
| 77 result.clear_copied(); | 83 result.clear_copied(); |
| 78 result.clear_sync(); | 84 result.clear_sync(); |
| 79 result.set_index(index); | 85 result.set_index(index); |
| 80 elements_[index].set_copied(); | 86 elements_[index].set_copied(); |
| 87 // Update backing element's number information. |
| 88 NumberInfo::Type existing = elements_[index].number_info(); |
| 89 ASSERT(existing != NumberInfo::kUninitialized); |
| 90 // Assert that the new type information (a) does not conflict with the |
| 91 // existing one and (b) is equally or more precise. |
| 92 ASSERT((info == NumberInfo::kUninitialized) || |
| 93 (existing | info) != NumberInfo::kUninitialized); |
| 94 ASSERT(existing <= info); |
| 95 elements_[index].set_number_info(info != NumberInfo::kUninitialized |
| 96 ? info |
| 97 : existing); |
| 81 break; | 98 break; |
| 82 | 99 } |
| 83 case FrameElement::INVALID: | 100 case FrameElement::INVALID: |
| 84 // We should not try to copy invalid elements. | 101 // We should not try to copy invalid elements. |
| 85 UNREACHABLE(); | 102 UNREACHABLE(); |
| 86 break; | 103 break; |
| 87 } | 104 } |
| 88 return result; | 105 return result; |
| 89 } | 106 } |
| 90 | 107 |
| 91 | 108 |
| 92 // Modify the state of the virtual frame to match the actual frame by adding | 109 // Modify the state of the virtual frame to match the actual frame by adding |
| 93 // extra in-memory elements to the top of the virtual frame. The extra | 110 // extra in-memory elements to the top of the virtual frame. The extra |
| 94 // elements will be externally materialized on the actual frame (eg, by | 111 // elements will be externally materialized on the actual frame (eg, by |
| 95 // pushing an exception handler). No code is emitted. | 112 // pushing an exception handler). No code is emitted. |
| 96 void VirtualFrame::Adjust(int count) { | 113 void VirtualFrame::Adjust(int count) { |
| 97 ASSERT(count >= 0); | 114 ASSERT(count >= 0); |
| 98 ASSERT(stack_pointer_ == element_count() - 1); | 115 ASSERT(stack_pointer_ == element_count() - 1); |
| 99 | 116 |
| 100 for (int i = 0; i < count; i++) { | 117 for (int i = 0; i < count; i++) { |
| 101 elements_.Add(FrameElement::MemoryElement()); | 118 elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown)); |
| 102 } | 119 } |
| 103 stack_pointer_ += count; | 120 stack_pointer_ += count; |
| 104 } | 121 } |
| 105 | 122 |
| 106 | 123 |
| 107 void VirtualFrame::ForgetElements(int count) { | 124 void VirtualFrame::ForgetElements(int count) { |
| 108 ASSERT(count >= 0); | 125 ASSERT(count >= 0); |
| 109 ASSERT(element_count() >= count); | 126 ASSERT(element_count() >= count); |
| 110 | 127 |
| 111 for (int i = 0; i < count; i++) { | 128 for (int i = 0; i < count; i++) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 137 } | 154 } |
| 138 return no_reg; | 155 return no_reg; |
| 139 } | 156 } |
| 140 | 157 |
| 141 | 158 |
| 142 // Make the type of the element at a given index be MEMORY. | 159 // Make the type of the element at a given index be MEMORY. |
| 143 void VirtualFrame::SpillElementAt(int index) { | 160 void VirtualFrame::SpillElementAt(int index) { |
| 144 if (!elements_[index].is_valid()) return; | 161 if (!elements_[index].is_valid()) return; |
| 145 | 162 |
| 146 SyncElementAt(index); | 163 SyncElementAt(index); |
| 164 // Number type information is preserved. |
| 165 // Copies get their number information from their backing element. |
| 166 NumberInfo::Type info; |
| 167 if (!elements_[index].is_copy()) { |
| 168 info = elements_[index].number_info(); |
| 169 } else { |
| 170 info = elements_[elements_[index].index()].number_info(); |
| 171 } |
| 147 // The element is now in memory. Its copied flag is preserved. | 172 // The element is now in memory. Its copied flag is preserved. |
| 148 FrameElement new_element = FrameElement::MemoryElement(); | 173 FrameElement new_element = FrameElement::MemoryElement(info); |
| 149 if (elements_[index].is_copied()) { | 174 if (elements_[index].is_copied()) { |
| 150 new_element.set_copied(); | 175 new_element.set_copied(); |
| 151 } | 176 } |
| 152 if (elements_[index].is_register()) { | 177 if (elements_[index].is_register()) { |
| 153 Unuse(elements_[index].reg()); | 178 Unuse(elements_[index].reg()); |
| 154 } | 179 } |
| 155 elements_[index] = new_element; | 180 elements_[index] = new_element; |
| 156 } | 181 } |
| 157 | 182 |
| 158 | 183 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 bool same_constant = original.is_constant() | 286 bool same_constant = original.is_constant() |
| 262 && value->is_constant() | 287 && value->is_constant() |
| 263 && original.handle().is_identical_to(value->handle()); | 288 && original.handle().is_identical_to(value->handle()); |
| 264 if (same_register || same_constant) { | 289 if (same_register || same_constant) { |
| 265 value->Unuse(); | 290 value->Unuse(); |
| 266 return; | 291 return; |
| 267 } | 292 } |
| 268 | 293 |
| 269 InvalidateFrameSlotAt(frame_index); | 294 InvalidateFrameSlotAt(frame_index); |
| 270 | 295 |
| 271 FrameElement new_element; | |
| 272 if (value->is_register()) { | 296 if (value->is_register()) { |
| 273 if (is_used(value->reg())) { | 297 if (is_used(value->reg())) { |
| 274 // The register already appears on the frame. Either the existing | 298 // The register already appears on the frame. Either the existing |
| 275 // register element, or the new element at frame_index, must be made | 299 // register element, or the new element at frame_index, must be made |
| 276 // a copy. | 300 // a copy. |
| 277 int i = register_location(value->reg()); | 301 int i = register_location(value->reg()); |
| 278 | 302 |
| 279 if (i < frame_index) { | 303 if (i < frame_index) { |
| 280 // The register FrameElement is lower in the frame than the new copy. | 304 // The register FrameElement is lower in the frame than the new copy. |
| 281 elements_[frame_index] = CopyElementAt(i); | 305 elements_[frame_index] = CopyElementAt(i); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 294 if (elements_[j].is_copy() && elements_[j].index() == i) { | 318 if (elements_[j].is_copy() && elements_[j].index() == i) { |
| 295 elements_[j].set_index(frame_index); | 319 elements_[j].set_index(frame_index); |
| 296 } | 320 } |
| 297 } | 321 } |
| 298 } | 322 } |
| 299 } else { | 323 } else { |
| 300 // The register value->reg() was not already used on the frame. | 324 // The register value->reg() was not already used on the frame. |
| 301 Use(value->reg(), frame_index); | 325 Use(value->reg(), frame_index); |
| 302 elements_[frame_index] = | 326 elements_[frame_index] = |
| 303 FrameElement::RegisterElement(value->reg(), | 327 FrameElement::RegisterElement(value->reg(), |
| 304 FrameElement::NOT_SYNCED); | 328 FrameElement::NOT_SYNCED, |
| 329 value->number_info()); |
| 305 } | 330 } |
| 306 } else { | 331 } else { |
| 307 ASSERT(value->is_constant()); | 332 ASSERT(value->is_constant()); |
| 308 elements_[frame_index] = | 333 elements_[frame_index] = |
| 309 FrameElement::ConstantElement(value->handle(), | 334 FrameElement::ConstantElement(value->handle(), |
| 310 FrameElement::NOT_SYNCED); | 335 FrameElement::NOT_SYNCED); |
| 311 } | 336 } |
| 312 value->Unuse(); | 337 value->Unuse(); |
| 313 } | 338 } |
| 314 | 339 |
| 315 | 340 |
| 316 void VirtualFrame::PushFrameSlotAt(int index) { | 341 void VirtualFrame::PushFrameSlotAt(int index) { |
| 317 elements_.Add(CopyElementAt(index)); | 342 elements_.Add(CopyElementAt(index)); |
| 318 } | 343 } |
| 319 | 344 |
| 320 | 345 |
| 321 void VirtualFrame::Push(Register reg) { | 346 void VirtualFrame::Push(Register reg, NumberInfo::Type info) { |
| 322 if (is_used(reg)) { | 347 if (is_used(reg)) { |
| 323 int index = register_location(reg); | 348 int index = register_location(reg); |
| 324 FrameElement element = CopyElementAt(index); | 349 FrameElement element = CopyElementAt(index, info); |
| 325 elements_.Add(element); | 350 elements_.Add(element); |
| 326 } else { | 351 } else { |
| 327 Use(reg, element_count()); | 352 Use(reg, element_count()); |
| 328 FrameElement element = | 353 FrameElement element = |
| 329 FrameElement::RegisterElement(reg, | 354 FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, info); |
| 330 FrameElement::NOT_SYNCED); | |
| 331 elements_.Add(element); | 355 elements_.Add(element); |
| 332 } | 356 } |
| 333 } | 357 } |
| 334 | 358 |
| 335 | 359 |
| 336 void VirtualFrame::Push(Handle<Object> value) { | 360 void VirtualFrame::Push(Handle<Object> value) { |
| 337 FrameElement element = | 361 FrameElement element = |
| 338 FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED); | 362 FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED); |
| 339 elements_.Add(element); | 363 elements_.Add(element); |
| 340 } | 364 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. | 396 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. |
| 373 // The function ResizeAdd becomes a real function, whose implementation is the | 397 // The function ResizeAdd becomes a real function, whose implementation is the |
| 374 // inlined ResizeAddInternal. | 398 // inlined ResizeAddInternal. |
| 375 template <> | 399 template <> |
| 376 void List<FrameElement, | 400 void List<FrameElement, |
| 377 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { | 401 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { |
| 378 ResizeAddInternal(element); | 402 ResizeAddInternal(element); |
| 379 } | 403 } |
| 380 | 404 |
| 381 } } // namespace v8::internal | 405 } } // namespace v8::internal |
| OLD | NEW |