| Index: src/arm/code-stubs-arm.cc
|
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
|
| index 9e6f7596e7fc60131cdaf956d07567854514e74b..3f85d6bc2f27617c58cbca3aee3e35ff25cb41d5 100644
|
| --- a/src/arm/code-stubs-arm.cc
|
| +++ b/src/arm/code-stubs-arm.cc
|
| @@ -4572,12 +4572,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(r1, Operand(kExternalStringTag));
|
| __ b(lt, &cons_string);
|
| - __ b(eq, &runtime);
|
| + __ b(eq, &external_string);
|
|
|
| // String is sliced.
|
| __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset));
|
| @@ -4588,8 +4588,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
| // String is a cons string, check whether it is flat.
|
| __ bind(&cons_string);
|
| __ ldr(r0, FieldMemOperand(subject, ConsString::kSecondOffset));
|
| - __ LoadRoot(r1, Heap::kEmptyStringRootIndex);
|
| - __ cmp(r0, r1);
|
| + __ CompareRoot(r0, Heap::kEmptyStringRootIndex);
|
| __ b(ne, &runtime);
|
| __ ldr(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
|
| // Is first part of cons or parent of slice a flat string?
|
| @@ -4598,7 +4597,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
| __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
|
| STATIC_ASSERT(kSeqStringTag == 0);
|
| __ tst(r0, Operand(kStringRepresentationMask));
|
| - __ b(ne, &runtime);
|
| + __ b(ne, &external_string);
|
| +
|
| __ bind(&seq_string);
|
| // subject: Subject string
|
| // regexp_data: RegExp data (FixedArray)
|
| @@ -4806,6 +4806,31 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
| __ add(sp, sp, Operand(4 * kPointerSize));
|
| __ Ret();
|
|
|
| + // String is external.
|
| + // r0: 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.
|
| + __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
|
| + __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
|
| + __ tst(r0, Operand(kIsIndirectStringMask));
|
| + __ Assert(eq, "unexpected indirect string encountered");
|
| + }
|
| + __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset));
|
| + __ ldr(subject,
|
| + FieldMemOperand(subject, ExternalString::kResourceDataOffset));
|
| + // Assert that the data pointer cache is valid.
|
| + __ tst(subject, subject);
|
| + __ b(eq, &runtime);
|
| + // Move the pointer so that offset-wise, it looks like a sequential string.
|
| + STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
|
| + __ sub(subject,
|
| + subject,
|
| + Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
|
| + __ ldrb(r0, FieldMemOperand(r0, Map::kInstanceTypeOffset));
|
| + __ jmp(&seq_string);
|
| +
|
| // Do the runtime call to execute the regexp.
|
| __ bind(&runtime);
|
| __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
|
|
|