Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix JSClosure leak #240

Merged
merged 4 commits into from
Apr 12, 2024
Merged

Fix JSClosure leak #240

merged 4 commits into from
Apr 12, 2024

Conversation

kateinoigakukun
Copy link
Member

let c1 = JSClosure { _ in .undefined }
consume c1

did not release the JSClosure itself and it leaked the underlying
JavaScript closure too because JSClosure -> JS closure thunk ->
Closure registry entry -> JSClosure reference cycle was not broken
when using FinalizationRegistry. (Without FR, it was broken by manual
release call.)

Note that weakening the reference does not violates the contract that
function reference should be unique because holding a weak reference does
deinit but not deallocate the object, so ObjectIdentifier is not reused
until the weak reference in the registry is removed.

```swift
let c1 = JSClosure { _ in .undefined }
consume c1
```

did not release the `JSClosure` itself and it leaked the underlying
JavaScript closure too because `JSClosure` -> JS closure thunk ->
Closure registry entry -> `JSClosure` reference cycle was not broken
when using FinalizationRegistry. (Without FR, it was broken by manual
`release` call.)

Note that weakening the reference does not violates the contract that
function reference should be unique because holding a weak reference does
deinit but not deallocate the object, so ObjectIdentifier is not reused
until the weak reference in the registry is removed.
The test suite was not properly releasing the closures but they have not
been revealed as a problem because those closures were leaked
conservatively.
…tract

This additional information will help developers to find the root cause
Copy link

github-actions bot commented Apr 7, 2024

Time Change: +325ms (3%)

Total Time: 9,697ms

Test name Duration Change
Serialization/JavaScript function call through Wasm import 23ms +2ms (6%) 🔍
Serialization/JavaScript function call through Wasm import with int 16ms +2ms (9%) 🔍
Serialization/JavaScript function call from Swift 103ms +7ms (7%) 🔍
Serialization/JavaScript Number to Swift Int 331ms +32ms (9%) 🔍
View Unchanged
Test name Duration Change
Serialization/Swift Int to JavaScript with assignment 334ms +17ms (4%)
Serialization/Swift Int to JavaScript with call 993ms +32ms (3%)
Serialization/Swift String to JavaScript with assignment 391ms +8ms (2%)
Serialization/Swift String to JavaScript with call 1,048ms +30ms (2%)
Serialization/JavaScript String to Swift String 3,821ms +158ms (4%)
Object heap/Increment and decrement RC 2,625ms +37ms (1%)
View Baselines
Test name Duration
Serialization/Call JavaScript function directly 3ms
Serialization/Assign JavaScript number directly 3ms
Serialization/Call with JavaScript number directly 3ms
Serialization/Write JavaScript string directly 3ms
Serialization/Call with JavaScript string directly 3ms

@kateinoigakukun kateinoigakukun requested a review from a team April 7, 2024 06:57
@kateinoigakukun
Copy link
Member Author

Tested with a random large-scale application and no major regression found

@kateinoigakukun kateinoigakukun merged commit d9a4a9f into main Apr 12, 2024
17 checks passed
@kateinoigakukun kateinoigakukun deleted the katei/fix-closure-leak branch April 12, 2024 09:02
kateinoigakukun added a commit that referenced this pull request Apr 12, 2024
kateinoigakukun added a commit that referenced this pull request Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant