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

GDExtension: PtrToArg::convert() uses const-reference where possible #80075

Merged
merged 1 commit into from
Sep 17, 2023

Conversation

Bromeon
Copy link
Contributor

@Bromeon Bromeon commented Jul 30, 2023

Fixes #80074.

In the cases where reinterpret_cast is immediately dereferenced, PtrToArg::convert() returns a const-reference instead of a value. This allows to reuse the object located at the address of the passed const void* pointer, instead of triggering the copy constructor.

We cannot return const-references where temporary values are constructed. Most manual PtrToArg specializations fall under this category and are thus untouched.

In some cases, we now return a const-reference to scalar types like int, bool etc. Since the function is annotated as _FORCE_INLINE_, I expect any such indirections to be optimized away though.

I did some tests with the Rust binding (gdext) already, but I'd appreciate some input on this!

@Bromeon Bromeon requested a review from a team as a code owner July 30, 2023 21:40
@Bromeon Bromeon force-pushed the gdextension/optimize-ptrcalls branch from 0998341 to df033aa Compare July 30, 2023 21:43
_FORCE_INLINE_ static TypedArray<T>
convert(const void *p_ptr) {
_FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is purely a whitespace change (should be more readable and still OK for clang-format) 🙂

@Bromeon Bromeon force-pushed the gdextension/optimize-ptrcalls branch from df033aa to 7acbbfb Compare July 30, 2023 21:49
@Bromeon Bromeon changed the title GDExtension: PtrArg::convert() uses const-reference where possible GDExtension: PtrToArg::convert() uses const-reference where possible Jul 30, 2023
@dalexeev dalexeev added the bug label Jul 31, 2023
@dalexeev dalexeev added this to the 4.2 milestone Jul 31, 2023
@Bromeon
Copy link
Contributor Author

Bromeon commented Jul 31, 2023

CI job Editor with doubles and GCC sanitizers failed with:

ranlib: /home/runner/work/godot/godot/godot-cpp/bin/libgodot-cpp.linux.template_debug.dev.x86_64.a: No space left on device

I encountered the same issue in my own nightly builds, also gcc memcheck running out of disk space... Was there a regression? Or GitHub decreased available disk space?

@dalexeev
Copy link
Member

@Bromeon See:

@dsnopek
Copy link
Contributor

dsnopek commented Jul 31, 2023

Good catch!

This makes sense to me. Even outside the context of GDExtension, we do ptrcalls with code like:

template <class T, class... P, size_t... Is>
void call_with_ptr_args_helper(T *p_instance, void (T::*p_method)(P...), const void **p_args, IndexSequence<Is...>) {
	(p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...);
}

In the case that one (or more) of the method's arguments takes a const &, this would also avoid a copy.

I ran godot-cpp's automated tests and they passed. So, this seems OK from the perspective of GDExtension. It could probably use to be reviewed by the core team as well.

@dsnopek dsnopek requested a review from a team July 31, 2023 22:00
@Bromeon Bromeon force-pushed the gdextension/optimize-ptrcalls branch from 7acbbfb to 38334fd Compare August 7, 2023 18:41
@Bromeon
Copy link
Contributor Author

Bromeon commented Aug 7, 2023

Rebased onto master.

@akien-mga akien-mga requested a review from vnen August 8, 2023 13:15
@dsnopek
Copy link
Contributor

dsnopek commented Aug 11, 2023

Discussed at the GDExtension meeting, and we think this makes sense. This is also on the agenda to discuss at the core team meeting, where we hope to double check with them that this won't cause any other problems.

@jsjtxietian
Copy link
Contributor

jsjtxietian commented Aug 23, 2023

Great Catch!
For anyone who is intersted, I made a small demo in compiler explorer, even with -O3 the copy can not be elimated.
https://godbolt.org/z/r4KfGdh1h

Copy link
Contributor

@dsnopek dsnopek left a comment

Choose a reason for hiding this comment

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

The core team meeting I was hoping to discuss this at didn't end up really happening. It'd still be nice to have a review from someone on the core team, however, I personally really think this should be OK. This is adding const & in a template and so I think any issues would be detected at compile time, and this is compiling just fine on all platforms in the CI.

@Bromeon
Copy link
Contributor Author

Bromeon commented Aug 24, 2023

For anyone who is intersted, I made a small demo in compiler explorer, even with -O3 the copy can not be elimated.

The compiler has to be conservative, because the pointer passed to convert() is opaque: it cannot know what happens to it once we've made a copy. This copy could as well be deliberate because we're intending to change the original object. The copy itself could have side effects (which might be disproved by inspecting the copy constructor implementation; not sure how deep compilers go here).

It is our "insider knowledge" that a GDExtension binding keeps that pointer unchanged, as it's in a function call.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

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

Couldn't get another review from the core team, but it looks overall sensible to me and I trust that if there's any issue with this change, we'll find out fast.

@akien-mga akien-mga merged commit 61df1de into godotengine:master Sep 17, 2023
@akien-mga
Copy link
Member

Thanks!

@Bromeon Bromeon deleted the gdextension/optimize-ptrcalls branch September 17, 2023 18:10
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.

GDExtension: PtrToArg::convert() creates unnecessary copies
5 participants