OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 __ movq(kScratchRegister, stack_limit); | 755 __ movq(kScratchRegister, stack_limit); |
756 __ subq(rcx, Operand(kScratchRegister, 0)); | 756 __ subq(rcx, Operand(kScratchRegister, 0)); |
757 // Handle it if the stack pointer is already below the stack limit. | 757 // Handle it if the stack pointer is already below the stack limit. |
758 __ j(below_equal, &stack_limit_hit); | 758 __ j(below_equal, &stack_limit_hit); |
759 // Check if there is room for the variable number of registers above | 759 // Check if there is room for the variable number of registers above |
760 // the stack limit. | 760 // the stack limit. |
761 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize)); | 761 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize)); |
762 __ j(above_equal, &stack_ok); | 762 __ j(above_equal, &stack_ok); |
763 // Exit with OutOfMemory exception. There is not enough space on the stack | 763 // Exit with OutOfMemory exception. There is not enough space on the stack |
764 // for our working registers. | 764 // for our working registers. |
765 __ movq(rax, Immediate(EXCEPTION)); | 765 __ Set(rax, EXCEPTION); |
766 __ jmp(&exit_label_); | 766 __ jmp(&exit_label_); |
767 | 767 |
768 __ bind(&stack_limit_hit); | 768 __ bind(&stack_limit_hit); |
769 __ Move(code_object_pointer(), masm_.CodeObject()); | 769 __ Move(code_object_pointer(), masm_.CodeObject()); |
770 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. | 770 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. |
771 __ testq(rax, rax); | 771 __ testq(rax, rax); |
772 // If returned value is non-zero, we exit with the returned value as result. | 772 // If returned value is non-zero, we exit with the returned value as result. |
773 __ j(not_zero, &exit_label_); | 773 __ j(not_zero, &exit_label_); |
774 | 774 |
775 __ bind(&stack_ok); | 775 __ bind(&stack_ok); |
(...skipping 16 matching lines...) Expand all Loading... |
792 __ lea(rax, Operand(rdi, rbx, times_1, -char_size())); | 792 __ lea(rax, Operand(rdi, rbx, times_1, -char_size())); |
793 } | 793 } |
794 // Store this value in a local variable, for use when clearing | 794 // Store this value in a local variable, for use when clearing |
795 // position registers. | 795 // position registers. |
796 __ movq(Operand(rbp, kInputStartMinusOne), rax); | 796 __ movq(Operand(rbp, kInputStartMinusOne), rax); |
797 | 797 |
798 if (num_saved_registers_ > 0) { | 798 if (num_saved_registers_ > 0) { |
799 // Fill saved registers with initial value = start offset - 1 | 799 // Fill saved registers with initial value = start offset - 1 |
800 // Fill in stack push order, to avoid accessing across an unwritten | 800 // Fill in stack push order, to avoid accessing across an unwritten |
801 // page (a problem on Windows). | 801 // page (a problem on Windows). |
802 __ movq(rcx, Immediate(kRegisterZero)); | 802 __ Set(rcx, kRegisterZero); |
803 Label init_loop; | 803 Label init_loop; |
804 __ bind(&init_loop); | 804 __ bind(&init_loop); |
805 __ movq(Operand(rbp, rcx, times_1, 0), rax); | 805 __ movq(Operand(rbp, rcx, times_1, 0), rax); |
806 __ subq(rcx, Immediate(kPointerSize)); | 806 __ subq(rcx, Immediate(kPointerSize)); |
807 __ cmpq(rcx, | 807 __ cmpq(rcx, |
808 Immediate(kRegisterZero - num_saved_registers_ * kPointerSize)); | 808 Immediate(kRegisterZero - num_saved_registers_ * kPointerSize)); |
809 __ j(greater, &init_loop); | 809 __ j(greater, &init_loop); |
810 } | 810 } |
811 // Ensure that we have written to each stack page, in order. Skipping a page | 811 // Ensure that we have written to each stack page, in order. Skipping a page |
812 // on Windows can cause segmentation faults. Assuming page size is 4k. | 812 // on Windows can cause segmentation faults. Assuming page size is 4k. |
813 const int kPageSize = 4096; | 813 const int kPageSize = 4096; |
814 const int kRegistersPerPage = kPageSize / kPointerSize; | 814 const int kRegistersPerPage = kPageSize / kPointerSize; |
815 for (int i = num_saved_registers_ + kRegistersPerPage - 1; | 815 for (int i = num_saved_registers_ + kRegistersPerPage - 1; |
816 i < num_registers_; | 816 i < num_registers_; |
817 i += kRegistersPerPage) { | 817 i += kRegistersPerPage) { |
818 __ movq(register_location(i), rax); // One write every page. | 818 __ movq(register_location(i), rax); // One write every page. |
819 } | 819 } |
820 | 820 |
821 // Initialize backtrack stack pointer. | 821 // Initialize backtrack stack pointer. |
822 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); | 822 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); |
823 // Initialize code object pointer. | 823 // Initialize code object pointer. |
824 __ Move(code_object_pointer(), masm_.CodeObject()); | 824 __ Move(code_object_pointer(), masm_.CodeObject()); |
825 // Load previous char as initial value of current-character. | 825 // Load previous char as initial value of current-character. |
826 Label at_start; | 826 Label at_start; |
827 __ cmpb(Operand(rbp, kStartIndex), Immediate(0)); | 827 __ cmpb(Operand(rbp, kStartIndex), Immediate(0)); |
828 __ j(equal, &at_start); | 828 __ j(equal, &at_start); |
829 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. | 829 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. |
830 __ jmp(&start_label_); | 830 __ jmp(&start_label_); |
831 __ bind(&at_start); | 831 __ bind(&at_start); |
832 __ movq(current_character(), Immediate('\n')); | 832 __ Set(current_character(), '\n'); |
833 __ jmp(&start_label_); | 833 __ jmp(&start_label_); |
834 | 834 |
835 | 835 |
836 // Exit code: | 836 // Exit code: |
837 if (success_label_.is_linked()) { | 837 if (success_label_.is_linked()) { |
838 // Save captures when successful. | 838 // Save captures when successful. |
839 __ bind(&success_label_); | 839 __ bind(&success_label_); |
840 if (num_saved_registers_ > 0) { | 840 if (num_saved_registers_ > 0) { |
841 // copy captures to output | 841 // copy captures to output |
842 __ movq(rdx, Operand(rbp, kStartIndex)); | 842 __ movq(rdx, Operand(rbp, kStartIndex)); |
843 __ movq(rbx, Operand(rbp, kRegisterOutput)); | 843 __ movq(rbx, Operand(rbp, kRegisterOutput)); |
844 __ movq(rcx, Operand(rbp, kInputEnd)); | 844 __ movq(rcx, Operand(rbp, kInputEnd)); |
845 __ subq(rcx, Operand(rbp, kInputStart)); | 845 __ subq(rcx, Operand(rbp, kInputStart)); |
846 if (mode_ == UC16) { | 846 if (mode_ == UC16) { |
847 __ lea(rcx, Operand(rcx, rdx, times_2, 0)); | 847 __ lea(rcx, Operand(rcx, rdx, times_2, 0)); |
848 } else { | 848 } else { |
849 __ addq(rcx, rdx); | 849 __ addq(rcx, rdx); |
850 } | 850 } |
851 for (int i = 0; i < num_saved_registers_; i++) { | 851 for (int i = 0; i < num_saved_registers_; i++) { |
852 __ movq(rax, register_location(i)); | 852 __ movq(rax, register_location(i)); |
853 __ addq(rax, rcx); // Convert to index from start, not end. | 853 __ addq(rax, rcx); // Convert to index from start, not end. |
854 if (mode_ == UC16) { | 854 if (mode_ == UC16) { |
855 __ sar(rax, Immediate(1)); // Convert byte index to character index. | 855 __ sar(rax, Immediate(1)); // Convert byte index to character index. |
856 } | 856 } |
857 __ movl(Operand(rbx, i * kIntSize), rax); | 857 __ movl(Operand(rbx, i * kIntSize), rax); |
858 } | 858 } |
859 } | 859 } |
860 __ movq(rax, Immediate(SUCCESS)); | 860 __ Set(rax, SUCCESS); |
861 } | 861 } |
862 | 862 |
863 // Exit and return rax | 863 // Exit and return rax |
864 __ bind(&exit_label_); | 864 __ bind(&exit_label_); |
865 | 865 |
866 #ifdef _WIN64 | 866 #ifdef _WIN64 |
867 // Restore callee save registers. | 867 // Restore callee save registers. |
868 __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister)); | 868 __ lea(rsp, Operand(rbp, kLastCalleeSaveRegister)); |
869 __ pop(rbx); | 869 __ pop(rbx); |
870 __ pop(rdi); | 870 __ pop(rdi); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 __ pop(rdi); | 952 __ pop(rdi); |
953 __ pop(rsi); | 953 __ pop(rsi); |
954 #endif | 954 #endif |
955 SafeReturn(); | 955 SafeReturn(); |
956 } | 956 } |
957 | 957 |
958 if (exit_with_exception.is_linked()) { | 958 if (exit_with_exception.is_linked()) { |
959 // If any of the code above needed to exit with an exception. | 959 // If any of the code above needed to exit with an exception. |
960 __ bind(&exit_with_exception); | 960 __ bind(&exit_with_exception); |
961 // Exit with Result EXCEPTION(-1) to signal thrown exception. | 961 // Exit with Result EXCEPTION(-1) to signal thrown exception. |
962 __ movq(rax, Immediate(EXCEPTION)); | 962 __ Set(rax, EXCEPTION); |
963 __ jmp(&exit_label_); | 963 __ jmp(&exit_label_); |
964 } | 964 } |
965 | 965 |
966 FixupCodeRelativePositions(); | 966 FixupCodeRelativePositions(); |
967 | 967 |
968 CodeDesc code_desc; | 968 CodeDesc code_desc; |
969 masm_.GetCode(&code_desc); | 969 masm_.GetCode(&code_desc); |
970 Isolate* isolate = ISOLATE; | 970 Isolate* isolate = ISOLATE; |
971 Handle<Code> code = isolate->factory()->NewCode( | 971 Handle<Code> code = isolate->factory()->NewCode( |
972 code_desc, Code::ComputeFlags(Code::REGEXP), | 972 code_desc, Code::ComputeFlags(Code::REGEXP), |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1389 } | 1389 } |
1390 } | 1390 } |
1391 | 1391 |
1392 #undef __ | 1392 #undef __ |
1393 | 1393 |
1394 #endif // V8_INTERPRETED_REGEXP | 1394 #endif // V8_INTERPRETED_REGEXP |
1395 | 1395 |
1396 }} // namespace v8::internal | 1396 }} // namespace v8::internal |
1397 | 1397 |
1398 #endif // V8_TARGET_ARCH_X64 | 1398 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |