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..f908c9372222b4d7e3402223c9db88f2f23790a6 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); |
Lasse Reichstein
2011/11/25 12:56:50
This was where you added the is-not-string test, r
|
// 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,30 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ add(sp, sp, Operand(4 * kPointerSize)); |
__ Ret(); |
+ // String is external. |
+ // r0: scratch |
+ __ bind(&external_string); |
+ __ ldr(r0, FieldMemOperand(subject, HeapObject::kMapOffset)); |
+ __ ldrb(r0, FieldMemOperand(r0, 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. |
+ __ tst(r0, Operand(kIsIndirectStringMask)); |
+ __ Assert(eq, "external string expected, but not found"); |
+ } |
+ // Rule out short external strings. |
+ STATIC_CHECK(kShortExternalStringTag != 0); |
+ __ tst(r0, Operand(kShortExternalStringMask)); |
+ __ b(ne, &runtime); |
+ __ ldr(subject, |
+ FieldMemOperand(subject, ExternalString::kResourceDataOffset)); |
+ // 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)); |
+ __ jmp(&seq_string); |
+ |
// Do the runtime call to execute the regexp. |
__ bind(&runtime); |
__ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |