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

Move GDScript uninitialization to GDScriptLanguage::finish() #69506

Merged

Conversation

adamscott
Copy link
Member

@adamscott adamscott commented Dec 2, 2022

GDScriptLanguage::finish() was empty. So I moved the uninitialization of GDScriptLanguage originally in GDScriptLanguage::~GDScriptLanguage() inside it, calling too a new GDScriptCache::clear() to clear the cache sooner than the destructor. And finish_languages is called before the servers uninit.

As cyclic references didn't exist, there wasn't any GDScript instance that could live after the removal of the root script, so it wasn't a problem until cyclic references (which could make it so that instances could live beyond the root script).

The problem existed when cyclic cached scripts would hold RID past the uninitialization of the servers.

Fixes #68973
Would be interesting to merge with #69077

@adamscott adamscott requested a review from a team as a code owner December 2, 2022 18:30
@adamscott adamscott force-pushed the move-gdscript-uninit-to-finalize branch from 9776b7c to a5dec4d Compare December 2, 2022 18:55
@adamscott
Copy link
Member Author

adamscott commented Dec 2, 2022

Credited @rburing as a co-author for his valuable help.

@Chaosus Chaosus added this to the 4.0 milestone Dec 2, 2022
@adamscott adamscott force-pushed the move-gdscript-uninit-to-finalize branch from a5dec4d to 65c3cd0 Compare December 2, 2022 20:19
@adamscott adamscott force-pushed the move-gdscript-uninit-to-finalize branch from 65c3cd0 to b615f7f Compare December 3, 2022 14:08
@adamscott
Copy link
Member Author

@unfa This PR should fix the crash that happens when closing Liblast.

Comment on lines 2026 to 2029
if (finalizing) {
return;
}
finalizing = true;
Copy link
Member

Choose a reason for hiding this comment

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

This would now work, but I'm a bit confused because now finalize() will be called both by GDScriptLanguage::finish() and GDScriptLanguage::~GDScriptLanguage(), but it will only do something for the first one that calls it.

Is that order non deterministic, or why do we need to call it in both?

Copy link
Member Author

Choose a reason for hiding this comment

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

Mmm. Yeah, calling it once should work. I'll let the finalizing variable there, just to be sure that it's not called twice.

Copy link
Member

Choose a reason for hiding this comment

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

I guess there's no need for a new finalize() method now and it can go in finish() directly?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. I was inspired by csharp_script.cpp, which explains a lot, but yes, I'll transfer everything into finish().

void CSharpLanguage::finish() {
finalize();
}
void CSharpLanguage::finalize() {
if (finalized) {
return;
}
finalizing = true;
// Make sure all script binding gchandles are released before finalizing GDMono
for (KeyValue<Object *, CSharpScriptBinding> &E : script_bindings) {

Copy link
Member

Choose a reason for hiding this comment

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

Maybe @neikeq can give some input then, there might be a good reason to still call finalize() in both finish() and the destructor.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe @neikeq can give some input then, there might be a good reason to still call finalize() in both finish() and the destructor.

I don't really remember, to be honest, and I'm afraid changing it could cause an issue. I wish I had left an explanatory comment there...

The reason it's a different method (finalize) is because clang-tidy warns when calling virtual methods (finish) from the destructor.

@adamscott adamscott force-pushed the move-gdscript-uninit-to-finalize branch 2 times, most recently from 4504117 to a7ce34c Compare December 3, 2022 22:23
@adamscott adamscott force-pushed the move-gdscript-uninit-to-finalize branch 2 times, most recently from 27d2163 to 480fcae Compare December 6, 2022 00:39
@adamscott
Copy link
Member Author

@kleonc I added you as co-author of the PR.

@kleonc
Copy link
Member

kleonc commented Dec 6, 2022

@kleonc I added you as co-author of the PR.

Barely did anything but sure, fine for me. Gotta be able to blame someone for these changes. 😄

@adamscott adamscott changed the title Move GDScript uninitialization to GDScriptLanguage::finalize() Move GDScript uninitialization to GDScriptLanguage::finish() Dec 6, 2022
@adamscott adamscott force-pushed the move-gdscript-uninit-to-finalize branch 2 times, most recently from b136167 to 46f4f94 Compare December 6, 2022 14:34
Co-authored-by: Ricardo Buring <ricardo.buring@gmail.com>
Co-authored-by: kleonc <9283098+kleonc@users.noreply.github.com>
@adamscott adamscott force-pushed the move-gdscript-uninit-to-finalize branch from 46f4f94 to 88f3045 Compare December 6, 2022 14:35
@akien-mga akien-mga merged commit 9bd7ad5 into godotengine:master Dec 6, 2022
@akien-mga
Copy link
Member

Thanks!

@adamscott
Copy link
Member Author

@akien-mga Thanks for the review! 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Shape2D and Shape3D RID allocations can leak since #67714
5 participants