| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 : cgen_(cgen), | 44 : cgen_(cgen), |
| 45 masm_(cgen->masm()), | 45 masm_(cgen->masm()), |
| 46 elements_(0), | 46 elements_(0), |
| 47 parameter_count_(cgen->scope()->num_parameters()), | 47 parameter_count_(cgen->scope()->num_parameters()), |
| 48 local_count_(0), | 48 local_count_(0), |
| 49 stack_pointer_(parameter_count_ + 1), // 0-based index of TOS. | 49 stack_pointer_(parameter_count_ + 1), // 0-based index of TOS. |
| 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++) { |
| 55 register_locations_[i] = kIllegalIndex; |
| 56 } |
| 54 } | 57 } |
| 55 | 58 |
| 56 | 59 |
| 57 // Clear the dirty bit for the element at a given index if it is a | 60 // Clear the dirty bit for the element at a given index if it is a |
| 58 // valid element. The stack address corresponding to the element must | 61 // valid element. The stack address corresponding to the element must |
| 59 // be allocated on the physical stack, or the first element above the | 62 // be allocated on the physical stack, or the first element above the |
| 60 // stack pointer so it can be allocated by a single push instruction. | 63 // stack pointer so it can be allocated by a single push instruction. |
| 61 void VirtualFrame::RawSyncElementAt(int index) { | 64 void VirtualFrame::RawSyncElementAt(int index) { |
| 62 FrameElement element = elements_[index]; | 65 FrameElement element = elements_[index]; |
| 63 | 66 |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 } | 321 } |
| 319 last_move_blocked = i; | 322 last_move_blocked = i; |
| 320 any_moves_blocked = true; | 323 any_moves_blocked = true; |
| 321 } | 324 } |
| 322 } else { | 325 } else { |
| 323 // The move is not blocked. This frame element can be moved from | 326 // The move is not blocked. This frame element can be moved from |
| 324 // its source register to its target register. | 327 // its source register to its target register. |
| 325 if (target.is_synced() && !source.is_synced()) { | 328 if (target.is_synced() && !source.is_synced()) { |
| 326 SyncElementAt(i); | 329 SyncElementAt(i); |
| 327 } | 330 } |
| 328 Use(target.reg()); | 331 Use(target.reg(), i); |
| 329 Unuse(source.reg()); | 332 Unuse(source.reg()); |
| 330 elements_[i] = target; | 333 elements_[i] = target; |
| 331 __ mov(target.reg(), source.reg()); | 334 __ mov(target.reg(), source.reg()); |
| 332 any_moves_made = true; | 335 any_moves_made = true; |
| 333 } | 336 } |
| 334 } | 337 } |
| 335 } | 338 } |
| 336 } | 339 } |
| 337 // Update control flags for next iteration. | 340 // Update control flags for next iteration. |
| 338 should_break_cycles = (any_moves_blocked && !any_moves_made); | 341 should_break_cycles = (any_moves_blocked && !any_moves_made); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 } else { | 384 } else { |
| 382 __ mov(target.reg(), backing.reg()); | 385 __ mov(target.reg(), backing.reg()); |
| 383 } | 386 } |
| 384 } | 387 } |
| 385 } | 388 } |
| 386 // Ensure the proper sync state. If the source was memory no | 389 // Ensure the proper sync state. If the source was memory no |
| 387 // code needs to be emitted. | 390 // code needs to be emitted. |
| 388 if (target.is_synced() && !source.is_memory()) { | 391 if (target.is_synced() && !source.is_memory()) { |
| 389 SyncElementAt(i); | 392 SyncElementAt(i); |
| 390 } | 393 } |
| 391 Use(target.reg()); | 394 Use(target.reg(), i); |
| 392 elements_[i] = target; | 395 elements_[i] = target; |
| 393 } | 396 } |
| 394 } | 397 } |
| 395 } | 398 } |
| 396 | 399 |
| 397 | 400 |
| 398 void VirtualFrame::Enter() { | 401 void VirtualFrame::Enter() { |
| 399 // Registers live on entry: esp, ebp, esi, edi. | 402 // Registers live on entry: esp, ebp, esi, edi. |
| 400 Comment cmnt(masm_, "[ Enter JS frame"); | 403 Comment cmnt(masm_, "[ Enter JS frame"); |
| 401 | 404 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 } | 523 } |
| 521 elements_[index] = FrameElement::InvalidElement(); | 524 elements_[index] = FrameElement::InvalidElement(); |
| 522 return kIllegalIndex; | 525 return kIllegalIndex; |
| 523 } | 526 } |
| 524 | 527 |
| 525 // This is the backing store of copies. | 528 // This is the backing store of copies. |
| 526 Register backing_reg; | 529 Register backing_reg; |
| 527 if (original.is_memory()) { | 530 if (original.is_memory()) { |
| 528 Result fresh = cgen_->allocator()->Allocate(); | 531 Result fresh = cgen_->allocator()->Allocate(); |
| 529 ASSERT(fresh.is_valid()); | 532 ASSERT(fresh.is_valid()); |
| 530 Use(fresh.reg()); | 533 Use(fresh.reg(), new_backing_index); |
| 531 backing_reg = fresh.reg(); | 534 backing_reg = fresh.reg(); |
| 532 __ mov(backing_reg, Operand(ebp, fp_relative(index))); | 535 __ mov(backing_reg, Operand(ebp, fp_relative(index))); |
| 533 } else { | 536 } else { |
| 534 // The original was in a register. | 537 // The original was in a register. |
| 535 backing_reg = original.reg(); | 538 backing_reg = original.reg(); |
| 539 register_locations_[backing_reg.code()] = new_backing_index; |
| 536 } | 540 } |
| 537 if (elements_[new_backing_index].is_synced()) { | 541 if (elements_[new_backing_index].is_synced()) { |
| 538 elements_[new_backing_index] = | 542 elements_[new_backing_index] = |
| 539 FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED); | 543 FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED); |
| 540 } else { | 544 } else { |
| 541 elements_[new_backing_index] = | 545 elements_[new_backing_index] = |
| 542 FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED); | 546 FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED); |
| 543 } | 547 } |
| 544 // Update the other copies. | 548 // Update the other copies. |
| 545 for (int i = new_backing_index + 1; i < elements_.length(); i++) { | 549 for (int i = new_backing_index + 1; i < elements_.length(); i++) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 564 | 568 |
| 565 switch (original.type()) { | 569 switch (original.type()) { |
| 566 case FrameElement::MEMORY: { | 570 case FrameElement::MEMORY: { |
| 567 // Emit code to load the original element's data into a register. | 571 // Emit code to load the original element's data into a register. |
| 568 // Push that register as a FrameElement on top of the frame. | 572 // Push that register as a FrameElement on top of the frame. |
| 569 Result fresh = cgen_->allocator()->Allocate(); | 573 Result fresh = cgen_->allocator()->Allocate(); |
| 570 ASSERT(fresh.is_valid()); | 574 ASSERT(fresh.is_valid()); |
| 571 FrameElement new_element = | 575 FrameElement new_element = |
| 572 FrameElement::RegisterElement(fresh.reg(), | 576 FrameElement::RegisterElement(fresh.reg(), |
| 573 FrameElement::NOT_SYNCED); | 577 FrameElement::NOT_SYNCED); |
| 574 Use(fresh.reg()); | 578 Use(fresh.reg(), elements_.length()); |
| 575 elements_.Add(new_element); | 579 elements_.Add(new_element); |
| 576 __ mov(fresh.reg(), Operand(ebp, fp_relative(index))); | 580 __ mov(fresh.reg(), Operand(ebp, fp_relative(index))); |
| 577 break; | 581 break; |
| 578 } | 582 } |
| 579 case FrameElement::REGISTER: | 583 case FrameElement::REGISTER: |
| 580 Use(original.reg()); | 584 Use(original.reg(), elements_.length()); |
| 581 // Fall through. | 585 // Fall through. |
| 582 case FrameElement::CONSTANT: | 586 case FrameElement::CONSTANT: |
| 583 case FrameElement::COPY: | 587 case FrameElement::COPY: |
| 584 original.clear_sync(); | 588 original.clear_sync(); |
| 585 elements_.Add(original); | 589 elements_.Add(original); |
| 586 break; | 590 break; |
| 587 case FrameElement::INVALID: | 591 case FrameElement::INVALID: |
| 588 UNREACHABLE(); | 592 UNREACHABLE(); |
| 589 break; | 593 break; |
| 590 } | 594 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 // have to move the actual value down in the stack. | 635 // have to move the actual value down in the stack. |
| 632 // | 636 // |
| 633 // TODO(209): considering allocating the stored-to slot to the | 637 // TODO(209): considering allocating the stored-to slot to the |
| 634 // temp register. Alternatively, allow copies to appear in | 638 // temp register. Alternatively, allow copies to appear in |
| 635 // any order in the frame and lazily move the value down to | 639 // any order in the frame and lazily move the value down to |
| 636 // the slot. | 640 // the slot. |
| 637 Result temp = cgen_->allocator()->Allocate(); | 641 Result temp = cgen_->allocator()->Allocate(); |
| 638 ASSERT(temp.is_valid()); | 642 ASSERT(temp.is_valid()); |
| 639 __ mov(temp.reg(), Operand(ebp, fp_relative(backing_index))); | 643 __ mov(temp.reg(), Operand(ebp, fp_relative(backing_index))); |
| 640 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); | 644 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); |
| 641 } else if (backing_element.is_synced()) { | 645 } else { |
| 642 // If the element is a register, we will not actually move | 646 register_locations_[backing_element.reg().code()] = index; |
| 643 // anything on the stack but only update the virtual frame | 647 if (backing_element.is_synced()) { |
| 644 // element. | 648 // If the element is a register, we will not actually move |
| 645 backing_element.clear_sync(); | 649 // anything on the stack but only update the virtual frame |
| 650 // element. |
| 651 backing_element.clear_sync(); |
| 652 } |
| 646 } | 653 } |
| 647 elements_[index] = backing_element; | 654 elements_[index] = backing_element; |
| 648 | 655 |
| 649 // The old backing element becomes a copy of the new backing | 656 // The old backing element becomes a copy of the new backing |
| 650 // element. | 657 // element. |
| 651 FrameElement new_element = CopyElementAt(index); | 658 FrameElement new_element = CopyElementAt(index); |
| 652 elements_[backing_index] = new_element; | 659 elements_[backing_index] = new_element; |
| 653 if (backing_element.is_synced()) { | 660 if (backing_element.is_synced()) { |
| 654 elements_[backing_index].set_sync(); | 661 elements_[backing_index].set_sync(); |
| 655 } | 662 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 676 new_top.set_sync(); | 683 new_top.set_sync(); |
| 677 elements_[top_index] = new_top; | 684 elements_[top_index] = new_top; |
| 678 | 685 |
| 679 // The sync state of the former top element is correct (synced). | 686 // The sync state of the former top element is correct (synced). |
| 680 // Emit code to move the value down in the frame. | 687 // Emit code to move the value down in the frame. |
| 681 Result temp = cgen_->allocator()->Allocate(); | 688 Result temp = cgen_->allocator()->Allocate(); |
| 682 ASSERT(temp.is_valid()); | 689 ASSERT(temp.is_valid()); |
| 683 __ mov(temp.reg(), Operand(esp, 0)); | 690 __ mov(temp.reg(), Operand(esp, 0)); |
| 684 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); | 691 __ mov(Operand(ebp, fp_relative(index)), temp.reg()); |
| 685 } else if (top.is_register()) { | 692 } else if (top.is_register()) { |
| 693 register_locations_[top.reg().code()] = index; |
| 686 // The stored-to slot has the (unsynced) register reference and | 694 // The stored-to slot has the (unsynced) register reference and |
| 687 // the top element becomes a copy. The sync state of the top is | 695 // the top element becomes a copy. The sync state of the top is |
| 688 // preserved. | 696 // preserved. |
| 689 FrameElement new_top = CopyElementAt(index); | 697 FrameElement new_top = CopyElementAt(index); |
| 690 if (top.is_synced()) { | 698 if (top.is_synced()) { |
| 691 new_top.set_sync(); | 699 new_top.set_sync(); |
| 692 elements_[index].clear_sync(); | 700 elements_[index].clear_sync(); |
| 693 } | 701 } |
| 694 elements_[top_index] = new_top; | 702 elements_[top_index] = new_top; |
| 695 } else { | 703 } else { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 882 } | 890 } |
| 883 ASSERT(!element.is_copy()); | 891 ASSERT(!element.is_copy()); |
| 884 | 892 |
| 885 // The element is memory, a register, or a constant. | 893 // The element is memory, a register, or a constant. |
| 886 if (element.is_memory()) { | 894 if (element.is_memory()) { |
| 887 // Memory elements could only be the backing store of a copy. | 895 // Memory elements could only be the backing store of a copy. |
| 888 // Allocate the original to a register. | 896 // Allocate the original to a register. |
| 889 ASSERT(index <= stack_pointer_); | 897 ASSERT(index <= stack_pointer_); |
| 890 Result temp = cgen_->allocator()->Allocate(); | 898 Result temp = cgen_->allocator()->Allocate(); |
| 891 ASSERT(temp.is_valid()); | 899 ASSERT(temp.is_valid()); |
| 892 Use(temp.reg()); | 900 Use(temp.reg(), index); |
| 893 FrameElement new_element = | 901 FrameElement new_element = |
| 894 FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED); | 902 FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED); |
| 895 elements_[index] = new_element; | 903 elements_[index] = new_element; |
| 896 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); | 904 __ mov(temp.reg(), Operand(ebp, fp_relative(index))); |
| 897 return Result(temp.reg(), cgen_); | 905 return Result(temp.reg(), cgen_); |
| 898 } else if (element.is_register()) { | 906 } else if (element.is_register()) { |
| 899 return Result(element.reg(), cgen_); | 907 return Result(element.reg(), cgen_); |
| 900 } else { | 908 } else { |
| 901 ASSERT(element.is_constant()); | 909 ASSERT(element.is_constant()); |
| 902 return Result(element.handle(), cgen_); | 910 return Result(element.handle(), cgen_); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 ASSERT(stack_pointer_ == elements_.length() - 1); | 948 ASSERT(stack_pointer_ == elements_.length() - 1); |
| 941 elements_.Add(FrameElement::MemoryElement()); | 949 elements_.Add(FrameElement::MemoryElement()); |
| 942 stack_pointer_++; | 950 stack_pointer_++; |
| 943 __ push(immediate); | 951 __ push(immediate); |
| 944 } | 952 } |
| 945 | 953 |
| 946 | 954 |
| 947 #undef __ | 955 #undef __ |
| 948 | 956 |
| 949 } } // namespace v8::internal | 957 } } // namespace v8::internal |
| OLD | NEW |