| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 94e4cbd commit 9e9e48b
5 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1118,6 +1118,7 @@ void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) { | |||
| 1118 | 1118 | inline void Environment::RegisterFinalizationGroupForCleanup( | |
| 1119 | 1119 | v8::Local<v8::FinalizationGroup> group) { | |
| 1120 | 1120 | cleanup_finalization_groups_.emplace_back(isolate(), group); | |
| 1121 | + uv_async_send(&cleanup_finalization_groups_async_); | ||
| 1121 | 1122 | } | |
| 1122 | 1123 | ||
| 1123 | 1124 | size_t CleanupHookCallback::Hash::operator()( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -460,8 +460,17 @@ void Environment::InitializeLibuv(bool start_profiler_idle_notifier) { | |||
| 460 | 460 | // will be recorded with state=IDLE. | |
| 461 | 461 | uv_prepare_init(event_loop(), &idle_prepare_handle_); | |
| 462 | 462 | uv_check_init(event_loop(), &idle_check_handle_); | |
| 463 | + uv_async_init( | ||
| 464 | + event_loop(), | ||
| 465 | + &cleanup_finalization_groups_async_, | ||
| 466 | + [](uv_async_t* async) { | ||
| 467 | + Environment* env = ContainerOf( | ||
| 468 | + &Environment::cleanup_finalization_groups_async_, async); | ||
| 469 | + env->CleanupFinalizationGroups(); | ||
| 470 | + }); | ||
| 463 | 471 | uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_)); | |
| 464 | 472 | uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_)); | |
| 473 | + uv_unref(reinterpret_cast<uv_handle_t*>(&cleanup_finalization_groups_async_)); | ||
| 465 | 474 | ||
| 466 | 475 | thread_stopper()->Install( | |
| 467 | 476 | this, static_cast<void*>(this), [](uv_async_t* handle) { | |
@@ -524,6 +533,10 @@ void Environment::RegisterHandleCleanups() { | |||
| 524 | 533 | reinterpret_cast<uv_handle_t*>(&idle_check_handle_), | |
| 525 | 534 | close_and_finish, | |
| 526 | 535 | nullptr); | |
| 536 | + RegisterHandleCleanup( | ||
| 537 | + reinterpret_cast<uv_handle_t*>(&cleanup_finalization_groups_async_), | ||
| 538 | + close_and_finish, | ||
| 539 | + nullptr); | ||
| 527 | 540 | } | |
| 528 | 541 | ||
| 529 | 542 | void Environment::CleanupHandles() { | |
@@ -1040,19 +1053,27 @@ char* Environment::Reallocate(char* data, size_t old_size, size_t size) { | |||
| 1040 | 1053 | return new_data; | |
| 1041 | 1054 | } | |
| 1042 | 1055 | ||
| 1043 | - bool Environment::RunWeakRefCleanup() { | ||
| 1056 | + void Environment::RunWeakRefCleanup() { | ||
| 1044 | 1057 | isolate()->ClearKeptObjects(); | |
| 1058 | + } | ||
| 1045 | 1059 | ||
| 1046 | - while (!cleanup_finalization_groups_.empty()) { | ||
| 1060 | + void Environment::CleanupFinalizationGroups() { | ||
| 1061 | + HandleScope handle_scope(isolate()); | ||
| 1062 | + Context::Scope context_scope(context()); | ||
| 1063 | + TryCatchScope try_catch(this); | ||
| 1064 | + | ||
| 1065 | + while (!cleanup_finalization_groups_.empty() && can_call_into_js()) { | ||
| 1047 | 1066 | Local<FinalizationGroup> fg = | |
| 1048 | 1067 | cleanup_finalization_groups_.front().Get(isolate()); | |
| 1049 | 1068 | cleanup_finalization_groups_.pop_front(); | |
| 1050 | 1069 | if (!FinalizationGroup::Cleanup(fg).FromMaybe(false)) { | |
| 1051 | - return false; | ||
| 1070 | + if (try_catch.HasCaught() && !try_catch.HasTerminated()) | ||
| 1071 | + errors::TriggerUncaughtException(isolate(), try_catch); | ||
| 1072 | + // Re-schedule the execution of the remainder of the queue. | ||
| 1073 | + uv_async_send(&cleanup_finalization_groups_async_); | ||
| 1074 | + return; | ||
| 1052 | 1075 | } | |
| 1053 | 1076 | } | |
| 1054 | - | ||
| 1055 | - return true; | ||
| 1056 | 1077 | } | |
| 1057 | 1078 | ||
| 1058 | 1079 | void AsyncRequest::Install(Environment* env, void* data, uv_async_cb target) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1128,7 +1128,8 @@ class Environment : public MemoryRetainer { | |||
| 1128 | 1128 | void RunAtExitCallbacks(); | |
| 1129 | 1129 | ||
| 1130 | 1130 | void RegisterFinalizationGroupForCleanup(v8::Local<v8::FinalizationGroup> fg); | |
| 1131 | - bool RunWeakRefCleanup(); | ||
| 1131 | + void RunWeakRefCleanup(); | ||
| 1132 | + void CleanupFinalizationGroups(); | ||
| 1132 | 1133 | ||
| 1133 | 1134 | // Strings and private symbols are shared across shared contexts | |
| 1134 | 1135 | // The getters simply proxy to the per-isolate primitive. | |
@@ -1270,6 +1271,7 @@ class Environment : public MemoryRetainer { | |||
| 1270 | 1271 | uv_idle_t immediate_idle_handle_; | |
| 1271 | 1272 | uv_prepare_t idle_prepare_handle_; | |
| 1272 | 1273 | uv_check_t idle_check_handle_; | |
| 1274 | + uv_async_t cleanup_finalization_groups_async_; | ||
| 1273 | 1275 | bool profiler_idle_notifier_started_ = false; | |
| 1274 | 1276 | ||
| 1275 | 1277 | AsyncHooks async_hooks_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,6 +18,10 @@ setTimeout(() => { | |||
| 18 | 18 | name: 'Error', | |
| 19 | 19 | message: 'test', | |
| 20 | 20 | }); | |
| 21 | + | ||
| 22 | + // Give the callbacks scheduled by global.gc() time to run, as the underlying | ||
| 23 | + // uv_async_t is unref’ed. | ||
| 24 | + setTimeout(() => {}, 200); | ||
| 21 | 25 | }, 200); | |
| 22 | 26 | ||
| 23 | 27 | process.on('uncaughtException', common.mustCall()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,25 @@ | |||
| 1 | + // Flags: --harmony-weak-refs | ||
| 2 | + 'use strict'; | ||
| 3 | + require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + | ||
| 6 | + // Test that finalization callbacks do not crash when caused through a regular | ||
| 7 | + // GC (not global.gc()). | ||
| 8 | + | ||
| 9 | + const start = Date.now(); | ||
| 10 | + const g = new globalThis.FinalizationGroup(() => { | ||
| 11 | + const diff = Date.now() - start; | ||
| 12 | + assert(diff < 10000, `${diff} >= 10000`); | ||
| 13 | + }); | ||
| 14 | + g.register({}, 42); | ||
| 15 | + | ||
| 16 | + setImmediate(() => { | ||
| 17 | + const arr = []; | ||
| 18 | + // Build up enough memory usage to hopefully trigger a platform task but not | ||
| 19 | + // enough to trigger GC as an interrupt. | ||
| 20 | + while (arr.length < 1000000) arr.push([]); | ||
| 21 | + | ||
| 22 | + setTimeout(() => { | ||
| 23 | + g; // Keep reference alive. | ||
| 24 | + }, 200000).unref(); | ||
| 25 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments