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 TODOs to address memory leaks #343

Closed

Conversation

gabrielschulhof
Copy link
Contributor

Fixes: #333

@gabrielschulhof gabrielschulhof force-pushed the fix-leak-symbol branch 3 times, most recently from d65616c to 96665dd Compare September 17, 2018 14:19
napi.h Show resolved Hide resolved
@gabrielschulhof
Copy link
Contributor Author

gabrielschulhof commented Sep 17, 2018

Finally, I chose to attach the data by creating a property whose key is an anonymous symbol and whose value is an external containing the data. This leaves the napi_wrap() slot free, and will not leave any unsightly anonymous symbols hanging around on an object once we have ubiquitous support for napi_add_finalizer().

@gabrielschulhof
Copy link
Contributor Author

Testing to make sure that the finalizer gets called could be done using assertions made about the output of a coverage tool. Basically, we have to make sure that the line where the data gets deleted gets hit a certain number of times in response to the global.gc() call here.

I manually verified this by adding an fprintf(stderr, ...) to the finalizer and running the thunking_manual test via node --expose-gc test/thunking_manual.js.

To test this on the CI, we need a code coverage build followed by a code coverage run, followed by parsing of the code coverage output so we can make assertions about when the finalizer gets called.

@gabrielschulhof gabrielschulhof force-pushed the fix-leak-symbol branch 2 times, most recently from c55522e to 3aac9eb Compare September 18, 2018 21:23
@mhdawson mhdawson mentioned this pull request Sep 18, 2018
6 tasks
@gabrielschulhof gabrielschulhof force-pushed the fix-leak-symbol branch 2 times, most recently from 3b36403 to d7143a5 Compare September 23, 2018 15:41
@gabrielschulhof
Copy link
Contributor Author

@mhdawson I've added back the deprecated stuff such that it's behind the new build flag NODE_ADDON_API_DISABLE_DEPRECATED. If such a flag is absent from the build, all deprecated stuff will be available.

@gabrielschulhof gabrielschulhof force-pushed the fix-leak-symbol branch 2 times, most recently from a5e4e04 to 791d161 Compare September 26, 2018 15:53
@gabrielschulhof
Copy link
Contributor Author

@mhdawson I had forgotten to update the PR to update the documentation. That's done now.

test/binding.gyp Outdated
@@ -39,6 +40,7 @@
'dependencies': ["<!(node -p \"require('../').gyp\")"],
'cflags': [ '-Werror', '-Wall', '-Wextra', '-Wpedantic', '-Wunused-parameter' ],
'cflags_cc': [ '-Werror', '-Wall', '-Wextra', '-Wpedantic', '-Wunused-parameter' ],
'defines': ['NODE_ADDON_API_DISABLE_DEPRECATED']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we won't test the deprecated functions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does mean that.

@mhdawson
Copy link
Member

@gabrielschulhof this is big enough it would probably be good to spend a few minutes together going through it. Maybe after the N-API meeting on Thursday.

// After defining the class we iterate once more over the property descriptors
// and attach the data associated with accessors and instance methods to the
// newly created JavaScript class.
for (size_t idx = 0; idx < props_count; idx++) {
Copy link
Contributor Author

@gabrielschulhof gabrielschulhof Sep 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mhdawson I realized that it's OK to always attach this data to the JS class. We do not need to afterwards retrieve the instance method and attach the data to it, because we do not need to worry about the scenario where someone "detaches" an instance method from the class' .prototype property. The reason we do not need to worry is that in our implementation of instance methods, we attempt to napi_unwrap() the this parameter in order to retrieve the instance of the native class, so we can then call the corresponding instance method on the native instance. Since the JavaScript class is garbage-collected, no new JavaScript instances can be created, and so no JavaScript objects can arrive via the this property that will successfully napi_unwrap() to give us the native instance. This fails nicely with a napi_object_expected or a napi_invalid_arg status that gets propagated back into JavaScript as an exception.

PropertyDescriptor::Function(env, str7, TestFunction),
#endif // !NODE_ADDON_API_DISABLE_DEPRECATED
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to test both the deprecated and non-deprecated so this should just be #ifndef, #endif as opposed to using #else ? Same goes to all of the other places as well.

@gabrielschulhof
Copy link
Contributor Author

gabrielschulhof commented Oct 1, 2018

@mhdawson I split the deprecated tests into their own test at test/object/object_deprecated.{cc,js} and modified the build to conditionally include test/object/object_deprecated.cc. The test runs unconditionally but short-circuits successfully if binding.object_deprecated is absent.

@mhdawson
Copy link
Member

mhdawson commented Oct 1, 2018

Looks good other than the comment about testing should test both deprecated and non-deprecated versions as opposed to one or the other. Looks like all of the other issues we discussed in person are addressed and I'll sign of land once the test ifdefs are fixed up.

@gabrielschulhof
Copy link
Contributor Author

@mhdawson I fixed that. Now, when you run npm test it runs both the deprecated and the non-deprecated tests, and when you run npm test --disable-deprecated it only runs the non-deprecated tests.

Copy link
Member

@mhdawson mhdawson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

mhdawson pushed a commit that referenced this pull request Oct 2, 2018
PR-URL: #343
Fixes: #333
Reviewed-By: Michael Dawson <[email protected]>
@mhdawson
Copy link
Member

mhdawson commented Oct 2, 2018

Landed as 917bd60

@mhdawson mhdawson closed this Oct 2, 2018
@gabrielschulhof gabrielschulhof deleted the fix-leak-symbol branch October 2, 2018 18:03
kevindavies8 added a commit to kevindavies8/node-addon-api-Develop that referenced this pull request Aug 24, 2022
Marlyfleitas added a commit to Marlyfleitas/node-api-addon-Development that referenced this pull request Aug 26, 2022
wroy7860 added a commit to wroy7860/addon-api-benchmark-node that referenced this pull request Sep 19, 2022
johnfrench3 pushed a commit to johnfrench3/node-addon-api-git that referenced this pull request Aug 11, 2023
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.

2 participants