diff --git a/src/coreclr/gc/CMakeLists.txt b/src/coreclr/gc/CMakeLists.txt index 89dbc0c5e42..79c7714bb73 100644 --- a/src/coreclr/gc/CMakeLists.txt +++ b/src/coreclr/gc/CMakeLists.txt @@ -114,6 +114,8 @@ if (CLR_CMAKE_TARGET_WIN32) satori/SatoriRegionQueue.h satori/SatoriAllocator.h satori/SatoriRecycler.h + satori/SatoriMarkChunk.h + satori/SatoriMarkChunkQueue.h satori/SatoriAllocationContext.h satori/SatoriUtil.h satori/SatoriLock.h diff --git a/src/coreclr/src/gc/satori/SatoriMarkChunk.h b/src/coreclr/src/gc/satori/SatoriMarkChunk.h new file mode 100644 index 00000000000..34514c30944 --- /dev/null +++ b/src/coreclr/src/gc/satori/SatoriMarkChunk.h @@ -0,0 +1,63 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// +// SatoriMarkChunk.h +// + +#ifndef __SATORI_MARK_CHUNK_H__ +#define __SATORI_MARK_CHUNK_H__ + +#include "common.h" +#include "../gc.h" +#include "SatoriUtil.h" +#include "SatoriQueue.h" + +class SatoriMarkChunk +{ + friend class SatoriQueue; + friend class SatoriObject; + +public: + SatoriMarkChunk() = delete; + ~SatoriMarkChunk() = delete; + + static SatoriMarkChunk* InitializeAt(size_t address) + { + SatoriMarkChunk* self = (SatoriMarkChunk*)address; + self->m_top = 0; + self->m_prev = self->m_next = nullptr; + self->m_containingQueue = nullptr; + + return self; + } + + bool TryPush(SatoriObject* obj) + { + if (m_top < Satori::MARK_CHUNK_SIZE - sizeof(SatoriMarkChunk)) + { + m_data[m_top++] = obj; + return true; + } + + return false; + } + + SatoriObject* TryPop() + { + return m_top ? + m_data[--m_top] : + nullptr; + } + +private: + size_t m_top; + + SatoriMarkChunk* m_prev; + SatoriMarkChunk* m_next; + SatoriQueue* m_containingQueue; + + SatoriObject* m_data[1]; +}; + +#endif diff --git a/src/coreclr/src/gc/satori/SatoriMarkChunkQueue.h b/src/coreclr/src/gc/satori/SatoriMarkChunkQueue.h new file mode 100644 index 00000000000..58283bf96c6 --- /dev/null +++ b/src/coreclr/src/gc/satori/SatoriMarkChunkQueue.h @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// +// SatoriRegionQueue.h +// + +#ifndef __SATORI_MARK_CHUNK_QUEUE_H__ +#define __SATORI_MARK_CHUNK_QUEUE_H__ + +#include "common.h" +#include "../gc.h" +#include "SatoriQueue.h" + +class SatoriMarkChunk; + +class SatoriMarkChunkQueue : public SatoriQueue +{ +public: + +}; + +#endif diff --git a/src/coreclr/src/gc/satori/SatoriRecycler.cpp b/src/coreclr/src/gc/satori/SatoriRecycler.cpp index b4ade420138..98ad431fa5c 100644 --- a/src/coreclr/src/gc/satori/SatoriRecycler.cpp +++ b/src/coreclr/src/gc/satori/SatoriRecycler.cpp @@ -14,10 +14,29 @@ #include "SatoriRecycler.h" #include "SatoriRegion.h" #include "SatoriRegion.inl" +#include "SatoriMarkChunk.h" void SatoriRecycler::Initialize(SatoriHeap* heap) { m_heap = heap; + + m_regions = new SatoriRegionQueue(); + m_work_list = new SatoriMarkChunkQueue(); + m_free_list = new SatoriMarkChunkQueue(); + + SatoriRegion* region = m_heap->Allocator()->GetRegion(Satori::REGION_SIZE_GRANULARITY); + + while (true) + { + size_t mem = region->Allocate(Satori::MARK_CHUNK_SIZE, /*ensureZeroInited*/ false); + if (!mem) + { + break; + } + + SatoriMarkChunk* chunk = SatoriMarkChunk::InitializeAt(mem); + m_free_list->Push(chunk); + } } void SatoriRecycler::AddRegion(SatoriRegion* region) diff --git a/src/coreclr/src/gc/satori/SatoriRecycler.h b/src/coreclr/src/gc/satori/SatoriRecycler.h index 21495a4fe0f..3dc671b4cb2 100644 --- a/src/coreclr/src/gc/satori/SatoriRecycler.h +++ b/src/coreclr/src/gc/satori/SatoriRecycler.h @@ -10,6 +10,8 @@ #include "common.h" #include "../gc.h" +#include "SatoriRegionQueue.h" +#include "SatoriMarkChunkQueue.h" class SatoriHeap; class SatoriRegion; @@ -22,6 +24,10 @@ public: private: SatoriHeap* m_heap; + + SatoriRegionQueue* m_regions; + SatoriMarkChunkQueue* m_work_list; + SatoriMarkChunkQueue* m_free_list; }; #endif diff --git a/src/coreclr/src/gc/satori/SatoriRegion.cpp b/src/coreclr/src/gc/satori/SatoriRegion.cpp index 92e9ec7279f..0bf3f5492b6 100644 --- a/src/coreclr/src/gc/satori/SatoriRegion.cpp +++ b/src/coreclr/src/gc/satori/SatoriRegion.cpp @@ -18,6 +18,7 @@ #include "SatoriObject.inl" #include "SatoriRegion.h" #include "SatoriRegion.inl" +#include "SatoriQueue.h" #ifdef memcpy #undef memcpy diff --git a/src/coreclr/src/gc/satori/SatoriUtil.h b/src/coreclr/src/gc/satori/SatoriUtil.h index 58743f1e777..5faeb70961f 100644 --- a/src/coreclr/src/gc/satori/SatoriUtil.h +++ b/src/coreclr/src/gc/satori/SatoriUtil.h @@ -45,6 +45,9 @@ namespace Satori // if we do cleaning, and if available // TODO: VS should this be a constant or be 1/2 L0 ? static const size_t MIN_REGULAR_ALLOC = 16 << 10; + + // 8K for now, we can fiddle with size a bit later + const static size_t MARK_CHUNK_SIZE = 8 * 1024; } class SatoriUtil diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt index 49649371ba0..ba3657eb806 100644 --- a/src/coreclr/vm/CMakeLists.txt +++ b/src/coreclr/vm/CMakeLists.txt @@ -551,6 +551,8 @@ set(GC_HEADERS_WKS ../gc/satori/SatoriRegionQueue.h ../gc/satori/SatoriAllocator.h ../gc/satori/SatoriRecycler.h + ../gc/satori/SatoriMarkChunk.h + ../gc/satori/SatoriMarkChunkQueue.h ../gc/satori/SatoriAllocationContext.h ../gc/satori/SatoriUtil.h ../gc/satori/SatoriLock.h