Removing Proxy hasOwn() trap (Was: [[Invoke]] and implicit method calls)
On Tue, Sep 24, 2013 at 7:23 AM, Tom Van Cutsem <tomvc.be at gmail.com> wrote:
[forking from [[invoke]]-thread for clarity]
Thanks!
Allen: would the removal of the hasOwn() trap imply that we can drop the [[HasOwnProperty]] internal method altogether?
I searched the spec. There are not very many places where [[HasOwnProperty]] is used; each one can be replaced with a call to an Abstract Operation defined like this:
When the abstract operation HasOwnProperty is called with Object O and property key P, the following steps are taken:
- Let desc be the result of calling the [[GetOwnProperty]] internal method of O with argument P.
- ReturnIfAbrupt(desc).
- If desc is undefined, then return false.
- Return true.
This allows five or six sections defining [[HasOwnProperty]] implementations to be deleted. It's a nice simplification.
On Tue, Sep 24, 2013 at 7:23 AM, Tom Van Cutsem <tomvc.be at gmail.com> wrote:
Allen: would the removal of the hasOwn() trap imply that we can drop the [[HasOwnProperty]] internal method altogether?
I look at the the opposite way -- we have an 'hasOwn' trap because be have a [[HasOwnProperty]] internal method ;-)
I pretty sure we discussed this before and decided we wanted to keep [[HasOwnProperty]]. However, the only reason I can think of for doing so now is to avoid forcing exotic objects to allocated the property descriptors that [[GetOwnProperty]] produces.
On Sep 24, 2013, at 8:13 AM, Jason Orendorff wrote:
I searched the spec. There are not very many places where [[HasOwnProperty]] is used; each one can be replaced with a call to an Abstract Operation defined like this:
Right, an none of the places seem particularly performance sensitive. In particular, ordinary property lookup uses [[GetOwnProperty]] rather than [[HasOwnProperlty]]
This allows five or six sections defining [[HasOwnProperty]] implementations to be deleted. It's a nice simplification.
Yes, I'm a big fan of minimizing the number of MOP functions. However, I'm a bit uneasy that I can't recall specifically why it is still there. I'm pretty sure we've discussed this before.
I look at the the opposite way -- we have an 'hasOwn' trap because be have a [[HasOwnProperty]] internal method ;-)
I pretty sure we discussed this before and decided we wanted to keep [[HasOwnProperty]]. However, the only reason I can think of for doing so now is to avoid forcing exotic objects to allocated the property descriptors that [[GetOwnProperty]] produces.
Exotic string and integer indexed objects ( = TypedArray instances) provide custom implementations for [[HasOwnProperty]] for exactly this reason.
Right, an none of the places seem particularly performance sensitive. In particular, ordinary property lookup uses [[GetOwnProperty]] rather than [[HasOwnProperlty]]
[[HasProperty]] for ordinary objects also uses [[HasOwnProperty]]. So this needs to be taken into account when searching for performance sensitive calls.
On Sep 24, 2013, at 12:15 PM, André Bargull wrote:
Exotic string and integer indexed objects ( = TypedArray instances) provide custom implementations for [[HasOwnProperty]] for exactly this reason.
And because of proxies, a specified call to [[GetOwnProperty]] can't be optimized away unless you're sure you are dealing with an ordinary object.
[[HasProperty]] for ordinary objects also uses [[HasOwnProperty]]. So this needs to be taken into account when searching for performance sensitive calls.
and most of those [[HasProperty]] calls in the spec. are abstracted within the HasProperty abstract operation, so that also needs to be taken into account.
Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
On Sep 24, 2013, at 12:15 PM, André Bargull wrote:
On Tue, Sep 24, 2013 at 2:34 PM, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
I pretty sure we discussed this before and decided we wanted to keep [[HasOwnProperty]]. However, the only reason I can think of for doing so now is to avoid forcing exotic objects to allocated the property descriptors that [[GetOwnProperty]] produces.
Exotic string and integer indexed objects ( = TypedArray instances) provide custom implementations for [[HasOwnProperty]] for exactly this reason.
And because of proxies, a specified call to [[GetOwnProperty]] can't be optimized away unless you're sure you are dealing with an ordinary object.
Here are three ways implementations can avoid this allocation.
-
We are usually sure we’re dealing with an ordinary object! The only performance-sensitive call site is in [[HasProperty]] for ordinary objects, and there it is of course given that O is ordinary. An implementation can easily avoid the allocation in this case.
-
In all HasOwnProperty call sites, the object will normally be ordinary. Implementations can optimize for that case using the same techniques they already use for everything else in the language.
-
An implementation can certainly have an Object::hasOwnProperty virtual method, if it’s faster, even if the spec calls it an abstract operation rather than an internal method. Proxy::hasOwnProperty would have to call the getOwnPropertyDescriptor trap; all other implementations could avoid the allocation.
I hope my point here is clear. There’s no performance reason to retain the .hasOwn trap or [[HasOwnProperty]].
I recall that Allen and I had previously agreed that it would be cleanest if each of the [[internal]] methods on Object would correspond 1-to-1 to a trap in the Proxy API (and I believe this is the case for the current ES6 draft).
So my stance is that we should either remove both hasOwn() and [[HasOwnProperty]], or else remove neither.
I'm fine either way, but I believe Jason is right that [[HasOwnProperty]] can be refactored as an abstract operation without any perf implications on non-proxy objects.
On Sep 25, 2013, at 1:26 AM, Tom Van Cutsem wrote:
I recall that Allen and I had previously agreed that it would be cleanest if each of the [[internal]] methods on Object would correspond 1-to-1 to a trap in the Proxy API (and I believe this is the case for the current ES6 draft).
So my stance is that we should either remove both hasOwn() and [[HasOwnProperty]], or else remove neither.
Of course, I had assumed that is implicit in the discussion.
I'm fine either way, but I believe Jason is right that [[HasOwnProperty]] can be refactored as an abstract operation without any perf implications on non-proxy objects.
I think so too. Since there doesn't seem to be any objections I'll tag [[HasOwnProperty]] for the scrap heap.
[forking from [[invoke]]-thread for clarity]
2013/9/23 Jason Orendorff <jason.orendorff at gmail.com>
My bad. I was still looking at the wiki page, which is outdated in that respect.
Given the Object.keys precedent, we could consider removing hasOwn() and re-specifying it in terms of getOwnPropertyDescriptor() !== undefined.
More object allocation, but the same holds true for removing the "keys" trap.
Allen: would the removal of the hasOwn() trap imply that we can drop the [[HasOwnProperty]] internal method altogether?