| OLD | NEW |
| 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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
| 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/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 // (5) One byte sequential. Load regexp code for one byte. | 597 // (5) One byte sequential. Load regexp code for one byte. |
| 598 // (E) Carry on. | 598 // (E) Carry on. |
| 599 /// [...] | 599 /// [...] |
| 600 | 600 |
| 601 // Deferred code at the end of the stub: | 601 // Deferred code at the end of the stub: |
| 602 // (6) Long external string? If not, go to (10). | 602 // (6) Long external string? If not, go to (10). |
| 603 // (7) External string. Make it, offset-wise, look like a sequential string. | 603 // (7) External string. Make it, offset-wise, look like a sequential string. |
| 604 // (8) Is the external string one byte? If yes, go to (5). | 604 // (8) Is the external string one byte? If yes, go to (5). |
| 605 // (9) Two byte sequential. Load regexp code for two byte. Go to (E). | 605 // (9) Two byte sequential. Load regexp code for two byte. Go to (E). |
| 606 // (10) Short external string or not a string? If yes, bail out to runtime. | 606 // (10) Short external string or not a string? If yes, bail out to runtime. |
| 607 // (11) Sliced string. Replace subject with parent. Go to (1). | 607 // (11) Sliced or thin string. Replace subject with parent. Go to (1). |
| 608 | 608 |
| 609 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */, | 609 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */, |
| 610 external_string /* 7 */, check_underlying /* 1 */, | 610 external_string /* 7 */, check_underlying /* 1 */, |
| 611 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */; | 611 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */; |
| 612 | 612 |
| 613 __ bind(&check_underlying); | 613 __ bind(&check_underlying); |
| 614 // (1) Sequential two byte? If yes, go to (9). | 614 // (1) Sequential two byte? If yes, go to (9). |
| 615 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 615 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 616 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 616 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 617 | 617 |
| 618 __ and_(ebx, kIsNotStringMask | | 618 __ and_(ebx, kIsNotStringMask | |
| 619 kStringRepresentationMask | | 619 kStringRepresentationMask | |
| 620 kStringEncodingMask | | 620 kStringEncodingMask | |
| 621 kShortExternalStringMask); | 621 kShortExternalStringMask); |
| 622 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); | 622 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); |
| 623 __ j(zero, &seq_two_byte_string); // Go to (9). | 623 __ j(zero, &seq_two_byte_string); // Go to (9). |
| 624 | 624 |
| 625 // (2) Sequential one byte? If yes, go to (5). | 625 // (2) Sequential one byte? If yes, go to (5). |
| 626 // Any other sequential string must be one byte. | 626 // Any other sequential string must be one byte. |
| 627 __ and_(ebx, Immediate(kIsNotStringMask | | 627 __ and_(ebx, Immediate(kIsNotStringMask | |
| 628 kStringRepresentationMask | | 628 kStringRepresentationMask | |
| 629 kShortExternalStringMask)); | 629 kShortExternalStringMask)); |
| 630 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5). | 630 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5). |
| 631 | 631 |
| 632 // (3) Sequential or cons? If not, go to (6). | 632 // (3) Sequential or cons? If not, go to (6). |
| 633 // We check whether the subject string is a cons, since sequential strings | 633 // We check whether the subject string is a cons, since sequential strings |
| 634 // have already been covered. | 634 // have already been covered. |
| 635 STATIC_ASSERT(kConsStringTag < kExternalStringTag); | 635 STATIC_ASSERT(kConsStringTag < kExternalStringTag); |
| 636 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); | 636 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); |
| 637 STATIC_ASSERT(kThinStringTag > kExternalStringTag); |
| 637 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); | 638 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); |
| 638 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); | 639 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); |
| 639 __ cmp(ebx, Immediate(kExternalStringTag)); | 640 __ cmp(ebx, Immediate(kExternalStringTag)); |
| 640 __ j(greater_equal, ¬_seq_nor_cons); // Go to (6). | 641 __ j(greater_equal, ¬_seq_nor_cons); // Go to (6). |
| 641 | 642 |
| 642 // (4) Cons string. Check that it's flat. | 643 // (4) Cons string. Check that it's flat. |
| 643 // Replace subject with first string and reload instance type. | 644 // Replace subject with first string and reload instance type. |
| 644 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string()); | 645 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string()); |
| 645 __ j(not_equal, &runtime); | 646 __ j(not_equal, &runtime); |
| 646 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); | 647 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 __ Move(ecx, Immediate(0)); // Type is two byte. | 906 __ Move(ecx, Immediate(0)); // Type is two byte. |
| 906 __ jmp(&check_code); // Go to (E). | 907 __ jmp(&check_code); // Go to (E). |
| 907 | 908 |
| 908 // (10) Not a string or a short external string? If yes, bail out to runtime. | 909 // (10) Not a string or a short external string? If yes, bail out to runtime. |
| 909 __ bind(¬_long_external); | 910 __ bind(¬_long_external); |
| 910 // Catch non-string subject or short external string. | 911 // Catch non-string subject or short external string. |
| 911 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); | 912 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); |
| 912 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag)); | 913 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag)); |
| 913 __ j(not_zero, &runtime); | 914 __ j(not_zero, &runtime); |
| 914 | 915 |
| 915 // (11) Sliced string. Replace subject with parent. Go to (1). | 916 // (11) Sliced or thin string. Replace subject with parent. Go to (1). |
| 917 Label thin_string; |
| 918 __ cmp(ebx, Immediate(kThinStringTag)); |
| 919 __ j(equal, &thin_string, Label::kNear); |
| 916 // Load offset into edi and replace subject string with parent. | 920 // Load offset into edi and replace subject string with parent. |
| 917 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset)); | 921 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset)); |
| 918 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset)); | 922 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset)); |
| 919 __ jmp(&check_underlying); // Go to (1). | 923 __ jmp(&check_underlying); // Go to (1). |
| 924 |
| 925 __ bind(&thin_string); |
| 926 __ mov(eax, FieldOperand(eax, ThinString::kActualOffset)); |
| 927 __ jmp(&check_underlying); // Go to (1). |
| 920 #endif // V8_INTERPRETED_REGEXP | 928 #endif // V8_INTERPRETED_REGEXP |
| 921 } | 929 } |
| 922 | 930 |
| 923 | 931 |
| 924 static int NegativeComparisonResult(Condition cc) { | 932 static int NegativeComparisonResult(Condition cc) { |
| 925 DCHECK(cc != equal); | 933 DCHECK(cc != equal); |
| 926 DCHECK((cc == less) || (cc == less_equal) | 934 DCHECK((cc == less) || (cc == less_equal) |
| 927 || (cc == greater) || (cc == greater_equal)); | 935 || (cc == greater) || (cc == greater_equal)); |
| 928 return (cc == greater || cc == greater_equal) ? LESS : GREATER; | 936 return (cc == greater || cc == greater_equal) ? LESS : GREATER; |
| 929 } | 937 } |
| (...skipping 3264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4194 kStackUnwindSpace, nullptr, return_value_operand, | 4202 kStackUnwindSpace, nullptr, return_value_operand, |
| 4195 NULL); | 4203 NULL); |
| 4196 } | 4204 } |
| 4197 | 4205 |
| 4198 #undef __ | 4206 #undef __ |
| 4199 | 4207 |
| 4200 } // namespace internal | 4208 } // namespace internal |
| 4201 } // namespace v8 | 4209 } // namespace v8 |
| 4202 | 4210 |
| 4203 #endif // V8_TARGET_ARCH_IA32 | 4211 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |