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

[BUGFIX] Make the custom tag system non-enumerable #1224

Merged
merged 1 commit into from
Dec 5, 2020

Conversation

pzuraq
Copy link
Member

@pzuraq pzuraq commented Dec 5, 2020

Currently, the custom tag system relies on an enumerable "symbol"-like
key, which is then placed on the objects that need to use it. This is an
expensive system, since it means we need to do a brand check to see if
the function exists, which means crawling the prototype chain every time
we look up a tag for a property on an object.

This PR instead places the functions in a WeakMap. This means that in
general, we can check to see if the WeakMap has the value, and if so
then we can use the function directly. WeakMap lookup is generally
faster, as it means we don't have to walk the entire prototype chain of
a megamorphic object, so this should generally be more performant.

It does mean that the functions in question need to be bound to the
instance, which could impact performance, but the functions should still
be inline-able when called (since they are called independent of the
object), and given that usage of tag lookup with non-proxies likely
dominates over usage with proxies, it should matter less than the
savings from using a WeakMap.

Finally, this means that CUSTOM_TAG_FOR is not exposed at all, so there
cannot be any observable side-effects such as the ones causing the bug
in: ember-m3/ember-m3#957

Unrelated Changes

In addition, I did a quick refactor of the proxy handlers to extract
them as classes. This is important for performance (POJOs with methods
on the instance do not inline, even as proxy handlers), I just never got
around to it before.

@rwjblue
Copy link
Member

rwjblue commented Dec 5, 2020

Were you able to confirm that this fixes ember-m3/ember-m3#957?

@pzuraq
Copy link
Member Author

pzuraq commented Dec 5, 2020

Confirmed that it does fix the bug!

Currently, the custom tag system relies on an enumerable "symbol"-like
key, which is then placed on the objects that need to use it. This is an
expensive system, since it means we need to do a brand check to see if
the function exists, which means crawling the prototype chain every time
we look up a tag for a property on an object.

This PR instead places the functions in a WeakMap. This means that in
general, we can check to see if the WeakMap has the value, and if so
then we can use the function directly. WeakMap lookup is generally
faster, as it means we don't have to walk the entire prototype chain of
a megamorphic object, so this should generally be more performant.

It does mean that the functions in question need to be bound to the
instance, which could impact performance, but the functions should still
be inline-able when called (since they are called independent of the
object), and given that usage of tag lookup with non-proxies likely
dominates over usage with proxies, it should matter less than the
savings from using a WeakMap.

Finally, this means that CUSTOM_TAG_FOR is not exposed at all, so there
cannot be any observable side-effects such as the ones causing the bug
in: ember-m3/ember-m3#957

\### Unrelated Changes

In addition, I did a quick refactor of the proxy handlers to extract
them as classes. This is important for performance (POJOs with methods
on the instance do not inline, even as proxy handlers), I just never got
around to it before.
@pzuraq pzuraq merged commit 09a959a into master Dec 5, 2020
@pzuraq pzuraq deleted the bugfix/make-custom-tag-for-non-enumerable branch December 5, 2020 23:12
@pzuraq pzuraq added the bug label Dec 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants