Fast-path in SlowFlatten for ConsStrings with empty first part

TurboFan can create ConsStrings with empty first parts (for history on
this decision, see da27e0c886). Add a
fast-path for such cases in String::SlowFlatten.

BUG=

Review-Url: https://codereview.chromium.org/2489273002
Cr-Commit-Position: refs/heads/master@{#40885}
This commit is contained in:
jgruber 2016-11-10 03:23:07 -08:00 committed by Commit bot
parent e5c1929c09
commit 806b350482
2 changed files with 41 additions and 1 deletions

View File

@ -2215,8 +2215,12 @@ static bool AnWord(String* str) {
Handle<String> String::SlowFlatten(Handle<ConsString> cons,
PretenureFlag pretenure) {
DCHECK(AllowHeapAllocation::IsAllowed());
DCHECK(cons->second()->length() != 0);
// TurboFan can create cons strings with empty first parts.
if (cons->first()->length() == 0) return handle(cons->second());
DCHECK(AllowHeapAllocation::IsAllowed());
Isolate* isolate = cons->GetIsolate();
int length = cons->length();
PretenureFlag tenure = isolate->heap()->InNewSpace(*cons) ? pretenure

View File

@ -600,6 +600,42 @@ TEST(Traverse) {
printf("18\n");
}
TEST(ConsStringWithEmptyFirstFlatten) {
printf("ConsStringWithEmptyFirstFlatten\n");
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
Isolate* isolate = CcTest::i_isolate();
i::Handle<i::String> initial_fst =
isolate->factory()->NewStringFromAsciiChecked("fst012345");
i::Handle<i::String> initial_snd =
isolate->factory()->NewStringFromAsciiChecked("snd012345");
i::Handle<i::String> str = isolate->factory()
->NewConsString(initial_fst, initial_snd)
.ToHandleChecked();
CHECK(str->IsConsString());
auto cons = i::Handle<i::ConsString>::cast(str);
const int initial_length = cons->length();
// set_first / set_second does not update the length (which the heap verifier
// checks), so we need to ensure the length stays the same.
i::Handle<i::String> new_fst = isolate->factory()->empty_string();
i::Handle<i::String> new_snd =
isolate->factory()->NewStringFromAsciiChecked("snd012345012345678");
cons->set_first(*new_fst);
cons->set_second(*new_snd);
CHECK(!cons->IsFlat());
CHECK_EQ(initial_length, new_fst->length() + new_snd->length());
CHECK_EQ(initial_length, cons->length());
// Make sure Flatten doesn't alloc a new string.
DisallowHeapAllocation no_alloc;
i::Handle<i::String> flat = i::String::Flatten(cons);
CHECK(flat->IsFlat());
CHECK_EQ(initial_length, flat->length());
}
static void VerifyCharacterStream(
String* flat_string, String* cons_string) {