| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index b8f820d7f5581e9727731f61fa8481a751258aa0..2dab8254b8a1cedefe5c72459bb8af49edefcaff 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -2660,12 +2660,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);
|
| __ cmpq(rbx, Immediate(kExternalStringTag));
|
| __ j(less, &cons_string, Label::kNear);
|
| - __ j(equal, &runtime);
|
| + __ j(equal, &external_string);
|
|
|
| // String is sliced.
|
| __ SmiToInteger32(r14, FieldOperand(rdi, SlicedString::kOffsetOffset));
|
| @@ -2689,10 +2689,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
| Immediate(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.
|
| __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
|
| Immediate(kStringRepresentationMask));
|
| - __ j(not_zero, &runtime);
|
| + __ j(not_zero, &external_string);
|
|
|
| __ bind(&seq_ascii_string);
|
| // rdi: subject string (sequential ascii)
|
| @@ -2926,6 +2926,32 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
| __ bind(&termination_exception);
|
| __ ThrowUncatchable(TERMINATION, rax);
|
|
|
| + // String is external.
|
| + // rdi: subject string (expected to be external)
|
| + // rbx: 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.
|
| + __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
|
| + __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
|
| + Immediate(kIsIndirectStringMask));
|
| + __ Assert(zero, "unexpected indirect string encountered");
|
| + }
|
| + __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
|
| + __ movq(rdi, FieldOperand(rdi, ExternalString::kResourceDataOffset));
|
| + // Assert that the data pointer cache is valid.
|
| + __ testq(rdi, rdi);
|
| + __ j(zero, &runtime, Label::kNear);
|
| + // Move the pointer so that offset-wise, it looks like a sequential string.
|
| + STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
|
| + __ subq(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
|
| + STATIC_ASSERT(kTwoByteStringTag == 0);
|
| + __ testb(FieldOperand(rbx, Map::kInstanceTypeOffset),
|
| + Immediate(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);
|
|
|