Repository navigation
Conversation
|
@lavenzg has exported this pull request. If you are a Meta employee, you can view the originating Diff in D123939407. |
lavenzg
pushed a commit
to lavenzg/react-native
that referenced
this pull request
Oct 7, 2026
…act#58935) Summary: `WithRuntimeDecorator` wraps every override in `Around around{with_};` except `createArrayBuffer(std::shared_ptr<MutableBuffer>)`, which calls `RD::createArrayBuffer` directly. It has been like that since external ArrayBuffers were added in facebook/hermes#793, where the overrides next to it did get the guard. `HermesRuntimeImpl::createArrayBuffer` allocates a `JSArrayBuffer` on the GC heap, so on `makeThreadSafeHermesRuntime` it runs without the runtime lock, and reentrancy checks built on `WithRuntimeDecorator` never see the call. react#45042 and react#45049 fixed the same kind of gap for methods that had no `WithRuntimeDecorator` override at all. This one has an override that just skips the guard, so it wasn't caught there. A small stress program shows the race: one thread runs an allocating JS loop on a thread-safe runtime while another creates external ArrayBuffers. In a Debug build it fails the `makeA() calls can not be interleaved` assert in HadesGC. With the guard it runs clean. I didn't add it as a test because it depends on timing. React Native's copy of `decorator.h` has the same line. X-link: facebook/hermes#2204 Test Plan: Added `HermesRuntimeDecoratorTest.CreateArrayBufferCallsWith`. It wraps `makeHermesRuntime()` in a counting `WithRuntimeDecorator`, creates an ArrayBuffer from a `MutableBuffer`, and checks that `before()` and `after()` each ran once. Without the change both counts are 0 and the test fails. With it the test passes, and so does the full `APITests` binary (356 tests) in a Debug + ASan build. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: avp Differential Revision: D123939407 Pulled By: lavenzg
lavenzg
force-pushed
the
export-D123939407
branch
from
October 7, 2026 21:05
4986e6d to
6de1a6e
Compare
…act#58935) Summary: Pull Request resolved: react#58935 `WithRuntimeDecorator` wraps every override in `Around around{with_};` except `createArrayBuffer(std::shared_ptr<MutableBuffer>)`, which calls `RD::createArrayBuffer` directly. It has been like that since external ArrayBuffers were added in facebook/hermes#793, where the overrides next to it did get the guard. `HermesRuntimeImpl::createArrayBuffer` allocates a `JSArrayBuffer` on the GC heap, so on `makeThreadSafeHermesRuntime` it runs without the runtime lock, and reentrancy checks built on `WithRuntimeDecorator` never see the call. react#45042 and react#45049 fixed the same kind of gap for methods that had no `WithRuntimeDecorator` override at all. This one has an override that just skips the guard, so it wasn't caught there. A small stress program shows the race: one thread runs an allocating JS loop on a thread-safe runtime while another creates external ArrayBuffers. In a Debug build it fails the `makeA() calls can not be interleaved` assert in HadesGC. With the guard it runs clean. I didn't add it as a test because it depends on timing. React Native's copy of `decorator.h` has the same line. X-link: facebook/hermes#2204 Test Plan: Added `HermesRuntimeDecoratorTest.CreateArrayBufferCallsWith`. It wraps `makeHermesRuntime()` in a counting `WithRuntimeDecorator`, creates an ArrayBuffer from a `MutableBuffer`, and checks that `before()` and `after()` each ran once. Without the change both counts are 0 and the test fails. With it the test passes, and so does the full `APITests` binary (356 tests) in a Debug + ASan build. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: avp Differential Revision: D123939407 Pulled By: lavenzg
lavenzg
force-pushed
the
export-D123939407
branch
from
October 7, 2026 21:08
6de1a6e to
990ad31
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary:
WithRuntimeDecoratorwraps every override inAround around{with_};exceptcreateArrayBuffer(std::shared_ptr<MutableBuffer>), which callsRD::createArrayBufferdirectly. It has been like that since external ArrayBuffers were added in facebook/hermes#793, where the overrides next to it did get the guard.HermesRuntimeImpl::createArrayBufferallocates aJSArrayBufferon the GC heap, so onmakeThreadSafeHermesRuntimeit runs without the runtime lock, and reentrancy checks built onWithRuntimeDecoratornever see the call.#45042 and #45049 fixed the same kind of gap for methods that had no
WithRuntimeDecoratoroverride at all. This one has an override that just skips the guard, so it wasn't caught there.A small stress program shows the race: one thread runs an allocating JS loop on a thread-safe runtime while another creates external ArrayBuffers. In a Debug build it fails the
makeA() calls can not be interleavedassert in HadesGC. With the guard it runs clean. I didn't add it as a test because it depends on timing. React Native's copy ofdecorator.hhas the same line.X-link: facebook/hermes#2204
Test Plan:
Added
HermesRuntimeDecoratorTest.CreateArrayBufferCallsWith. It wrapsmakeHermesRuntime()in a countingWithRuntimeDecorator, creates an ArrayBuffer from aMutableBuffer, and checks thatbefore()andafter()each ran once. Without the change both counts are 0 and the test fails. With it the test passes, and so does the fullAPITestsbinary (356 tests) in a Debug + ASan build.🤖 Generated with Claude Code
Reviewed By: avp
Differential Revision: D123939407
Pulled By: lavenzg