Skip to content

Commit 1650a17

Browse files
committed
fix(patch): allow JS execution in finalizer callbacks
V8 14.9 holds a DisallowJavascriptExecution across the whole collection, the epilogue included, and turns entering JS from a GC callback into a GRACEFUL_FATAL. 10.3 ran the second-pass callbacks under an explicit AllowJavascriptExecution, which the iOS runtime relies on: disposing an ObjC wrapper runs -dealloc, and any JS-backed override that teardown reaches re-enters JS through ArgConverter::MethodCallback. The scope is lifted around the finalizer drain alone, so the second-pass callbacks below it still satisfy their own assertion that JS is disallowed. Verified by compiling global-handles.o for arm64-simulator.
1 parent 9696214 commit 1650a17

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ platform), dispatch the workflow with `platforms: android` or `platforms: ios`.
127127

128128
| Patch | Why |
129129
|---|---|
130-
| `v8_resurrecting_finalizers.patch` | Restores `WeakCallbackType::kFinalizer`, removed upstream immediately after 10.3.22. Both runtimes' object managers depend on resurrecting finalizers. |
130+
| `v8_resurrecting_finalizers.patch` | Restores `WeakCallbackType::kFinalizer`, removed upstream immediately after 10.3.22. Both runtimes' object managers depend on resurrecting finalizers. It also lifts, for the finalizer drain only, the `DisallowJavascriptExecution` scope that `Heap::CollectGarbage` now holds across the whole collection: 14.9 turns entering JS from a GC callback into a `GRACEFUL_FATAL`, and the iOS runtime reaches JS whenever a released ObjC object's `-dealloc` hits a JS-backed override. |
131131
| `android_build.patch` | Lowers chromium's minimum SDK to 21 (that floor is for Java/dex tooling; this builds only the native target), makes `android_ndk_root` a gn arg, and widens the hard Linux-host assert so macOS can build the 64-bit ABIs. |
132132

133133
## The gn args are load-bearing

patches/v8_resurrecting_finalizers.patch

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ index ad2ae1f4517..c2c76af2830 100644
2121

2222
template <class T>
2323
diff --git a/src/handles/global-handles.cc b/src/handles/global-handles.cc
24-
index e03603371cd..481e317df87 100644
24+
index e03603371cd..ad2172fdd5e 100644
2525
--- a/src/handles/global-handles.cc
2626
+++ b/src/handles/global-handles.cc
2727
@@ -55,6 +55,11 @@ enum class WeaknessType {
@@ -242,16 +242,25 @@ index e03603371cd..481e317df87 100644
242242
void GlobalHandles::PostGarbageCollectionProcessing(
243243
v8::GCCallbackFlags gc_callback_flags) {
244244
// Process weak global handle callbacks. This must be done after the
245-
@@ -874,6 +986,8 @@ void GlobalHandles::PostGarbageCollectionProcessing(
245+
@@ -874,6 +986,17 @@ void GlobalHandles::PostGarbageCollectionProcessing(
246246
// API functions.
247247
DCHECK_EQ(Heap::NOT_IN_GC, isolate_->heap()->gc_state());
248248

249-
+ InvokeFinalizerCallbacks();
249+
+ {
250+
+ // `Heap::CollectGarbage` holds a `DisallowJavascriptExecution` across the
251+
+ // whole collection, including the epilogue this runs from, and
252+
+ // `InvokeExternalCallbacks()` re-enables allocation but deliberately not
253+
+ // JS. Finalizer callbacks are documented to permit both (see
254+
+ // `v8::WeakCallbackType::kFinalizer`), so lift it for them alone -- the
255+
+ // second-pass callbacks below assert that JS is still disallowed.
256+
+ AllowJavascriptExecution allow_js(isolate_);
257+
+ InvokeFinalizerCallbacks();
258+
+ }
250259
+
251260
if (second_pass_callbacks_.empty()) return;
252261

253262
const bool synchronous_second_pass =
254-
@@ -902,7 +1016,10 @@ void GlobalHandles::PostGarbageCollectionProcessing(
263+
@@ -902,7 +1025,10 @@ void GlobalHandles::PostGarbageCollectionProcessing(
255264

256265
void GlobalHandles::IterateStrongRoots(RootVisitor* v) {
257266
for (Node* node : *regular_nodes_) {

0 commit comments

Comments
 (0)