Chromium Code Reviews| Index: src/code-stub-assembler.cc | 
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc | 
| index 7062da63eef2a5b6d0c31972d276e683a23e5c18..1c8fc9f358649c0e76f3688132485796976fff95 100644 | 
| --- a/src/code-stub-assembler.cc | 
| +++ b/src/code-stub-assembler.cc | 
| @@ -3457,23 +3457,8 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, | 
| // Handle external string. | 
| Bind(&external_string); | 
| { | 
| - // Rule out short external strings. | 
| - STATIC_ASSERT(kShortExternalStringTag != 0); | 
| - GotoIf(Word32NotEqual(Word32And(var_instance_type.value(), | 
| - Int32Constant(kShortExternalStringMask)), | 
| - Int32Constant(0)), | 
| - &runtime); | 
| - | 
| - // Move the pointer so that offset-wise, it looks like a sequential string. | 
| - STATIC_ASSERT(SeqTwoByteString::kHeaderSize == | 
| - SeqOneByteString::kHeaderSize); | 
| - | 
| - Node* resource_data = | 
| - LoadObjectField(var_string.value(), ExternalString::kResourceDataOffset, | 
| - MachineType::Pointer()); | 
| - Node* const fake_sequential_string = IntPtrSub( | 
| - resource_data, | 
| - IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 
| + Node* const fake_sequential_string = TryDerefExternalString( | 
| + var_string.value(), var_instance_type.value(), &runtime); | 
| var_result.Bind(AllocAndCopyStringCharacters( | 
| this, context, fake_sequential_string, var_instance_type.value(), | 
| @@ -3522,6 +3507,48 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, | 
| return var_result.value(); | 
| } | 
| +namespace { | 
| + | 
| +Node* IsExternalStringInstanceType(CodeStubAssembler* a, | 
| + Node* const instance_type) { | 
| + CSA_ASSERT(a, a->IsStringInstanceType(instance_type)); | 
| + return a->Word32Equal( | 
| + a->Word32And(instance_type, a->Int32Constant(kStringRepresentationMask)), | 
| + a->Int32Constant(kExternalStringTag)); | 
| +} | 
| 
 
Camillo Bruni
2017/02/22 12:02:05
we can probably push those even on the CodeStubAss
 
jgruber
2017/02/22 12:06:07
Agreed, but atm it doesn't look like we'd save muc
 
 | 
| + | 
| +Node* IsShortExternalStringInstanceType(CodeStubAssembler* a, | 
| + Node* const instance_type) { | 
| + CSA_ASSERT(a, a->IsStringInstanceType(instance_type)); | 
| + STATIC_ASSERT(kShortExternalStringTag != 0); | 
| + return a->Word32NotEqual( | 
| + a->Word32And(instance_type, a->Int32Constant(kShortExternalStringMask)), | 
| + a->Int32Constant(0)); | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +Node* CodeStubAssembler::TryDerefExternalString(Node* const string, | 
| + Node* const instance_type, | 
| + Label* if_bailout) { | 
| + Label out(this); | 
| + | 
| + USE(IsExternalStringInstanceType); | 
| + CSA_ASSERT(this, IsExternalStringInstanceType(this, instance_type)); | 
| + GotoIf(IsShortExternalStringInstanceType(this, instance_type), if_bailout); | 
| + | 
| + // Move the pointer so that offset-wise, it looks like a sequential string. | 
| + STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); | 
| + | 
| + Node* resource_data = LoadObjectField( | 
| + string, ExternalString::kResourceDataOffset, MachineType::Pointer()); | 
| + Node* const fake_sequential_string = | 
| + IntPtrSub(resource_data, | 
| + IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 
| + | 
| + return fake_sequential_string; | 
| +} | 
| + | 
| void CodeStubAssembler::MaybeDerefIndirectString(Variable* var_string, | 
| Node* instance_type, | 
| Variable* var_did_something) { |