diff options
author | Michaël Zasso <targos@protonmail.com> | 2021-04-17 17:28:47 +0300 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2021-04-30 13:54:09 +0300 |
commit | 5dc82469d5cb87e4451336f31483d8d69dd16dff (patch) | |
tree | f14bd3228f9d680603d92a9d731f98f49bd9b392 /deps | |
parent | 77b7a3b7100960fdd59a2f7b5785e56c42398961 (diff) |
deps: V8: cherry-pick 254c7945eea2
Original commit message:
Merged: [deoptimizer] Fix bug in OptimizedFrame::Summarize
Revision: 3353a7d0b017146d543434be4036a81aaf7d25ae
BUG=chromium:1182647
NOTRY=true
NOPRESUBMIT=true
NOTREECHECKS=true
R=bmeurer@chromium.org
(cherry picked from commit c0c96b768a7d3463b11403874549e6496529740d)
Change-Id: I86abd6a3f34169be5f99aa9f54bb7bb3706fa85a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2780300
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Original-Commit-Position: refs/branch-heads/8.9@{#49}
Cr-Original-Branched-From: 16b9bbbd581c25391981aa03180b76aa60463a3e-refs/heads/8.9.255@{#1}
Cr-Original-Branched-From: d16a2a688498bd1c3e6a49edb25d8c4ca56232dc-refs/heads/master@{#72039}
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2794427
Reviewed-by: Victor-Gabriel Savu <vsavu@google.com>
Commit-Queue: Artem Sumaneev <asumaneev@google.com>
Cr-Commit-Position: refs/branch-heads/8.6@{#72}
Cr-Branched-From: a64aed2333abf49e494d2a5ce24bbd14fff19f60-refs/heads/8.6.395@{#1}
Cr-Branched-From: a626bc036236c9bf92ac7b87dc40c9e538b087e3-refs/heads/master@{#69472}
Refs: https://github.com/v8/v8/commit/254c7945eea2ee85e2bab98dd802b9d940fc1f4b
PR-URL: https://github.com/nodejs/node/pull/38275
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r-- | deps/v8/src/deoptimizer/deoptimizer.cc | 58 | ||||
-rw-r--r-- | deps/v8/src/deoptimizer/deoptimizer.h | 19 | ||||
-rw-r--r-- | deps/v8/test/mjsunit/compiler/regress-1182647.js | 25 |
3 files changed, 92 insertions, 10 deletions
diff --git a/deps/v8/src/deoptimizer/deoptimizer.cc b/deps/v8/src/deoptimizer/deoptimizer.cc index 05cd675bedc..970723839ca 100644 --- a/deps/v8/src/deoptimizer/deoptimizer.cc +++ b/deps/v8/src/deoptimizer/deoptimizer.cc @@ -3266,7 +3266,8 @@ Address TranslatedState::DecompressIfNeeded(intptr_t value) { } } -TranslatedState::TranslatedState(const JavaScriptFrame* frame) { +TranslatedState::TranslatedState(const JavaScriptFrame* frame) + : purpose_(kFrameInspection) { int deopt_index = Safepoint::kNoDeoptimizationIndex; DeoptimizationData data = static_cast<const OptimizedFrame*>(frame)->GetDeoptimizationData( @@ -3641,25 +3642,63 @@ void TranslatedState::EnsureCapturedObjectAllocatedAt( } default: - CHECK(map->IsJSObjectMap()); EnsureJSObjectAllocated(slot, map); - TranslatedValue* properties_slot = &(frame->values_[value_index]); - value_index++; + int remaining_children_count = slot->GetChildrenCount() - 1; + + TranslatedValue* properties_slot = frame->ValueAt(value_index); + value_index++, remaining_children_count--; if (properties_slot->kind() == TranslatedValue::kCapturedObject) { - // If we are materializing the property array, make sure we put - // the mutable heap numbers at the right places. + // We are materializing the property array, so make sure we put the + // mutable heap numbers at the right places. EnsurePropertiesAllocatedAndMarked(properties_slot, map); EnsureChildrenAllocated(properties_slot->GetChildrenCount(), frame, &value_index, worklist); + } else { + CHECK_EQ(properties_slot->kind(), TranslatedValue::kTagged); } - // Make sure all the remaining children (after the map and properties) are - // allocated. - return EnsureChildrenAllocated(slot->GetChildrenCount() - 2, frame, + + TranslatedValue* elements_slot = frame->ValueAt(value_index); + value_index++, remaining_children_count--; + if (elements_slot->kind() == TranslatedValue::kCapturedObject || + !map->IsJSArrayMap()) { + // Handle this case with the other remaining children below. + value_index--, remaining_children_count++; + } else { + CHECK_EQ(elements_slot->kind(), TranslatedValue::kTagged); + elements_slot->GetValue(); + if (purpose_ == kFrameInspection) { + // We are materializing a JSArray for the purpose of frame inspection. + // If we were to construct it with the above elements value then an + // actual deopt later on might create another JSArray instance with + // the same elements store. That would violate the key assumption + // behind left-trimming. + elements_slot->ReplaceElementsArrayWithCopy(); + } + } + + // Make sure all the remaining children (after the map, properties store, + // and possibly elements store) are allocated. + return EnsureChildrenAllocated(remaining_children_count, frame, &value_index, worklist); } UNREACHABLE(); } +void TranslatedValue::ReplaceElementsArrayWithCopy() { + DCHECK_EQ(kind(), TranslatedValue::kTagged); + DCHECK_EQ(materialization_state(), TranslatedValue::kFinished); + auto elements = Handle<FixedArrayBase>::cast(GetValue()); + DCHECK(elements->IsFixedArray() || elements->IsFixedDoubleArray()); + if (elements->IsFixedDoubleArray()) { + DCHECK(!elements->IsCowArray()); + set_storage(isolate()->factory()->CopyFixedDoubleArray( + Handle<FixedDoubleArray>::cast(elements))); + } else if (!elements->IsCowArray()) { + set_storage(isolate()->factory()->CopyFixedArray( + Handle<FixedArray>::cast(elements))); + } +} + void TranslatedState::EnsureChildrenAllocated(int count, TranslatedFrame* frame, int* value_index, std::stack<int>* worklist) { @@ -3724,6 +3763,7 @@ Handle<ByteArray> TranslatedState::AllocateStorageFor(TranslatedValue* slot) { void TranslatedState::EnsureJSObjectAllocated(TranslatedValue* slot, Handle<Map> map) { + CHECK(map->IsJSObjectMap()); CHECK_EQ(map->instance_size(), slot->GetChildrenCount() * kTaggedSize); Handle<ByteArray> object_storage = AllocateStorageFor(slot); diff --git a/deps/v8/src/deoptimizer/deoptimizer.h b/deps/v8/src/deoptimizer/deoptimizer.h index ee6978e6292..eaf0578878d 100644 --- a/deps/v8/src/deoptimizer/deoptimizer.h +++ b/deps/v8/src/deoptimizer/deoptimizer.h @@ -117,6 +117,8 @@ class TranslatedValue { return storage_; } + void ReplaceElementsArrayWithCopy(); + Kind kind_; MaterializationState materialization_state_ = kUninitialized; TranslatedState* container_; // This is only needed for materialization of @@ -313,7 +315,15 @@ class TranslatedFrame { class TranslatedState { public: - TranslatedState() = default; + // There are two constructors, each for a different purpose: + + // The default constructor is for the purpose of deoptimizing an optimized + // frame (replacing it with one or several unoptimized frames). It is used by + // the Deoptimizer. + TranslatedState() : purpose_(kDeoptimization) {} + + // This constructor is for the purpose of merely inspecting an optimized + // frame. It is used by stack trace generation and various debugging features. explicit TranslatedState(const JavaScriptFrame* frame); void Prepare(Address stack_frame_pointer); @@ -347,6 +357,12 @@ class TranslatedState { private: friend TranslatedValue; + // See the description of the constructors for an explanation of the two + // purposes. The only actual difference is that in the kFrameInspection case + // extra work is needed to not violate assumptions made by left-trimming. For + // details, see the code around ReplaceElementsArrayWithCopy. + enum Purpose { kDeoptimization, kFrameInspection }; + TranslatedFrame CreateNextTranslatedFrame(TranslationIterator* iterator, FixedArray literal_array, Address fp, FILE* trace_file); @@ -404,6 +420,7 @@ class TranslatedState { static Float32 GetFloatSlot(Address fp, int slot_index); static Float64 GetDoubleSlot(Address fp, int slot_index); + Purpose const purpose_; std::vector<TranslatedFrame> frames_; Isolate* isolate_ = nullptr; Address stack_frame_pointer_ = kNullAddress; diff --git a/deps/v8/test/mjsunit/compiler/regress-1182647.js b/deps/v8/test/mjsunit/compiler/regress-1182647.js new file mode 100644 index 00000000000..e0582f7cbfb --- /dev/null +++ b/deps/v8/test/mjsunit/compiler/regress-1182647.js @@ -0,0 +1,25 @@ +// Copyright 2021 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 --verify-heap + +function foo() { + const arr = Array(1000); + + function bar() { + try { ({a: p4nda, b: arr.length}); } catch(e) {} + } + + for (var i = 0; i < 25; i++) bar(); + + /p4nda/.test({}); // Deopt here. + + arr.shift(); +} + +%PrepareFunctionForOptimization(foo); +foo(); +foo(); +%OptimizeFunctionOnNextCall(foo); +foo(); |