Changeset 201359 in webkit
- Timestamp:
- May 24, 2016, 3:28:20 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
bytecode/CodeBlock.cpp (modified) (6 diffs)
-
runtime/GetPutInfo.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r201342 r201359 1 2016-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 1 23 2016-05-24 Filip Pizlo <fpizlo@apple.com> 2 24 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r201239 r201359 1847 1847 } 1848 1848 1849 struct 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 1849 1880 void CodeBlock::finishCreation(VM& vm, CopyParsedBlockTag, CodeBlock& other) 1850 1881 { … … 2015 2046 #endif 2016 2047 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 2017 2061 // Copy and translate the UnlinkedInstructions 2018 2062 unsigned instructionCount = unlinkedCodeBlock->instructions().count(); … … 2126 2170 int localScopeDepth = pc[5].u.operand; 2127 2171 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); 2129 2173 instructions[i + 4].u.operand = op.type; 2130 2174 instructions[i + 5].u.operand = op.depth; … … 2163 2207 2164 2208 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); 2166 2210 2167 2211 instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand(); … … 2198 2242 int localScopeDepth = pc[5].u.operand; 2199 2243 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()); 2201 2245 2202 2246 instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand(); … … 2232 2276 // Even though type profiling may be profiling either a Get or a Put, we can always claim a Get because 2233 2277 // 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); 2235 2279 2236 2280 if (op.type == ClosureVar || op.type == ModuleVar) -
trunk/Source/JavaScriptCore/runtime/GetPutInfo.h
r199699 r201359 180 180 181 181 struct ResolveOp { 182 ResolveOp() 183 : depth(0) 184 , structure(nullptr) 185 , lexicalEnvironment(nullptr) 186 , watchpointSet(nullptr) 187 , importedName(nullptr) 188 { } 189 182 190 ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand, UniquedStringImpl* importedName = nullptr) 183 191 : type(type)
Note:
See TracChangeset
for help on using the changeset viewer.