Closed Bug 516857 Opened 13 years ago Closed 11 years ago

Setting expando properties on DOM nodes falls off trace

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED INVALID

People

(Reporter: bzbarsky, Unassigned)

References

(Blocks 2 open bugs)

Details

(Keywords: regression)

Attachments

(1 file)

Attached file Testcase
Testcase is basically:

      for (var i = 0; i < 10; ++i) {
        var d = document.createElement("div");
        d.test = "test"+i;
      }

I get:

  abort: 10042: can't trace uncacheable property set
  Abort recording of tree file:///Users/bzbarsky/baz.html:5@14 at
    file:///Users/bzbarsky/baz.html:7@41: SetPropHit.
Note to self: if |d| is outside the loop, the abort is different; may want a different bug there.
So what happens is that we land in js_FillPropertyCache.  cs->format includes JSOF_SET. |adding| is true, sprop == scope->lastProp and scope->shape == sprop->shape, so we enter that branch.  sprop->parent is null.  So we look up the proto, and then the protoscope.  protoscope->emptyScope is null, so we return JS_NO_PROP_CACHE_FILL.

The sprop is more or less what one would expect here: its id is "test" and it has:

  getter = <XPC_WN_Helper_GetProperty(JSContext*, JSObject*, long, long*)>
  setter = <XPC_WN_Helper_SetProperty(JSContext*, JSObject*, long, long*)>

since those are the class get/set property hooks for XPConnectified objects.

proto is of class XPC_WN_ModsAllowed_NoCall_Proto_JSClass.

In particular, the JSClass of proto is NOT the same as the JSClass of obj (the latter is HTMLDivElement).  So js_ObjectIsSimilarToProto is false in this case (and hence InitScopeForObject never called getEmptyScope and emptyScope is null).

In fact, the two classes have different flags, different getObjectOps, etc.

So it looks like the _first_ expando property we set on any xpconnectified object will always be a property cache miss, and hence a trace abort.  The original testcase I ran into this on created a bunch of DOM nodes in a loop and set a bunch of properties on them; the loop didn't trace, of course.

Any ideas how we can make this better, either in jseng or in xpconnect?
Possible regression from bug 503080.
Blocks: 503080
Blocks: 40988
(In reply to comment #2)
> In particular, the JSClass of proto is NOT the same as the JSClass of obj (the
> latter is HTMLDivElement).  So js_ObjectIsSimilarToProto is false in this case
> (and hence InitScopeForObject never called getEmptyScope and emptyScope is
> null).

This is after bug 505523, right? I think before that patch js_ObjectIsSimilarToProto would have returned true in this case.
Er, yes.  It is.  That makes me feel better about the fact that we just noticed the regression....
Blocks: 505523
Keywords: regression
Hmm.  The XPConnect behavior of changing classes when switching from slimwrapper to XPCWrappedNative that Peter mentions in bug 505523 might be a problem for the solution Jason and I discussed of branding the emptyScope with the child's class.  Are there things that would cause the change but leave the child with an empty scope?  What things actually cause a conversion nowadays?
No longer blocks: 503080
We no longer switch classes dynamically for xpconnect.  So we should revisit this, but probably as part of bug 622298.
Blocks: domperf, 622298
The common case (same origin) has no wrapper in between any more. The uncommon case is always off trace right now (since wrappers are non-native).
I'm not sure what wrappers have to do with anything.  They weren't involved in comment 2...

In the bug this blocks, removing the expando sets speeds up a DOM loop creating nodes by 2x
No longer relevant now that the tracer is gone.
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.