-
-
Notifications
You must be signed in to change notification settings - Fork 580
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
Automatically register only engine classes whose header has been included #1266
Automatically register only engine classes whose header has been included #1266
Conversation
497bc13
to
09a3fa6
Compare
Compiling the test GDExtension (used in the automated tests) with the default
So, it appears to be working, at least in my case! I'd be very curious to see what results others get with other compilers on other OS's. EDIT: Updated after getting editor plugin related classes correctly excluded as well. |
My setup in Godot Jolt is admittedly somewhat unorthodox compared to most other godot-cpp usage, so this is not really a representative sample, but here are the numbers I'm seeing on Windows:
It's certainly an improvement across the board, but nothing astronomical in my particular case. I can give it a try on other platforms later to see if it's specific to the linker/platform perhaps. For reference, I saw about a ~1.2 MB increase with clang-cl when #1050 was introduced, and a ~2 MB bump with MSVC. I have since added quite a few godot-cpp includes though (the total of which can be seen here) so I assume I wouldn't win it all back even if this PR had cancelled out #1050 completely. |
78d7257
to
7222c38
Compare
Based on a RocketChat conversation with @mihe and @maiself, I've come to realize that I was trying to use Also, I noticed that we were still including some editor plugin classes, even if the GDExtension didn't do anything with editor plugins. So, I rearranged some of that code, and now those will be excluded too! It saved an additional ~200kb in my testing. |
7222c38
to
ecadb65
Compare
@mihe Thanks for testing and posting your numbers!
Hm, you're probably right that you have enough includes now that it won't cancel out all of the size gains from #1050, but the difference still seems quite large (~200kb vs 1.2mb). It'd be really interesting to try reverting #1050 and see if you reclaim the same amount of memory, or if it's somewhat less, although, reverting it would probably be pretty messy at this point given all the changes that have been made since then. |
ecadb65
to
5c9ee1c
Compare
I just tried the latest PR with my SG Physics 2D extension (using the same platform, compiler and setup as described in my previous comment) and got this result:
So, I'm personally seeing a pretty dramatic improvement in this case! |
Seeing as how this PR has gotten rid of the generated As such, I just now tried simply removing that new I also tried building on Linux with both Clang and GCC, and with this PR I'm still seeing very modest reductions in my project, in the range of -0.1-ish MB, but when I omit this new I guess I'll need to fire up SizeBench to better understand what's happening. Either way, clearly this PR is a net positive, so I'm all for it. |
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.
I didn't test the size reduction but code-wise this looks good, and the discussion seems to agree it's an improvement.
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.
Just a tiny nitpick, looks good otherwise
5c9ee1c
to
b507b3e
Compare
Cherry-picked for 4.1 in PR #1281 |
This is based on an idea from @maiself at a GDExtension meeting from a couple months ago!
In PR #1050, we added a
HashMap
that stores the binding callbacks for all engine types, in order to fix a serious bug where the wrapper class used could be an arbitrary parent class (rather than the actual engine class) leading to unexpected behavior in some situations.Unfortunately, this led to issue #1160 where builds would be ~1-5mb bigger than previously.
This was due to the linker previously being able to optimize away any class that wasn't actually used in the GDExtension. However, if we have to reference every class in order to add their binding callbacks to the
HashMap
, they are all technically "used", and so none could be optimized away.@maiself had this really clever idea, which was recorded in the meeting notes as:
This would mean that classes are only added to the
HashMap
, if the developer actually includes the header file for them! This should allow the linker to do it's old optimization again (I hope :-))This PR attempts to implement that, however, I encountered some interesting issues when actually trying to do it:
static inline
variables can't be anonymous -- apparently the variable name is used to tell that each declaration refers to the same object, so all but one can be removed by the linker (which what theinline
is aiming to do here).HashMap
in the registration object, because theHashMap
is keyed byStringName
, and we can't createStringName
's until after godot-cpp has been initialized. So, instead, theEngineClassRegistration<T>
constructor is adding a callback which will do the actual registration at the appropriate time.std::vector
as a static variable at the compilation unit level, because static variables can be initialized in any order, and we can't know that ourinline static EngineClassRegistration<T>
variables won't be initialized before thestd::vector
. This is why that is a static variable at the function level, so that it will be initialized on demand.None of those are really necessarily a problem, but it's why the code in this PR is more complicated than the simple psuedo-code that I started with :-)
Any feedback on how I could simplify this would be appreciated! But, personally, assuming it actually solves the problem, I think even with all these complications this is still an acceptable way to do this.
Fixes #1160