Skip to content

Commit

Permalink
Pre-process out more precise tracing code when RECYCLER_VISITED_HOST …
Browse files Browse the repository at this point in the history
…is not defined
  • Loading branch information
Bo Cupp committed Oct 5, 2017
1 parent 7961526 commit a8587fe
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 2 deletions.
18 changes: 18 additions & 0 deletions lib/Common/Memory/MarkContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ MarkContext::MarkContext(Recycler * recycler, PagePool * pagePool) :
recycler(recycler),
pagePool(pagePool),
markStack(pagePool),
#ifdef RECYCLER_VISITED_HOST
preciseStack(pagePool),
#endif
trackStack(pagePool)
{
}
Expand All @@ -40,21 +42,27 @@ void MarkContext::OnObjectMarked(void* object, void* parent)
void MarkContext::Init(uint reservedPageCount)
{
markStack.Init(reservedPageCount);
#ifdef RECYCLER_VISITED_HOST
preciseStack.Init();
#endif
trackStack.Init();
}

void MarkContext::Clear()
{
markStack.Clear();
#ifdef RECYCLER_VISITED_HOST
preciseStack.Clear();
#endif
trackStack.Clear();
}

void MarkContext::Abort()
{
markStack.Abort();
#ifdef RECYCLER_VISITED_HOST
preciseStack.Abort();
#endif
trackStack.Abort();

pagePool->ReleaseFreePages();
Expand All @@ -64,7 +72,9 @@ void MarkContext::Abort()
void MarkContext::Release()
{
markStack.Release();
#ifdef RECYCLER_VISITED_HOST
preciseStack.Release();
#endif
trackStack.Release();

pagePool->ReleaseFreePages();
Expand All @@ -78,20 +88,28 @@ uint MarkContext::Split(uint targetCount, __in_ecount(targetCount) MarkContext *
__analysis_assume(targetCount <= PageStack<IRecyclerVisitedObject*>::MaxSplitTargets);

PageStack<MarkCandidate> * targetMarkStacks[PageStack<MarkCandidate>::MaxSplitTargets];
#ifdef RECYCLER_VISITED_HOST
PageStack<IRecyclerVisitedObject*> * targetPreciseStacks[PageStack<IRecyclerVisitedObject*>::MaxSplitTargets];
#endif

for (uint i = 0; i < targetCount; i++)
{
targetMarkStacks[i] = &targetContexts[i]->markStack;
#ifdef RECYCLER_VISITED_HOST
targetPreciseStacks[i] = &targetContexts[i]->preciseStack;
#endif
}

// Return the max count of the two splits - since the stacks have more or less unrelated sizes, they
// could yield different number of splits, but the caller wants to know the max parallelism it
// should use on the results of the split.
const uint markStackSplitCount = this->markStack.Split(targetCount, targetMarkStacks);
#ifdef RECYCLER_VISITED_HOST
const uint preciseStackSplitCount = this->preciseStack.Split(targetCount, targetPreciseStacks);
return max(markStackSplitCount, preciseStackSplitCount);
#else
return markStackSplitCount;
#endif
}


Expand Down
20 changes: 18 additions & 2 deletions lib/Common/Memory/MarkContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ class MarkContext
Recycler * GetRecycler() { return this->recycler; }

bool AddMarkedObject(void * obj, size_t byteCount);
#ifdef RECYCLER_VISITED_HOST
bool AddPreciselyTracedObject(IRecyclerVisitedObject *obj);
#endif
#if ENABLE_CONCURRENT_GC
bool AddTrackedObject(FinalizableObject * obj);
#endif
Expand All @@ -56,9 +58,17 @@ class MarkContext
void Release();

bool HasPendingMarkObjects() const { return !markStack.IsEmpty(); }
#ifdef RECYCLER_VISITED_HOST
bool HasPendingPreciselyTracedObjects() const { return !preciseStack.IsEmpty(); }
#endif
bool HasPendingTrackObjects() const { return !trackStack.IsEmpty(); }
bool HasPendingObjects() const { return HasPendingMarkObjects() || HasPendingPreciselyTracedObjects() || HasPendingTrackObjects(); }
bool HasPendingObjects() const {
return HasPendingMarkObjects()
#ifdef RECYCLER_VISITED_HOST
|| HasPendingPreciselyTracedObjects()
#endif
|| HasPendingTrackObjects();
}

PageAllocator * GetPageAllocator() { return this->pagePool->GetPageAllocator(); }

Expand Down Expand Up @@ -92,7 +102,13 @@ class MarkContext


#ifdef ENABLE_DEBUG_CONFIG_OPTIONS
void SetMaxPageCount(size_t maxPageCount) { markStack.SetMaxPageCount(maxPageCount); preciseStack.SetMaxPageCount(maxPageCount); trackStack.SetMaxPageCount(maxPageCount); }
void SetMaxPageCount(size_t maxPageCount) {
markStack.SetMaxPageCount(maxPageCount);
#ifdef RECYCLER_VISITED_HOST
preciseStack.SetMaxPageCount(maxPageCount);
#endif
trackStack.SetMaxPageCount(maxPageCount);
}
#endif

#ifdef RECYCLER_MARK_TRACK
Expand Down
6 changes: 6 additions & 0 deletions lib/Common/Memory/MarkContext.inl
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ bool MarkContext::AddMarkedObject(void * objectAddress, size_t objectSize)
return markStack.Push(markCandidate);
}

#ifdef RECYCLER_VISITED_HOST
inline bool MarkContext::AddPreciselyTracedObject(IRecyclerVisitedObject* obj)
{
FAULTINJECT_MEMORY_MARK_NOTHROW(_u("AddPreciselyTracedObject"), 0);

return preciseStack.Push(obj);
}
#endif

#if ENABLE_CONCURRENT_GC
inline
Expand Down Expand Up @@ -195,11 +197,13 @@ void MarkContext::ProcessMark()
}
#endif

#ifdef RECYCLER_VISITED_HOST
// Flip between processing the generic mark stack (conservatively traced with ScanMemory) and
// the precise stack (precisely traced via IRecyclerVisitedObject::Trace). Each of those
// operations on an object has the potential to add new marked objects to either or both
// stacks so we must loop until they are both empty.
while (!markStack.IsEmpty() || !preciseStack.IsEmpty())
#endif
{
#if defined(_M_IX86) || defined(_M_X64)
MarkCandidate current, next;
Expand Down Expand Up @@ -239,6 +243,7 @@ void MarkContext::ProcessMark()

Assert(markStack.IsEmpty());

#ifdef RECYCLER_VISITED_HOST
if (!preciseStack.IsEmpty())
{
MarkContextWrapper<parallel> markContextWrapper(this);
Expand All @@ -250,5 +255,6 @@ void MarkContext::ProcessMark()
}

Assert(preciseStack.IsEmpty());
#endif
}
}
2 changes: 2 additions & 0 deletions lib/Common/Memory/Recycler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1575,7 +1575,9 @@ class Recycler
template <bool doSpecialMark>
void ScanMemory(void ** obj, size_t byteCount) { if (byteCount != 0) { ScanMemoryInline<doSpecialMark>(obj, byteCount); } }
bool AddMark(void * candidate, size_t byteCount);
#ifdef RECYCLER_VISITED_HOST
bool AddPreciselyTracedMark(IRecyclerVisitedObject * candidate);
#endif

// Sweep
#if ENABLE_PARTIAL_GC
Expand Down
2 changes: 2 additions & 0 deletions lib/Common/Memory/Recycler.inl
Original file line number Diff line number Diff line change
Expand Up @@ -521,13 +521,15 @@ Recycler::AddMark(void * candidate, size_t byteCount) throw()
return markContext.AddMarkedObject(candidate, byteCount);
}

#ifdef RECYCLER_VISITED_HOST
inline bool
Recycler::AddPreciselyTracedMark(IRecyclerVisitedObject * candidate) throw()
{
// This API cannot be used for parallel marking as we don't have enough information to determine which MarkingContext to use.
Assert((this->collectionState & Collection_Parallel) == 0);
return markContext.AddPreciselyTracedObject(candidate);
}
#endif

template <typename T>
void
Expand Down

0 comments on commit a8587fe

Please sign in to comment.