Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 17e0bf4

Browse filesBrowse files
devsnekMylesBorins
authored andcommitted
src: implement v8 host weakref hooks
PR-URL: #29874 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent 512a0cc commit 17e0bf4
Copy full SHA for 17e0bf4

File tree

Expand file treeCollapse file tree

11 files changed

+94
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

11 files changed

+94
-0
lines changed
Open diff view settings
Collapse file

‎.eslintrc.js‎

Copy file name to clipboardExpand all lines: .eslintrc.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,5 +324,6 @@ module.exports = {
324324
TextEncoder: 'readable',
325325
TextDecoder: 'readable',
326326
queueMicrotask: 'readable',
327+
globalThis: 'readable',
327328
},
328329
};
Collapse file

‎src/api/callback.cc‎

Copy file name to clipboardExpand all lines: src/api/callback.cc
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ void InternalCallbackScope::Close() {
100100
TickInfo* tick_info = env_->tick_info();
101101

102102
if (!env_->can_call_into_js()) return;
103+
104+
OnScopeLeave weakref_cleanup([&]() { env_->RunWeakRefCleanup(); });
105+
103106
if (!tick_info->has_tick_scheduled()) {
104107
MicrotasksScope::PerformCheckpoint(env_->isolate());
105108
}
Collapse file

‎src/api/environment.cc‎

Copy file name to clipboardExpand all lines: src/api/environment.cc
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ using errors::TryCatchScope;
1212
using v8::Array;
1313
using v8::Context;
1414
using v8::EscapableHandleScope;
15+
using v8::FinalizationGroup;
1516
using v8::Function;
1617
using v8::HandleScope;
1718
using v8::Isolate;
@@ -76,6 +77,15 @@ static MaybeLocal<Value> PrepareStackTraceCallback(Local<Context> context,
7677
return result;
7778
}
7879

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+
7989
void* NodeArrayBufferAllocator::Allocate(size_t size) {
8090
if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers)
8191
return UncheckedCalloc(size);
@@ -203,6 +213,8 @@ void SetIsolateUpForNode(v8::Isolate* isolate, IsolateSettingCategories cat) {
203213
isolate->SetAllowWasmCodeGenerationCallback(
204214
AllowWasmCodeGenerationCallback);
205215
isolate->SetPromiseRejectCallback(task_queue::PromiseRejectCallback);
216+
isolate->SetHostCleanupFinalizationGroupCallback(
217+
HostCleanupFinalizationGroupCallback);
206218
v8::CpuProfiler::UseDetailedSourcePositionsForProfiling(isolate);
207219
break;
208220
default:
Collapse file

‎src/env-inl.h‎

Copy file name to clipboardExpand all lines: src/env-inl.h
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,11 @@ void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
11151115
cleanup_hooks_.erase(search);
11161116
}
11171117

1118+
inline void Environment::RegisterFinalizationGroupForCleanup(
1119+
v8::Local<v8::FinalizationGroup> group) {
1120+
cleanup_finalization_groups_.emplace_back(isolate(), group);
1121+
}
1122+
11181123
size_t CleanupHookCallback::Hash::operator()(
11191124
const CleanupHookCallback& cb) const {
11201125
return std::hash<void*>()(cb.arg_);
Collapse file

‎src/env.cc‎

Copy file name to clipboardExpand all lines: src/env.cc
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ using v8::ArrayBuffer;
2828
using v8::Boolean;
2929
using v8::Context;
3030
using v8::EmbedderGraph;
31+
using v8::FinalizationGroup;
3132
using v8::Function;
3233
using v8::FunctionTemplate;
3334
using v8::HandleScope;
@@ -1050,6 +1051,21 @@ void Environment::AddArrayBufferAllocatorToKeepAliveUntilIsolateDispose(
10501051
keep_alive_allocators_->insert(allocator);
10511052
}
10521053

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+
10531069
void AsyncRequest::Install(Environment* env, void* data, uv_async_cb target) {
10541070
CHECK_NULL(async_);
10551071
env_ = env;
Collapse file

‎src/env.h‎

Copy file name to clipboardExpand all lines: src/env.h
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,9 @@ class Environment : public MemoryRetainer {
11321132
void AtExit(void (*cb)(void* arg), void* arg);
11331133
void RunAtExitCallbacks();
11341134

1135+
void RegisterFinalizationGroupForCleanup(v8::Local<v8::FinalizationGroup> fg);
1136+
bool RunWeakRefCleanup();
1137+
11351138
// Strings and private symbols are shared across shared contexts
11361139
// The getters simply proxy to the per-isolate primitive.
11371140
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
@@ -1338,6 +1341,8 @@ class Environment : public MemoryRetainer {
13381341
uint64_t thread_id_;
13391342
std::unordered_set<worker::Worker*> sub_worker_contexts_;
13401343

1344+
std::deque<v8::Global<v8::FinalizationGroup>> cleanup_finalization_groups_;
1345+
13411346
static void* const kNodeContextTagPtr;
13421347
static int const kNodeContextTag;
13431348

Collapse file

‎src/node_task_queue.cc‎

Copy file name to clipboardExpand all lines: src/node_task_queue.cc
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ static void EnqueueMicrotask(const FunctionCallbackInfo<Value>& args) {
4343

4444
// Should be in sync with runNextTicks in internal/process/task_queues.js
4545
bool RunNextTicksNative(Environment* env) {
46+
OnScopeLeave weakref_cleanup([&]() { env->RunWeakRefCleanup(); });
47+
4648
TickInfo* tick_info = env->tick_info();
4749
if (!tick_info->has_tick_scheduled() && !tick_info->has_rejection_to_warn())
4850
MicrotasksScope::PerformCheckpoint(env->isolate());
Collapse file

‎test/.eslintrc.yaml‎

Copy file name to clipboardExpand all lines: test/.eslintrc.yaml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ globals:
3434
BigInt64Array: false
3535
BigUint64Array: false
3636
SharedArrayBuffer: false
37+
globalThis: false
Collapse file
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff 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());
Collapse file
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff 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);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.