Implement Global::finalizeGC to prevent memory leak

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2026-01-29 16:38:06 +09:00 committed by Boram Bae
commit a130b108a5
5 changed files with 21 additions and 9 deletions

View file

@ -269,15 +269,15 @@ void Globals::initialize(PlatformRef* platform)
void Globals::finalize()
{
RELEASE_ASSERT(!!g_globalsInited);
g_globalsInited = false;
// finalize global value or context including thread-local variables
// this function should be invoked once at the end of the program
RELEASE_ASSERT(!!g_globalsInited);
ThreadLocal::finalize();
// Global::finalize should be called at the end of program
// because it holds Platform which could be used in other Object's finalizer
Global::finalize();
g_globalsInited = false;
}
bool Globals::isInitialized()
@ -296,11 +296,12 @@ void Globals::initializeThread()
void Globals::finalizeThread()
{
RELEASE_ASSERT(!!g_globalsInited);
g_globalsInited = false;
Global::finalizeGC();
// finalize thread-local variables
// this function should be invoked once at the end of sub-thread
RELEASE_ASSERT(!!g_globalsInited);
ThreadLocal::finalize();
g_globalsInited = false;
}
bool Globals::supportsThreading()

View file

@ -29,6 +29,7 @@
#include "interpreter/ByteCode.h"
#include "parser/CodeBlock.h"
#include "util/Util.h"
#include "api/EscargotPublic.h"
namespace Escargot {
@ -197,7 +198,7 @@ void FinalizationRegistryObject::finalizer(PointerValue* self, void* data)
}
}
if (!wasCallbackDeleted) {
if (!wasCallbackDeleted && Globals::isInitialized()) {
try {
ExecutionState tempState(item->source->m_realm);
Value argv = item->heldValue;

View file

@ -75,10 +75,7 @@ void Global::finalize()
std::vector<Waiter*>().swap(g_waiter);
#endif
GC_gcollect_and_unmap();
GC_gcollect_and_unmap();
GC_gcollect_and_unmap();
GC_invoke_finalizers();
Global::finalizeGC();
delete g_platform;
g_platform = nullptr;

View file

@ -47,6 +47,15 @@ class Global {
public:
static void initialize(Platform* platform);
static void finalize();
static void finalizeGC()
{
GC_register_mark_stack_func([]() {});
GC_gcollect_and_unmap();
GC_gcollect_and_unmap();
GC_gcollect_and_unmap();
GC_invoke_finalizers();
GC_register_mark_stack_func(nullptr);
}
static Platform* platform();
#if defined(ENABLE_ATOMICS_GLOBAL_LOCK)

View file

@ -29,6 +29,7 @@
#include "wasm/WASMObject.h"
#include "wasm/WASMValueConverter.h"
#include "wasm/ExportedFunctionObject.h"
#include "api/EscargotPublic.h"
// represent ownership of each object
// object marked with 'own' should be deleted in the current context
@ -138,6 +139,9 @@ WASMMemoryObject::WASMMemoryObject(ExecutionState& state, Object* proto, wasm_me
addFinalizer([](PointerValue* obj, void* data) {
WASMMemoryObject* self = (WASMMemoryObject*)obj;
if (!Globals::isInitialized()) {
return;
}
if (!wasm_memory_is_shared(self->memory())) {
self->buffer()->asArrayBufferObject()->detachArrayBuffer();
}