| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -324,5 +324,6 @@ module.exports = { | |||
| 324 | 324 | TextEncoder: 'readable', | |
| 325 | 325 | TextDecoder: 'readable', | |
| 326 | 326 | queueMicrotask: 'readable', | |
| 327 | + globalThis: 'readable', | ||
| 327 | 328 | }, | |
| 328 | 329 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -100,6 +100,9 @@ void InternalCallbackScope::Close() { | |||
| 100 | 100 | TickInfo* tick_info = env_->tick_info(); | |
| 101 | 101 | ||
| 102 | 102 | if (!env_->can_call_into_js()) return; | |
| 103 | + | ||
| 104 | + OnScopeLeave weakref_cleanup([&]() { env_->RunWeakRefCleanup(); }); | ||
| 105 | + | ||
| 103 | 106 | if (!tick_info->has_tick_scheduled()) { | |
| 104 | 107 | MicrotasksScope::PerformCheckpoint(env_->isolate()); | |
| 105 | 108 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,6 +12,7 @@ using errors::TryCatchScope; | |||
| 12 | 12 | using v8::Array; | |
| 13 | 13 | using v8::Context; | |
| 14 | 14 | using v8::EscapableHandleScope; | |
| 15 | + using v8::FinalizationGroup; | ||
| 15 | 16 | using v8::Function; | |
| 16 | 17 | using v8::HandleScope; | |
| 17 | 18 | using v8::Isolate; | |
@@ -76,6 +77,15 @@ static MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context, | |||
| 76 | 77 | return result; | |
| 77 | 78 | } | |
| 78 | 79 | ||
| 80 | + static void HostCleanupFinalizationGroupCallback( | ||
| 81 | + Local<Context> context, Local<FinalizationGroup> group) { | ||
| 82 | + Environment* env = Environment::GetCurrent(context); | ||
| 83 | + if (env == nullptr) { | ||
| 84 | + return; | ||
| 85 | + } | ||
| 86 | + env->RegisterFinalizationGroupForCleanup(group); | ||
| 87 | + } | ||
| 88 | + | ||
| 79 | 89 | void* NodeArrayBufferAllocator::Allocate(size_t size) { | |
| 80 | 90 | if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers) | |
| 81 | 91 | return UncheckedCalloc(size); | |
@@ -203,6 +213,8 @@ void SetIsolateUpForNode(v8::Isolate* isolate, IsolateSettingCategories cat) { | |||
| 203 | 213 | isolate->SetAllowWasmCodeGenerationCallback( | |
| 204 | 214 | AllowWasmCodeGenerationCallback); | |
| 205 | 215 | isolate->SetPromiseRejectCallback(task_queue::PromiseRejectCallback); | |
| 216 | + isolate->SetHostCleanupFinalizationGroupCallback( | ||
| 217 | + HostCleanupFinalizationGroupCallback); | ||
| 206 | 218 | v8::CpuProfiler::UseDetailedSourcePositionsForProfiling(isolate); | |
| 207 | 219 | break; | |
| 208 | 220 | default: | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1115,6 +1115,11 @@ void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) { | |||
| 1115 | 1115 | cleanup_hooks_.erase(search); | |
| 1116 | 1116 | } | |
| 1117 | 1117 | ||
| 1118 | + inline void Environment::RegisterFinalizationGroupForCleanup( | ||
| 1119 | + v8::Local<v8::FinalizationGroup> group) { | ||
| 1120 | + cleanup_finalization_groups_.emplace_back(isolate(), group); | ||
| 1121 | + } | ||
| 1122 | + | ||
| 1118 | 1123 | size_t CleanupHookCallback::Hash::operator()( | |
| 1119 | 1124 | const CleanupHookCallback& cb) const { | |
| 1120 | 1125 | return std::hash<void*>()(cb.arg_); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,6 +28,7 @@ using v8::ArrayBuffer; | |||
| 28 | 28 | using v8::Boolean; | |
| 29 | 29 | using v8::Context; | |
| 30 | 30 | using v8::EmbedderGraph; | |
| 31 | + using v8::FinalizationGroup; | ||
| 31 | 32 | using v8::Function; | |
| 32 | 33 | using v8::FunctionTemplate; | |
| 33 | 34 | using v8::HandleScope; | |
@@ -1050,6 +1051,21 @@ void Environment::AddArrayBufferAllocatorToKeepAliveUntilIsolateDispose( | |||
| 1050 | 1051 | keep_alive_allocators_->insert(allocator); | |
| 1051 | 1052 | } | |
| 1052 | 1053 | ||
| 1054 | + bool Environment::RunWeakRefCleanup() { | ||
| 1055 | + isolate()->ClearKeptObjects(); | ||
| 1056 | + | ||
| 1057 | + while (!cleanup_finalization_groups_.empty()) { | ||
| 1058 | + Local<FinalizationGroup> fg = | ||
| 1059 | + cleanup_finalization_groups_.front().Get(isolate()); | ||
| 1060 | + cleanup_finalization_groups_.pop_front(); | ||
| 1061 | + if (!FinalizationGroup::Cleanup(fg).FromMaybe(false)) { | ||
| 1062 | + return false; | ||
| 1063 | + } | ||
| 1064 | + } | ||
| 1065 | + | ||
| 1066 | + return true; | ||
| 1067 | + } | ||
| 1068 | + | ||
| 1053 | 1069 | void AsyncRequest::Install(Environment* env, void* data, uv_async_cb target) { | |
| 1054 | 1070 | CHECK_NULL(async_); | |
| 1055 | 1071 | env_ = env; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1132,6 +1132,9 @@ class Environment : public MemoryRetainer { | |||
| 1132 | 1132 | void AtExit(void (*cb)(void* arg), void* arg); | |
| 1133 | 1133 | void RunAtExitCallbacks(); | |
| 1134 | 1134 | ||
| 1135 | + void RegisterFinalizationGroupForCleanup(v8::Local<v8::FinalizationGroup> fg); | ||
| 1136 | + bool RunWeakRefCleanup(); | ||
| 1137 | + | ||
| 1135 | 1138 | // Strings and private symbols are shared across shared contexts | |
| 1136 | 1139 | // The getters simply proxy to the per-isolate primitive. | |
| 1137 | 1140 | #define VP(PropertyName, StringValue) V(v8::Private, PropertyName) | |
@@ -1338,6 +1341,8 @@ class Environment : public MemoryRetainer { | |||
| 1338 | 1341 | uint64_t thread_id_; | |
| 1339 | 1342 | std::unordered_set<worker::Worker*> sub_worker_contexts_; | |
| 1340 | 1343 | ||
| 1344 | + std::deque<v8::Global<v8::FinalizationGroup>> cleanup_finalization_groups_; | ||
| 1345 | + | ||
| 1341 | 1346 | static void* const kNodeContextTagPtr; | |
| 1342 | 1347 | static int const kNodeContextTag; | |
| 1343 | 1348 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -43,6 +43,8 @@ static void EnqueueMicrotask(const FunctionCallbackInfo<Value>& args) { | |||
| 43 | 43 | ||
| 44 | 44 | // Should be in sync with runNextTicks in internal/process/task_queues.js | |
| 45 | 45 | bool RunNextTicksNative(Environment* env) { | |
| 46 | + OnScopeLeave weakref_cleanup([&]() { env->RunWeakRefCleanup(); }); | ||
| 47 | + | ||
| 46 | 48 | TickInfo* tick_info = env->tick_info(); | |
| 47 | 49 | if (!tick_info->has_tick_scheduled() && !tick_info->has_rejection_to_warn()) | |
| 48 | 50 | MicrotasksScope::PerformCheckpoint(env->isolate()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -34,3 +34,4 @@ globals: | |||
| 34 | 34 | BigInt64Array: false | |
| 35 | 35 | BigUint64Array: false | |
| 36 | 36 | SharedArrayBuffer: false | |
| 37 | + globalThis: false | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,23 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Flags: --expose-gc --harmony-weak-refs | ||
| 4 | + | ||
| 5 | + const common = require('../common'); | ||
| 6 | + const assert = require('assert'); | ||
| 7 | + | ||
| 8 | + const g = new globalThis.FinalizationGroup(common.mustCallAtLeast(() => { | ||
| 9 | + throw new Error('test'); | ||
| 10 | + }, 1)); | ||
| 11 | + g.register({}, 42); | ||
| 12 | + | ||
| 13 | + setTimeout(() => { | ||
| 14 | + globalThis.gc(); | ||
| 15 | + assert.throws(() => { | ||
| 16 | + g.cleanupSome(); | ||
| 17 | + }, { | ||
| 18 | + name: 'Error', | ||
| 19 | + message: 'test', | ||
| 20 | + }); | ||
| 21 | + }, 200); | ||
| 22 | + | ||
| 23 | + process.on('uncaughtException', common.mustCall()); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + // Flags: --expose-gc --harmony-weak-refs | ||
| 4 | + | ||
| 5 | + const common = require('../common'); | ||
| 6 | + | ||
| 7 | + const g = new globalThis.FinalizationGroup(common.mustCallAtLeast(1)); | ||
| 8 | + g.register({}, 42); | ||
| 9 | + | ||
| 10 | + setTimeout(() => { | ||
| 11 | + globalThis.gc(); | ||
| 12 | + g.cleanupSome(); | ||
| 13 | + }, 200); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments