1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-11 02:13:38 +09:00

SatoriObject + some cleanup

This commit is contained in:
vsadov 2020-06-16 15:46:15 -07:00
parent cd4ed29a53
commit 2a2c840007
27 changed files with 712 additions and 578 deletions

View file

@ -25,10 +25,11 @@ set( GC_SOURCES
gceewks.cpp
gcload.cpp
handletablecache.cpp
satori/SatoriGCHeap.cpp
satori/SatoriGC.cpp
satori/SatoriHeap.cpp
satori/SatoriPage.cpp
satori/SatoriRegion.cpp
satori/SatoriObject.cpp
satori/SatoriRegionQueue.cpp
satori/SatoriAllocator.cpp
satori/SatoriRecycler.cpp
@ -101,11 +102,14 @@ if (CLR_CMAKE_TARGET_WIN32)
handletablepriv.h
objecthandle.h
softwarewritewatch.h
satori/SatoriGC.h
vxsort/do_vxsort.h
satori/SatoriGCHeap.h
satori/SatoriHeap.h
satori/SatoriPage.h
satori/SatoriRegion.h
satori/SatoriObject.h
satori/SatoriObject.inl
satori/SatoriRegionQueue.h
satori/SatoriAllocator.h
satori/SatoriRecycler.h

View file

@ -11,7 +11,7 @@
#include "common.h"
#include "gcenv.h"
#include "gc.h"
#include "satori/SatoriGCHeap.h"
#include "satori/SatoriGC.h"
#ifdef BUILD_AS_STANDALONE
#ifndef DLLEXPORT
@ -106,7 +106,7 @@ GC_Initialize(
{
//TODO: Satori
g_gc_heap_type = GC_HEAP_SATORI;
heap = new(nothrow) SatoriGCHeap();
heap = new(nothrow) SatoriGC();
}
else
#endif

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriAllocationContext.cpp
//
#include "common.h"

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriAllocationContext.h
//
#ifndef __SATORI_ALLOCATION_CONTEXT_H__

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriAllocator.cpp
//
#include "common.h"
@ -11,6 +11,8 @@
#include "SatoriUtil.h"
#include "SatoriHeap.h"
#include "SatoriObject.h"
#include "SatoriObject.inl"
#include "SatoriPage.h"
#include "SatoriAllocator.h"
#include "SatoriRegion.h"
@ -118,13 +120,13 @@ Object* SatoriAllocator::Alloc(SatoriAllocationContext* context, size_t size, ui
if (size < Satori::LARGE_OBJECT_THRESHOLD)
{
return AllocSmall(context, size, flags);
return AllocRegular(context, size, flags);
}
return AllocLarge(context, size, flags);
}
Object* SatoriAllocator::AllocSmall(SatoriAllocationContext* context, size_t size, uint32_t flags)
SatoriObject* SatoriAllocator::AllocRegular(SatoriAllocationContext* context, size_t size, uint32_t flags)
{
SatoriRegion* region = context->RegularRegion();
@ -145,10 +147,9 @@ Object* SatoriAllocator::AllocSmall(SatoriAllocationContext* context, size_t siz
context->alloc_bytes += alloc;
context->alloc_limit += alloc;
Object* result = (Object*)context->alloc_ptr;
SatoriObject* result = SatoriObject::At((size_t)context->alloc_ptr);
context->alloc_ptr += size;
// clean syncblock.
((size_t*)result)[-1] = 0;
result->CleanSyncBlock();
return result;
}
}
@ -159,10 +160,10 @@ Object* SatoriAllocator::AllocSmall(SatoriAllocationContext* context, size_t siz
context->alloc_bytes -= context->alloc_limit - context->alloc_ptr;
_ASSERTE((size_t)context->alloc_ptr < region->End());
SatoriUtil::MakeFreeObject((Object*)context->alloc_ptr, region->End() - (size_t)context->alloc_ptr);
SatoriObject::FormatAsFree((size_t)context->alloc_ptr, region->End() - (size_t)context->alloc_ptr);
// TODO: VS try compact current
region->MarkThreadLocal();
region->ThreadLocalMark();
m_heap->Recycler()->AddRegion(region);
context->alloc_ptr = context->alloc_limit = nullptr;
@ -179,16 +180,16 @@ Object* SatoriAllocator::AllocSmall(SatoriAllocationContext* context, size_t siz
}
}
Object* SatoriAllocator::AllocLarge(SatoriAllocationContext* context, size_t size, uint32_t flags)
SatoriObject* SatoriAllocator::AllocLarge(SatoriAllocationContext* context, size_t size, uint32_t flags)
{
size_t result = 0;
size_t location = 0;
// try large region first, if present
SatoriRegion* region = context->LargeRegion();
if (region)
{
result = region->Allocate(size, true);
if (result)
location = region->Allocate(size, true);
if (location)
{
goto done;
}
@ -199,11 +200,11 @@ Object* SatoriAllocator::AllocLarge(SatoriAllocationContext* context, size_t siz
if (regionSize == Satori::REGION_SIZE_GRANULARITY)
{
result = region->Allocate(size, true);
location = region->Allocate(size, true);
}
else
{
result = region->AllocateHuge(size, true);
location = region->AllocateHuge(size, true);
}
if (context->LargeRegion() == nullptr)
@ -223,8 +224,8 @@ Object* SatoriAllocator::AllocLarge(SatoriAllocationContext* context, size_t siz
}
done:
// clean syncblock.
((size_t*)result)[-1] = 0;
SatoriObject* result = SatoriObject::At(location);
result->CleanSyncBlock();
context->alloc_bytes_uoh += size;
return (Object*)result;
return result;
}

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriAllocator.h
//
#ifndef __SATORI_ALLOCATOR_H__
@ -16,6 +16,7 @@
class SatoriHeap;
class SatoriRegion;
class SatoriObject;
class SatoriAllocationContext;
class SatoriAllocator
@ -33,8 +34,8 @@ private:
//TODO: VS embed
SatoriRegionQueue* m_queues[Satori::BUCKET_COUNT];
Object* AllocLarge(SatoriAllocationContext* context, size_t size, uint32_t flags);
Object* AllocSmall(SatoriAllocationContext* context, size_t size, uint32_t flags);
SatoriObject* AllocLarge(SatoriAllocationContext* context, size_t size, uint32_t flags);
SatoriObject* AllocRegular(SatoriAllocationContext* context, size_t size, uint32_t flags);
static int SizeToBucket(size_t size)
{

View file

@ -0,0 +1,451 @@
// 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.
//
// SatoriGC.cpp
//
#include "common.h"
#include "gcenv.h"
#include "../env/gcenv.os.h"
#include "SatoriObject.h"
#include "SatoriGC.h"
#include "SatoriAllocationContext.h"
#include "SatoriHeap.h"
bool SatoriGC::IsValidSegmentSize(size_t size)
{
__UNREACHABLE();
return false;
}
bool SatoriGC::IsValidGen0MaxSize(size_t size)
{
__UNREACHABLE();
return false;
}
size_t SatoriGC::GetValidSegmentSize(bool large_seg)
{
__UNREACHABLE();
return 0;
}
void SatoriGC::SetReservedVMLimit(size_t vmlimit)
{
__UNREACHABLE();
}
void SatoriGC::WaitUntilConcurrentGCComplete()
{
}
bool SatoriGC::IsConcurrentGCInProgress()
{
// Satori may move thread local objects asyncronously,
// but noone should see that (that is the point).
//
// The only thing that may get to TL objects is object verification.
// Return "true" for now.
return true;
}
void SatoriGC::TemporaryEnableConcurrentGC()
{
}
void SatoriGC::TemporaryDisableConcurrentGC()
{
}
bool SatoriGC::IsConcurrentGCEnabled()
{
return false;
}
HRESULT SatoriGC::WaitUntilConcurrentGCCompleteAsync(int millisecondsTimeout)
{
return S_OK;
}
void SatoriGC::SetFinalizeQueueForShutdown(bool fHasLock)
{
__UNREACHABLE();
}
size_t SatoriGC::GetNumberOfFinalizable()
{
__UNREACHABLE();
return 0;
}
bool SatoriGC::ShouldRestartFinalizerWatchDog()
{
__UNREACHABLE();
return false;
}
Object* SatoriGC::GetNextFinalizable()
{
return nullptr;
}
void SatoriGC::SetFinalizeRunOnShutdown(bool value)
{
__UNREACHABLE();
}
void SatoriGC::GetMemoryInfo(uint64_t* highMemLoadThresholdBytes, uint64_t* totalPhysicalMemoryBytes, uint64_t* lastRecordedMemLoadBytes, uint32_t* lastRecordedMemLoadPct, size_t* lastRecordedHeapSizeBytes, size_t* lastRecordedFragmentationBytes)
{
__UNREACHABLE();
}
int SatoriGC::GetGcLatencyMode()
{
return 0;
}
int SatoriGC::SetGcLatencyMode(int newLatencyMode)
{
return 0;
}
int SatoriGC::GetLOHCompactionMode()
{
return 0;
}
void SatoriGC::SetLOHCompactionMode(int newLOHCompactionMode)
{
}
bool SatoriGC::RegisterForFullGCNotification(uint32_t gen2Percentage, uint32_t lohPercentage)
{
return false;
}
bool SatoriGC::CancelFullGCNotification()
{
return false;
}
int SatoriGC::WaitForFullGCApproach(int millisecondsTimeout)
{
__UNREACHABLE();
return 0;
}
int SatoriGC::WaitForFullGCComplete(int millisecondsTimeout)
{
__UNREACHABLE();
return 0;
}
unsigned SatoriGC::WhichGeneration(Object* obj)
{
return 2;
}
int SatoriGC::CollectionCount(int generation, int get_bgc_fgc_coutn)
{
__UNREACHABLE();
return 0;
}
int SatoriGC::StartNoGCRegion(uint64_t totalSize, bool lohSizeKnown, uint64_t lohSize, bool disallowFullBlockingGC)
{
__UNREACHABLE();
return 0;
}
int SatoriGC::EndNoGCRegion()
{
__UNREACHABLE();
return 0;
}
size_t SatoriGC::GetTotalBytesInUse()
{
__UNREACHABLE();
return 0;
}
uint64_t SatoriGC::GetTotalAllocatedBytes()
{
__UNREACHABLE();
return 0;
}
HRESULT SatoriGC::GarbageCollect(int generation, bool low_memory_p, int mode)
{
// TODO: Satori
return S_OK;
}
unsigned SatoriGC::GetMaxGeneration()
{
__UNREACHABLE();
return 0;
}
void SatoriGC::SetFinalizationRun(Object* obj)
{
//TODO: Satori Finalizers;
}
bool SatoriGC::RegisterForFinalization(int gen, Object* obj)
{
__UNREACHABLE();
return false;
}
int SatoriGC::GetLastGCPercentTimeInGC()
{
__UNREACHABLE();
return 0;
}
size_t SatoriGC::GetLastGCGenerationSize(int gen)
{
__UNREACHABLE();
return 0;
}
HRESULT SatoriGC::Initialize()
{
m_perfCounterFrequency = GCToOSInterface::QueryPerformanceFrequency();
SatoriObject::Initialize();
m_heap = SatoriHeap::Create();
if (m_heap == nullptr)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
bool SatoriGC::IsPromoted(Object* object)
{
__UNREACHABLE();
return false;
}
bool SatoriGC::IsHeapPointer(void* object, bool small_heap_only)
{
return m_heap->IsHeapAddress((uint8_t*)object);
//TODO: Satori small_heap_only ?
}
unsigned SatoriGC::GetCondemnedGeneration()
{
__UNREACHABLE();
return 0;
}
bool SatoriGC::IsGCInProgressHelper(bool bConsiderGCStart)
{
return m_gcInProgress;
}
unsigned SatoriGC::GetGcCount()
{
//TODO: Satori Collect
return 0;
}
bool SatoriGC::IsThreadUsingAllocationContextHeap(gc_alloc_context* acontext, int thread_number)
{
__UNREACHABLE();
return false;
}
bool SatoriGC::IsEphemeral(Object* object)
{
__UNREACHABLE();
return false;
}
uint32_t SatoriGC::WaitUntilGCComplete(bool bConsiderGCStart)
{
return NOERROR;
}
void SatoriGC::FixAllocContext(gc_alloc_context* acontext, void* arg, void* heap)
{
// this is only called when thread is terminating and about to clear its context.
((SatoriAllocationContext*)acontext)->OnTerminateThread(m_heap);
}
size_t SatoriGC::GetCurrentObjSize()
{
__UNREACHABLE();
return 0;
}
void SatoriGC::SetGCInProgress(bool fInProgress)
{
m_gcInProgress = fInProgress;
}
bool SatoriGC::RuntimeStructuresValid()
{
return true;
}
void SatoriGC::SetSuspensionPending(bool fSuspensionPending)
{
m_suspensionPending = fSuspensionPending;
}
void SatoriGC::SetYieldProcessorScalingFactor(float yieldProcessorScalingFactor)
{
}
void SatoriGC::Shutdown()
{
}
size_t SatoriGC::GetLastGCStartTime(int generation)
{
return 0;
}
size_t SatoriGC::GetLastGCDuration(int generation)
{
return 0;
}
size_t SatoriGC::GetNow()
{
int64_t t = GCToOSInterface::QueryPerformanceCounter();
return (size_t)(t / (m_perfCounterFrequency / 1000));
}
Object* SatoriGC::Alloc(gc_alloc_context* acontext, size_t size, uint32_t flags)
{
return m_heap->Allocator()->Alloc((SatoriAllocationContext*)acontext, size, flags);
}
void SatoriGC::PublishObject(uint8_t* obj)
{
}
void SatoriGC::SetWaitForGCEvent()
{
}
void SatoriGC::ResetWaitForGCEvent()
{
}
bool SatoriGC::IsLargeObject(Object* pObj)
{
return false;
}
void SatoriGC::ValidateObjectMember(Object* obj)
{
}
Object* SatoriGC::NextObj(Object* object)
{
return nullptr;
}
Object* SatoriGC::GetContainingObject(void* pInteriorPtr, bool fCollectedGenOnly)
{
__UNREACHABLE();
return nullptr;
}
void SatoriGC::DiagWalkObject(Object* obj, walk_fn fn, void* context)
{
}
void SatoriGC::DiagWalkObject2(Object* obj, walk_fn2 fn, void* context)
{
}
void SatoriGC::DiagWalkHeap(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p)
{
}
void SatoriGC::DiagWalkSurvivorsWithType(void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type, int gen_number)
{
}
void SatoriGC::DiagWalkFinalizeQueue(void* gc_context, fq_walk_fn fn)
{
}
void SatoriGC::DiagScanFinalizeQueue(fq_scan_fn fn, ScanContext* context)
{
}
void SatoriGC::DiagScanHandles(handle_scan_fn fn, int gen_number, ScanContext* context)
{
}
void SatoriGC::DiagScanDependentHandles(handle_scan_fn fn, int gen_number, ScanContext* context)
{
}
void SatoriGC::DiagDescrGenerations(gen_walk_fn fn, void* context)
{
}
void SatoriGC::DiagTraceGCSegments()
{
}
bool SatoriGC::StressHeap(gc_alloc_context* acontext)
{
return false;
}
segment_handle SatoriGC::RegisterFrozenSegment(segment_info* pseginfo)
{
__UNREACHABLE();
return segment_handle();
}
void SatoriGC::UnregisterFrozenSegment(segment_handle seg)
{
__UNREACHABLE();
}
bool SatoriGC::IsInFrozenSegment(Object* object)
{
return false;
}
void SatoriGC::ControlEvents(GCEventKeyword keyword, GCEventLevel level)
{
}
void SatoriGC::ControlPrivateEvents(GCEventKeyword keyword, GCEventLevel level)
{
}
int SatoriGC::GetNumberOfHeaps()
{
// TODO: Satori we return the max degree of concurrency here
// return g_SystemInfo.dwNumberOfProcessors;
return 1;
}
int SatoriGC::GetHomeHeapNumber()
{
// TODO: Satori this is a number in [0, procNum) associated with thread
// it is implementable, do 0 for now.
return 0;
}
size_t SatoriGC::GetPromotedBytes(int heap_index)
{
__UNREACHABLE();
return 0;
}

View file

@ -2,11 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriGC.h
//
#ifndef __SATORI_GC_HEAP_H__
#define __SATORI_GC_HEAP_H__
#ifndef __SATORI_GC_H__
#define __SATORI_GC_H__
#include "common.h"
#include "../gc.h"
@ -15,7 +15,7 @@ class SatoriHeap;
class SatoriAllocator;
class SatoriRecycler;
class SatoriGCHeap : public IGCHeapInternal
class SatoriGC : public IGCHeapInternal
{
private:
int64_t m_perfCounterFrequency;

View file

@ -1,452 +0,0 @@
// 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.
//
// SatoriGCHeap.cpp
//
#include "common.h"
#include "gcenv.h"
#include "../env/gcenv.os.h"
#include "SatoriUtil.h"
#include "SatoriGCHeap.h"
#include "SatoriAllocationContext.h"
#include "SatoriHeap.h"
bool SatoriGCHeap::IsValidSegmentSize(size_t size)
{
__UNREACHABLE();
return false;
}
bool SatoriGCHeap::IsValidGen0MaxSize(size_t size)
{
__UNREACHABLE();
return false;
}
size_t SatoriGCHeap::GetValidSegmentSize(bool large_seg)
{
__UNREACHABLE();
return 0;
}
void SatoriGCHeap::SetReservedVMLimit(size_t vmlimit)
{
__UNREACHABLE();
}
void SatoriGCHeap::WaitUntilConcurrentGCComplete()
{
}
bool SatoriGCHeap::IsConcurrentGCInProgress()
{
// Satori may move thread local objects asyncronously,
// but noone should see that (that is the point).
//
// The only thing that may get to TL objects is object verification.
// Return "true" for now.
return true;
}
void SatoriGCHeap::TemporaryEnableConcurrentGC()
{
}
void SatoriGCHeap::TemporaryDisableConcurrentGC()
{
}
bool SatoriGCHeap::IsConcurrentGCEnabled()
{
return false;
}
HRESULT SatoriGCHeap::WaitUntilConcurrentGCCompleteAsync(int millisecondsTimeout)
{
return S_OK;
}
void SatoriGCHeap::SetFinalizeQueueForShutdown(bool fHasLock)
{
__UNREACHABLE();
}
size_t SatoriGCHeap::GetNumberOfFinalizable()
{
__UNREACHABLE();
return 0;
}
bool SatoriGCHeap::ShouldRestartFinalizerWatchDog()
{
__UNREACHABLE();
return false;
}
Object* SatoriGCHeap::GetNextFinalizable()
{
return nullptr;
}
void SatoriGCHeap::SetFinalizeRunOnShutdown(bool value)
{
__UNREACHABLE();
}
void SatoriGCHeap::GetMemoryInfo(uint64_t* highMemLoadThresholdBytes, uint64_t* totalPhysicalMemoryBytes, uint64_t* lastRecordedMemLoadBytes, uint32_t* lastRecordedMemLoadPct, size_t* lastRecordedHeapSizeBytes, size_t* lastRecordedFragmentationBytes)
{
__UNREACHABLE();
}
int SatoriGCHeap::GetGcLatencyMode()
{
return 0;
}
int SatoriGCHeap::SetGcLatencyMode(int newLatencyMode)
{
return 0;
}
int SatoriGCHeap::GetLOHCompactionMode()
{
return 0;
}
void SatoriGCHeap::SetLOHCompactionMode(int newLOHCompactionMode)
{
}
bool SatoriGCHeap::RegisterForFullGCNotification(uint32_t gen2Percentage, uint32_t lohPercentage)
{
return false;
}
bool SatoriGCHeap::CancelFullGCNotification()
{
return false;
}
int SatoriGCHeap::WaitForFullGCApproach(int millisecondsTimeout)
{
__UNREACHABLE();
return 0;
}
int SatoriGCHeap::WaitForFullGCComplete(int millisecondsTimeout)
{
__UNREACHABLE();
return 0;
}
unsigned SatoriGCHeap::WhichGeneration(Object* obj)
{
return 2;
}
int SatoriGCHeap::CollectionCount(int generation, int get_bgc_fgc_coutn)
{
__UNREACHABLE();
return 0;
}
int SatoriGCHeap::StartNoGCRegion(uint64_t totalSize, bool lohSizeKnown, uint64_t lohSize, bool disallowFullBlockingGC)
{
__UNREACHABLE();
return 0;
}
int SatoriGCHeap::EndNoGCRegion()
{
__UNREACHABLE();
return 0;
}
size_t SatoriGCHeap::GetTotalBytesInUse()
{
__UNREACHABLE();
return 0;
}
uint64_t SatoriGCHeap::GetTotalAllocatedBytes()
{
__UNREACHABLE();
return 0;
}
HRESULT SatoriGCHeap::GarbageCollect(int generation, bool low_memory_p, int mode)
{
// TODO: Satori
return S_OK;
}
unsigned SatoriGCHeap::GetMaxGeneration()
{
__UNREACHABLE();
return 0;
}
void SatoriGCHeap::SetFinalizationRun(Object* obj)
{
//TODO: Satori Finalizers;
}
bool SatoriGCHeap::RegisterForFinalization(int gen, Object* obj)
{
__UNREACHABLE();
return false;
}
int SatoriGCHeap::GetLastGCPercentTimeInGC()
{
__UNREACHABLE();
return 0;
}
size_t SatoriGCHeap::GetLastGCGenerationSize(int gen)
{
__UNREACHABLE();
return 0;
}
HRESULT SatoriGCHeap::Initialize()
{
m_perfCounterFrequency = GCToOSInterface::QueryPerformanceFrequency();
SatoriUtil::Initialize();
m_heap = SatoriHeap::Create();
if (m_heap == nullptr)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
bool SatoriGCHeap::IsPromoted(Object* object)
{
__UNREACHABLE();
return false;
}
bool SatoriGCHeap::IsHeapPointer(void* object, bool small_heap_only)
{
return m_heap->IsHeapAddress((uint8_t*)object);
//TODO: Satori small_heap_only ?
}
unsigned SatoriGCHeap::GetCondemnedGeneration()
{
__UNREACHABLE();
return 0;
}
bool SatoriGCHeap::IsGCInProgressHelper(bool bConsiderGCStart)
{
return m_gcInProgress;
}
unsigned SatoriGCHeap::GetGcCount()
{
//TODO: Satori Collect
return 0;
}
bool SatoriGCHeap::IsThreadUsingAllocationContextHeap(gc_alloc_context* acontext, int thread_number)
{
__UNREACHABLE();
return false;
}
bool SatoriGCHeap::IsEphemeral(Object* object)
{
__UNREACHABLE();
return false;
}
uint32_t SatoriGCHeap::WaitUntilGCComplete(bool bConsiderGCStart)
{
return NOERROR;
}
void SatoriGCHeap::FixAllocContext(gc_alloc_context* acontext, void* arg, void* heap)
{
// this is only called when thread is terminating and about to clear its context.
((SatoriAllocationContext*)acontext)->OnTerminateThread(m_heap);
}
size_t SatoriGCHeap::GetCurrentObjSize()
{
__UNREACHABLE();
return 0;
}
void SatoriGCHeap::SetGCInProgress(bool fInProgress)
{
m_gcInProgress = fInProgress;
}
bool SatoriGCHeap::RuntimeStructuresValid()
{
return true;
}
void SatoriGCHeap::SetSuspensionPending(bool fSuspensionPending)
{
m_suspensionPending = fSuspensionPending;
}
void SatoriGCHeap::SetYieldProcessorScalingFactor(float yieldProcessorScalingFactor)
{
}
void SatoriGCHeap::Shutdown()
{
}
size_t SatoriGCHeap::GetLastGCStartTime(int generation)
{
return 0;
}
size_t SatoriGCHeap::GetLastGCDuration(int generation)
{
return 0;
}
size_t SatoriGCHeap::GetNow()
{
int64_t t = GCToOSInterface::QueryPerformanceCounter();
return (size_t)(t / (m_perfCounterFrequency / 1000));
}
Object* SatoriGCHeap::Alloc(gc_alloc_context* acontext, size_t size, uint32_t flags)
{
return m_heap->Allocator()->Alloc((SatoriAllocationContext*)acontext, size, flags);
}
void SatoriGCHeap::PublishObject(uint8_t* obj)
{
}
void SatoriGCHeap::SetWaitForGCEvent()
{
}
void SatoriGCHeap::ResetWaitForGCEvent()
{
}
bool SatoriGCHeap::IsLargeObject(Object* pObj)
{
return false;
}
void SatoriGCHeap::ValidateObjectMember(Object* obj)
{
}
Object* SatoriGCHeap::NextObj(Object* object)
{
return nullptr;
}
Object* SatoriGCHeap::GetContainingObject(void* pInteriorPtr, bool fCollectedGenOnly)
{
__UNREACHABLE();
return nullptr;
}
void SatoriGCHeap::DiagWalkObject(Object* obj, walk_fn fn, void* context)
{
}
void SatoriGCHeap::DiagWalkObject2(Object* obj, walk_fn2 fn, void* context)
{
}
void SatoriGCHeap::DiagWalkHeap(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p)
{
}
void SatoriGCHeap::DiagWalkSurvivorsWithType(void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type, int gen_number)
{
}
void SatoriGCHeap::DiagWalkFinalizeQueue(void* gc_context, fq_walk_fn fn)
{
}
void SatoriGCHeap::DiagScanFinalizeQueue(fq_scan_fn fn, ScanContext* context)
{
}
void SatoriGCHeap::DiagScanHandles(handle_scan_fn fn, int gen_number, ScanContext* context)
{
}
void SatoriGCHeap::DiagScanDependentHandles(handle_scan_fn fn, int gen_number, ScanContext* context)
{
}
void SatoriGCHeap::DiagDescrGenerations(gen_walk_fn fn, void* context)
{
}
void SatoriGCHeap::DiagTraceGCSegments()
{
}
bool SatoriGCHeap::StressHeap(gc_alloc_context* acontext)
{
return false;
}
segment_handle SatoriGCHeap::RegisterFrozenSegment(segment_info* pseginfo)
{
__UNREACHABLE();
return segment_handle();
}
void SatoriGCHeap::UnregisterFrozenSegment(segment_handle seg)
{
__UNREACHABLE();
}
bool SatoriGCHeap::IsInFrozenSegment(Object* object)
{
return false;
}
void SatoriGCHeap::ControlEvents(GCEventKeyword keyword, GCEventLevel level)
{
}
void SatoriGCHeap::ControlPrivateEvents(GCEventKeyword keyword, GCEventLevel level)
{
}
int SatoriGCHeap::GetNumberOfHeaps()
{
// TODO: Satori we return the max degree of concurrency here
// return g_SystemInfo.dwNumberOfProcessors;
return 1;
}
int SatoriGCHeap::GetHomeHeapNumber()
{
// TODO: Satori this is a number in [0, procNum) associated with thread
// it is implementable, do 0 for now.
return 0;
}
size_t SatoriGCHeap::GetPromotedBytes(int heap_index)
{
__UNREACHABLE();
return 0;
}

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriHeap.cpp
//
#include "common.h"

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriGC.h
//
#ifndef __SATORI_HEAP_H__

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriLock.cpp
//
#include "common.h"

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriLock.h
//
#ifndef __SATORI_LOCK_H__

View file

@ -0,0 +1,42 @@
// 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.
//
// SatoriObject.cpp
//
#include "common.h"
#include "gcenv.h"
#include "../env/gcenv.os.h"
#include "SatoriObject.h"
#include "SatoriObject.inl"
MethodTable* SatoriObject::s_emptyObjectMt;
void SatoriObject::Initialize()
{
s_emptyObjectMt = GCToEEInterface::GetFreeObjectMethodTable();
}
SatoriObject* SatoriObject::FormatAsFree(size_t location, size_t size)
{
_ASSERTE(size >= sizeof(Object) + sizeof(size_t));
SatoriObject* obj = SatoriObject::At(location);
obj->CleanSyncBlock();
obj->RawSetMethodTable(s_emptyObjectMt);
// Note: we allow empty objects to be more than 4Gb on 64bit and use the "pad" for higher bits.
#if BIGENDIAN
#error "This won't work on big endian platforms"
#endif
((size_t*)obj)[ArrayBase::GetOffsetOfNumComponents() / sizeof(size_t)] = size - sizeof(ArrayBase);
return obj;
}
inline void SatoriObject::Validate()
{
//TODO: VS
}

View file

@ -0,0 +1,50 @@
// 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.
//
// SatoriObject.h
//
#ifndef __SATORI_OBJECT_H__
#define __SATORI_OBJECT_H__
#include "common.h"
#include "../gc.h"
class SatoriGC;
class SatoriRegion;
class SatoriObject : public Object
{
friend SatoriGC;
public:
SatoriObject() = delete;
~SatoriObject() = delete;
static SatoriObject* At(size_t location);
static SatoriObject* FormatAsFree(size_t location, size_t size);
SatoriRegion* ContainingRegion();
SatoriObject* Next();
size_t Size();
bool IsFree();
bool IsEscaped();
void SetEscaped();
bool IsMarked();
void SetMarked();
bool IsPinned();
void SetPinned();
void CleanSyncBlock();
void Validate();
private:
static MethodTable* s_emptyObjectMt;
static void Initialize();
};
#endif

View file

@ -0,0 +1,85 @@
// 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.
//
// SatoriObject.inl
//
#ifndef __SATORI_OBJECT_INL__
#define __SATORI_OBJECT_INL__
#include "common.h"
#include "../gc.h"
#include "SatoriUtil.h"
#include "SatoriObject.h"
inline size_t SatoriObject::Size()
{
MethodTable* mt = RawGetMethodTable();
size_t size = mt->GetBaseSize();
if (mt->HasComponentSize())
{
size += (size_t)((ArrayBase*)mt)->GetNumComponents() * mt->RawGetComponentSize();
}
return ALIGN_UP(size, Satori::OBJECT_ALIGNMENT);
}
inline SatoriObject* SatoriObject::Next()
{
return (SatoriObject*)((size_t)this + Size());
}
inline SatoriRegion* SatoriObject::ContainingRegion()
{
return (SatoriRegion*)((size_t)this >> Satori::REGION_BITS);
}
inline SatoriObject* SatoriObject::At(size_t location)
{
return (SatoriObject*)location;
}
inline bool SatoriObject::IsFree()
{
return RawGetMethodTable() == s_emptyObjectMt;
}
inline bool SatoriObject::IsEscaped()
{
}
inline void SatoriObject::SetEscaped()
{
}
inline bool SatoriObject::IsMarked()
{
}
inline void SatoriObject::SetMarked()
{
}
inline bool SatoriObject::IsPinned()
{
}
inline void SatoriObject::SetPinned()
{
}
inline void SatoriObject::CleanSyncBlock()
{
((size_t*)this)[-1] = 0;
}
#endif

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriPage.cpp
//
#include "common.h"

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriPage.h
//
#ifndef __SATORI_PAGE_H__

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriRecycler.cpp
//
#include "common.h"

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriRecycler.h
//
#ifndef __SATORI_RECYCLER_H__

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriRegion.cpp
//
#include "common.h"
@ -10,10 +10,12 @@
#include "gcenv.h"
#include "../env/gcenv.os.h"
#include "../env/gcenv.ee.h"
#include "SatoriGCHeap.h"
#include "SatoriGC.h"
#include "SatoriAllocator.h"
#include "SatoriRecycler.h"
#include "SatoriUtil.h"
#include "SatoriObject.h"
#include "SatoriObject.inl"
#include "SatoriRegion.h"
SatoriRegion* SatoriRegion::InitializeAt(SatoriPage* containingPage, size_t address, size_t regionSize, size_t committed, size_t zeroInitedAfter)
@ -126,7 +128,7 @@ void SatoriRegion::StopAllocating()
{
_ASSERTE(IsAllocating());
SatoriUtil::MakeFreeObject((Object*)m_allocStart, AllocSize());
SatoriObject::FormatAsFree(m_allocStart, AllocSize());
// TODO: VS update index
m_allocEnd = 0;
}
@ -151,7 +153,7 @@ void SatoriRegion::Deactivate(SatoriHeap* heap)
bool SatoriRegion::IsEmpty()
{
_ASSERTE(!IsAllocating());
return (size_t)SatoriUtil::Next(&m_firstObject) > m_end;
return (size_t)m_firstObject.Next() > m_end;
}
void SatoriRegion::SplitCore(size_t regionSize, size_t& nextStart, size_t& nextCommitted, size_t& nextZeroInitedAfter)
@ -298,20 +300,20 @@ size_t SatoriRegion::AllocateHuge(size_t size, bool ensureZeroInited)
return result;
}
Object* SatoriRegion::FindObject(size_t location)
SatoriObject* SatoriRegion::FindObject(size_t location)
{
_ASSERTE(location >= (size_t)FistObject() && location <= End());
// TODO: VS use index
Object* current = FistObject();
Object* next = SatoriUtil::Next(current);
SatoriObject* current = FistObject();
SatoriObject* next = current->Next();
while ((size_t)next <= location)
{
current = next;
next = SatoriUtil::Next(current);
next =current->Next();
}
return SatoriUtil::IsFreeObject(current) ? nullptr : current;
return current->IsFree() ? nullptr : current;
}
void SatoriRegion::MarkFn(PTR_PTR_Object ppObject, ScanContext* sc, uint32_t flags)
@ -324,7 +326,7 @@ void SatoriRegion::MarkFn(PTR_PTR_Object ppObject, ScanContext* sc, uint32_t fla
return;
}
Object* obj;
SatoriObject* obj;
if (flags & GC_CALL_INTERIOR)
{
obj = region->FindObject(location);
@ -335,19 +337,20 @@ void SatoriRegion::MarkFn(PTR_PTR_Object ppObject, ScanContext* sc, uint32_t fla
}
else
{
obj = (Object*)location;
obj = SatoriObject::At(location);
}
if (flags & GC_CALL_PINNED)
{
// PinObject(obj);
obj->SetPinned();
}
else
{
obj->SetMarked();
}
// MarkObject(obj);
};
void SatoriRegion::MarkThreadLocal()
void SatoriRegion::ThreadLocalMark()
{
ScanContext sc;
sc.promotion = TRUE;

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriRegion.h
//
#ifndef __SATORI_REGION_H__
@ -12,6 +12,7 @@
#include "../gc.h"
#include "SatoriHeap.h"
#include "SatoriUtil.h"
#include "SatoriObject.h"
enum class SatoriRegionState : int8_t
{
@ -77,19 +78,14 @@ public:
return m_allocEnd - m_allocStart;
}
Object* FistObject()
SatoriObject* FistObject()
{
return &m_firstObject;
}
static SatoriRegion* RegionForObject(Object* obj)
{
return (SatoriRegion*)(((size_t)obj) >> Satori::REGION_BITS);
}
SatoriObject* FindObject(size_t location);
Object* FindObject(size_t location);
void MarkThreadLocal();
void ThreadLocalMark();
void Publish()
{
@ -116,10 +112,10 @@ private:
size_t m_allocStart;
size_t m_allocEnd;
Object* m_index[Satori::INDEX_ITEMS];
SatoriObject* m_index[Satori::INDEX_ITEMS];
size_t m_syncBlock;
Object m_firstObject;
SatoriObject m_firstObject;
private:
void SplitCore(size_t regionSize, size_t& newStart, size_t& newCommitted, size_t& newZeroInitedAfter);

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriRegionQueue.cpp
//
#include "common.h"

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriRegionQueue.h
//
#ifndef __SATORI_REGION_QUEUE_H__

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.cpp
// SatoriUtil.cpp
//
#include "common.h"
@ -11,28 +11,3 @@
#include "../env/gcenv.os.h"
#include "SatoriUtil.h"
MethodTable* SatoriUtil::s_emptyObjectMt;
void SatoriUtil::Initialize()
{
s_emptyObjectMt = GCToEEInterface::GetFreeObjectMethodTable();
}
void SatoriUtil::MakeFreeObject(Object* obj, size_t size)
{
_ASSERTE(size >= sizeof(Object) + sizeof(size_t));
// sync block
((size_t*)obj)[-1] = 0;
// mt
obj->RawSetMethodTable(s_emptyObjectMt);
// size
// Note: we allow empty objects to be more than 4Gb on 64bit and use the "pad" for higher bits.
#if BIGENDIAN
#error "This won't work on big endian platforms"
#endif
((size_t*)obj)[ArrayBase::GetOffsetOfNumComponents() / sizeof(size_t)] = size - sizeof(ArrayBase);
}

View file

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// SatoriGCHeap.h
// SatoriUtil.h
//
#ifndef __SATORI_UTIL_H__
@ -35,23 +35,20 @@ namespace Satori
// objects smaller than this go into regular region. A random big number.
static const int LARGE_OBJECT_THRESHOLD = 85000;
// TODO: VS consider: in theory could be 2, but that would complicate walking.
// object starts are aligned to this
static const size_t OBJECT_ALIGNMENT = sizeof(size_t);
// in theory min size could be 2 heap words, but that would complicate walking.
static const size_t MIN_FREE_SIZE = 3 * sizeof(size_t);
// when doing rgular allocation we clean this much memory
// if we do cleaning, and if available
static const size_t MIN_REGULAR_ALLOC = 1 << 12;
}
class SatoriUtil
{
private:
static MethodTable* s_emptyObjectMt;
public:
static void Initialize();
//TODO: VS Free vs. Empty
static void MakeFreeObject(Object* obj, size_t size);
static size_t RoundDownPwr2(size_t value)
{
_ASSERTE(value > 0);
@ -64,28 +61,6 @@ public:
return (size_t)1 << highestBit;
}
static size_t Size(Object* obj)
{
MethodTable* mt = obj->RawGetMethodTable();
size_t size = mt->GetBaseSize();
if (mt->HasComponentSize())
{
size += (size_t)((ArrayBase*)mt)->GetNumComponents() * mt->RawGetComponentSize();
}
return size;
}
static Object* Next(Object* obj)
{
return (Object*)((size_t)obj + Size(obj));
}
static bool SatoriUtil::IsFreeObject(Object* obj)
{
return obj->RawGetMethodTable() == s_emptyObjectMt;
}
};
#endif

View file

@ -505,9 +505,10 @@ set(GC_SOURCES_WKS
../gc/gcload.cpp
../gc/softwarewritewatch.cpp
../gc/handletablecache.cpp
../gc/satori/SatoriGCHeap.cpp
../gc/satori/SatoriGC.cpp
../gc/satori/SatoriHeap.cpp
../gc/satori/SatoriPage.cpp
../gc/satori/SatoriObject.cpp
../gc/satori/SatoriRegion.cpp
../gc/satori/SatoriRegionQueue.cpp
../gc/satori/SatoriAllocator.cpp
@ -539,10 +540,12 @@ set(GC_HEADERS_WKS
../gc/gcscan.h
../gc/gchandletableimpl.h
../gc/softwarewritewatch.h
../gc/satori/SatoriGCHeap.h
../gc/satori/SatoriGC.h
../gc/satori/SatoriHeap.h
../gc/satori/SatoriPage.h
../gc/satori/SatoriRegion.h
../gc/satori/SatoriObject.h
../gc/satori/SatoriObject.inl
../gc/satori/SatoriRegionQueue.h
../gc/satori/SatoriAllocator.h
../gc/satori/SatoriRecycler.h