Closed Bug 619592 Opened 14 years ago Closed 14 years ago

JM: TypeInference: fast path compares on known objects

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: bhackett1024, Unassigned)

References

Details

(Whiteboard: fixed-in-jaegermonkey)

When doing equality on two values of unknown type, JM has an equality IC that can handle comparisons between two objects. When the equality is on known objects, however, a fast path is only generated when the other side of the equality is undefined or null. This is killing inference performance on ai-astar, whose main loop compares two things known to be objects: for(var i=0;i<this.length;i++) { if(this[i].pos == obj.pos) { return this[i]; } }
FWIW, that loop in ai-astar should really trace -- that's bug 606890. Also, see https://wiki.mozilla.org/Kraken_Info#ai-astar.
This is a nifty loop that benefits from a host of optimizations, whether on or off trace. Ideal code, which JM will be at before toooo long (property stuff is unlikely for Fx5): - this.length, obj.pos and slots(this) are loop invariant, hoist them and carry them around the loop in registers (don't reload at loop head). - Hoist array bounds check for this[i], compute whether this.length <= initializedLength(this) at the loop head (it will be). - Carry i around the loop in a register (JM currently currently requires a write of i at the backedge, but that should be basically free). - No type or shape checks for 'this[i].pos', do it in two loads and zero branches. Due to some stupid avoid-recompilation heuristics (see bug 619343) the inference currently thinks this may be unpacked and this[i] may be void, after those are fixed (by throwing them out) and inference is incorporated into property accesses this will be possible.
Blocks: 640897
http://hg.mozilla.org/projects/jaegermonkey/rev/526876bb3ff8 Add this path. We now track whether a type can represent objects with equality hooks in their clasp->ext, and compare the JSObject* when the operands are both known objects without these hooks. function foo(a, b) { var c = 0; for (var i = 0; i < 10000000; i++) { if (a == b) c++; } } foo({}, {}); JM+TI (old): 194 JM+TI (new): 18 JM: 47 TM: 25 V8: 16 Kraken ai-astar: JM+TI (old): 1810 JM+TI (new): 573 JM: 946 JM+TM: 863 TM: 840 V8: 260 As noted in comment 2, there's still lots of optimizations to do in this benchmark that should bring us roughly in line with V8 (hopefully better, though this depends on the cache effects of having fatter objects).
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Whiteboard: fixed-in-jaegermonkey
You need to log in before you can comment on or make changes to this bug.