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

[emval] Reuse method calling optimisation in regular calls #20383

Merged
merged 11 commits into from
Oct 18, 2023

Conversation

RReverser
Copy link
Collaborator

Method, function and constructor calls are very similar in nature but used different code paths: method calls have an optimisation where an optimised caller trampoline is generated once and reused for each function signature, whereas the other two serialized arguments and types every time.

There is no reason for them to diverge, so I made function calls and constructors reuse the same optimisation.

Results on a silly microbenchmark running a side-effect-ful JS function with 100 integer args in a loop:

Before

with dynamic execution:

as method: 224.504ns
as function: 5367.9ns

without dynamic execution:

as method: 845.044ns
as function: 5350.96ns

After

with dynamic execution:

as method: 262.74ns
as function: 246.593ns

without dynamic execution:

as method: 859.534ns
as function: 823.498ns

In real world the difference is unlikely to be perceptible, but at the very least this makes the code more consistent and deletes a bunch of duplication.

Copy link
Collaborator

@brendandahl brendandahl left a comment

Choose a reason for hiding this comment

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

Looks good, minor nits.

@@ -509,16 +480,28 @@ class val {
return internal::_emval_delete(as_handle(), val_ref(property).as_handle());
}

template<typename... Args>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why was this moved?

Copy link
Collaborator Author

@RReverser RReverser Oct 17, 2023

Choose a reason for hiding this comment

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

Just to keep all variants / usages of internalCall together, I found it makes it easier to iterate on it when you can see all places that need to be updated together on one screen.

@RReverser
Copy link
Collaborator Author

Addressed the feedback.

@RReverser RReverser force-pushed the emval-optimised-call-new branch from 7ba7779 to b4fef41 Compare October 17, 2023 23:29
@RReverser RReverser merged commit 12777ca into emscripten-core:main Oct 18, 2023
@RReverser RReverser deleted the emval-optimised-call-new branch October 18, 2023 17:53
brendandahl added a commit to brendandahl/emscripten that referenced this pull request Jan 5, 2024
Before PR emscripten-core#20383 val's `call` and `operator()` had different behaviors where
one would automatically destroy arguments after the call and the other
didn't. After that PR, they both called destroy. The automatic destruction
wasn't really documented anywhere and and led to some unexpected behavior.

This changes it so neither automatically destroys the arguments which I
think is more inline with the rest of embind where it's up to the user
to handle object lifetimes.

Fixes: emscripten-core#21016 and emscripten-core#20095
brendandahl added a commit to brendandahl/emscripten that referenced this pull request Jan 8, 2024
Before PR emscripten-core#20383 val's `call` and `operator()` had different behaviors where
one would automatically destroy arguments after the call and the other
didn't. After that PR, they both called destroy. The automatic destruction
wasn't really documented anywhere and and led to some unexpected behavior.

This changes it so neither automatically destroys the arguments which I
think is more inline with the rest of embind where it's up to the user
to handle object lifetimes.

Fixes: emscripten-core#21016 and emscripten-core#20095
brendandahl added a commit to brendandahl/emscripten that referenced this pull request Jan 11, 2024
Before PR emscripten-core#20383 val's `call` and `operator()` had different behaviors where
one would automatically destroy arguments after the call and the other
didn't. After that PR, they both called destroy. The automatic destruction
wasn't really documented anywhere and and led to some unexpected behavior.

This changes it so neither automatically destroys the arguments which I
think is more inline with the rest of embind where it's up to the user
to handle object lifetimes.

Fixes: emscripten-core#21016 and emscripten-core#20095
brendandahl added a commit that referenced this pull request Jan 11, 2024
…21022)

Before PR #20383 val's `call` and `operator()` had different behaviors where
one would automatically destroy arguments after the call and the other
didn't. After that PR, they both called destroy. The automatic destruction
wasn't really documented anywhere and and led to some unexpected behavior.

This changes it so neither automatically destroys the arguments which I
think is more inline with the rest of embind where it's up to the user
to handle object lifetimes.

Fixes: #21016 and #20095
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