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) { |