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 25 matching lines...) Expand all Loading... |
36 | 36 |
37 namespace v8 { | 37 namespace v8 { |
38 namespace internal { | 38 namespace internal { |
39 | 39 |
40 #define __ ACCESS_MASM(masm()) | 40 #define __ ACCESS_MASM(masm()) |
41 | 41 |
42 void VirtualFrame::PopToR1R0() { | 42 void VirtualFrame::PopToR1R0() { |
43 // Shuffle things around so the top of stack is in r0 and r1. | 43 // Shuffle things around so the top of stack is in r0 and r1. |
44 MergeTOSTo(R0_R1_TOS); | 44 MergeTOSTo(R0_R1_TOS); |
45 // Pop the two registers off the stack so they are detached from the frame. | 45 // Pop the two registers off the stack so they are detached from the frame. |
46 element_count_ -= 2; | 46 LowerHeight(2); |
47 top_of_stack_state_ = NO_TOS_REGISTERS; | 47 top_of_stack_state_ = NO_TOS_REGISTERS; |
48 } | 48 } |
49 | 49 |
50 | 50 |
51 void VirtualFrame::PopToR1() { | 51 void VirtualFrame::PopToR1() { |
52 // Shuffle things around so the top of stack is only in r1. | 52 // Shuffle things around so the top of stack is only in r1. |
53 MergeTOSTo(R1_TOS); | 53 MergeTOSTo(R1_TOS); |
54 // Pop the register off the stack so it is detached from the frame. | 54 // Pop the register off the stack so it is detached from the frame. |
55 element_count_ -= 1; | 55 LowerHeight(1); |
56 top_of_stack_state_ = NO_TOS_REGISTERS; | 56 top_of_stack_state_ = NO_TOS_REGISTERS; |
57 } | 57 } |
58 | 58 |
59 | 59 |
60 void VirtualFrame::PopToR0() { | 60 void VirtualFrame::PopToR0() { |
61 // Shuffle things around so the top of stack only in r0. | 61 // Shuffle things around so the top of stack only in r0. |
62 MergeTOSTo(R0_TOS); | 62 MergeTOSTo(R0_TOS); |
63 // Pop the register off the stack so it is detached from the frame. | 63 // Pop the register off the stack so it is detached from the frame. |
64 element_count_ -= 1; | 64 LowerHeight(1); |
65 top_of_stack_state_ = NO_TOS_REGISTERS; | 65 top_of_stack_state_ = NO_TOS_REGISTERS; |
66 } | 66 } |
67 | 67 |
68 | 68 |
69 void VirtualFrame::MergeTo(const VirtualFrame* expected, Condition cond) { | 69 void VirtualFrame::MergeTo(const VirtualFrame* expected, Condition cond) { |
70 if (Equals(expected)) return; | 70 if (Equals(expected)) return; |
| 71 ASSERT(expected->IsCompatibleWith(this)); |
| 72 MergeTOSTo(expected->top_of_stack_state_, cond); |
| 73 ASSERT(register_allocation_map_ == expected->register_allocation_map_); |
| 74 } |
| 75 |
| 76 |
| 77 void VirtualFrame::MergeTo(VirtualFrame* expected, Condition cond) { |
| 78 if (Equals(expected)) return; |
| 79 expected->tos_known_smi_map_ &= tos_known_smi_map_; |
71 MergeTOSTo(expected->top_of_stack_state_, cond); | 80 MergeTOSTo(expected->top_of_stack_state_, cond); |
72 ASSERT(register_allocation_map_ == expected->register_allocation_map_); | 81 ASSERT(register_allocation_map_ == expected->register_allocation_map_); |
73 } | 82 } |
74 | 83 |
75 | 84 |
76 void VirtualFrame::MergeTOSTo( | 85 void VirtualFrame::MergeTOSTo( |
77 VirtualFrame::TopOfStack expected_top_of_stack_state, Condition cond) { | 86 VirtualFrame::TopOfStack expected_top_of_stack_state, Condition cond) { |
78 #define CASE_NUMBER(a, b) ((a) * TOS_STATES + (b)) | 87 #define CASE_NUMBER(a, b) ((a) * TOS_STATES + (b)) |
79 switch (CASE_NUMBER(top_of_stack_state_, expected_top_of_stack_state)) { | 88 switch (CASE_NUMBER(top_of_stack_state_, expected_top_of_stack_state)) { |
80 case CASE_NUMBER(NO_TOS_REGISTERS, NO_TOS_REGISTERS): | 89 case CASE_NUMBER(NO_TOS_REGISTERS, NO_TOS_REGISTERS): |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 // Discard elements from the virtual frame and free any registers. | 422 // Discard elements from the virtual frame and free any registers. |
414 int num_virtual_elements = kVirtualElements[top_of_stack_state_]; | 423 int num_virtual_elements = kVirtualElements[top_of_stack_state_]; |
415 while (num_virtual_elements > 0) { | 424 while (num_virtual_elements > 0) { |
416 Pop(); | 425 Pop(); |
417 num_virtual_elements--; | 426 num_virtual_elements--; |
418 count--; | 427 count--; |
419 if (count == 0) return; | 428 if (count == 0) return; |
420 } | 429 } |
421 if (count == 0) return; | 430 if (count == 0) return; |
422 __ add(sp, sp, Operand(count * kPointerSize)); | 431 __ add(sp, sp, Operand(count * kPointerSize)); |
423 element_count_ -= count; | 432 LowerHeight(count); |
424 } | 433 } |
425 | 434 |
426 | 435 |
427 void VirtualFrame::Pop() { | 436 void VirtualFrame::Pop() { |
428 if (top_of_stack_state_ == NO_TOS_REGISTERS) { | 437 if (top_of_stack_state_ == NO_TOS_REGISTERS) { |
429 __ add(sp, sp, Operand(kPointerSize)); | 438 __ add(sp, sp, Operand(kPointerSize)); |
430 } else { | 439 } else { |
431 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; | 440 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; |
432 } | 441 } |
433 element_count_--; | 442 LowerHeight(1); |
434 } | 443 } |
435 | 444 |
436 | 445 |
437 void VirtualFrame::EmitPop(Register reg) { | 446 void VirtualFrame::EmitPop(Register reg) { |
438 ASSERT(!is_used(RegisterAllocator::ToNumber(reg))); | 447 ASSERT(!is_used(RegisterAllocator::ToNumber(reg))); |
439 if (top_of_stack_state_ == NO_TOS_REGISTERS) { | 448 if (top_of_stack_state_ == NO_TOS_REGISTERS) { |
440 __ pop(reg); | 449 __ pop(reg); |
441 } else { | 450 } else { |
442 __ mov(reg, kTopRegister[top_of_stack_state_]); | 451 __ mov(reg, kTopRegister[top_of_stack_state_]); |
443 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; | 452 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; |
444 } | 453 } |
445 element_count_--; | 454 LowerHeight(1); |
446 } | 455 } |
447 | 456 |
448 | 457 |
449 void VirtualFrame::SpillAllButCopyTOSToR0() { | 458 void VirtualFrame::SpillAllButCopyTOSToR0() { |
450 switch (top_of_stack_state_) { | 459 switch (top_of_stack_state_) { |
451 case NO_TOS_REGISTERS: | 460 case NO_TOS_REGISTERS: |
452 __ ldr(r0, MemOperand(sp, 0)); | 461 __ ldr(r0, MemOperand(sp, 0)); |
453 break; | 462 break; |
454 case R0_TOS: | 463 case R0_TOS: |
455 __ push(r0); | 464 __ push(r0); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 case R1_R0_TOS: | 552 case R1_R0_TOS: |
544 __ push(r0); | 553 __ push(r0); |
545 __ mov(r0, r1); | 554 __ mov(r0, r1); |
546 // r0 and r1 contains the same value. Prefer state with r0 holding TOS. | 555 // r0 and r1 contains the same value. Prefer state with r0 holding TOS. |
547 top_of_stack_state_ = R0_R1_TOS; | 556 top_of_stack_state_ = R0_R1_TOS; |
548 break; | 557 break; |
549 default: | 558 default: |
550 UNREACHABLE(); | 559 UNREACHABLE(); |
551 } | 560 } |
552 } | 561 } |
553 element_count_++; | 562 RaiseHeight(1, tos_known_smi_map_ & 1); |
554 } | 563 } |
555 | 564 |
556 | 565 |
557 void VirtualFrame::Dup2() { | 566 void VirtualFrame::Dup2() { |
558 if (SpilledScope::is_spilled()) { | 567 if (SpilledScope::is_spilled()) { |
559 __ ldr(ip, MemOperand(sp, kPointerSize)); | 568 __ ldr(ip, MemOperand(sp, kPointerSize)); |
560 __ push(ip); | 569 __ push(ip); |
561 __ ldr(ip, MemOperand(sp, kPointerSize)); | 570 __ ldr(ip, MemOperand(sp, kPointerSize)); |
562 __ push(ip); | 571 __ push(ip); |
563 } else { | 572 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
582 top_of_stack_state_ = R0_R1_TOS; | 591 top_of_stack_state_ = R0_R1_TOS; |
583 break; | 592 break; |
584 case R1_R0_TOS: | 593 case R1_R0_TOS: |
585 __ Push(r0, r1); | 594 __ Push(r0, r1); |
586 top_of_stack_state_ = R1_R0_TOS; | 595 top_of_stack_state_ = R1_R0_TOS; |
587 break; | 596 break; |
588 default: | 597 default: |
589 UNREACHABLE(); | 598 UNREACHABLE(); |
590 } | 599 } |
591 } | 600 } |
592 element_count_ += 2; | 601 RaiseHeight(2, tos_known_smi_map_ & 3); |
593 } | 602 } |
594 | 603 |
595 | 604 |
596 Register VirtualFrame::PopToRegister(Register but_not_to_this_one) { | 605 Register VirtualFrame::PopToRegister(Register but_not_to_this_one) { |
597 ASSERT(but_not_to_this_one.is(r0) || | 606 ASSERT(but_not_to_this_one.is(r0) || |
598 but_not_to_this_one.is(r1) || | 607 but_not_to_this_one.is(r1) || |
599 but_not_to_this_one.is(no_reg)); | 608 but_not_to_this_one.is(no_reg)); |
600 element_count_--; | 609 LowerHeight(1); |
601 if (top_of_stack_state_ == NO_TOS_REGISTERS) { | 610 if (top_of_stack_state_ == NO_TOS_REGISTERS) { |
602 if (but_not_to_this_one.is(r0)) { | 611 if (but_not_to_this_one.is(r0)) { |
603 __ pop(r1); | 612 __ pop(r1); |
604 return r1; | 613 return r1; |
605 } else { | 614 } else { |
606 __ pop(r0); | 615 __ pop(r0); |
607 return r0; | 616 return r0; |
608 } | 617 } |
609 } else { | 618 } else { |
610 Register answer = kTopRegister[top_of_stack_state_]; | 619 Register answer = kTopRegister[top_of_stack_state_]; |
611 ASSERT(!answer.is(but_not_to_this_one)); | 620 ASSERT(!answer.is(but_not_to_this_one)); |
612 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; | 621 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; |
613 return answer; | 622 return answer; |
614 } | 623 } |
615 } | 624 } |
616 | 625 |
617 | 626 |
618 void VirtualFrame::EnsureOneFreeTOSRegister() { | 627 void VirtualFrame::EnsureOneFreeTOSRegister() { |
619 if (kVirtualElements[top_of_stack_state_] == kMaxTOSRegisters) { | 628 if (kVirtualElements[top_of_stack_state_] == kMaxTOSRegisters) { |
620 __ push(kBottomRegister[top_of_stack_state_]); | 629 __ push(kBottomRegister[top_of_stack_state_]); |
621 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; | 630 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; |
622 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; | 631 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; |
623 } | 632 } |
624 ASSERT(kVirtualElements[top_of_stack_state_] != kMaxTOSRegisters); | 633 ASSERT(kVirtualElements[top_of_stack_state_] != kMaxTOSRegisters); |
625 } | 634 } |
626 | 635 |
627 | 636 |
628 void VirtualFrame::EmitPush(Register reg) { | 637 void VirtualFrame::EmitPush(Register reg, TypeInfo info) { |
629 element_count_++; | 638 RaiseHeight(1, info.IsSmi() ? 1 : 0); |
630 if (reg.is(cp)) { | 639 if (reg.is(cp)) { |
631 // If we are pushing cp then we are about to make a call and things have to | 640 // If we are pushing cp then we are about to make a call and things have to |
632 // be pushed to the physical stack. There's nothing to be gained my moving | 641 // be pushed to the physical stack. There's nothing to be gained my moving |
633 // to a TOS register and then pushing that, we might as well push to the | 642 // to a TOS register and then pushing that, we might as well push to the |
634 // physical stack immediately. | 643 // physical stack immediately. |
635 MergeTOSTo(NO_TOS_REGISTERS); | 644 MergeTOSTo(NO_TOS_REGISTERS); |
636 __ push(reg); | 645 __ push(reg); |
637 return; | 646 return; |
638 } | 647 } |
639 if (SpilledScope::is_spilled()) { | 648 if (SpilledScope::is_spilled()) { |
(...skipping 12 matching lines...) Expand all Loading... |
652 } | 661 } |
653 } | 662 } |
654 EnsureOneFreeTOSRegister(); | 663 EnsureOneFreeTOSRegister(); |
655 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; | 664 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; |
656 Register dest = kTopRegister[top_of_stack_state_]; | 665 Register dest = kTopRegister[top_of_stack_state_]; |
657 __ Move(dest, reg); | 666 __ Move(dest, reg); |
658 } | 667 } |
659 | 668 |
660 | 669 |
661 void VirtualFrame::SetElementAt(Register reg, int this_far_down) { | 670 void VirtualFrame::SetElementAt(Register reg, int this_far_down) { |
| 671 if (this_far_down < kTOSKnownSmiMapSize) { |
| 672 tos_known_smi_map_ &= ~(1 << this_far_down); |
| 673 } |
662 if (this_far_down == 0) { | 674 if (this_far_down == 0) { |
663 Pop(); | 675 Pop(); |
664 Register dest = GetTOSRegister(); | 676 Register dest = GetTOSRegister(); |
665 if (dest.is(reg)) { | 677 if (dest.is(reg)) { |
666 // We already popped one item off the top of the stack. If the only | 678 // We already popped one item off the top of the stack. If the only |
667 // free register is the one we were asked to push then we have been | 679 // free register is the one we were asked to push then we have been |
668 // asked to push a register that was already in use, which cannot | 680 // asked to push a register that was already in use, which cannot |
669 // happen. It therefore folows that there are two free TOS registers: | 681 // happen. It therefore folows that there are two free TOS registers: |
670 ASSERT(top_of_stack_state_ == NO_TOS_REGISTERS); | 682 ASSERT(top_of_stack_state_ == NO_TOS_REGISTERS); |
671 dest = dest.is(r0) ? r1 : r0; | 683 dest = dest.is(r0) ? r1 : r0; |
(...skipping 20 matching lines...) Expand all Loading... |
692 | 704 |
693 | 705 |
694 Register VirtualFrame::GetTOSRegister() { | 706 Register VirtualFrame::GetTOSRegister() { |
695 if (SpilledScope::is_spilled()) return r0; | 707 if (SpilledScope::is_spilled()) return r0; |
696 | 708 |
697 EnsureOneFreeTOSRegister(); | 709 EnsureOneFreeTOSRegister(); |
698 return kTopRegister[kStateAfterPush[top_of_stack_state_]]; | 710 return kTopRegister[kStateAfterPush[top_of_stack_state_]]; |
699 } | 711 } |
700 | 712 |
701 | 713 |
702 void VirtualFrame::EmitPush(Operand operand) { | 714 void VirtualFrame::EmitPush(Operand operand, TypeInfo info) { |
703 element_count_++; | 715 RaiseHeight(1, info.IsSmi() ? 1 : 0); |
704 if (SpilledScope::is_spilled()) { | 716 if (SpilledScope::is_spilled()) { |
705 __ mov(r0, operand); | 717 __ mov(r0, operand); |
706 __ push(r0); | 718 __ push(r0); |
707 return; | 719 return; |
708 } | 720 } |
709 EnsureOneFreeTOSRegister(); | 721 EnsureOneFreeTOSRegister(); |
710 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; | 722 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; |
711 __ mov(kTopRegister[top_of_stack_state_], operand); | 723 __ mov(kTopRegister[top_of_stack_state_], operand); |
712 } | 724 } |
713 | 725 |
714 | 726 |
715 void VirtualFrame::EmitPush(MemOperand operand) { | 727 void VirtualFrame::EmitPush(MemOperand operand, TypeInfo info) { |
716 element_count_++; | 728 RaiseHeight(1, info.IsSmi() ? 1 : 0); |
717 if (SpilledScope::is_spilled()) { | 729 if (SpilledScope::is_spilled()) { |
718 __ ldr(r0, operand); | 730 __ ldr(r0, operand); |
719 __ push(r0); | 731 __ push(r0); |
720 return; | 732 return; |
721 } | 733 } |
722 EnsureOneFreeTOSRegister(); | 734 EnsureOneFreeTOSRegister(); |
723 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; | 735 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; |
724 __ ldr(kTopRegister[top_of_stack_state_], operand); | 736 __ ldr(kTopRegister[top_of_stack_state_], operand); |
725 } | 737 } |
726 | 738 |
727 | 739 |
728 void VirtualFrame::EmitPushRoot(Heap::RootListIndex index) { | 740 void VirtualFrame::EmitPushRoot(Heap::RootListIndex index) { |
729 element_count_++; | 741 RaiseHeight(1, 0); |
730 if (SpilledScope::is_spilled()) { | 742 if (SpilledScope::is_spilled()) { |
731 __ LoadRoot(r0, index); | 743 __ LoadRoot(r0, index); |
732 __ push(r0); | 744 __ push(r0); |
733 return; | 745 return; |
734 } | 746 } |
735 EnsureOneFreeTOSRegister(); | 747 EnsureOneFreeTOSRegister(); |
736 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; | 748 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; |
737 __ LoadRoot(kTopRegister[top_of_stack_state_], index); | 749 __ LoadRoot(kTopRegister[top_of_stack_state_], index); |
738 } | 750 } |
739 | 751 |
(...skipping 28 matching lines...) Expand all Loading... |
768 break; | 780 break; |
769 } | 781 } |
770 ASSERT(register_allocation_map_ == 0); // Not yet implemented. | 782 ASSERT(register_allocation_map_ == 0); // Not yet implemented. |
771 } | 783 } |
772 | 784 |
773 #undef __ | 785 #undef __ |
774 | 786 |
775 } } // namespace v8::internal | 787 } } // namespace v8::internal |
776 | 788 |
777 #endif // V8_TARGET_ARCH_ARM | 789 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |