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

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

Issue 1927003003: Version 5.0.71.40 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@5.0
Patch Set: Created 4 years, 7 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/x64/code-stubs-x64.cc ('k') | test/cctest/test-regexp.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 493 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
494 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2); 494 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
495 __ cmp(edx, Isolate::kJSRegexpStaticOffsetsVectorSize - 2); 495 __ cmp(edx, Isolate::kJSRegexpStaticOffsetsVectorSize - 2);
496 __ j(above, &runtime); 496 __ j(above, &runtime);
497 497
498 // Reset offset for possibly sliced string. 498 // Reset offset for possibly sliced string.
499 __ Move(edi, Immediate(0)); 499 __ Move(edi, Immediate(0));
500 __ mov(eax, Operand(esp, kSubjectOffset)); 500 __ mov(eax, Operand(esp, kSubjectOffset));
501 __ JumpIfSmi(eax, &runtime); 501 __ JumpIfSmi(eax, &runtime);
502 __ mov(edx, eax); // Make a copy of the original subject string. 502 __ mov(edx, eax); // Make a copy of the original subject string.
503 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
504 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
505 503
506 // eax: subject string 504 // eax: subject string
507 // edx: subject string 505 // edx: subject string
508 // ebx: subject string instance type
509 // ecx: RegExp data (FixedArray) 506 // ecx: RegExp data (FixedArray)
510 // Handle subject string according to its encoding and representation: 507 // Handle subject string according to its encoding and representation:
511 // (1) Sequential two byte? If yes, go to (9). 508 // (1) Sequential two byte? If yes, go to (9).
512 // (2) Sequential one byte? If yes, go to (6). 509 // (2) Sequential one byte? If yes, go to (5).
513 // (3) Anything but sequential or cons? If yes, go to (7). 510 // (3) Sequential or cons? If not, go to (6).
514 // (4) Cons string. If the string is flat, replace subject with first string. 511 // (4) Cons string. If the string is flat, replace subject with first string
515 // Otherwise bailout. 512 // and go to (1). Otherwise bail out to runtime.
516 // (5a) Is subject sequential two byte? If yes, go to (9). 513 // (5) One byte sequential. Load regexp code for one byte.
517 // (5b) Is subject external? If yes, go to (8).
518 // (6) One byte sequential. Load regexp code for one byte.
519 // (E) Carry on. 514 // (E) Carry on.
520 /// [...] 515 /// [...]
521 516
522 // Deferred code at the end of the stub: 517 // Deferred code at the end of the stub:
523 // (7) Not a long external string? If yes, go to (10). 518 // (6) Long external string? If not, go to (10).
524 // (8) External string. Make it, offset-wise, look like a sequential string. 519 // (7) External string. Make it, offset-wise, look like a sequential string.
525 // (8a) Is the external string one byte? If yes, go to (6). 520 // (8) Is the external string one byte? If yes, go to (5).
526 // (9) Two byte sequential. Load regexp code for one byte. Go to (E). 521 // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
527 // (10) Short external string or not a string? If yes, bail out to runtime. 522 // (10) Short external string or not a string? If yes, bail out to runtime.
528 // (11) Sliced string. Replace subject with parent. Go to (5a). 523 // (11) Sliced string. Replace subject with parent. Go to (1).
529 524
530 Label seq_one_byte_string /* 6 */, seq_two_byte_string /* 9 */, 525 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */,
531 external_string /* 8 */, check_underlying /* 5a */, 526 external_string /* 7 */, check_underlying /* 1 */,
532 not_seq_nor_cons /* 7 */, check_code /* E */, 527 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */;
533 not_long_external /* 10 */;
534 528
529 __ bind(&check_underlying);
535 // (1) Sequential two byte? If yes, go to (9). 530 // (1) Sequential two byte? If yes, go to (9).
531 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
532 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
533
536 __ and_(ebx, kIsNotStringMask | 534 __ and_(ebx, kIsNotStringMask |
537 kStringRepresentationMask | 535 kStringRepresentationMask |
538 kStringEncodingMask | 536 kStringEncodingMask |
539 kShortExternalStringMask); 537 kShortExternalStringMask);
540 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 538 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
541 __ j(zero, &seq_two_byte_string); // Go to (9). 539 __ j(zero, &seq_two_byte_string); // Go to (9).
542 540
543 // (2) Sequential one byte? If yes, go to (6). 541 // (2) Sequential one byte? If yes, go to (5).
544 // Any other sequential string must be one byte. 542 // Any other sequential string must be one byte.
545 __ and_(ebx, Immediate(kIsNotStringMask | 543 __ and_(ebx, Immediate(kIsNotStringMask |
546 kStringRepresentationMask | 544 kStringRepresentationMask |
547 kShortExternalStringMask)); 545 kShortExternalStringMask));
548 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (6). 546 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5).
549 547
550 // (3) Anything but sequential or cons? If yes, go to (7). 548 // (3) Sequential or cons? If not, go to (6).
551 // We check whether the subject string is a cons, since sequential strings 549 // We check whether the subject string is a cons, since sequential strings
552 // have already been covered. 550 // have already been covered.
553 STATIC_ASSERT(kConsStringTag < kExternalStringTag); 551 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
554 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); 552 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
555 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); 553 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
556 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); 554 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
557 __ cmp(ebx, Immediate(kExternalStringTag)); 555 __ cmp(ebx, Immediate(kExternalStringTag));
558 __ j(greater_equal, &not_seq_nor_cons); // Go to (7). 556 __ j(greater_equal, &not_seq_nor_cons); // Go to (6).
559 557
560 // (4) Cons string. Check that it's flat. 558 // (4) Cons string. Check that it's flat.
561 // Replace subject with first string and reload instance type. 559 // Replace subject with first string and reload instance type.
562 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string()); 560 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string());
563 __ j(not_equal, &runtime); 561 __ j(not_equal, &runtime);
564 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); 562 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
565 __ bind(&check_underlying); 563 __ jmp(&check_underlying);
566 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
567 __ mov(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
568
569 // (5a) Is subject sequential two byte? If yes, go to (9).
570 __ test_b(ebx, kStringRepresentationMask | kStringEncodingMask);
571 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
572 __ j(zero, &seq_two_byte_string); // Go to (9).
573 // (5b) Is subject external? If yes, go to (8).
574 __ test_b(ebx, kStringRepresentationMask);
575 // The underlying external string is never a short external string.
576 STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
577 STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
578 __ j(not_zero, &external_string); // Go to (8).
579 564
580 // eax: sequential subject string (or look-alike, external string) 565 // eax: sequential subject string (or look-alike, external string)
581 // edx: original subject string 566 // edx: original subject string
582 // ecx: RegExp data (FixedArray) 567 // ecx: RegExp data (FixedArray)
583 // (6) One byte sequential. Load regexp code for one byte. 568 // (5) One byte sequential. Load regexp code for one byte.
584 __ bind(&seq_one_byte_string); 569 __ bind(&seq_one_byte_string);
585 // Load previous index and check range before edx is overwritten. We have 570 // Load previous index and check range before edx is overwritten. We have
586 // to use edx instead of eax here because it might have been only made to 571 // to use edx instead of eax here because it might have been only made to
587 // look like a sequential string when it actually is an external string. 572 // look like a sequential string when it actually is an external string.
588 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); 573 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
589 __ JumpIfNotSmi(ebx, &runtime); 574 __ JumpIfNotSmi(ebx, &runtime);
590 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset)); 575 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset));
591 __ j(above_equal, &runtime); 576 __ j(above_equal, &runtime);
592 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataOneByteCodeOffset)); 577 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataOneByteCodeOffset));
593 __ Move(ecx, Immediate(1)); // Type is one byte. 578 __ Move(ecx, Immediate(1)); // Type is one byte.
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 779
795 // Return last match info. 780 // Return last match info.
796 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); 781 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
797 __ ret(4 * kPointerSize); 782 __ ret(4 * kPointerSize);
798 783
799 // Do the runtime call to execute the regexp. 784 // Do the runtime call to execute the regexp.
800 __ bind(&runtime); 785 __ bind(&runtime);
801 __ TailCallRuntime(Runtime::kRegExpExec); 786 __ TailCallRuntime(Runtime::kRegExpExec);
802 787
803 // Deferred code for string handling. 788 // Deferred code for string handling.
804 // (7) Not a long external string? If yes, go to (10). 789 // (6) Long external string? If not, go to (10).
805 __ bind(&not_seq_nor_cons); 790 __ bind(&not_seq_nor_cons);
806 // Compare flags are still set from (3). 791 // Compare flags are still set from (3).
807 __ j(greater, &not_long_external, Label::kNear); // Go to (10). 792 __ j(greater, &not_long_external, Label::kNear); // Go to (10).
808 793
809 // (8) External string. Short external strings have been ruled out. 794 // (7) External string. Short external strings have been ruled out.
810 __ bind(&external_string); 795 __ bind(&external_string);
811 // Reload instance type. 796 // Reload instance type.
812 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 797 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
813 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 798 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
814 if (FLAG_debug_code) { 799 if (FLAG_debug_code) {
815 // Assert that we do not have a cons or slice (indirect strings) here. 800 // Assert that we do not have a cons or slice (indirect strings) here.
816 // Sequential strings have already been ruled out. 801 // Sequential strings have already been ruled out.
817 __ test_b(ebx, kIsIndirectStringMask); 802 __ test_b(ebx, kIsIndirectStringMask);
818 __ Assert(zero, kExternalStringExpectedButNotFound); 803 __ Assert(zero, kExternalStringExpectedButNotFound);
819 } 804 }
820 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset)); 805 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset));
821 // Move the pointer so that offset-wise, it looks like a sequential string. 806 // Move the pointer so that offset-wise, it looks like a sequential string.
822 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 807 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
823 __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 808 __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
824 STATIC_ASSERT(kTwoByteStringTag == 0); 809 STATIC_ASSERT(kTwoByteStringTag == 0);
825 // (8a) Is the external string one byte? If yes, go to (6). 810 // (8) Is the external string one byte? If yes, go to (5).
826 __ test_b(ebx, kStringEncodingMask); 811 __ test_b(ebx, kStringEncodingMask);
827 __ j(not_zero, &seq_one_byte_string); // Goto (6). 812 __ j(not_zero, &seq_one_byte_string); // Go to (5).
828 813
829 // eax: sequential subject string (or look-alike, external string) 814 // eax: sequential subject string (or look-alike, external string)
830 // edx: original subject string 815 // edx: original subject string
831 // ecx: RegExp data (FixedArray) 816 // ecx: RegExp data (FixedArray)
832 // (9) Two byte sequential. Load regexp code for one byte. Go to (E). 817 // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
833 __ bind(&seq_two_byte_string); 818 __ bind(&seq_two_byte_string);
834 // Load previous index and check range before edx is overwritten. We have 819 // Load previous index and check range before edx is overwritten. We have
835 // to use edx instead of eax here because it might have been only made to 820 // to use edx instead of eax here because it might have been only made to
836 // look like a sequential string when it actually is an external string. 821 // look like a sequential string when it actually is an external string.
837 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); 822 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
838 __ JumpIfNotSmi(ebx, &runtime); 823 __ JumpIfNotSmi(ebx, &runtime);
839 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset)); 824 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset));
840 __ j(above_equal, &runtime); 825 __ j(above_equal, &runtime);
841 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); 826 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
842 __ Move(ecx, Immediate(0)); // Type is two byte. 827 __ Move(ecx, Immediate(0)); // Type is two byte.
843 __ jmp(&check_code); // Go to (E). 828 __ jmp(&check_code); // Go to (E).
844 829
845 // (10) Not a string or a short external string? If yes, bail out to runtime. 830 // (10) Not a string or a short external string? If yes, bail out to runtime.
846 __ bind(&not_long_external); 831 __ bind(&not_long_external);
847 // Catch non-string subject or short external string. 832 // Catch non-string subject or short external string.
848 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); 833 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
849 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag)); 834 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag));
850 __ j(not_zero, &runtime); 835 __ j(not_zero, &runtime);
851 836
852 // (11) Sliced string. Replace subject with parent. Go to (5a). 837 // (11) Sliced string. Replace subject with parent. Go to (1).
853 // Load offset into edi and replace subject string with parent. 838 // Load offset into edi and replace subject string with parent.
854 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset)); 839 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset));
855 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset)); 840 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset));
856 __ jmp(&check_underlying); // Go to (5a). 841 __ jmp(&check_underlying); // Go to (1).
857 #endif // V8_INTERPRETED_REGEXP 842 #endif // V8_INTERPRETED_REGEXP
858 } 843 }
859 844
860 845
861 static int NegativeComparisonResult(Condition cc) { 846 static int NegativeComparisonResult(Condition cc) {
862 DCHECK(cc != equal); 847 DCHECK(cc != equal);
863 DCHECK((cc == less) || (cc == less_equal) 848 DCHECK((cc == less) || (cc == less_equal)
864 || (cc == greater) || (cc == greater_equal)); 849 || (cc == greater) || (cc == greater_equal));
865 return (cc == greater || cc == greater_equal) ? LESS : GREATER; 850 return (cc == greater || cc == greater_equal) ? LESS : GREATER;
866 } 851 }
(...skipping 4719 matching lines...) Expand 10 before | Expand all | Expand 10 after
5586 return_value_operand, NULL); 5571 return_value_operand, NULL);
5587 } 5572 }
5588 5573
5589 5574
5590 #undef __ 5575 #undef __
5591 5576
5592 } // namespace internal 5577 } // namespace internal
5593 } // namespace v8 5578 } // namespace v8
5594 5579
5595 #endif // V8_TARGET_ARCH_X87 5580 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698