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 |