| 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 or thin string. Replace subject with parent. Go to (1). | 487 // (11) Sliced 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). |
| 498 __ andb(rbx, Immediate(kIsNotStringMask | | 498 __ andb(rbx, Immediate(kIsNotStringMask | |
| 499 kStringRepresentationMask | | 499 kStringRepresentationMask | |
| 500 kStringEncodingMask | | 500 kStringEncodingMask | |
| 501 kShortExternalStringMask)); | 501 kShortExternalStringMask)); |
| 502 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); | 502 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); |
| 503 __ j(zero, &seq_two_byte_string); // Go to (9). | 503 __ j(zero, &seq_two_byte_string); // Go to (9). |
| 504 | 504 |
| 505 // (2) Sequential one byte? If yes, go to (5). | 505 // (2) Sequential one byte? If yes, go to (5). |
| 506 // Any other sequential string must be one byte. | 506 // Any other sequential string must be one byte. |
| 507 __ andb(rbx, Immediate(kIsNotStringMask | | 507 __ andb(rbx, Immediate(kIsNotStringMask | |
| 508 kStringRepresentationMask | | 508 kStringRepresentationMask | |
| 509 kShortExternalStringMask)); | 509 kShortExternalStringMask)); |
| 510 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5). | 510 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5). |
| 511 | 511 |
| 512 // (3) Sequential or cons? If not, go to (6). | 512 // (3) Sequential or cons? If not, go to (6). |
| 513 // We check whether the subject string is a cons, since sequential strings | 513 // We check whether the subject string is a cons, since sequential strings |
| 514 // have already been covered. | 514 // have already been covered. |
| 515 STATIC_ASSERT(kConsStringTag < kExternalStringTag); | 515 STATIC_ASSERT(kConsStringTag < kExternalStringTag); |
| 516 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); | 516 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); |
| 517 STATIC_ASSERT(kThinStringTag > kExternalStringTag); | |
| 518 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); | 517 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); |
| 519 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); | 518 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); |
| 520 __ cmpp(rbx, Immediate(kExternalStringTag)); | 519 __ cmpp(rbx, Immediate(kExternalStringTag)); |
| 521 __ j(greater_equal, ¬_seq_nor_cons); // Go to (6). | 520 __ j(greater_equal, ¬_seq_nor_cons); // Go to (6). |
| 522 | 521 |
| 523 // (4) Cons string. Check that it's flat. | 522 // (4) Cons string. Check that it's flat. |
| 524 // Replace subject with first string and reload instance type. | 523 // Replace subject with first string and reload instance type. |
| 525 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset), | 524 __ CompareRoot(FieldOperand(rdi, ConsString::kSecondOffset), |
| 526 Heap::kempty_stringRootIndex); | 525 Heap::kempty_stringRootIndex); |
| 527 __ j(not_equal, &runtime); | 526 __ j(not_equal, &runtime); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 __ Set(rcx, 0); // Type is two byte. | 795 __ Set(rcx, 0); // Type is two byte. |
| 797 __ jmp(&check_code); // Go to (E). | 796 __ jmp(&check_code); // Go to (E). |
| 798 | 797 |
| 799 // (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. |
| 800 __ bind(¬_long_external); | 799 __ bind(¬_long_external); |
| 801 // Catch non-string subject or short external string. | 800 // Catch non-string subject or short external string. |
| 802 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); | 801 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); |
| 803 __ testb(rbx, Immediate(kIsNotStringMask | kShortExternalStringMask)); | 802 __ testb(rbx, Immediate(kIsNotStringMask | kShortExternalStringMask)); |
| 804 __ j(not_zero, &runtime); | 803 __ j(not_zero, &runtime); |
| 805 | 804 |
| 806 // (11) Sliced or thin string. Replace subject with parent. Go to (1). | 805 // (11) Sliced string. Replace subject with parent. Go to (1). |
| 807 Label thin_string; | |
| 808 __ cmpl(rbx, Immediate(kThinStringTag)); | |
| 809 __ j(equal, &thin_string, Label::kNear); | |
| 810 // Load offset into r14 and replace subject string with parent. | 806 // Load offset into r14 and replace subject string with parent. |
| 811 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset)); | 807 __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset)); |
| 812 __ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset)); | 808 __ movp(rdi, FieldOperand(rdi, SlicedString::kParentOffset)); |
| 813 __ jmp(&check_underlying); | 809 __ jmp(&check_underlying); |
| 814 | |
| 815 __ bind(&thin_string); | |
| 816 __ movp(rdi, FieldOperand(rdi, ThinString::kActualOffset)); | |
| 817 __ jmp(&check_underlying); | |
| 818 #endif // V8_INTERPRETED_REGEXP | 810 #endif // V8_INTERPRETED_REGEXP |
| 819 } | 811 } |
| 820 | 812 |
| 821 | 813 |
| 822 static int NegativeComparisonResult(Condition cc) { | 814 static int NegativeComparisonResult(Condition cc) { |
| 823 DCHECK(cc != equal); | 815 DCHECK(cc != equal); |
| 824 DCHECK((cc == less) || (cc == less_equal) | 816 DCHECK((cc == less) || (cc == less_equal) |
| 825 || (cc == greater) || (cc == greater_equal)); | 817 || (cc == greater) || (cc == greater_equal)); |
| 826 return (cc == greater || cc == greater_equal) ? LESS : GREATER; | 818 return (cc == greater || cc == greater_equal) ? LESS : GREATER; |
| 827 } | 819 } |
| (...skipping 3359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4187 kStackUnwindSpace, nullptr, return_value_operand, | 4179 kStackUnwindSpace, nullptr, return_value_operand, |
| 4188 NULL); | 4180 NULL); |
| 4189 } | 4181 } |
| 4190 | 4182 |
| 4191 #undef __ | 4183 #undef __ |
| 4192 | 4184 |
| 4193 } // namespace internal | 4185 } // namespace internal |
| 4194 } // namespace v8 | 4186 } // namespace v8 |
| 4195 | 4187 |
| 4196 #endif // V8_TARGET_ARCH_X64 | 4188 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |