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
16namespace v8 {
17namespace internal {
18
19class BasicTracedReferenceExtractor {
20 public:
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
36void 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