⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 201359 in webkit


Ignore:
Timestamp:
May 24, 2016, 3:28:20 PM (10 years ago)
Author:
sbarati@apple.com
Message:

We can cache lookups to JSScope::abstractResolve inside CodeBlock::finishCreation
https://bugs.webkit.org/show_bug.cgi?id=158036

Reviewed by Geoffrey Garen.

This patch implements a 1 item cache for JSScope::abstractResolve. I also tried
implementing the cache as a HashMap, but it seemed either less profitable on some
benchmarks or just as profitable on others. Therefore, it's cleaner to just
use a 1 item cache.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::CodeBlock):
(JSC::AbstractResolveKey::AbstractResolveKey):
(JSC::AbstractResolveKey::operator==):
(JSC::AbstractResolveKey::isEmptyValue):
(JSC::CodeBlock::finishCreation):

  • runtime/GetPutInfo.h:

(JSC::needsVarInjectionChecks):
(JSC::ResolveOp::ResolveOp):

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r201342 r201359  
     12016-05-24  Saam barati  <sbarati@apple.com>
     2
     3        We can cache lookups to JSScope::abstractResolve inside CodeBlock::finishCreation
     4        https://bugs.webkit.org/show_bug.cgi?id=158036
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        This patch implements a 1 item cache for JSScope::abstractResolve. I also tried
     9        implementing the cache as a HashMap, but it seemed either less profitable on some
     10        benchmarks or just as profitable on others. Therefore, it's cleaner to just
     11        use a 1 item cache.
     12
     13        * bytecode/CodeBlock.cpp:
     14        (JSC::CodeBlock::CodeBlock):
     15        (JSC::AbstractResolveKey::AbstractResolveKey):
     16        (JSC::AbstractResolveKey::operator==):
     17        (JSC::AbstractResolveKey::isEmptyValue):
     18        (JSC::CodeBlock::finishCreation):
     19        * runtime/GetPutInfo.h:
     20        (JSC::needsVarInjectionChecks):
     21        (JSC::ResolveOp::ResolveOp):
     22
    1232016-05-24  Filip Pizlo  <fpizlo@apple.com>
    224
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r201239 r201359  
    18471847}
    18481848
     1849struct AbstractResolveKey {
     1850    AbstractResolveKey()
     1851        : m_impl(nullptr)
     1852    { }
     1853    AbstractResolveKey(size_t depth, const Identifier& ident, GetOrPut getOrPut, ResolveType resolveType, InitializationMode initializationMode)
     1854        : m_depth(depth)
     1855        , m_impl(ident.impl())
     1856        , m_getOrPut(getOrPut)
     1857        , m_resolveType(resolveType)
     1858        , m_initializationMode(initializationMode)
     1859    { }
     1860
     1861
     1862    bool operator==(const AbstractResolveKey& other) const
     1863    {
     1864        return m_impl == other.m_impl
     1865            && m_depth == other.m_depth
     1866            && m_getOrPut == other.m_getOrPut
     1867            && m_resolveType == other.m_resolveType
     1868            && m_initializationMode == other.m_initializationMode;
     1869    }
     1870
     1871    bool isNull() const { return !m_impl; }
     1872
     1873    size_t m_depth;
     1874    UniquedStringImpl* m_impl;
     1875    GetOrPut m_getOrPut;
     1876    ResolveType m_resolveType;
     1877    InitializationMode m_initializationMode;
     1878};
     1879
    18491880void CodeBlock::finishCreation(VM& vm, CopyParsedBlockTag, CodeBlock& other)
    18501881{
     
    20152046#endif
    20162047
     2048    AbstractResolveKey lastResolveKey;
     2049    ResolveOp lastCachedOp;
     2050    auto cachedAbstractResolve = [&] (size_t localScopeDepth, const Identifier& ident, GetOrPut getOrPut, ResolveType resolveType, InitializationMode initializationMode) -> const ResolveOp& {
     2051        AbstractResolveKey key(localScopeDepth, ident, getOrPut, resolveType, initializationMode);
     2052        if (key == lastResolveKey) {
     2053            ASSERT(!lastResolveKey.isNull());
     2054            return lastCachedOp;
     2055        }
     2056        lastCachedOp = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, getOrPut, resolveType, initializationMode);
     2057        lastResolveKey = key;
     2058        return lastCachedOp;
     2059    };
     2060
    20172061    // Copy and translate the UnlinkedInstructions
    20182062    unsigned instructionCount = unlinkedCodeBlock->instructions().count();
     
    21262170            int localScopeDepth = pc[5].u.operand;
    21272171
    2128             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type, InitializationMode::NotInitialization);
     2172            const ResolveOp& op = cachedAbstractResolve(localScopeDepth, ident, Get, type, InitializationMode::NotInitialization);
    21292173            instructions[i + 4].u.operand = op.type;
    21302174            instructions[i + 5].u.operand = op.depth;
     
    21632207
    21642208            const Identifier& ident = identifier(pc[3].u.operand);
    2165             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, getPutInfo.resolveType(), InitializationMode::NotInitialization);
     2209            const ResolveOp& op = cachedAbstractResolve(localScopeDepth, ident, Get, getPutInfo.resolveType(), InitializationMode::NotInitialization);
    21662210
    21672211            instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand();
     
    21982242            int localScopeDepth = pc[5].u.operand;
    21992243            instructions[i + 5].u.pointer = nullptr;
    2200             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Put, getPutInfo.resolveType(), getPutInfo.initializationMode());
     2244            const ResolveOp& op = cachedAbstractResolve(localScopeDepth, ident, Put, getPutInfo.resolveType(), getPutInfo.initializationMode());
    22012245
    22022246            instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand();
     
    22322276                // Even though type profiling may be profiling either a Get or a Put, we can always claim a Get because
    22332277                // we're abstractly "read"ing from a JSScope.
    2234                 ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type, InitializationMode::NotInitialization);
     2278                const ResolveOp& op = cachedAbstractResolve(localScopeDepth, ident, Get, type, InitializationMode::NotInitialization);
    22352279
    22362280                if (op.type == ClosureVar || op.type == ModuleVar)
  • trunk/Source/JavaScriptCore/runtime/GetPutInfo.h

    r199699 r201359  
    180180
    181181struct ResolveOp {
     182    ResolveOp()
     183        : depth(0)
     184        , structure(nullptr)
     185        , lexicalEnvironment(nullptr)
     186        , watchpointSet(nullptr)
     187        , importedName(nullptr)
     188    { }
     189
    182190    ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand, UniquedStringImpl* importedName = nullptr)
    183191        : type(type)
Note: See TracChangeset for help on using the changeset viewer.