• Benedikt Meurer's avatar
    [turbofan] Optimize fast enum cache driven for..in. · f1ec44e2
    Benedikt Meurer authored
    This CL adds support to optimize for..in in fast enum-cache mode to the
    same degree that it was optimized in Crankshaft, without adding the same
    deoptimization loop that Crankshaft had with missing enum cache indices.
    That means code like
    
      for (var k in o) {
        var v = o[k];
        // ...
      }
    
    and code like
    
      for (var k in o) {
        if (Object.prototype.hasOwnProperty.call(o, k)) {
          var v = o[k];
          // ...
        }
      }
    
    which follows the https://eslint.org/docs/rules/guard-for-in linter
    rule, can now utilize the enum cache indices if o has only fast
    properties on the receiver, which speeds up the access o[k]
    significantly and reduces the pollution of the global megamorphic
    stub cache.
    
    For example the micro-benchmark in the tracking bug v8:6702 now runs
    faster than ever before:
    
     forIn: 1516 ms.
     forInHasOwnProperty: 1674 ms.
     forInHasOwnPropertySafe: 1595 ms.
     forInSum: 2051 ms.
     forInSumSafe: 2215 ms.
    
    Compared to numbers from V8 5.8 which is the last version running with
    Crankshaft
    
     forIn: 1641 ms.
     forInHasOwnProperty: 1719 ms.
     forInHasOwnPropertySafe: 1802 ms.
     forInSum: 2226 ms.
     forInSumSafe: 2409 ms.
    
    and V8 6.0 which is the current stable version with TurboFan:
    
     forIn: 1713 ms.
     forInHasOwnProperty: 5417 ms.
     forInHasOwnPropertySafe: 5324 ms.
     forInSum: 7556 ms.
     forInSumSafe: 11067 ms.
    
    It also improves the throughput on the string-fasta benchmark by
    around 7-10%, and there seems to be a ~5% improvement on the
    Speedometer/React benchmark locally.
    
    For this to work, the ForInPrepare bytecode was split into
    ForInEnumerate and ForInPrepare, which is very similar to how it was
    handled in Fullcodegen initially. In TurboFan we introduce a new
    operator LoadFieldByIndex that does the dynamic property load.
    
    This also removes the CheckMapValue operator again in favor of
    just using LoadField, ReferenceEqual and CheckIf, which work
    automatically with the EscapeAnalysis and the
    BranchConditionElimination.
    
    Bug: v8:6702
    Change-Id: I91235413eea478ba77ace7bd14bb2f62e155dd9a
    Reviewed-on: https://chromium-review.googlesource.com/645949
    Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
    Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
    Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
    Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#47768}
    f1ec44e2
bytecode-graph-builder.h 16.1 KB