Yeah, this would work. It'd be kind of ugly, though - whenever we see
__noSuchMethod__ being set, it's not just a matter of not generating new
stubs.. we'd have to go back and discard all IC stubs which have already
been generated.
Given that the proposal to remove __noSuchMethod__ has been raised
several times even before this particular issue, I'm presenting this as
yet-another-reason-to-remove.
Kannan
On 13-09-10 11:55 AM, Mike Shaver wrote:
Somewhat gross, but could you condition the generation of that code on
seeing a __noSuchMethod__ property set anywhere in the compartment or
whatever the right unit of isolation is? IIRC we did this for mutated
Array.prototype at one point.
Mike
On Tuesday, September 10, 2013, Kannan Vijayan wrote:
I'd like to dredge up this topic and resolve it once and for all.
Please see bug 912303 for why I'm bringing this up now:
https://bugzilla.mozilla.org/show_bug.cgi?id=912303
As it stands, our current JITs (neither Ion nor Baseline, nor
Jaeger before that) do not respect __noSuchMethod__ semantics, and
the fix for this bug will be painful and unnecessarily complex and
heavyweight. __noSuchMethod__ hurts us in ways that we can't
defend against with the usual techniques. Let me explain in more
detail.
Whenever we attach an optimized stub (either Baseline or Ion) for
any CALLELEM or CALLPROP operation, we MUST check the result to
see if it's a primitive, and MUST jump to a slowpath to make a
VM-call to run |OnUnknownMethod|. This is the _best_ possible
solution, and it involves at the minimum the insertion of a
likely-to-fail primitive-value check into property-access hot
paths, and a whole lot of complexity (and bloat) to every IC stub
that does property accesses.
"But wait!" you say, "why don't we just not attach stubs when we
know that __onUnknownMethod__ may need to be called?". Well, we
can't do that, because we don't know when __onUnknownMethod__ will
be bound on an ancestral prototype of the holder object of the
property being retrieved. We could generate an optimized stub,
and then later an ancestral prototype object modified to bind
__onUnknownMethod__, and the optimized stub would have no way of
knowing, short of always guarding against all shapes in the proto
chain of every CALLPROP/CALLELEM, which is worse than the
primitive-value check described previously.
This is a huge amount of pain and complexity for handling a very
rare corner case. Unlike most corner cases which can be easily
guarded against, this feature forces additional checks in common
hot-paths, and there's no way around it. Baseline has several
GetProp and GetElem stubs that would need to be modified in this
way. Ion has several variants of each as well.
This pain can be reduced by either removing __noSuchMethod__
entirely, or by reducing its scope so that it only gets called for
nonexistant properties (as opposed to getting called for both
nonexistant and primitive-valued properties).
Combining the above argument with previously presented arguments,
the reasons for removal are:
1. It's a non-standard extension and it's not going to get
standardized.
2. A good amount of its functionality can be implemented using
Object.prototype.__proto__ = new Proxy(...), which has the
additional boon of being standardized.
3. It adds a lot of unnecessary complexity to the JITS, bloats the
generated jitcode, and slows down hot paths.
I'm open to either removal or limiting its behaviour to only
non-existant properties, but I want to get moving ahead with at
least one of those two options.
My vote is for removal.
Cheers.
Kannan
_______________________________________________
dev-tech-js-engine-internals mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals
_______________________________________________
dev-tech-js-engine-internals mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals