• 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 #ifndef V8_HEAP_CPPGC_JS_UNIFIED_HEAP_MARKING_STATE_INL_H_
6 #define V8_HEAP_CPPGC_JS_UNIFIED_HEAP_MARKING_STATE_INL_H_
7 
8 #include "include/v8-traced-handle.h"
9 #include "src/base/logging.h"
10 #include "src/handles/global-handles.h"
11 #include "src/heap/cppgc-js/unified-heap-marking-state.h"
12 #include "src/heap/heap.h"
13 #include "src/heap/mark-compact.h"
14 #include "src/heap/marking-worklist-inl.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 class BasicTracedReferenceExtractor {
20  public:
GetObjectForMarking(const TracedReferenceBase & ref)21   static Object GetObjectForMarking(const TracedReferenceBase& ref) {
22     Address* global_handle_location = const_cast<Address*>(
23         reinterpret_cast<const Address*>(ref.GetSlotThreadSafe()));
24     // We cannot assume that the reference is non-null as we may get here by
25     // tracing an ephemeron which doesn't have early bailouts, see
26     // `cppgc::Visitor::TraceEphemeron()` for non-Member values.
27     if (!global_handle_location) return Object();
28 
29     GlobalHandles::MarkTraced(global_handle_location);
30     return Object(
31         reinterpret_cast<std::atomic<Address>*>(global_handle_location)
32             ->load(std::memory_order_relaxed));
33   }
34 };
35 
MarkAndPush(const TracedReferenceBase & reference)36 void UnifiedHeapMarkingState::MarkAndPush(
37     const TracedReferenceBase& reference) {
38   // The following code will crash with null pointer derefs when finding a
39   // non-empty `TracedReferenceBase` when `CppHeap` is in detached mode.
40 
41   Object object = BasicTracedReferenceExtractor::GetObjectForMarking(reference);
42   if (!object.IsHeapObject()) {
43     // The embedder is not aware of whether numbers are materialized as heap
44     // objects are just passed around as Smis.
45     return;
46   }
47   HeapObject heap_object = HeapObject::cast(object);
48   if (marking_state_->WhiteToGrey(heap_object)) {
49     local_marking_worklist_->Push(heap_object);
50   }
51   if (V8_UNLIKELY(track_retaining_path_)) {
52     heap_->AddRetainingRoot(Root::kWrapperTracing, heap_object);
53   }
54 }
55 
56 }  // namespace internal
57 }  // namespace v8
58 
59 #endif  // V8_HEAP_CPPGC_JS_UNIFIED_HEAP_MARKING_STATE_INL_H_
60