Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 1901573003: [regexp] do not assume short external strings have a minimum size. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: mips port. functional mips64 port not available yet. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | test/cctest/cctest.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 // Or number_of_captures <= offsets vector size / 2 - 1 637 // Or number_of_captures <= offsets vector size / 2 - 1
638 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2); 638 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
639 __ cmpl(rdx, Immediate(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1)); 639 __ cmpl(rdx, Immediate(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1));
640 __ j(above, &runtime); 640 __ j(above, &runtime);
641 641
642 // Reset offset for possibly sliced string. 642 // Reset offset for possibly sliced string.
643 __ Set(r14, 0); 643 __ Set(r14, 0);
644 __ movp(rdi, args.GetArgumentOperand(SUBJECT_STRING_ARGUMENT_INDEX)); 644 __ movp(rdi, args.GetArgumentOperand(SUBJECT_STRING_ARGUMENT_INDEX));
645 __ JumpIfSmi(rdi, &runtime); 645 __ JumpIfSmi(rdi, &runtime);
646 __ movp(r15, rdi); // Make a copy of the original subject string. 646 __ movp(r15, rdi); // Make a copy of the original subject string.
647 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
648 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
649 // rax: RegExp data (FixedArray) 647 // rax: RegExp data (FixedArray)
650 // rdi: subject string 648 // rdi: subject string
651 // r15: subject string 649 // r15: subject string
652 // Handle subject string according to its encoding and representation: 650 // Handle subject string according to its encoding and representation:
653 // (1) Sequential two byte? If yes, go to (9). 651 // (1) Sequential two byte? If yes, go to (9).
654 // (2) Sequential one byte? If yes, go to (6). 652 // (2) Sequential one byte? If yes, go to (5).
655 // (3) Anything but sequential or cons? If yes, go to (7). 653 // (3) Sequential or cons? If not, go to (6).
656 // (4) Cons string. If the string is flat, replace subject with first string. 654 // (4) Cons string. If the string is flat, replace subject with first string
657 // Otherwise bailout. 655 // and go to (1). Otherwise bail out to runtime.
658 // (5a) Is subject sequential two byte? If yes, go to (9). 656 // (5) One byte sequential. Load regexp code for one byte.
659 // (5b) Is subject external? If yes, go to (8).
660 // (6) One byte sequential. Load regexp code for one byte.
661 // (E) Carry on. 657 // (E) Carry on.
662 /// [...] 658 /// [...]
663 659
664 // Deferred code at the end of the stub: 660 // Deferred code at the end of the stub:
665 // (7) Not a long external string? If yes, go to (10). 661 // (6) Long external string? If not, go to (10).
666 // (8) External string. Make it, offset-wise, look like a sequential string. 662 // (7) External string. Make it, offset-wise, look like a sequential string.
667 // (8a) Is the external string one byte? If yes, go to (6). 663 // (8) Is the external string one byte? If yes, go to (5).
668 // (9) Two byte sequential. Load regexp code for one byte. Go to (E). 664 // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
669 // (10) Short external string or not a string? If yes, bail out to runtime. 665 // (10) Short external string or not a string? If yes, bail out to runtime.
670 // (11) Sliced string. Replace subject with parent. Go to (5a). 666 // (11) Sliced string. Replace subject with parent. Go to (1).
671 667
672 Label seq_one_byte_string /* 6 */, seq_two_byte_string /* 9 */, 668 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */,
673 external_string /* 8 */, check_underlying /* 5a */, 669 external_string /* 7 */, check_underlying /* 1 */,
674 not_seq_nor_cons /* 7 */, check_code /* E */, 670 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */;
675 not_long_external /* 10 */; 671
672 __ bind(&check_underlying);
673 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
674 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
676 675
677 // (1) Sequential two byte? If yes, go to (9). 676 // (1) Sequential two byte? If yes, go to (9).
678 __ andb(rbx, Immediate(kIsNotStringMask | 677 __ andb(rbx, Immediate(kIsNotStringMask |
679 kStringRepresentationMask | 678 kStringRepresentationMask |
680 kStringEncodingMask | 679 kStringEncodingMask |
681 kShortExternalStringMask)); 680 kShortExternalStringMask));
682 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 681 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
683 __ j(zero, &seq_two_byte_string); // Go to (9). 682 __ j(zero, &seq_two_byte_string); // Go to (9).
684 683
685 // (2) Sequential one byte? If yes, go to (6). 684 // (2) Sequential one byte? If yes, go to (5).
686 // Any other sequential string must be one byte. 685 // Any other sequential string must be one byte.
687 __ andb(rbx, Immediate(kIsNotStringMask | 686 __ andb(rbx, Immediate(kIsNotStringMask |
688 kStringRepresentationMask | 687 kStringRepresentationMask |
689 kShortExternalStringMask)); 688 kShortExternalStringMask));
690 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (6). 689 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5).
691 690
692 // (3) Anything but sequential or cons? If yes, go to (7). 691 // (3) Sequential or cons? If not, go to (6).
693 // We check whether the subject string is a cons, since sequential strings 692 // We check whether the subject string is a cons, since sequential strings
694 // have already been covered. 693 // have already been covered.
695 STATIC_ASSERT(kConsStringTag < kExternalStringTag); 694 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
696 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); 695 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
697 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); 696 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
698 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); 697 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
699 __ cmpp(rbx, Immediate(kExternalStringTag)); 698 __ cmpp(rbx, Immediate(kExternalStringTag));
700 __ j(greater_equal, &not_seq_nor_cons); // Go to (7). 699 __ j(greater_equal, &not_seq_nor_cons); // Go to (6).
701 700
702 // (4) Cons string. Check that it's flat. 701 // (4) Cons string. Check that it's flat.
703 // Replace subject with first string and reload instance type. 702 // Replace subject with first string and reload instance type.
704 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset), 703 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset),
705 Heap::kempty_stringRootIndex); 704 Heap::kempty_stringRootIndex);
706 __ j(not_equal, &runtime); 705 __ j(not_equal, &runtime);
707 __ movp(rdi, FieldOperand(rdi, ConsString::kFirstOffset)); 706 __ movp(rdi, FieldOperand(rdi, ConsString::kFirstOffset));
708 __ bind(&check_underlying); 707 __ jmp(&check_underlying);
709 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
710 __ movp(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
711 708
712 // (5a) Is subject sequential two byte? If yes, go to (9). 709 // (5) One byte sequential. Load regexp code for one byte.
713 __ testb(rbx, Immediate(kStringRepresentationMask | kStringEncodingMask));
714 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
715 __ j(zero, &seq_two_byte_string); // Go to (9).
716 // (5b) Is subject external? If yes, go to (8).
717 __ testb(rbx, Immediate(kStringRepresentationMask));
718 // The underlying external string is never a short external string.
719 STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
720 STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
721 __ j(not_zero, &external_string); // Go to (8)
722
723 // (6) One byte sequential. Load regexp code for one byte.
724 __ bind(&seq_one_byte_string); 710 __ bind(&seq_one_byte_string);
725 // rax: RegExp data (FixedArray) 711 // rax: RegExp data (FixedArray)
726 __ movp(r11, FieldOperand(rax, JSRegExp::kDataOneByteCodeOffset)); 712 __ movp(r11, FieldOperand(rax, JSRegExp::kDataOneByteCodeOffset));
727 __ Set(rcx, 1); // Type is one byte. 713 __ Set(rcx, 1); // Type is one byte.
728 714
729 // (E) Carry on. String handling is done. 715 // (E) Carry on. String handling is done.
730 __ bind(&check_code); 716 __ bind(&check_code);
731 // r11: irregexp code 717 // r11: irregexp code
732 // Check that the irregexp code has been generated for the actual string 718 // Check that the irregexp code has been generated for the actual string
733 // encoding. If it has, the field contains a code object otherwise it contains 719 // encoding. If it has, the field contains a code object otherwise it contains
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 __ j(equal, &runtime); 946 __ j(equal, &runtime);
961 947
962 // For exception, throw the exception again. 948 // For exception, throw the exception again.
963 __ TailCallRuntime(Runtime::kRegExpExecReThrow); 949 __ TailCallRuntime(Runtime::kRegExpExecReThrow);
964 950
965 // Do the runtime call to execute the regexp. 951 // Do the runtime call to execute the regexp.
966 __ bind(&runtime); 952 __ bind(&runtime);
967 __ TailCallRuntime(Runtime::kRegExpExec); 953 __ TailCallRuntime(Runtime::kRegExpExec);
968 954
969 // Deferred code for string handling. 955 // Deferred code for string handling.
970 // (7) Not a long external string? If yes, go to (10). 956 // (6) Long external string? If not, go to (10).
971 __ bind(&not_seq_nor_cons); 957 __ bind(&not_seq_nor_cons);
972 // Compare flags are still set from (3). 958 // Compare flags are still set from (3).
973 __ j(greater, &not_long_external, Label::kNear); // Go to (10). 959 __ j(greater, &not_long_external, Label::kNear); // Go to (10).
974 960
975 // (8) External string. Short external strings have been ruled out. 961 // (7) External string. Short external strings have been ruled out.
976 __ bind(&external_string); 962 __ bind(&external_string);
977 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 963 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
978 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 964 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
979 if (FLAG_debug_code) { 965 if (FLAG_debug_code) {
980 // Assert that we do not have a cons or slice (indirect strings) here. 966 // Assert that we do not have a cons or slice (indirect strings) here.
981 // Sequential strings have already been ruled out. 967 // Sequential strings have already been ruled out.
982 __ testb(rbx, Immediate(kIsIndirectStringMask)); 968 __ testb(rbx, Immediate(kIsIndirectStringMask));
983 __ Assert(zero, kExternalStringExpectedButNotFound); 969 __ Assert(zero, kExternalStringExpectedButNotFound);
984 } 970 }
985 __ movp(rdi, FieldOperand(rdi, ExternalString::kResourceDataOffset)); 971 __ movp(rdi, FieldOperand(rdi, ExternalString::kResourceDataOffset));
986 // Move the pointer so that offset-wise, it looks like a sequential string. 972 // Move the pointer so that offset-wise, it looks like a sequential string.
987 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 973 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
988 __ subp(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 974 __ subp(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
989 STATIC_ASSERT(kTwoByteStringTag == 0); 975 STATIC_ASSERT(kTwoByteStringTag == 0);
990 // (8a) Is the external string one byte? If yes, go to (6). 976 // (8) Is the external string one byte? If yes, go to (5).
991 __ testb(rbx, Immediate(kStringEncodingMask)); 977 __ testb(rbx, Immediate(kStringEncodingMask));
992 __ j(not_zero, &seq_one_byte_string); // Goto (6). 978 __ j(not_zero, &seq_one_byte_string); // Go to (5).
993 979
994 // rdi: subject string (flat two-byte) 980 // rdi: subject string (flat two-byte)
995 // rax: RegExp data (FixedArray) 981 // rax: RegExp data (FixedArray)
996 // (9) Two byte sequential. Load regexp code for one byte. Go to (E). 982 // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
997 __ bind(&seq_two_byte_string); 983 __ bind(&seq_two_byte_string);
998 __ movp(r11, FieldOperand(rax, JSRegExp::kDataUC16CodeOffset)); 984 __ movp(r11, FieldOperand(rax, JSRegExp::kDataUC16CodeOffset));
999 __ Set(rcx, 0); // Type is two byte. 985 __ Set(rcx, 0); // Type is two byte.
1000 __ jmp(&check_code); // Go to (E). 986 __ jmp(&check_code); // Go to (E).
1001 987
1002 // (10) Not a string or a short external string? If yes, bail out to runtime. 988 // (10) Not a string or a short external string? If yes, bail out to runtime.
1003 __ bind(&not_long_external); 989 __ bind(&not_long_external);
1004 // Catch non-string subject or short external string. 990 // Catch non-string subject or short external string.
1005 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); 991 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
1006 __ testb(rbx, Immediate(kIsNotStringMask | kShortExternalStringMask)); 992 __ testb(rbx, Immediate(kIsNotStringMask | kShortExternalStringMask));
1007 __ j(not_zero, &runtime); 993 __ j(not_zero, &runtime);
1008 994
1009 // (11) Sliced string. Replace subject with parent. Go to (5a). 995 // (11) Sliced string. Replace subject with parent. Go to (1).
1010 // Load offset into r14 and replace subject string with parent. 996 // Load offset into r14 and replace subject string with parent.
1011 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset)); 997 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset));
1012 __ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset)); 998 __ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset));
1013 __ jmp(&check_underlying); 999 __ jmp(&check_underlying);
1014 #endif // V8_INTERPRETED_REGEXP 1000 #endif // V8_INTERPRETED_REGEXP
1015 } 1001 }
1016 1002
1017 1003
1018 static int NegativeComparisonResult(Condition cc) { 1004 static int NegativeComparisonResult(Condition cc) {
1019 DCHECK(cc != equal); 1005 DCHECK(cc != equal);
(...skipping 4565 matching lines...) Expand 10 before | Expand all | Expand 10 after
5585 kStackUnwindSpace, nullptr, return_value_operand, 5571 kStackUnwindSpace, nullptr, return_value_operand,
5586 NULL); 5572 NULL);
5587 } 5573 }
5588 5574
5589 #undef __ 5575 #undef __
5590 5576
5591 } // namespace internal 5577 } // namespace internal
5592 } // namespace v8 5578 } // namespace v8
5593 5579
5594 #endif // V8_TARGET_ARCH_X64 5580 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/cctest/cctest.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698