| 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..db2b578ae1739fc845089ae07b5da18457056e21 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);
|
| + if (FLAG_debug_code) {
|
| + // Assert that we do not have a cons or slice (indirect strings) here.
|
| + // Sequential strings have already been ruled out.
|
| + __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
| + __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
|
| + kIsIndirectStringMask);
|
| + __ Assert(zero, "unexpected indirect string encountered");
|
| + }
|
| + __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
|
| + __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset));
|
| + // Assert that the data pointer cache is valid.
|
| + __ test(eax, eax);
|
| + __ j(zero, &runtime, Label::kNear);
|
| + // 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(FieldOperand(ebx, Map::kInstanceTypeOffset), 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);
|
|
|