| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 : object_(object), | 537 : object_(object), |
| 538 value_(value), | 538 value_(value), |
| 539 address_(address), | 539 address_(address), |
| 540 remembered_set_action_(remembered_set_action), | 540 remembered_set_action_(remembered_set_action), |
| 541 save_fp_regs_mode_(fp_mode), | 541 save_fp_regs_mode_(fp_mode), |
| 542 regs_(object, // An input reg. | 542 regs_(object, // An input reg. |
| 543 address, // An input reg. | 543 address, // An input reg. |
| 544 value) { // One scratch reg. | 544 value) { // One scratch reg. |
| 545 } | 545 } |
| 546 | 546 |
| 547 static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8. | 547 enum Mode { |
| 548 static const byte kSkipNonIncrementalPartInstruction = 0xeb; // Jmp #imm8. | 548 STORE_BUFFER_ONLY, |
| 549 INCREMENTAL, |
| 550 INCREMENTAL_COMPACTION |
| 551 }; |
| 549 | 552 |
| 550 static byte GetInstruction(bool enable) { | 553 static const byte kTwoByteNopInstruction = 0x3c; // Cmpb al, #imm8. |
| 551 // Can't use ternary operator here, because gcc makes an undefined | 554 static const byte kTwoByteJumpInstruction = 0xeb; // Jmp #imm8. |
| 552 // reference to a static const int. | 555 |
| 553 if (enable) { | 556 static const byte kFiveByteNopInstruction = 0x3d; // Cmpl eax, #imm32. |
| 554 return kSkipNonIncrementalPartInstruction; | 557 static const byte kFiveByteJumpInstruction = 0xe9; // Jmp #imm32. |
| 555 } else { | 558 |
| 556 return kTwoByteNopInstruction; | 559 static Mode GetMode(Code* stub) { |
| 560 byte first_instruction = stub->instruction_start()[0]; |
| 561 byte second_instruction = stub->instruction_start()[2]; |
| 562 |
| 563 if (first_instruction == kTwoByteJumpInstruction) { |
| 564 return INCREMENTAL; |
| 557 } | 565 } |
| 566 |
| 567 ASSERT(first_instruction == kTwoByteNopInstruction); |
| 568 |
| 569 if (second_instruction == kFiveByteJumpInstruction) { |
| 570 return INCREMENTAL_COMPACTION; |
| 571 } |
| 572 |
| 573 ASSERT(second_instruction == kFiveByteNopInstruction); |
| 574 |
| 575 return STORE_BUFFER_ONLY; |
| 558 } | 576 } |
| 559 | 577 |
| 560 static void Patch(Code* stub, bool enable) { | 578 static void Patch(Code* stub, Mode mode) { |
| 561 ASSERT(*stub->instruction_start() == GetInstruction(!enable)); | 579 switch (mode) { |
| 562 *stub->instruction_start() = GetInstruction(enable); | 580 case STORE_BUFFER_ONLY: |
| 581 ASSERT(GetMode(stub) == INCREMENTAL || |
| 582 GetMode(stub) == INCREMENTAL_COMPACTION); |
| 583 stub->instruction_start()[0] = kTwoByteNopInstruction; |
| 584 stub->instruction_start()[2] = kFiveByteNopInstruction; |
| 585 break; |
| 586 case INCREMENTAL: |
| 587 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); |
| 588 stub->instruction_start()[0] = kTwoByteJumpInstruction; |
| 589 break; |
| 590 case INCREMENTAL_COMPACTION: |
| 591 ASSERT(GetMode(stub) == STORE_BUFFER_ONLY); |
| 592 stub->instruction_start()[0] = kTwoByteNopInstruction; |
| 593 stub->instruction_start()[2] = kFiveByteJumpInstruction; |
| 594 break; |
| 595 } |
| 596 ASSERT(GetMode(stub) == mode); |
| 563 } | 597 } |
| 564 | 598 |
| 565 private: | 599 private: |
| 566 // This is a helper class for freeing up 3 scratch registers, where the third | 600 // This is a helper class for freeing up 3 scratch registers, where the third |
| 567 // is always ecx (needed for shift operations). The input is two registers | 601 // is always ecx (needed for shift operations). The input is two registers |
| 568 // that must be preserved and one scratch register provided by the caller. | 602 // that must be preserved and one scratch register provided by the caller. |
| 569 class RegisterAllocation { | 603 class RegisterAllocation { |
| 570 public: | 604 public: |
| 571 RegisterAllocation(Register object, | 605 RegisterAllocation(Register object, |
| 572 Register address, | 606 Register address, |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 701 } | 735 } |
| 702 UNREACHABLE(); | 736 UNREACHABLE(); |
| 703 return no_reg; | 737 return no_reg; |
| 704 } | 738 } |
| 705 friend class RecordWriteStub; | 739 friend class RecordWriteStub; |
| 706 }; | 740 }; |
| 707 | 741 |
| 708 enum OnNoNeedToInformIncrementalMarker { | 742 enum OnNoNeedToInformIncrementalMarker { |
| 709 kReturnOnNoNeedToInformIncrementalMarker, | 743 kReturnOnNoNeedToInformIncrementalMarker, |
| 710 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker | 744 kUpdateRememberedSetOnNoNeedToInformIncrementalMarker |
| 711 }; | 745 } |
| 712 | 746 ; |
| 713 void Generate(MacroAssembler* masm); | 747 void Generate(MacroAssembler* masm); |
| 714 void GenerateIncremental(MacroAssembler* masm); | 748 void GenerateIncremental(MacroAssembler* masm, Mode mode); |
| 715 void CheckNeedsToInformIncrementalMarker( | 749 void CheckNeedsToInformIncrementalMarker( |
| 716 MacroAssembler* masm, | 750 MacroAssembler* masm, |
| 717 OnNoNeedToInformIncrementalMarker on_no_need); | 751 OnNoNeedToInformIncrementalMarker on_no_need, |
| 718 void InformIncrementalMarker(MacroAssembler* masm); | 752 Mode mode); |
| 753 void InformIncrementalMarker(MacroAssembler* masm, Mode mode); |
| 719 | 754 |
| 720 Major MajorKey() { return RecordWrite; } | 755 Major MajorKey() { return RecordWrite; } |
| 721 | 756 |
| 722 int MinorKey() { | 757 int MinorKey() { |
| 723 return ObjectBits::encode(object_.code()) | | 758 return ObjectBits::encode(object_.code()) | |
| 724 ValueBits::encode(value_.code()) | | 759 ValueBits::encode(value_.code()) | |
| 725 AddressBits::encode(address_.code()) | | 760 AddressBits::encode(address_.code()) | |
| 726 RememberedSetActionBits::encode(remembered_set_action_) | | 761 RememberedSetActionBits::encode(remembered_set_action_) | |
| 727 SaveFPRegsModeBits::encode(save_fp_regs_mode_); | 762 SaveFPRegsModeBits::encode(save_fp_regs_mode_); |
| 728 } | 763 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 Register scratch1, | 814 Register scratch1, |
| 780 bool load_elements_from_receiver, | 815 bool load_elements_from_receiver, |
| 781 Label* key_not_smi, | 816 Label* key_not_smi, |
| 782 Label* value_not_smi, | 817 Label* value_not_smi, |
| 783 Label* not_pixel_array, | 818 Label* not_pixel_array, |
| 784 Label* out_of_range); | 819 Label* out_of_range); |
| 785 | 820 |
| 786 } } // namespace v8::internal | 821 } } // namespace v8::internal |
| 787 | 822 |
| 788 #endif // V8_IA32_CODE_STUBS_IA32_H_ | 823 #endif // V8_IA32_CODE_STUBS_IA32_H_ |
| OLD | NEW |