Index: src/mips/code-stubs-mips.cc |
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc |
index 679b23fffa39f8215282bb1dc018dfac2f7d0e22..08db956bda659fbc5e9e712bd2279edc3df48714 100644 |
--- a/src/mips/code-stubs-mips.cc |
+++ b/src/mips/code-stubs-mips.cc |
@@ -4747,8 +4747,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); |
__ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); |
// First check for flat string. None of the following string type tests will |
- // succeed if kIsNotStringTag is set. |
- __ And(a1, a0, Operand(kIsNotStringMask | kStringRepresentationMask)); |
+ // succeed if subject is not a string or a short external string. |
+ __ And(a1, |
+ a0, |
+ Operand(kIsNotStringMask | |
+ kStringRepresentationMask | |
+ kShortExternalStringMask)); |
STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); |
__ Branch(&seq_string, eq, a1, Operand(zero_reg)); |
@@ -4762,16 +4766,17 @@ 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); |
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); |
+ STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); |
__ Branch(&cons_string, lt, a1, Operand(kExternalStringTag)); |
- __ Branch(&runtime, eq, a1, Operand(kExternalStringTag)); |
+ __ Branch(&external_string, eq, a1, Operand(kExternalStringTag)); |
- // Catch non-string subject (should already have been guarded against). |
- STATIC_ASSERT(kNotStringTag != 0); |
- __ And(at, a1, Operand(kIsNotStringMask)); |
+ // Catch non-string subject or short external string. |
+ STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); |
+ __ And(at, a1, Operand(kIsNotStringMask | kShortExternalStringMask)); |
__ Branch(&runtime, ne, at, Operand(zero_reg)); |
// String is sliced. |
@@ -4792,7 +4797,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); |
STATIC_ASSERT(kSeqStringTag == 0); |
__ And(at, a0, Operand(kStringRepresentationMask)); |
- __ Branch(&runtime, ne, at, Operand(zero_reg)); |
+ __ Branch(&external_string, ne, at, Operand(zero_reg)); |
__ bind(&seq_string); |
// subject: Subject string |
@@ -5018,6 +5023,27 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { |
__ Addu(sp, sp, Operand(4 * kPointerSize)); |
__ Ret(); |
+ // External string. Short external strings have already been ruled out. |
+ // a0: scratch |
+ __ bind(&external_string); |
+ __ lw(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); |
+ __ lbu(a0, FieldMemOperand(a0, 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. |
+ __ And(at, a0, Operand(kIsIndirectStringMask)); |
+ __ Assert(eq, "external string expected, but not found", |
+ at, Operand(zero_reg)); |
+ } |
+ __ lw(subject, |
+ FieldMemOperand(subject, ExternalString::kResourceDataOffset)); |
+ // Move the pointer so that offset-wise, it looks like a sequential string. |
+ STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); |
+ __ Subu(subject, |
+ subject, |
+ SeqTwoByteString::kHeaderSize - kHeapObjectTag); |
+ __ jmp(&seq_string); |
+ |
// Do the runtime call to execute the regexp. |
__ bind(&runtime); |
__ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |