diff --git a/deps/message-port/nd/gc-util.cc b/deps/message-port/nd/gc-util.cc index a3ddedefba..a597c4670d 100644 --- a/deps/message-port/nd/gc-util.cc +++ b/deps/message-port/nd/gc-util.cc @@ -19,6 +19,8 @@ #include "nd-debug.h" #include "nd-logger.h" +namespace nd { + #define CLR_YELLOW "\033[0;33m" #define CLR_MAGENTA "\033[0;35m" #define TRACE_GC_START(fmt, ...) TRACEF0(GC, "GC" fmt, ##__VA_ARGS__) @@ -253,18 +255,25 @@ void MemoryUtil::PrintEveryReachableGCObjects() { #endif } -void MemoryUtil::GcFull() { +void MemoryUtil::GcFull(bool includeStack) { TRACE_GC_START(); LOG_HANDLER("[FULL GC]"); - GC_register_mark_stack_func([]() { - // do nothing for skip stack - // assume there is no gc-object on stack - }); + + if (includeStack) { + GC_register_mark_stack_func([]() { + // do nothing for skip stack + // assume there is no gc-object on stack + }); + } GC_gcollect(); GC_gcollect(); GC_gcollect_and_unmap(); - GC_register_mark_stack_func(nullptr); + + if (includeStack) { + GC_register_mark_stack_func(nullptr); + } + GC_gcollect(); TRACE_GC_END(); } @@ -336,3 +345,5 @@ void MemoryUtil::GcRegisterFinalizer( void* gcPtr, GCAllocatedMemoryFinalizerWithData callback, void* data) { REGISTER_FINALIZER(gcPtr, callback, data); } + +} // namespace nd diff --git a/deps/message-port/nd/gc-util.h b/deps/message-port/nd/gc-util.h index 93cc759761..a1f4b02535 100644 --- a/deps/message-port/nd/gc-util.h +++ b/deps/message-port/nd/gc-util.h @@ -28,6 +28,8 @@ class ValueRef; class ObjectRef; } // namespace Escargot +namespace nd { + // typedef of GC-aware vector template filter = nullptr); static GCTracer tracer; }; + +} // namespace nd diff --git a/include/lwnode/gc-descriptor.h b/include/lwnode/gc-descriptor.h index e52d17e37d..99f406b4dd 100644 --- a/include/lwnode/gc-descriptor.h +++ b/include/lwnode/gc-descriptor.h @@ -19,8 +19,8 @@ #define _TYPED_GC_NEW_ARG1(Class) \ void* operator new(size_t size) { \ - static bool typeInited = false; \ - static GC_descr descr; \ + thread_local static bool typeInited = false; \ + thread_local static GC_descr descr; \ if (!typeInited) { \ GC_word desc[GC_BITMAP_SIZE(Class)] = {0}; \ Class::fillGCDescriptor(desc); \ @@ -57,7 +57,7 @@ inline void markHashTable(GC_word* desc, size_t base) { #endif } -#define SET_GC_COLLECTION(Class, name) \ +#define SET_GC_MAP_OR_SET(Class, name) \ markHashTable(desc, GC_WORD_OFFSET(Class, name)); #define END_IMPLEMENT_TYPED_GC_NEW() } diff --git a/message-port.gyp b/message-port.gyp index c173d5bfde..373a74d474 100644 --- a/message-port.gyp +++ b/message-port.gyp @@ -20,6 +20,7 @@ '<(source_dir)/nd/es-helper.cc', '<(source_dir)/nd/nd-debug.cc', '<(source_dir)/nd/nd-logger.cc', + '<(source_dir)/nd/gc-util.cc', ], 'all_dependent_settings': { 'include_dirs': [ diff --git a/src/api/arraybuffer-allocator.h b/src/api/arraybuffer-allocator.h index c0326b279e..70da8b9b1c 100644 --- a/src/api/arraybuffer-allocator.h +++ b/src/api/arraybuffer-allocator.h @@ -35,6 +35,9 @@ class ArrayBufferAllocatorDecorator : public v8::ArrayBuffer::Allocator, } void printState(); + BEGIN_IMPLEMENT_TYPED_GC_NEW(ArrayBufferAllocatorDecorator); + END_IMPLEMENT_TYPED_GC_NEW(); + private: size_t currentMemorySize_ = 0; size_t peakMemorySize_ = 0; diff --git a/src/api/context.h b/src/api/context.h index c4b1e908e9..0ffdcf8a1a 100644 --- a/src/api/context.h +++ b/src/api/context.h @@ -61,14 +61,23 @@ class ContextWrap : public ValueWrap { void initDebugger(); - private: - EmbedderDataMap* embedder_data_{nullptr}; + BEGIN_IMPLEMENT_TYPED_GC_NEW(ContextWrap, ValueWrap); + SET_GC_POINTER(ContextWrap, embedder_data_); + SET_GC_POINTER(ContextWrap, isolate_); + SET_GC_POINTER(ContextWrap, context_); + SET_GC_POINTER(ContextWrap, bindingObject_); + SET_GC_POINTER(ContextWrap, security_token_); + SET_GC_POINTER(ContextWrap, callSite_); + END_IMPLEMENT_TYPED_GC_NEW(); + private: ContextWrap(IsolateWrap* isolate, v8::ExtensionConfiguration* extensionConfiguration); void setEmbedderData(int index, void* value); void* getEmbedderData(int index); + EmbedderDataMap* embedder_data_{nullptr}; + IsolateWrap* isolate_ = nullptr; Escargot::ContextRef* context_ = nullptr; Escargot::ObjectRef* bindingObject_ = nullptr; diff --git a/src/api/global-handles.h b/src/api/global-handles.h index 4d6caa2387..be941bde20 100644 --- a/src/api/global-handles.h +++ b/src/api/global-handles.h @@ -39,6 +39,9 @@ class GlobalHandles : public gc { virtual size_t handles_count() const = 0; + BEGIN_IMPLEMENT_TYPED_GC_NEW(GlobalHandles); + END_IMPLEMENT_TYPED_GC_NEW(); + private: Isolate* const isolate_ = nullptr; }; @@ -107,6 +110,11 @@ class GlobalHandles final : public v8::internal::GlobalHandles { GcObjectInfo* findGcObjectInfo(ValueWrap* value); void removeGcObjectInfo(ValueWrap* lwValue); + BEGIN_IMPLEMENT_TYPED_GC_NEW(GlobalHandles, v8::internal::GlobalHandles); + SET_GC_MAP_OR_SET(GlobalHandles, persistentValues_); + SET_GC_POINTER(GlobalHandles, isolate_); + END_IMPLEMENT_TYPED_GC_NEW(); + private: GCUnorderedMap persistentValues_; IsolateWrap* isolate_{nullptr}; diff --git a/src/api/handle.h b/src/api/handle.h index 3e6ba4b541..75acfe66bb 100644 --- a/src/api/handle.h +++ b/src/api/handle.h @@ -62,6 +62,10 @@ class HandleWrap : public gc { std::string getHandleInfoString() const; static HandleWrap* as(void* address); + BEGIN_IMPLEMENT_TYPED_GC_NEW(HandleWrap); + SET_GC_POINTER(HandleWrap, val_); + END_IMPLEMENT_TYPED_GC_NEW(); + protected: HandleWrap() = default; void copy(HandleWrap* that, Location location); @@ -130,6 +134,10 @@ class PersistentWrap : public ValueWrap { std::string getPersistentInfoString(); void invokeFinalizer(); + BEGIN_IMPLEMENT_TYPED_GC_NEW(PersistentWrap, ValueWrap); + SET_GC_POINTER(PersistentWrap, holder_); + END_IMPLEMENT_TYPED_GC_NEW(); + private: PersistentWrap(ValueWrap* ptr); diff --git a/src/api/handlescope.h b/src/api/handlescope.h index 7736e48c15..52201da85b 100644 --- a/src/api/handlescope.h +++ b/src/api/handlescope.h @@ -43,6 +43,10 @@ class HandleScopeWrap : public gc { Type type() const { return type_; } v8Scope_t* v8Scope() const { return v8scope_; } + BEGIN_IMPLEMENT_TYPED_GC_NEW(HandleScopeWrap); + SET_GC_POINTER(HandleScopeWrap, handles_); + END_IMPLEMENT_TYPED_GC_NEW(); + private: HandleScopeWrap(HandleScopeWrap::Type type); void add(HandleWrap* value); diff --git a/src/api/isolate.cc b/src/api/isolate.cc index 76770a950f..5d84d077ed 100755 --- a/src/api/isolate.cc +++ b/src/api/isolate.cc @@ -283,8 +283,9 @@ IsolateWrap::IsolateWrap() { threadManager_ = new ThreadManager(); - // NOTE: check lock_gc_release(); is needed (and where) - // lock_gc_release(); + // The following ensures this instance is retained using PersistentHolder. + lock_gc_release(); + Memory::gcRegisterFinalizer(this, [](void* self) { reinterpret_cast(self)->~IsolateWrap(); }); @@ -320,8 +321,8 @@ IsolateWrap* IsolateWrap::New() { void IsolateWrap::Dispose() { LWNODE_CALL_TRACE_ID(ISOWRAP); LWNODE_CALL_TRACE_GC_START(); - // NOTE: check unlock_gc_release(); is needed (and where) - // unlock_gc_release(); + + unlock_gc_release(); global_handles()->dispose(); RegisteredExtension::unregisterAll(); diff --git a/src/api/isolate.h b/src/api/isolate.h index 71d10647ff..bde7ca50f2 100755 --- a/src/api/isolate.h +++ b/src/api/isolate.h @@ -109,6 +109,13 @@ class Isolate : public gc { EscargotShim::GlobalHandles* global_handles() { return global_handles_; } + BEGIN_IMPLEMENT_TYPED_GC_NEW(Isolate); + SET_GC_POINTER(Isolate, scheduled_exception_); + SET_GC_POINTER(Isolate, global_handles_); + SET_GC_POINTER(Isolate, pending_exception_); + SET_GC_POINTER(Isolate, pending_message_obj_); + END_IMPLEMENT_TYPED_GC_NEW(); + protected: void set_pending_exception(Escargot::ValueRef* exception_obj); void set_pending_message_obj(Escargot::ValueRef* message_obj); @@ -197,8 +204,6 @@ class IsolateWrap final : public v8::internal::Isolate { return arrayBufferDecorator_->array_buffer_allocator(); } - ArrayBufferAllocatorDecorator* arrayBufferDecorator_ = nullptr; - static IsolateWrap* GetCurrent(); // HandleScope & Handle @@ -279,6 +284,19 @@ class IsolateWrap final : public v8::internal::Isolate { State getState() { return state_; } + BEGIN_IMPLEMENT_TYPED_GC_NEW(IsolateWrap, v8::internal::Isolate); + SET_GC_POINTER(IsolateWrap, arrayBufferDecorator_); + SET_GC_POINTER(IsolateWrap, eternals_); + SET_GC_MAP_OR_SET(IsolateWrap, backingStoreCounter_); + SET_GC_POINTER(IsolateWrap, handleScopes_); + SET_GC_POINTER(IsolateWrap, contextScopes_); + SET_GC_POINTER(IsolateWrap, apiSymbols_); + SET_GC_POINTER(IsolateWrap, apiPrivateSymbols_); + SET_GC_POINTER(IsolateWrap, threadManager_); + END_IMPLEMENT_TYPED_GC_NEW(); + + ArrayBufferAllocatorDecorator* arrayBufferDecorator_ = nullptr; + private: IsolateWrap(); diff --git a/src/api/utils/gc-util.h b/src/api/utils/gc-util.h index 6c2be03541..898fde4be9 100644 --- a/src/api/utils/gc-util.h +++ b/src/api/utils/gc-util.h @@ -23,6 +23,7 @@ #include #include "compiler.h" #include "gc-container.h" +#include "gc-descriptor.h" #include "sf-vector.h" #include