// Copyright 2019 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. #ifndef V8_HEAP_MARKING_WORKLIST_H_ #define V8_HEAP_MARKING_WORKLIST_H_ #include <cstddef> #include <memory> #include <unordered_map> #include <vector> #include "src/heap/base/worklist.h" #include "src/heap/cppgc-js/cpp-marking-state.h" #include "src/objects/heap-object.h" #include "src/utils/address-map.h" namespace v8 { namespace internal { class CppMarkingState; class JSObject; // The index of the main thread task used by concurrent/parallel GC. const int kMainThreadTask = …; MarkingWorklist; // We piggyback on marking to compute object sizes per native context that is // needed for the new memory measurement API. The algorithm works as follows: // 1) At the start of marking we create a marking worklist for each context. // The existing shared, on_hold, and embedder worklists continue to work // as they did before, but they hold objects that are not attributed to any // context yet. // 2) Each marker has an active worklist where it pushes newly discovered // objects. Initially the shared worklist is set as active for all markers. // 3) When a marker pops an object from the active worklist: // a) It checks if the object has a known context (e.g. JSObjects, Maps, // Contexts know the context they belong to). If that's the case, then // the marker changes its active worklist to the worklist corresponding // to the context of the object. // b) It account the size of object to the active context. // c) It visits all pointers in the object and pushes new objects onto the // active worklist. // 4) When the active worklist becomes empty the marker selects any other // non-empty worklist as the active worklist. // 5) The write barrier pushes onto the shared worklist. // // The main invariant for context worklists: // If object X is in the worklist of context C, then either // a) X has a context and that context is C. // b) X is retained by object Y that has context C. // // The algorithm allows us to attribute context-independent objects such as // strings, numbers, FixedArrays to their retaining contexts. The algorithm is // not precise for context-independent objects that are shared between multiple // contexts. Such objects may be attributed to any retaining context. // Named pair of native context address and its marking worklist. // Since native contexts are allocated in the old generation, their addresses // a stable across Scavenges and stay valid throughout the marking phase. struct ContextWorklistPair { … }; // A helper class that owns all global marking worklists. class V8_EXPORT_PRIVATE MarkingWorklists final { … }; // A thread-local view of the marking worklists. It owns all local marking // worklists and keeps track of the currently active local marking worklist // for per-context marking. In order to avoid additional indirections for // pushing and popping entries, the active_ worklist is not a pointer to // Local but an actual instance of Local with the following invariants: // - active_owner == worlist_by_context[active_context_].get() // - *active_owner is empty (all fields are null) because its content has // been moved to active_. class V8_EXPORT_PRIVATE MarkingWorklists::Local final { … }; } // namespace internal } // namespace v8 #endif // V8_HEAP_MARKING_WORKLIST_H_