| 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..309e3e0f1eeae73f93c0fafd67bc7782c37d27d7 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);
 | 
| +  __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
 | 
| +  __ movzx_b(ebx, FieldOperand(ebx, 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.
 | 
| +    __ test_b(ebx, kIsIndirectStringMask);
 | 
| +    __ Assert(zero, "external string expected, but not found");
 | 
| +  }
 | 
| +  // Rule out short external strings.
 | 
| +  STATIC_CHECK(kShortExternalStringTag != 0);
 | 
| +  __ test_b(ebx, kShortExternalStringMask);
 | 
| +  __ j(not_zero, &runtime);
 | 
| +  __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset));
 | 
| +  // 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(ebx, 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);
 | 
| 
 |