Skip to content

Commit

Permalink
Replace finalization queue with the linked list.
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikolay Igotti authored and olonho committed Nov 23, 2018
1 parent cedcd2c commit 58a82b2
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 30 deletions.
47 changes: 17 additions & 30 deletions runtime/src/main/cpp/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,21 +134,6 @@ class MemoryStatistic {
void incAlloc(size_t size, const ContainerHeader* header) {
containerAllocs[toIndex(header)][0]++;
++(*allocationHistogram)[size];
#if 0
auto queue = memoryState->finalizerQueue;
bool hit = false;
for (int i = 0; i < queue->size(); i++) {
auto container = (*queue)[i];
if (containerSize(container) == size) {
hit = true;
break;
}
}
if (hit)
allocCacheHit++;
else
allocCacheMiss++;
#endif // USE_GC
}

void incFree(const ContainerHeader* header) {
Expand Down Expand Up @@ -230,9 +215,10 @@ struct MemoryState {
#endif

#if USE_GC
// Finalizer queue.
ContainerHeaderDeque* finalizerQueue;

// Finalizer queue - linked list of containers scheduled for finalization.
ContainerHeader* finalizerQueue;
int finalizerQueueSize;
int finalizerQueueSuspendCount;
/*
* Typical scenario for GC is as following:
* we have 90% of objects with refcount = 0 which will be deleted during
Expand All @@ -249,7 +235,6 @@ struct MemoryState {
size_t gcThreshold;
// If collection is in progress.
bool gcInProgress;
int finalizerQueueSuspendCount;

#if GC_ERGONOMICS
uint64_t lastGcTimestamp;
Expand Down Expand Up @@ -509,25 +494,29 @@ inline ContainerHeader* markAsRemoved(ContainerHeader* container) {

inline void processFinalizerQueue(MemoryState* state) {
// TODO: reuse elements of finalizer queue for new allocations.
while (!state->finalizerQueue->empty()) {
auto container = memoryState->finalizerQueue->back();
state->finalizerQueue->pop_back();
while (state->finalizerQueue != nullptr) {
auto* container = state->finalizerQueue;
state->finalizerQueue = container->nextLink();
state->finalizerQueueSize--;
#if TRACE_MEMORY
state->containers->erase(container);
#endif
CONTAINER_DESTROY_EVENT(state, container)
konanFreeMemory(container);
atomicAdd(&allocCount, -1);
}
RuntimeAssert(state->finalizerQueueSize == 0, "Queue must be empty here");
}
#endif

inline void scheduleDestroyContainer(
MemoryState* state, ContainerHeader* container) {
inline void scheduleDestroyContainer(MemoryState* state, ContainerHeader* container) {
#if USE_GC
state->finalizerQueue->push_front(container);
RuntimeAssert(container != nullptr, "Cannot destroy null container");
container->setNextLink(state->finalizerQueue);
state->finalizerQueue = container;
state->finalizerQueueSize++;
// We cannot clean finalizer queue while in GC.
if (!state->gcInProgress && state->finalizerQueueSuspendCount == 0 && state->finalizerQueue->size() > 256) {
if (!state->gcInProgress && state->finalizerQueueSuspendCount == 0 && state->finalizerQueueSize > 256) {
processFinalizerQueue(state);
}
#else
Expand All @@ -537,7 +526,6 @@ inline void scheduleDestroyContainer(
#endif
}


#if !USE_GC

template <bool Atomic>
Expand Down Expand Up @@ -1137,7 +1125,6 @@ MemoryState* InitMemory() {
memoryState = konanConstructInstance<MemoryState>();
INIT_EVENT(memoryState)
#if USE_GC
memoryState->finalizerQueue = konanConstructInstance<ContainerHeaderDeque>();
memoryState->toFree = konanConstructInstance<ContainerHeaderList>();
memoryState->roots = konanConstructInstance<ContainerHeaderList>();
memoryState->gcInProgress = false;
Expand All @@ -1155,8 +1142,8 @@ void DeinitMemory(MemoryState* memoryState) {
konanDestructInstance(memoryState->toFree);
konanDestructInstance(memoryState->roots);

konanDestructInstance(memoryState->finalizerQueue);
memoryState->finalizerQueue = nullptr;
RuntimeAssert(memoryState->finalizerQueue == nullptr, "Finalizer queue must be empty");
RuntimeAssert(memoryState->finalizerQueueSize == 0, "Finalizer queue must be empty");

#endif // USE_GC

Expand Down
9 changes: 9 additions & 0 deletions runtime/src/main/cpp/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,15 @@ struct ContainerHeader {
inline void resetSeen() {
objectCount_ &= ~CONTAINER_TAG_GC_SEEN;
}

// We cannot use 'this' here, as it conflicts with aliasing analysis in clang.
inline void setNextLink(ContainerHeader* next) {
*reinterpret_cast<ContainerHeader**>(this + 1) = next;
}

inline ContainerHeader* nextLink() {
return *reinterpret_cast<ContainerHeader**>(this + 1);
}
};

struct ArrayHeader;
Expand Down

0 comments on commit 58a82b2

Please sign in to comment.