From 8c10f67611dae9c601f703278d691e8bc47386e9 Mon Sep 17 00:00:00 2001 From: Patrick Thier Date: Tue, 14 Jun 2022 09:12:10 +0000 Subject: [PATCH] [strings] Fix flattening ConsStrings with StringForwardingTable enabled When using the StringForwardingTable for all strings, string shapes can change during GC. This led to an issue when a ConsString was transitioned to a ThinString (and potentially shortcutted to InternalizedString) while flattening. Bug: chromium:1335826, chromium:1329726 Change-Id: Ide243a5e24fd41374053972fb7bab8217d7a14fd Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3705377 Reviewed-by: Camillo Bruni Commit-Queue: Camillo Bruni Auto-Submit: Patrick Thier Cr-Commit-Position: refs/heads/main@{#81131} --- src/objects/string.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/objects/string.cc b/src/objects/string.cc index b192e18add..674f242638 100644 --- a/src/objects/string.cc +++ b/src/objects/string.cc @@ -61,6 +61,14 @@ Handle String::SlowFlatten(Isolate* isolate, Handle cons, isolate->factory() ->NewRawOneByteString(length, allocation) .ToHandleChecked(); + // When the ConsString had a forwarding index, it is possible that it was + // transitioned to a ThinString (and eventually shortcutted to + // InternalizedString) during GC. + if (V8_UNLIKELY(FLAG_always_use_string_forwarding_table && + !cons->IsConsString())) { + DCHECK(cons->IsInternalizedString() || cons->IsThinString()); + return String::Flatten(isolate, cons, allocation); + } DisallowGarbageCollection no_gc; WriteToFlat(*cons, flat->GetChars(no_gc), 0, length); result = flat; @@ -69,6 +77,14 @@ Handle String::SlowFlatten(Isolate* isolate, Handle cons, isolate->factory() ->NewRawTwoByteString(length, allocation) .ToHandleChecked(); + // When the ConsString had a forwarding index, it is possible that it was + // transitioned to a ThinString (and eventually shortcutted to + // InternalizedString) during GC. + if (V8_UNLIKELY(FLAG_always_use_string_forwarding_table && + !cons->IsConsString())) { + DCHECK(cons->IsInternalizedString() || cons->IsThinString()); + return String::Flatten(isolate, cons, allocation); + } DisallowGarbageCollection no_gc; WriteToFlat(*cons, flat->GetChars(no_gc), 0, length); result = flat;