Open Bug 1825791 Opened 1 year ago Updated 2 months ago

checkAndUpdateView is slower in SM than V8

Categories

(Core :: JavaScript Engine: JIT, enhancement, P2)

enhancement

Tracking

()

People

(Reporter: jrmuizel, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [sp3])

function benchmark() {
    var ViewAction = {};
    ViewAction.CreateViewNodes = 0;
    ViewAction.CheckNoChanges = 1;
    ViewAction.CheckNoChangesProjectedViews = 2;
    ViewAction.CheckAndUpdate = 3;
    ViewAction.CheckAndUpdateProjectedViews = 4;
    ViewAction.Destroy = 5;
    var Services = {
         updateDirectives(view, x) {},
         updateRenderer(view, x) {}
    }
    function markProjectedViewsForCheck(view) {}
    function execEmbeddedViewsAction(view, x) {}
    function execQueriesAction(view, x, y, z) {}
    function callLifecycleHooksChildrenFirst(view, x) {}
    function execComponentViewsAction(view, x) {}
    function callLifecycleHooksChildrenFirst(view, x) {}
    function checkAndUpdateView(view) {
        if (view.state & 1) {
            view.state &= ~1;
            view.state |= 2;
        } else {
            view.state &= ~2;
        }
        markProjectedViewsForCheck(view);
        Services.updateDirectives(view, 0);
        execEmbeddedViewsAction(view, ViewAction.CheckAndUpdate);
        execQueriesAction(view, 67108864, 536870912, 0);
        callLifecycleHooksChildrenFirst(view, 2097152 | (view.state & 2 ? 1048576 : 0));
        Services.updateRenderer(view, 0);
        execComponentViewsAction(view, ViewAction.CheckAndUpdate);
        execQueriesAction(view, 134217728, 536870912, 0);
        callLifecycleHooksChildrenFirst(view, 8388608 | (view.state & 2 ? 4194304 : 0));
        if (view.def.flags & 2) {
            view.state &= ~8;
        }
        view.state &= ~(64 | 32);
    }

    function run() {
        var start = performance.now();
        var view = { state: 0, def: { flags: 2} }
        for (var i = 0; i < 10000000; i++) {
            checkAndUpdateView(view);
        }
        var end = performance.now();
        console.log(`took ${end - start}ms`)
    }
    run()
}
benchmark()

Running the benchmark above with inlining disabled gives:
d8 --no-turbo-inlining: took 338.722ms
js --only-inline-selfhosted: took 418ms
jsc --maximumInliningDepth=1: took 402ms

We do quite bad with inlining enabled as well:
d8: took 39ms
js: took 173ms
jsc: took 69ms

Whiteboard: [sp3]
Blocks: sm-opt-jits
Severity: -- → N/A
Type: defect → enhancement
Priority: -- → P2

The checkAndUpdateView function is too large for us to inline (bytecode is 431 bytes). With --small-function-length=500 the shell test improves from 155 ms to 48 ms.

Inlining that function lets the compiler hoist a lot of code out of the loop.

The second issue is that our codegen for StoreFixedSlotT isn't great because we check if we need a pre-barrier etc even though that's unlikely when storing an int32 value. We might be able to figure that out at compile time with better MIR analysis.

You need to log in before you can comment on or make changes to this bug.