| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 // Load RegExp data. | 686 // Load RegExp data. |
| 687 __ bind(&success); | 687 __ bind(&success); |
| 688 __ movp(rax, args.GetArgumentOperand(JS_REG_EXP_OBJECT_ARGUMENT_INDEX)); | 688 __ movp(rax, args.GetArgumentOperand(JS_REG_EXP_OBJECT_ARGUMENT_INDEX)); |
| 689 __ movp(rcx, FieldOperand(rax, JSRegExp::kDataOffset)); | 689 __ movp(rcx, FieldOperand(rax, JSRegExp::kDataOffset)); |
| 690 __ SmiToInteger32(rax, | 690 __ SmiToInteger32(rax, |
| 691 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset)); | 691 FieldOperand(rcx, JSRegExp::kIrregexpCaptureCountOffset)); |
| 692 // Calculate number of capture registers (number_of_captures + 1) * 2. | 692 // Calculate number of capture registers (number_of_captures + 1) * 2. |
| 693 __ leal(rdx, Operand(rax, rax, times_1, 2)); | 693 __ leal(rdx, Operand(rax, rax, times_1, 2)); |
| 694 | 694 |
| 695 // rdx: Number of capture registers | 695 // rdx: Number of capture registers |
| 696 // Check that the fourth object is a JSObject. | 696 // Check that the last match info is a FixedArray. |
| 697 __ movp(r15, args.GetArgumentOperand(LAST_MATCH_INFO_ARGUMENT_INDEX)); | 697 __ movp(rbx, args.GetArgumentOperand(LAST_MATCH_INFO_ARGUMENT_INDEX)); |
| 698 __ JumpIfSmi(r15, &runtime); | 698 __ JumpIfSmi(rbx, &runtime); |
| 699 __ CmpObjectType(r15, JS_OBJECT_TYPE, kScratchRegister); | |
| 700 __ j(not_equal, &runtime); | |
| 701 // Check that the object has fast elements. | 699 // Check that the object has fast elements. |
| 702 __ movp(rbx, FieldOperand(r15, JSArray::kElementsOffset)); | |
| 703 __ movp(rax, FieldOperand(rbx, HeapObject::kMapOffset)); | 700 __ movp(rax, FieldOperand(rbx, HeapObject::kMapOffset)); |
| 704 __ CompareRoot(rax, Heap::kFixedArrayMapRootIndex); | 701 __ CompareRoot(rax, Heap::kFixedArrayMapRootIndex); |
| 705 __ j(not_equal, &runtime); | 702 __ j(not_equal, &runtime); |
| 706 // Check that the last match info has space for the capture registers and the | 703 // Check that the last match info has space for the capture registers and the |
| 707 // additional information. Ensure no overflow in add. | 704 // additional information. Ensure no overflow in add. |
| 708 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); | 705 STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); |
| 709 __ SmiToInteger32(rax, FieldOperand(rbx, FixedArray::kLengthOffset)); | 706 __ SmiToInteger32(rax, FieldOperand(rbx, FixedArray::kLengthOffset)); |
| 710 __ subl(rax, Immediate(RegExpImpl::kLastMatchOverhead)); | 707 __ subl(rax, Immediate(RegExpMatchInfo::kLastMatchOverhead)); |
| 711 __ cmpl(rdx, rax); | 708 __ cmpl(rdx, rax); |
| 712 __ j(greater, &runtime); | 709 __ j(greater, &runtime); |
| 713 | 710 |
| 714 // rbx: last_match_info backing store (FixedArray) | 711 // rbx: last_match_info (FixedArray) |
| 715 // rdx: number of capture registers | 712 // rdx: number of capture registers |
| 716 // Store the capture count. | 713 // Store the capture count. |
| 717 __ Integer32ToSmi(kScratchRegister, rdx); | 714 __ Integer32ToSmi(kScratchRegister, rdx); |
| 718 __ movp(FieldOperand(rbx, RegExpImpl::kLastCaptureCountOffset), | 715 __ movp(FieldOperand(rbx, RegExpMatchInfo::kNumberOfCapturesOffset), |
| 719 kScratchRegister); | 716 kScratchRegister); |
| 720 // Store last subject and last input. | 717 // Store last subject and last input. |
| 721 __ movp(rax, args.GetArgumentOperand(SUBJECT_STRING_ARGUMENT_INDEX)); | 718 __ movp(rax, args.GetArgumentOperand(SUBJECT_STRING_ARGUMENT_INDEX)); |
| 722 __ movp(FieldOperand(rbx, RegExpImpl::kLastSubjectOffset), rax); | 719 __ movp(FieldOperand(rbx, RegExpMatchInfo::kLastSubjectOffset), rax); |
| 723 __ movp(rcx, rax); | 720 __ movp(rcx, rax); |
| 724 __ RecordWriteField(rbx, | 721 __ RecordWriteField(rbx, RegExpMatchInfo::kLastSubjectOffset, rax, rdi, |
| 725 RegExpImpl::kLastSubjectOffset, | |
| 726 rax, | |
| 727 rdi, | |
| 728 kDontSaveFPRegs); | 722 kDontSaveFPRegs); |
| 729 __ movp(rax, rcx); | 723 __ movp(rax, rcx); |
| 730 __ movp(FieldOperand(rbx, RegExpImpl::kLastInputOffset), rax); | 724 __ movp(FieldOperand(rbx, RegExpMatchInfo::kLastInputOffset), rax); |
| 731 __ RecordWriteField(rbx, | 725 __ RecordWriteField(rbx, RegExpMatchInfo::kLastInputOffset, rax, rdi, |
| 732 RegExpImpl::kLastInputOffset, | |
| 733 rax, | |
| 734 rdi, | |
| 735 kDontSaveFPRegs); | 726 kDontSaveFPRegs); |
| 736 | 727 |
| 737 // Get the static offsets vector filled by the native regexp code. | 728 // Get the static offsets vector filled by the native regexp code. |
| 738 __ LoadAddress( | 729 __ LoadAddress( |
| 739 rcx, ExternalReference::address_of_static_offsets_vector(isolate())); | 730 rcx, ExternalReference::address_of_static_offsets_vector(isolate())); |
| 740 | 731 |
| 741 // rbx: last_match_info backing store (FixedArray) | 732 // rbx: last_match_info (FixedArray) |
| 742 // rcx: offsets vector | 733 // rcx: offsets vector |
| 743 // rdx: number of capture registers | 734 // rdx: number of capture registers |
| 744 Label next_capture, done; | 735 Label next_capture, done; |
| 745 // Capture register counter starts from number of capture registers and | 736 // Capture register counter starts from number of capture registers and |
| 746 // counts down until wraping after zero. | 737 // counts down until wrapping after zero. |
| 747 __ bind(&next_capture); | 738 __ bind(&next_capture); |
| 748 __ subp(rdx, Immediate(1)); | 739 __ subp(rdx, Immediate(1)); |
| 749 __ j(negative, &done, Label::kNear); | 740 __ j(negative, &done, Label::kNear); |
| 750 // Read the value from the static offsets vector buffer and make it a smi. | 741 // Read the value from the static offsets vector buffer and make it a smi. |
| 751 __ movl(rdi, Operand(rcx, rdx, times_int_size, 0)); | 742 __ movl(rdi, Operand(rcx, rdx, times_int_size, 0)); |
| 752 __ Integer32ToSmi(rdi, rdi); | 743 __ Integer32ToSmi(rdi, rdi); |
| 753 // Store the smi value in the last match info. | 744 // Store the smi value in the last match info. |
| 754 __ movp(FieldOperand(rbx, | 745 __ movp(FieldOperand(rbx, rdx, times_pointer_size, |
| 755 rdx, | 746 RegExpMatchInfo::kFirstCaptureOffset), |
| 756 times_pointer_size, | |
| 757 RegExpImpl::kFirstCaptureOffset), | |
| 758 rdi); | 747 rdi); |
| 759 __ jmp(&next_capture); | 748 __ jmp(&next_capture); |
| 760 __ bind(&done); | 749 __ bind(&done); |
| 761 | 750 |
| 762 // Return last match info. | 751 // Return last match info. |
| 763 __ movp(rax, r15); | 752 __ movp(rax, rbx); |
| 764 __ ret(REG_EXP_EXEC_ARGUMENT_COUNT * kPointerSize); | 753 __ ret(REG_EXP_EXEC_ARGUMENT_COUNT * kPointerSize); |
| 765 | 754 |
| 766 __ bind(&exception); | 755 __ bind(&exception); |
| 767 // Result must now be exception. If there is no pending exception already a | 756 // Result must now be exception. If there is no pending exception already a |
| 768 // stack overflow (on the backtrack stack) was detected in RegExp code but | 757 // stack overflow (on the backtrack stack) was detected in RegExp code but |
| 769 // haven't created the exception yet. Handle that in the runtime system. | 758 // haven't created the exception yet. Handle that in the runtime system. |
| 770 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 759 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
| 771 ExternalReference pending_exception_address( | 760 ExternalReference pending_exception_address( |
| 772 Isolate::kPendingExceptionAddress, isolate()); | 761 Isolate::kPendingExceptionAddress, isolate()); |
| 773 Operand pending_exception_operand = | 762 Operand pending_exception_operand = |
| (...skipping 3857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4631 kStackUnwindSpace, nullptr, return_value_operand, | 4620 kStackUnwindSpace, nullptr, return_value_operand, |
| 4632 NULL); | 4621 NULL); |
| 4633 } | 4622 } |
| 4634 | 4623 |
| 4635 #undef __ | 4624 #undef __ |
| 4636 | 4625 |
| 4637 } // namespace internal | 4626 } // namespace internal |
| 4638 } // namespace v8 | 4627 } // namespace v8 |
| 4639 | 4628 |
| 4640 #endif // V8_TARGET_ARCH_X64 | 4629 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |