Commit c7762231 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[runtime] Fix flattening of ConsStrings with empty first parts.

String::SlowFlatten assumed that ConsStrings with empty first parts have
flattened strings as their second part. TurboFan, however, can create
ConsStrings with empty first parts and arbitrary second parts. With
this CL we call String::Flatten on the second part of a ConsString if
the first part is empty, but only when String::Flatten would not call
String::SlowFlatten.

R=jkummerow@chromium.org

BUG=chromium:696651

Change-Id: I9acb681de1be695e1ec2f6f6d28b9e4dc4344e98
Reviewed-on: https://chromium-review.googlesource.com/448457
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43513}
parent 88c240bd
...@@ -2463,7 +2463,16 @@ Handle<String> String::SlowFlatten(Handle<ConsString> cons, ...@@ -2463,7 +2463,16 @@ Handle<String> String::SlowFlatten(Handle<ConsString> cons,
DCHECK(cons->second()->length() != 0); DCHECK(cons->second()->length() != 0);
// TurboFan can create cons strings with empty first parts. // TurboFan can create cons strings with empty first parts.
if (cons->first()->length() == 0) return handle(cons->second()); while (cons->first()->length() == 0) {
// We do not want to call this function recursively. Therefore we call
// String::Flatten only in those cases where String::SlowFlatten is not
// called again.
if (cons->second()->IsConsString() && !cons->second()->IsFlat()) {
cons = handle(ConsString::cast(cons->second()));
} else {
return String::Flatten(handle(cons->second()));
}
}
DCHECK(AllowHeapAllocation::IsAllowed()); DCHECK(AllowHeapAllocation::IsAllowed());
Isolate* isolate = cons->GetIsolate(); Isolate* isolate = cons->GetIsolate();
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --turbo
function get_a() { return "aaaaaaaaaaaaaa"; }
function get_b() { return "bbbbbbbbbbbbbb"; }
function get_string() {
return get_a() + get_b();
}
function prefix(s) {
return s + get_string();
}
prefix("");
prefix("");
%OptimizeFunctionOnNextCall(prefix);
var s = prefix("");
assertFalse(s === "aaaaaaaaaaaaaabbbbbbbbbbbbbc");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment