Memory.cpp: refactoring
This commit is contained in:
@@ -366,11 +366,11 @@ THREAD_LOCAL_VARIABLE MemoryState* memoryState = nullptr;
|
|||||||
constexpr int kFrameOverlaySlots = sizeof(FrameOverlay) / sizeof(ObjHeader**);
|
constexpr int kFrameOverlaySlots = sizeof(FrameOverlay) / sizeof(ObjHeader**);
|
||||||
|
|
||||||
inline bool isFreeable(const ContainerHeader* header) {
|
inline bool isFreeable(const ContainerHeader* header) {
|
||||||
return (header->refCount_ & CONTAINER_TAG_MASK) < CONTAINER_TAG_PERMANENT;
|
return header->tag() < CONTAINER_TAG_PERMANENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isArena(const ContainerHeader* header) {
|
inline bool isArena(const ContainerHeader* header) {
|
||||||
return (header->refCount_ & CONTAINER_TAG_MASK) == CONTAINER_TAG_STACK;
|
return header->stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline container_size_t alignUp(container_size_t size, int alignment) {
|
inline container_size_t alignUp(container_size_t size, int alignment) {
|
||||||
@@ -409,8 +409,7 @@ inline FrameOverlay* asFrameOverlay(ObjHeader** slot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool isRefCounted(KConstRef object) {
|
inline bool isRefCounted(KConstRef object) {
|
||||||
return (object->container()->refCount_ & CONTAINER_TAG_MASK) ==
|
return isFreeable(object->container());
|
||||||
CONTAINER_TAG_NORMAL;
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -491,18 +490,25 @@ void traverseContainerReferredObjects(ContainerHeader* container, func process)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if USE_GC
|
#if USE_GC
|
||||||
|
|
||||||
|
inline bool isMarkedAsRemoved(ContainerHeader* container) {
|
||||||
|
return (reinterpret_cast<uintptr_t>(container) & 1) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ContainerHeader* markAsRemoved(ContainerHeader* container) {
|
||||||
|
return reinterpret_cast<ContainerHeader*>(reinterpret_cast<uintptr_t>(container) | 1);
|
||||||
|
}
|
||||||
|
|
||||||
inline void processFinalizerQueue(MemoryState* state) {
|
inline void processFinalizerQueue(MemoryState* state) {
|
||||||
// TODO: reuse elements of finalizer queue for new allocations.
|
// TODO: reuse elements of finalizer queue for new allocations.
|
||||||
while (!state->finalizerQueue->empty()) {
|
while (!state->finalizerQueue->empty()) {
|
||||||
auto container = memoryState->finalizerQueue->back();
|
auto container = memoryState->finalizerQueue->back();
|
||||||
state->finalizerQueue->pop_back();
|
state->finalizerQueue->pop_back();
|
||||||
if ((reinterpret_cast<uintptr_t>(container) & 1) != 0) {
|
|
||||||
container = reinterpret_cast<ContainerHeader*>(reinterpret_cast<uintptr_t>(container) & ~1);
|
|
||||||
#if TRACE_MEMORY
|
#if TRACE_MEMORY
|
||||||
state->containers->erase(container);
|
state->containers->erase(container);
|
||||||
#endif
|
#endif
|
||||||
runDeallocationHooks(container);
|
runDeallocationHooks(container);
|
||||||
}
|
|
||||||
CONTAINER_DESTROY_EVENT(state, container)
|
CONTAINER_DESTROY_EVENT(state, container)
|
||||||
konanFreeMemory(container);
|
konanFreeMemory(container);
|
||||||
atomicAdd(&allocCount, -1);
|
atomicAdd(&allocCount, -1);
|
||||||
@@ -513,8 +519,7 @@ inline void processFinalizerQueue(MemoryState* state) {
|
|||||||
inline void scheduleDestroyContainer(
|
inline void scheduleDestroyContainer(
|
||||||
MemoryState* state, ContainerHeader* container, bool clearExternalRefs) {
|
MemoryState* state, ContainerHeader* container, bool clearExternalRefs) {
|
||||||
if (clearExternalRefs) {
|
if (clearExternalRefs) {
|
||||||
traverseContainerObjectFields(reinterpret_cast<ContainerHeader*>(reinterpret_cast<uintptr_t>(container) & ~1),
|
traverseContainerObjectFields(container, [](ObjHeader** location) {
|
||||||
[](ObjHeader** location) {
|
|
||||||
ObjHeader* ref = *location;
|
ObjHeader* ref = *location;
|
||||||
// Frozen object references do not participate in trial deletion, so shall be explicitly freed.
|
// Frozen object references do not participate in trial deletion, so shall be explicitly freed.
|
||||||
if (ref != nullptr && ref->container()->frozen())
|
if (ref != nullptr && ref->container()->frozen())
|
||||||
@@ -681,7 +686,7 @@ void CollectCycles(MemoryState* state) {
|
|||||||
|
|
||||||
void MarkRoots(MemoryState* state) {
|
void MarkRoots(MemoryState* state) {
|
||||||
for (auto container : *(state->toFree)) {
|
for (auto container : *(state->toFree)) {
|
||||||
if ((reinterpret_cast<uintptr_t>(container) & 1) != 0)
|
if (isMarkedAsRemoved(container))
|
||||||
continue;
|
continue;
|
||||||
auto color = container->color();
|
auto color = container->color();
|
||||||
auto rcIsZero = container->refCount() == 0;
|
auto rcIsZero = container->refCount() == 0;
|
||||||
@@ -691,7 +696,7 @@ void MarkRoots(MemoryState* state) {
|
|||||||
} else {
|
} else {
|
||||||
container->resetBuffered();
|
container->resetBuffered();
|
||||||
if (color == CONTAINER_TAG_GC_BLACK && rcIsZero) {
|
if (color == CONTAINER_TAG_GC_BLACK && rcIsZero) {
|
||||||
scheduleDestroyContainer(state, reinterpret_cast<ContainerHeader*>(reinterpret_cast<uintptr_t>(container) | 1), true);
|
scheduleDestroyContainer(state, container, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -738,7 +743,7 @@ void CollectWhite(MemoryState* state, ContainerHeader* container) {
|
|||||||
CollectWhite(state, childContainer);
|
CollectWhite(state, childContainer);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
scheduleDestroyContainer(state, reinterpret_cast<ContainerHeader*>(reinterpret_cast<uintptr_t>(container) | 1), true);
|
scheduleDestroyContainer(state, container, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AddRef(ContainerHeader* header) {
|
inline void AddRef(ContainerHeader* header) {
|
||||||
@@ -839,13 +844,8 @@ void FreeContainer(ContainerHeader* header) {
|
|||||||
runDeallocationHooks(header);
|
runDeallocationHooks(header);
|
||||||
} else {
|
} else {
|
||||||
header->setColor(CONTAINER_TAG_GC_BLACK);
|
header->setColor(CONTAINER_TAG_GC_BLACK);
|
||||||
if (!header->buffered()) {
|
if (!header->buffered())
|
||||||
runDeallocationHooks(header);
|
|
||||||
#if TRACE_MEMORY
|
|
||||||
memoryState->containers->erase(header);
|
|
||||||
#endif
|
|
||||||
scheduleDestroyContainer(state, header, false);
|
scheduleDestroyContainer(state, header, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1404,7 +1404,7 @@ bool ClearSubgraphReferences(ObjHeader* root, bool checked) {
|
|||||||
if (visited.find(container) != visited.end()) {
|
if (visited.find(container) != visited.end()) {
|
||||||
container->resetBuffered();
|
container->resetBuffered();
|
||||||
container->setColor(CONTAINER_TAG_GC_BLACK);
|
container->setColor(CONTAINER_TAG_GC_BLACK);
|
||||||
*it = reinterpret_cast<ContainerHeader*>(reinterpret_cast<uintptr_t>(container) | 1);
|
*it = markAsRemoved(container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1509,7 +1509,7 @@ void FreezeSubgraph(ObjHeader* root) {
|
|||||||
for (auto it = state->toFree->begin(); it != state->toFree->end(); ++it) {
|
for (auto it = state->toFree->begin(); it != state->toFree->end(); ++it) {
|
||||||
auto container = *it;
|
auto container = *it;
|
||||||
if (container->frozen()) {
|
if (container->frozen()) {
|
||||||
*it = reinterpret_cast<ContainerHeader*>(reinterpret_cast<uintptr_t>(container) | 1);
|
*it = markAsRemoved(container);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user