mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 21:22:46 +00:00 
			
		
		
		
	 4bbb0a5c35
			
		
	
	
		4bbb0a5c35
		
	
	
	
	
		
			
			This works very similarly to MarkedVector<T>, but instead of expecting
T to be Value or a GC-allocated pointer type, T can be anything.
Every pointer-sized value in the vector's storage will be checked during
conservative root scanning.
In other words, this allows you to put something like this in a
ConservativeVector<Foo> and it will be protected from GC:
    struct Foo {
        i64 number;
        Value some_value;
        GCPtr<Object> some_object;
    };
		
	
			
		
			
				
	
	
		
			73 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2024, Andreas Kling <kling@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <AK/HashMap.h>
 | |
| #include <AK/IntrusiveList.h>
 | |
| #include <AK/Vector.h>
 | |
| #include <LibJS/Forward.h>
 | |
| #include <LibJS/Heap/Cell.h>
 | |
| #include <LibJS/Heap/HeapRoot.h>
 | |
| 
 | |
| namespace JS {
 | |
| 
 | |
| class ConservativeVectorBase {
 | |
| public:
 | |
|     virtual ReadonlySpan<FlatPtr> possible_values() const = 0;
 | |
| 
 | |
| protected:
 | |
|     explicit ConservativeVectorBase(Heap&);
 | |
|     ~ConservativeVectorBase();
 | |
| 
 | |
|     ConservativeVectorBase& operator=(ConservativeVectorBase const&);
 | |
| 
 | |
|     Heap* m_heap { nullptr };
 | |
|     IntrusiveListNode<ConservativeVectorBase> m_list_node;
 | |
| 
 | |
| public:
 | |
|     using List = IntrusiveList<&ConservativeVectorBase::m_list_node>;
 | |
| };
 | |
| 
 | |
| template<typename T, size_t inline_capacity>
 | |
| class ConservativeVector final
 | |
|     : public ConservativeVectorBase
 | |
|     , public Vector<T, inline_capacity> {
 | |
| 
 | |
| public:
 | |
|     explicit ConservativeVector(Heap& heap)
 | |
|         : ConservativeVectorBase(heap)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual ~ConservativeVector() = default;
 | |
| 
 | |
|     ConservativeVector(ConservativeVector const& other)
 | |
|         : ConservativeVectorBase(*other.m_heap)
 | |
|         , Vector<T, inline_capacity>(other)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     ConservativeVector(ConservativeVector&& other)
 | |
|         : ConservativeVectorBase(*other.m_heap)
 | |
|         , Vector<T, inline_capacity>(move(static_cast<Vector<T, inline_capacity>&>(other)))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     ConservativeVector& operator=(ConservativeVector const& other)
 | |
|     {
 | |
|         Vector<T, inline_capacity>::operator=(other);
 | |
|         ConservativeVectorBase::operator=(other);
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
|     virtual ReadonlySpan<FlatPtr> possible_values() const override
 | |
|     {
 | |
|         return ReadonlySpan<FlatPtr> { reinterpret_cast<FlatPtr const*>(this->data()), this->size() };
 | |
|     }
 | |
| };
 | |
| 
 | |
| }
 |