From b96d8490dbbd4c9b3cf231fa4e2b5ab87b376a25 Mon Sep 17 00:00:00 2001 From: Dimitar Trendafilov Date: Thu, 24 Dec 2020 14:18:18 +0200 Subject: Allow for copying collectors to be implemented --- gctest/gc.h | 12 +++++++----- gctest/gc_leak.cpp | 8 ++++---- gctest/main.cpp | 34 ++++++++++++++++++++-------------- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/gctest/gc.h b/gctest/gc.h index 42612ed..fcd180e 100644 --- a/gctest/gc.h +++ b/gctest/gc.h @@ -17,7 +17,8 @@ class ObjectVisitor public: virtual ~ObjectVisitor() {} - virtual void VisitReference(Object* from, Object* to, void* state) = 0; + // Object** to allows the reference to be moved + virtual void VisitReference(Object* from, Object** to, void* state) = 0; }; class GarbageCollector : public ObjectVisitor @@ -25,7 +26,8 @@ class GarbageCollector : public ObjectVisitor public: virtual void* Allocate(size_t size) = 0; - virtual void SetRoot(Object* root) = 0; + // Object** to allows the root to be moved + virtual void SetRoot(Object** root) = 0; virtual void Shutdown() = 0; }; @@ -43,11 +45,11 @@ public: } } - void VisitReference(Object*, Object* to, void*) override + void VisitReference(Object*, Object** to, void*) override { - if (to) + if (*to) { - Destroy(to); + Destroy(*to); } } std::unordered_set m_Visited; diff --git a/gctest/gc_leak.cpp b/gctest/gc_leak.cpp index 2a1b493..896ddf2 100644 --- a/gctest/gc_leak.cpp +++ b/gctest/gc_leak.cpp @@ -6,17 +6,17 @@ class LeakGC : public GarbageCollector { void* Allocate(size_t size) override { return ::operator new(size); } - void SetRoot(Object* root) override { m_Root = root; } + void SetRoot(Object** root) override { m_Root = root; } - void VisitReference(Object*, Object*, void*) override {} + void VisitReference(Object*, Object**, void*) override {} void Shutdown() override { DestroyVisitor dv; - dv.Destroy(m_Root); + dv.Destroy(*m_Root); } - Object* m_Root; + Object** m_Root; }; std::unique_ptr CreateGarbageCollector(int&, const char*[]) diff --git a/gctest/main.cpp b/gctest/main.cpp index 06bb5a8..e59f60a 100644 --- a/gctest/main.cpp +++ b/gctest/main.cpp @@ -57,9 +57,15 @@ private: uint8_t m_Extra[1]; }; +void* AllocateGCMemory(GarbageCollector* gc, size_t size) +{ + MTR_SCOPE_I("GC", "Allocate", "size", int(size)); + return gc->Allocate(size); +} + Object* CreateLeaf(GarbageCollector* gc, unsigned extraSize) { - auto memory = gc->Allocate(sizeof(LeafObject) + extraSize); + auto memory = AllocateGCMemory(gc, sizeof(LeafObject) + extraSize); auto result = new (memory) LeafObject(extraSize); return result; } @@ -75,10 +81,10 @@ public: void VisitReferences(ObjectVisitor* visitor, void* state) override { - for (auto i = 0u; i < m_Size; ++i) + auto end = m_Children + m_Size; + for (auto child = m_Children; child < end; ++child) { - auto child = m_Children[i]; - if (child) + if (*child) { visitor->VisitReference(this, child, state); } @@ -104,7 +110,7 @@ private: Object* CreateScanned(GarbageCollector* gc, unsigned children) { auto extraSize = children * sizeof(Object*); - auto memory = gc->Allocate(sizeof(ScannedObject) + extraSize); + auto memory = AllocateGCMemory(gc, sizeof(ScannedObject) + extraSize); auto result = new (memory) ScannedObject(children); return result; } @@ -235,9 +241,9 @@ struct HeapStatsVisitor : ObjectVisitor unsigned depth = 1; root->VisitReferences(this, &depth); } - void VisitReference(Object*, Object* to, void* state) override + void VisitReference(Object*, Object** to, void* state) override { - auto recycled = static_cast(to); + auto recycled = static_cast(*to); if (recycled->m_Generation < m_CurrentGeneration) { ++m_Reachable; @@ -249,7 +255,7 @@ struct HeapStatsVisitor : ObjectVisitor { m_Depth = depth; } - to->VisitReferences(this, &depth); + recycled->VisitReferences(this, &depth); } } size_t m_Reachable = 0; @@ -294,22 +300,22 @@ int main(int argc, const char* argv[]) create.AddAction(MakeFactory(CreateScanned, size_large, &rg, gc.get()), 20); auto root = static_cast(CreateScanned(gc.get(), 1000)); - gc->SetRoot(root); + gc->SetRoot(reinterpret_cast(&root)); WeightedActionTable operations(&rg); operations.AddAction( - [&create, &rg, root]() { NewObject(root, create, rg); }, 30); + [&create, &rg, &root]() { NewObject(root, create, rg); }, 30); operations.AddAction([&create]() { NewTempObject(create); }, 40); - operations.AddAction([root, &rg]() { DeleteObject(root, rg); }, 5); + operations.AddAction([&root, &rg]() { DeleteObject(root, rg); }, 5); - operations.AddAction([root, &rg]() { CopyObject(root, rg); }, 20); + operations.AddAction([&root, &rg]() { CopyObject(root, rg); }, 20); - operations.AddAction([root, &rg]() { MoveObject(root, rg); }, 10); + operations.AddAction([&root, &rg]() { MoveObject(root, rg); }, 10); - operations.AddAction([root, &rg]() { SwapObjects(root, rg); }, 20); + operations.AddAction([&root, &rg]() { SwapObjects(root, rg); }, 20); auto initial_count = 50000u; auto loops = 100u; -- cgit v1.3.1-23-gd82d