Index: src/ia32/code-stubs-ia32.cc |
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc |
index c6c1009c8cf7d28e2d8bf6ea12259783b5424a64..309e3e0f1eeae73f93c0fafd67bc7782c37d27d7 100644 |
--- a/src/ia32/code-stubs-ia32.cc |
+++ b/src/ia32/code-stubs-ia32.cc |
@@ -3613,12 +3613,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
// string. Also in this case the first part of the cons string is known to be |
// a sequential string or an external string. |
// In the case of a sliced string its offset has to be taken into account. |
- Label cons_string, check_encoding; |
+ Label cons_string, external_string, check_encoding; |
STATIC_ASSERT(kConsStringTag < kExternalStringTag); |
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); |
__ cmp(ebx, Immediate(kExternalStringTag)); |
__ j(less, &cons_string); |
- __ j(equal, &runtime); |
+ __ j(equal, &external_string); |
// String is sliced. |
__ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset)); |
@@ -3640,10 +3640,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
kStringRepresentationMask | kStringEncodingMask); |
STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); |
__ j(zero, &seq_two_byte_string, Label::kNear); |
- // Any other flat string must be ascii. |
+ // Any other flat string must be sequential ascii or external. |
__ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset), |
kStringRepresentationMask); |
- __ j(not_zero, &runtime); |
+ __ j(not_zero, &external_string); |
__ bind(&seq_ascii_string); |
// eax: subject string (flat ascii) |
@@ -3864,6 +3864,31 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ mov(eax, Operand(esp, kLastMatchInfoOffset)); |
__ ret(4 * kPointerSize); |
+ // String is external. |
+ // eax: subject string (expected to be external) |
+ // ebx: scratch |
+ __ bind(&external_string); |
+ __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
+ __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
+ if (FLAG_debug_code) { |
+ // Assert that we do not have a cons or slice (indirect strings) here. |
+ // Sequential strings have already been ruled out. |
+ __ test_b(ebx, kIsIndirectStringMask); |
+ __ Assert(zero, "external string expected, but not found"); |
+ } |
+ // Rule out short external strings. |
+ STATIC_CHECK(kShortExternalStringTag != 0); |
+ __ test_b(ebx, kShortExternalStringMask); |
+ __ j(not_zero, &runtime); |
+ __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset)); |
+ // Move the pointer so that offset-wise, it looks like a sequential string. |
+ STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); |
+ __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
+ STATIC_ASSERT(kTwoByteStringTag == 0); |
+ __ test_b(ebx, kStringEncodingMask); |
+ __ j(not_zero, &seq_ascii_string); |
+ __ jmp(&seq_two_byte_string); |
+ |
// Do the runtime call to execute the regexp. |
__ bind(&runtime); |
__ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |