• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/heap/reference-summarizer.h"
6 
7 #include "src/heap/mark-compact-inl.h"
8 #include "src/heap/marking-visitor-inl.h"
9 #include "src/objects/embedder-data-array-inl.h"
10 #include "src/objects/js-array-buffer-inl.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 namespace {
16 
17 // A class which acts as a MarkingState but does not actually update any marking
18 // bits. It reports all objects as white and all transitions as successful. It
19 // also tracks which objects are retained by the primary object according to the
20 // marking visitor.
21 class ReferenceSummarizerMarkingState final {
22  public:
23   // Declares that this marking state is collecting retainers, so the marking
24   // visitor must fully visit each object and can't update on-heap state.
25   static constexpr bool kCollectRetainers = true;
26 
ReferenceSummarizerMarkingState(HeapObject object)27   explicit ReferenceSummarizerMarkingState(HeapObject object)
28       : primary_object_(object),
29         local_marking_worklists_(&marking_worklists_),
30         local_weak_objects_(&weak_objects_) {}
31 
~ReferenceSummarizerMarkingState()32   ~ReferenceSummarizerMarkingState() {
33     // Clean up temporary state.
34     local_weak_objects_.Publish();
35     weak_objects_.Clear();
36     local_marking_worklists_.Publish();
37     marking_worklists_.Clear();
38   }
39 
40   // Retrieves the references that were collected by this marker. This operation
41   // transfers ownership of the set, so calling it again would yield an empty
42   // result.
DestructivelyRetrieveReferences()43   ReferenceSummary DestructivelyRetrieveReferences() {
44     ReferenceSummary tmp = std::move(references_);
45     references_.Clear();
46     return tmp;
47   }
48 
49   // Standard marking visitor functions:
50 
IsWhite(HeapObject obj) const51   bool IsWhite(HeapObject obj) const { return true; }
52 
IsBlackOrGrey(HeapObject obj) const53   bool IsBlackOrGrey(HeapObject obj) const { return false; }
54 
WhiteToGrey(HeapObject obj)55   bool WhiteToGrey(HeapObject obj) { return true; }
56 
GreyToBlack(HeapObject obj)57   bool GreyToBlack(HeapObject obj) { return true; }
58 
59   // Adds a retaining relationship found by the marking visitor.
AddStrongReferenceForReferenceSummarizer(HeapObject host,HeapObject obj)60   void AddStrongReferenceForReferenceSummarizer(HeapObject host,
61                                                 HeapObject obj) {
62     AddReference(host, obj, references_.strong_references());
63   }
64 
65   // Adds a non-retaining weak reference found by the marking visitor. The value
66   // in an ephemeron hash table entry is also included here, since it is not
67   // known to be strong without further information about the key.
AddWeakReferenceForReferenceSummarizer(HeapObject host,HeapObject obj)68   void AddWeakReferenceForReferenceSummarizer(HeapObject host, HeapObject obj) {
69     AddReference(host, obj, references_.weak_references());
70   }
71 
72   // Other member functions, not part of the marking visitor contract:
73 
local_marking_worklists()74   MarkingWorklists::Local* local_marking_worklists() {
75     return &local_marking_worklists_;
76   }
local_weak_objects()77   WeakObjects::Local* local_weak_objects() { return &local_weak_objects_; }
78 
79  private:
AddReference(HeapObject host,HeapObject obj,std::unordered_set<HeapObject,Object::Hasher> & references)80   void AddReference(
81       HeapObject host, HeapObject obj,
82       std::unordered_set<HeapObject, Object::Hasher>& references) {
83     // It's possible that the marking visitor handles multiple objects at once,
84     // such as a Map and its DescriptorArray, but we're only interested in
85     // references from the primary object.
86     if (host == primary_object_) {
87       references.insert(obj);
88     }
89   }
90 
91   ReferenceSummary references_;
92   HeapObject primary_object_;
93   MarkingWorklists marking_worklists_;
94   MarkingWorklists::Local local_marking_worklists_;
95   WeakObjects weak_objects_;
96   WeakObjects::Local local_weak_objects_;
97 };
98 
99 }  // namespace
100 
SummarizeReferencesFrom(Heap * heap,HeapObject obj)101 ReferenceSummary ReferenceSummary::SummarizeReferencesFrom(Heap* heap,
102                                                            HeapObject obj) {
103   ReferenceSummarizerMarkingState marking_state(obj);
104 
105   MainMarkingVisitor<ReferenceSummarizerMarkingState> visitor(
106       &marking_state, marking_state.local_marking_worklists(),
107       marking_state.local_weak_objects(), heap, 0 /*mark_compact_epoch*/,
108       {} /*code_flush_mode*/, false /*embedder_tracing_enabled*/,
109       true /*should_keep_ages_unchanged*/);
110   visitor.Visit(obj.map(heap->isolate()), obj);
111 
112   return marking_state.DestructivelyRetrieveReferences();
113 }
114 
115 }  // namespace internal
116 }  // namespace v8
117