-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
src: avoid making JSTransferable wrapper object weak #50026
src: avoid making JSTransferable wrapper object weak #50026
Conversation
JSTransferable wrapper object is a short-lived wrapper in the scope of the serialization or the deserialization. Make the JSTransferable wrapper object pointer as a strongly-referenced detached BaseObjectPtr so that a JSTransferable wrapper object and its target object will never be garbage-collected during a ser-des process, and the wrapper object will be immediately destroyed when the process is completed.
} | ||
|
||
JSTransferable::~JSTransferable() { | ||
HandleScope scope(env()->isolate()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For education purposes: What is the purpose of initializing a scope in here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A local handle is created with target_.Get(env()->isolate())
in the next line. A handle scope is needed in place to collect the local handle when it goes out of lexical scope.
The crash still occurs even with this commit:
|
Stress test: https://ci.nodejs.org/job/node-stress-single-test/459/ I can reproduce with |
@H4ad the stress test passed. Would you mind sharing more information about your local test? Thank you. |
@legendecas Try with this code: 'use strict';
const assert = require('assert');
const common = require('../common.js');
const { createHistogram } = require('perf_hooks');
const bench = common.createBenchmark(main, {
n: [1e5],
operation: ['creation', 'clone'],
});
let _histogram;
function main({ n, operation }) {
switch (operation) {
case 'creation': {
bench.start();
for (let i = 0; i < n; i++)
_histogram = createHistogram();
bench.end(n);
// Avoid V8 deadcode (elimination)
assert.ok(_histogram);
break;
}
case 'clone': {
bench.start();
for (let i = 0; i < n; i++)
_histogram = structuredClone(createHistogram());
bench.end(n);
// Avoid V8 deadcode (elimination)
assert.ok(_histogram);
break;
}
default:
throw new Error(`Unsupported operation ${operation}`);
}
} Put it inside |
Note that |
Oh, you are right, I forgot to compile the old version with your patch, sorry about that. In this case, I can confirm this PR fixes my bug! Thanks for your work! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Landed in 78a1570 |
JSTransferable wrapper object is a short-lived wrapper in the scope of the serialization or the deserialization. Make the JSTransferable wrapper object pointer as a strongly-referenced detached BaseObjectPtr so that a JSTransferable wrapper object and its target object will never be garbage-collected during a ser-des process, and the wrapper object will be immediately destroyed when the process is completed. PR-URL: nodejs#50026 Fixes: nodejs#49852 Fixes: nodejs#49844 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
JSTransferable wrapper object is a short-lived wrapper in the scope of the serialization or the deserialization. Make the JSTransferable wrapper object pointer as a strongly-referenced detached BaseObjectPtr so that a JSTransferable wrapper object and its target object will never be garbage-collected during a ser-des process, and the wrapper object will be immediately destroyed when the process is completed. PR-URL: nodejs#50026 Fixes: nodejs#49852 Fixes: nodejs#49844 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
JSTransferable wrapper object is a short-lived wrapper in the scope of
the serialization or the deserialization. Make the JSTransferable
wrapper object pointer as a strongly-referenced detached BaseObjectPtr
so that a JSTransferable wrapper object and its target object will never
be garbage-collected during a ser-des process, and the wrapper object
will be immediately destroyed when the process is completed.
Fixes: #49852
Fixes: #49844