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 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 // (5) One byte sequential. Load regexp code for one byte. | 477 // (5) One byte sequential. Load regexp code for one byte. |
478 // (E) Carry on. | 478 // (E) Carry on. |
479 /// [...] | 479 /// [...] |
480 | 480 |
481 // Deferred code at the end of the stub: | 481 // Deferred code at the end of the stub: |
482 // (6) Long external string? If not, go to (10). | 482 // (6) Long external string? If not, go to (10). |
483 // (7) External string. Make it, offset-wise, look like a sequential string. | 483 // (7) External string. Make it, offset-wise, look like a sequential string. |
484 // (8) Is the external string one byte? If yes, go to (5). | 484 // (8) Is the external string one byte? If yes, go to (5). |
485 // (9) Two byte sequential. Load regexp code for two byte. Go to (E). | 485 // (9) Two byte sequential. Load regexp code for two byte. Go to (E). |
486 // (10) Short external string or not a string? If yes, bail out to runtime. | 486 // (10) Short external string or not a string? If yes, bail out to runtime. |
487 // (11) Sliced string. Replace subject with parent. Go to (1). | 487 // (11) Sliced or thin string. Replace subject with parent. Go to (1). |
488 | 488 |
489 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */, | 489 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */, |
490 external_string /* 7 */, check_underlying /* 1 */, | 490 external_string /* 7 */, check_underlying /* 1 */, |
491 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */; | 491 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */; |
492 | 492 |
493 __ bind(&check_underlying); | 493 __ bind(&check_underlying); |
494 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); | 494 __ movp(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); |
495 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); | 495 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); |
496 | 496 |
497 // (1) Sequential two byte? If yes, go to (9). | 497 // (1) Sequential two byte? If yes, go to (9). |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 __ Set(rcx, 0); // Type is two byte. | 795 __ Set(rcx, 0); // Type is two byte. |
796 __ jmp(&check_code); // Go to (E). | 796 __ jmp(&check_code); // Go to (E). |
797 | 797 |
798 // (10) Not a string or a short external string? If yes, bail out to runtime. | 798 // (10) Not a string or a short external string? If yes, bail out to runtime. |
799 __ bind(¬_long_external); | 799 __ bind(¬_long_external); |
800 // Catch non-string subject or short external string. | 800 // Catch non-string subject or short external string. |
801 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); | 801 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); |
802 __ testb(rbx, Immediate(kIsNotStringMask | kShortExternalStringMask)); | 802 __ testb(rbx, Immediate(kIsNotStringMask | kShortExternalStringMask)); |
803 __ j(not_zero, &runtime); | 803 __ j(not_zero, &runtime); |
804 | 804 |
805 // (11) Sliced string. Replace subject with parent. Go to (1). | 805 // (11) Sliced or thin string. Replace subject with parent. Go to (1). |
| 806 Label thin_string; |
| 807 __ cmpl(rbx, Immediate(kThinStringTag)); |
| 808 __ j(equal, &thin_string, Label::kNear); |
806 // Load offset into r14 and replace subject string with parent. | 809 // Load offset into r14 and replace subject string with parent. |
807 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset)); | 810 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset)); |
808 __ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset)); | 811 __ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset)); |
809 __ jmp(&check_underlying); | 812 __ jmp(&check_underlying); |
| 813 |
| 814 __ bind(&thin_string); |
| 815 __ movp(rdi, FieldOperand(rdi, ThinString::kActualOffset)); |
| 816 __ jmp(&check_underlying); |
810 #endif // V8_INTERPRETED_REGEXP | 817 #endif // V8_INTERPRETED_REGEXP |
811 } | 818 } |
812 | 819 |
813 | 820 |
814 static int NegativeComparisonResult(Condition cc) { | 821 static int NegativeComparisonResult(Condition cc) { |
815 DCHECK(cc != equal); | 822 DCHECK(cc != equal); |
816 DCHECK((cc == less) || (cc == less_equal) | 823 DCHECK((cc == less) || (cc == less_equal) |
817 || (cc == greater) || (cc == greater_equal)); | 824 || (cc == greater) || (cc == greater_equal)); |
818 return (cc == greater || cc == greater_equal) ? LESS : GREATER; | 825 return (cc == greater || cc == greater_equal) ? LESS : GREATER; |
819 } | 826 } |
(...skipping 3514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4334 kStackUnwindSpace, nullptr, return_value_operand, | 4341 kStackUnwindSpace, nullptr, return_value_operand, |
4335 NULL); | 4342 NULL); |
4336 } | 4343 } |
4337 | 4344 |
4338 #undef __ | 4345 #undef __ |
4339 | 4346 |
4340 } // namespace internal | 4347 } // namespace internal |
4341 } // namespace v8 | 4348 } // namespace v8 |
4342 | 4349 |
4343 #endif // V8_TARGET_ARCH_X64 | 4350 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |