From 0d25fc2c8eb13e17a51ebb2d46d95848da621ded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Z=C3=BCnd?= Date: Tue, 20 Sep 2022 10:22:41 +0200 Subject: [PATCH] [debug] Introduce EphemeronHashTable root for locals block lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This CL introduces a new root that is conceptually a WeakMap> Instead of storing the "locals block list" for debug-evaluate on the `ScopeInfo` object directly, we will store it instead in a global WeakMap. This enables us to re-use the "locals block lists" across multiple debug-evaluate invocations without having to modify the `ScopeInfo` of `SharedFunctionInfo`s. R=bmeurer@chromium.org Doc: https://bit.ly/chrome-devtools-debug-evaluate-design Bug: chromium:1363561 Change-Id: Ib52f9abd97cf1c8fa3053ff3c61a6062c4b814be Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3902041 Reviewed-by: Dominik Inführ Commit-Queue: Simon Zünd Reviewed-by: Benedikt Meurer Cr-Commit-Position: refs/heads/main@{#83318} --- src/execution/isolate.cc | 40 +++++++++++++++++++++++++++++++++ src/execution/isolate.h | 10 +++++++++ src/heap/setup-heap-internal.cc | 1 + src/roots/roots.h | 2 ++ 4 files changed, 53 insertions(+) diff --git a/src/execution/isolate.cc b/src/execution/isolate.cc index ed88407757..d36a504894 100644 --- a/src/execution/isolate.cc +++ b/src/execution/isolate.cc @@ -94,6 +94,7 @@ #include "src/objects/slots.h" #include "src/objects/smi.h" #include "src/objects/source-text-module-inl.h" +#include "src/objects/string-set-inl.h" #include "src/objects/visitors.h" #include "src/profiler/heap-profiler.h" #include "src/profiler/tracing-cpu-profiler.h" @@ -6004,6 +6005,45 @@ ExternalPointerHandle Isolate::GetOrCreateWaiterQueueNodeExternalPointer() { } #endif // V8_COMPRESS_POINTERS +void Isolate::LocalsBlockListCacheSet(Handle scope_info, + Handle outer_scope_info, + Handle locals_blocklist) { + Handle cache; + if (heap()->locals_block_list_cache().IsEphemeronHashTable()) { + cache = handle(EphemeronHashTable::cast(heap()->locals_block_list_cache()), + this); + } else { + CHECK(heap()->locals_block_list_cache().IsUndefined()); + constexpr int kInitialCapacity = 8; + cache = EphemeronHashTable::New(this, kInitialCapacity); + } + DCHECK(cache->IsEphemeronHashTable()); + + Handle outer_scope_info_and_locals = factory()->NewTuple2( + outer_scope_info, locals_blocklist, AllocationType::kYoung); + + cache = + EphemeronHashTable::Put(cache, scope_info, outer_scope_info_and_locals); + heap()->set_locals_block_list_cache(*cache); +} + +Object Isolate::LocalsBlockListCacheGet(Handle scope_info) { + DisallowGarbageCollection no_gc; + + if (!heap()->locals_block_list_cache().IsEphemeronHashTable()) { + return ReadOnlyRoots(this).the_hole_value(); + } + + Object maybe_outer_scope_info_and_locals = + EphemeronHashTable::cast(heap()->locals_block_list_cache()) + .Lookup(scope_info); + if (maybe_outer_scope_info_and_locals.IsTheHole()) { + return maybe_outer_scope_info_and_locals; + } + + return Tuple2::cast(maybe_outer_scope_info_and_locals).value2(); +} + namespace { class DefaultWasmAsyncResolvePromiseTask : public v8::Task { public: diff --git a/src/execution/isolate.h b/src/execution/isolate.h index 6868b8c280..4c913d63fa 100644 --- a/src/execution/isolate.h +++ b/src/execution/isolate.h @@ -2036,6 +2036,16 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory { wasm::StackMemory*& wasm_stacks() { return wasm_stacks_; } #endif + // Access to the global "locals block list cache". Caches outer-stack + // allocated variables per ScopeInfo for debug-evaluate. + // We also store a strong reference to the outer ScopeInfo to keep all + // blocklists along a scope chain alive. + void LocalsBlockListCacheSet(Handle scope_info, + Handle outer_scope_info, + Handle locals_blocklist); + // Returns either `TheHole` or `StringSet`. + Object LocalsBlockListCacheGet(Handle scope_info); + private: explicit Isolate(std::unique_ptr isolate_allocator, bool is_shared); diff --git a/src/heap/setup-heap-internal.cc b/src/heap/setup-heap-internal.cc index deb0bb1c26..93c1a12b47 100644 --- a/src/heap/setup-heap-internal.cc +++ b/src/heap/setup-heap-internal.cc @@ -878,6 +878,7 @@ void Heap::CreateInitialObjects() { set_feedback_vectors_for_profiling_tools(roots.undefined_value()); set_pending_optimize_for_test_bytecode(roots.undefined_value()); set_shared_wasm_memories(roots.empty_weak_array_list()); + set_locals_block_list_cache(roots.undefined_value()); #ifdef V8_ENABLE_WEBASSEMBLY set_active_continuation(roots.undefined_value()); set_active_suspender(roots.undefined_value()); diff --git a/src/roots/roots.h b/src/roots/roots.h index 3709a2478f..112786e0bb 100644 --- a/src/roots/roots.h +++ b/src/roots/roots.h @@ -334,6 +334,8 @@ class Symbol; PendingOptimizeForTestBytecode) \ V(ArrayList, basic_block_profiling_data, BasicBlockProfilingData) \ V(WeakArrayList, shared_wasm_memories, SharedWasmMemories) \ + /* EphemeronHashTable for debug scopes (local debug evaluate) */ \ + V(HeapObject, locals_block_list_cache, DebugLocalsBlockListCache) \ IF_WASM(V, HeapObject, active_continuation, ActiveContinuation) \ IF_WASM(V, HeapObject, active_suspender, ActiveSuspender) \ IF_WASM(V, WeakArrayList, js_to_wasm_wrappers, JSToWasmWrappers) \