1 // Copyright 2020 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 #ifndef V8_HEAP_MARKING_WORKLIST_INL_H_ 5 #define V8_HEAP_MARKING_WORKLIST_INL_H_ 6 7 #include <unordered_map> 8 9 #include "src/heap/cppgc-js/cpp-marking-state-inl.h" 10 #include "src/heap/marking-worklist.h" 11 #include "src/objects/embedder-data-slot.h" 12 #include "src/objects/js-objects-inl.h" 13 14 namespace v8 { 15 namespace internal { 16 17 template <typename Callback> Update(Callback callback)18void MarkingWorklists::Update(Callback callback) { 19 shared_.Update(callback); 20 on_hold_.Update(callback); 21 wrapper_.Update(callback); 22 other_.Update(callback); 23 for (auto cw : context_worklists_) { 24 if (cw.context == kSharedContext || cw.context == kOtherContext) { 25 // These contexts were updated above. 26 continue; 27 } 28 cw.worklist->Update(callback); 29 } 30 } 31 Push(HeapObject object)32void MarkingWorklists::Local::Push(HeapObject object) { active_.Push(object); } 33 Pop(HeapObject * object)34bool MarkingWorklists::Local::Pop(HeapObject* object) { 35 if (active_.Pop(object)) return true; 36 if (!is_per_context_mode_) return false; 37 // The active worklist is empty. Find any other non-empty worklist and 38 // switch the active worklist to it. 39 return PopContext(object); 40 } 41 PushOnHold(HeapObject object)42void MarkingWorklists::Local::PushOnHold(HeapObject object) { 43 on_hold_.Push(object); 44 } 45 PopOnHold(HeapObject * object)46bool MarkingWorklists::Local::PopOnHold(HeapObject* object) { 47 return on_hold_.Pop(object); 48 } 49 SupportsExtractWrapper()50bool MarkingWorklists::Local::SupportsExtractWrapper() { 51 return cpp_marking_state_.get(); 52 } 53 ExtractWrapper(Map map,JSObject object,WrapperSnapshot & snapshot)54bool MarkingWorklists::Local::ExtractWrapper(Map map, JSObject object, 55 WrapperSnapshot& snapshot) { 56 DCHECK_NOT_NULL(cpp_marking_state_); 57 return cpp_marking_state_->ExtractEmbedderDataSnapshot(map, object, snapshot); 58 } 59 PushExtractedWrapper(const WrapperSnapshot & snapshot)60void MarkingWorklists::Local::PushExtractedWrapper( 61 const WrapperSnapshot& snapshot) { 62 DCHECK_NOT_NULL(cpp_marking_state_); 63 cpp_marking_state_->MarkAndPush(snapshot); 64 } 65 PushWrapper(HeapObject object)66void MarkingWorklists::Local::PushWrapper(HeapObject object) { 67 DCHECK_NULL(cpp_marking_state_); 68 wrapper_.Push(object); 69 } 70 PopWrapper(HeapObject * object)71bool MarkingWorklists::Local::PopWrapper(HeapObject* object) { 72 DCHECK_NULL(cpp_marking_state_); 73 return wrapper_.Pop(object); 74 } 75 SwitchToContext(Address context)76Address MarkingWorklists::Local::SwitchToContext(Address context) { 77 if (context == active_context_) return context; 78 return SwitchToContextSlow(context); 79 } 80 SwitchToShared()81Address MarkingWorklists::Local::SwitchToShared() { 82 return SwitchToContext(kSharedContext); 83 } 84 SwitchToContext(Address context,MarkingWorklist::Local * worklist)85void MarkingWorklists::Local::SwitchToContext( 86 Address context, MarkingWorklist::Local* worklist) { 87 // Save the current worklist. 88 *active_owner_ = std::move(active_); 89 // Switch to the new worklist. 90 active_owner_ = worklist; 91 active_ = std::move(*worklist); 92 active_context_ = context; 93 } 94 PublishWrapper()95bool MarkingWorklists::Local::PublishWrapper() { 96 if (!cpp_marking_state_) return false; 97 cpp_marking_state_->Publish(); 98 return true; 99 } 100 101 } // namespace internal 102 } // namespace v8 103 104 #endif // V8_HEAP_MARKING_WORKLIST_INL_H_ 105