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)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