| 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_X87 | 5 #if V8_TARGET_ARCH_X87 |
| 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 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 // (5) One byte sequential. Load regexp code for one byte. | 418 // (5) One byte sequential. Load regexp code for one byte. |
| 419 // (E) Carry on. | 419 // (E) Carry on. |
| 420 /// [...] | 420 /// [...] |
| 421 | 421 |
| 422 // Deferred code at the end of the stub: | 422 // Deferred code at the end of the stub: |
| 423 // (6) Long external string? If not, go to (10). | 423 // (6) Long external string? If not, go to (10). |
| 424 // (7) External string. Make it, offset-wise, look like a sequential string. | 424 // (7) External string. Make it, offset-wise, look like a sequential string. |
| 425 // (8) Is the external string one byte? If yes, go to (5). | 425 // (8) Is the external string one byte? If yes, go to (5). |
| 426 // (9) Two byte sequential. Load regexp code for two byte. Go to (E). | 426 // (9) Two byte sequential. Load regexp code for two byte. Go to (E). |
| 427 // (10) Short external string or not a string? If yes, bail out to runtime. | 427 // (10) Short external string or not a string? If yes, bail out to runtime. |
| 428 // (11) Sliced or thin string. Replace subject with parent. Go to (1). | 428 // (11) Sliced string. Replace subject with parent. Go to (1). |
| 429 | 429 |
| 430 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */, | 430 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */, |
| 431 external_string /* 7 */, check_underlying /* 1 */, | 431 external_string /* 7 */, check_underlying /* 1 */, |
| 432 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */; | 432 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */; |
| 433 | 433 |
| 434 __ bind(&check_underlying); | 434 __ bind(&check_underlying); |
| 435 // (1) Sequential two byte? If yes, go to (9). | 435 // (1) Sequential two byte? If yes, go to (9). |
| 436 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 436 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 437 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 437 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 438 | 438 |
| 439 __ and_(ebx, kIsNotStringMask | | 439 __ and_(ebx, kIsNotStringMask | |
| 440 kStringRepresentationMask | | 440 kStringRepresentationMask | |
| 441 kStringEncodingMask | | 441 kStringEncodingMask | |
| 442 kShortExternalStringMask); | 442 kShortExternalStringMask); |
| 443 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); | 443 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); |
| 444 __ j(zero, &seq_two_byte_string); // Go to (9). | 444 __ j(zero, &seq_two_byte_string); // Go to (9). |
| 445 | 445 |
| 446 // (2) Sequential one byte? If yes, go to (5). | 446 // (2) Sequential one byte? If yes, go to (5). |
| 447 // Any other sequential string must be one byte. | 447 // Any other sequential string must be one byte. |
| 448 __ and_(ebx, Immediate(kIsNotStringMask | | 448 __ and_(ebx, Immediate(kIsNotStringMask | |
| 449 kStringRepresentationMask | | 449 kStringRepresentationMask | |
| 450 kShortExternalStringMask)); | 450 kShortExternalStringMask)); |
| 451 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5). | 451 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5). |
| 452 | 452 |
| 453 // (3) Sequential or cons? If not, go to (6). | 453 // (3) Sequential or cons? If not, go to (6). |
| 454 // We check whether the subject string is a cons, since sequential strings | 454 // We check whether the subject string is a cons, since sequential strings |
| 455 // have already been covered. | 455 // have already been covered. |
| 456 STATIC_ASSERT(kConsStringTag < kExternalStringTag); | 456 STATIC_ASSERT(kConsStringTag < kExternalStringTag); |
| 457 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); | 457 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); |
| 458 STATIC_ASSERT(kThinStringTag > kExternalStringTag); | |
| 459 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); | 458 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); |
| 460 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); | 459 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); |
| 461 __ cmp(ebx, Immediate(kExternalStringTag)); | 460 __ cmp(ebx, Immediate(kExternalStringTag)); |
| 462 __ j(greater_equal, ¬_seq_nor_cons); // Go to (6). | 461 __ j(greater_equal, ¬_seq_nor_cons); // Go to (6). |
| 463 | 462 |
| 464 // (4) Cons string. Check that it's flat. | 463 // (4) Cons string. Check that it's flat. |
| 465 // Replace subject with first string and reload instance type. | 464 // Replace subject with first string and reload instance type. |
| 466 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string()); | 465 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string()); |
| 467 __ j(not_equal, &runtime); | 466 __ j(not_equal, &runtime); |
| 468 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); | 467 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 __ Move(ecx, Immediate(0)); // Type is two byte. | 726 __ Move(ecx, Immediate(0)); // Type is two byte. |
| 728 __ jmp(&check_code); // Go to (E). | 727 __ jmp(&check_code); // Go to (E). |
| 729 | 728 |
| 730 // (10) Not a string or a short external string? If yes, bail out to runtime. | 729 // (10) Not a string or a short external string? If yes, bail out to runtime. |
| 731 __ bind(¬_long_external); | 730 __ bind(¬_long_external); |
| 732 // Catch non-string subject or short external string. | 731 // Catch non-string subject or short external string. |
| 733 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); | 732 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); |
| 734 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag)); | 733 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag)); |
| 735 __ j(not_zero, &runtime); | 734 __ j(not_zero, &runtime); |
| 736 | 735 |
| 737 // (11) Sliced or thin string. Replace subject with parent. Go to (1). | 736 // (11) Sliced string. Replace subject with parent. Go to (1). |
| 738 Label thin_string; | |
| 739 __ cmp(ebx, Immediate(kThinStringTag)); | |
| 740 __ j(equal, &thin_string, Label::kNear); | |
| 741 // Load offset into edi and replace subject string with parent. | 737 // Load offset into edi and replace subject string with parent. |
| 742 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset)); | 738 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset)); |
| 743 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset)); | 739 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset)); |
| 744 __ jmp(&check_underlying); // Go to (1). | 740 __ jmp(&check_underlying); // Go to (1). |
| 745 | |
| 746 __ bind(&thin_string); | |
| 747 __ mov(eax, FieldOperand(eax, ThinString::kActualOffset)); | |
| 748 __ jmp(&check_underlying); // Go to (1). | |
| 749 #endif // V8_INTERPRETED_REGEXP | 741 #endif // V8_INTERPRETED_REGEXP |
| 750 } | 742 } |
| 751 | 743 |
| 752 | 744 |
| 753 static int NegativeComparisonResult(Condition cc) { | 745 static int NegativeComparisonResult(Condition cc) { |
| 754 DCHECK(cc != equal); | 746 DCHECK(cc != equal); |
| 755 DCHECK((cc == less) || (cc == less_equal) | 747 DCHECK((cc == less) || (cc == less_equal) |
| 756 || (cc == greater) || (cc == greater_equal)); | 748 || (cc == greater) || (cc == greater_equal)); |
| 757 return (cc == greater || cc == greater_equal) ? LESS : GREATER; | 749 return (cc == greater || cc == greater_equal) ? LESS : GREATER; |
| 758 } | 750 } |
| (...skipping 3308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4067 kStackUnwindSpace, nullptr, return_value_operand, | 4059 kStackUnwindSpace, nullptr, return_value_operand, |
| 4068 NULL); | 4060 NULL); |
| 4069 } | 4061 } |
| 4070 | 4062 |
| 4071 #undef __ | 4063 #undef __ |
| 4072 | 4064 |
| 4073 } // namespace internal | 4065 } // namespace internal |
| 4074 } // namespace v8 | 4066 } // namespace v8 |
| 4075 | 4067 |
| 4076 #endif // V8_TARGET_ARCH_X87 | 4068 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |