From ee01d6b7fc7746153e47915f2210b453fe0e0530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Tue, 12 Jan 2021 13:03:12 +0100 Subject: [PATCH] deps: V8: cherry-pick 2059ee813359 Original commit message: [heap] Make CompactTransitionArray deserializer friendly Add a pre-loop over transition arrays during compaction, that checks whether compaction is needed at all, and whether any of the entries are still uninitialized values as part of deserialization (and therefore no other targets can be dead). Bails out of compaction early if this is the case. Bug: v8:11305 Change-Id: I27af792a8a0bd3df17892f54ac95ed15e4bdfcc0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2622910 Reviewed-by: Ulan Degenbaev Commit-Queue: Leszek Swirski Cr-Commit-Position: refs/heads/master@{#72038} Refs: https://github.com/v8/v8/commit/2059ee8133591830c5050b4839ec52889abaa34e PR-URL: https://github.com/nodejs/node/pull/36139 Reviewed-By: Jiawen Geng Reviewed-By: Colin Ihrig Reviewed-By: Myles Borins Reviewed-By: Shelley Vohr --- common.gypi | 2 +- deps/v8/src/heap/mark-compact.cc | 34 ++++++++++++++++++++++++++++++++ deps/v8/src/heap/mark-compact.h | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/common.gypi b/common.gypi index 86d6029cea8599..2eb9d1d6846448 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.17', + 'v8_embedder_string': '-node.18', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/heap/mark-compact.cc b/deps/v8/src/heap/mark-compact.cc index 91a19021821065..ea1902c972a154 100644 --- a/deps/v8/src/heap/mark-compact.cc +++ b/deps/v8/src/heap/mark-compact.cc @@ -2288,11 +2288,45 @@ void MarkCompactCollector::ClearFullMapTransitions() { } } +// Returns false if no maps have died, or if the transition array is +// still being deserialized. +bool MarkCompactCollector::TransitionArrayNeedsCompaction( + TransitionArray transitions, int num_transitions) { + for (int i = 0; i < num_transitions; ++i) { + MaybeObject raw_target = transitions.GetRawTarget(i); + if (raw_target.IsSmi()) { + // This target is still being deserialized, + DCHECK(isolate()->has_active_deserializer()); + DCHECK_EQ(raw_target.ToSmi(), Deserializer::uninitialized_field_value()); +#ifdef DEBUG + // Targets can only be dead iff this array is fully deserialized. + for (int i = 0; i < num_transitions; ++i) { + DCHECK(!non_atomic_marking_state()->IsWhite(transitions.GetTarget(i))); + } +#endif + return false; + } else if (non_atomic_marking_state()->IsWhite( + TransitionsAccessor::GetTargetFromRaw(raw_target))) { +#ifdef DEBUG + // Targets can only be dead iff this array is fully deserialized. + for (int i = 0; i < num_transitions; ++i) { + DCHECK(!transitions.GetRawTarget(i).IsSmi()); + } +#endif + return true; + } + } + return false; +} + bool MarkCompactCollector::CompactTransitionArray(Map map, TransitionArray transitions, DescriptorArray descriptors) { DCHECK(!map.is_prototype_map()); int num_transitions = transitions.number_of_entries(); + if (!TransitionArrayNeedsCompaction(transitions, num_transitions)) { + return false; + } bool descriptors_owner_died = false; int transition_index = 0; // Compact all live transitions to the left. diff --git a/deps/v8/src/heap/mark-compact.h b/deps/v8/src/heap/mark-compact.h index 4d598f71ff756c..34206a825ffe74 100644 --- a/deps/v8/src/heap/mark-compact.h +++ b/deps/v8/src/heap/mark-compact.h @@ -681,6 +681,8 @@ class MarkCompactCollector final : public MarkCompactCollectorBase { void TrimEnumCache(Map map, DescriptorArray descriptors); bool CompactTransitionArray(Map map, TransitionArray transitions, DescriptorArray descriptors); + bool TransitionArrayNeedsCompaction(TransitionArray transitions, + int num_transitions); // After all reachable objects have been marked those weak map entries // with an unreachable key are removed from all encountered weak maps.