Changeset 241645 in webkit
- Timestamp:
- Feb 16, 2019 12:58:36 AM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r241644 r241645 1 2019-02-16 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Shrink UnlinkedFunctionExecutable 4 https://bugs.webkit.org/show_bug.cgi?id=194733 5 6 Reviewed by Mark Lam. 7 8 UnlinkedFunctionExecutable has sourceURLDirective and sourceMappingURLDirective. These 9 directives can be found in the comment of non typical function's source code (Program, 10 Eval code, and Global function from function constructor etc.), and tricky thing is that 11 SourceProvider's directives are updated by Parser. The reason why we have these fields in 12 UnlinkedFunctionExecutable is that we need to update the SourceProvider's directives even 13 if we skip parsing by using CodeCache. These fields are effective only if (1) 14 UnlinkedFunctionExecutable is for non typical function things, and (2) it has sourceURLDirective 15 or sourceMappingURLDirective. This is rare enough to purge them to a separated 16 UnlinkedFunctionExecutable::RareData to make UnlinkedFunctionExecutable small. 17 sizeof(UnlinkedFunctionExecutable) is very important since it is super frequently allocated 18 cell. Furthermore, the current JSC allocates two MarkedBlocks for UnlinkedFunctionExecutable 19 in JSGlobalObject initialization, but the usage of the second MarkedBlock is quite low (8%). 20 If we can reduce the size of UnlinkedFunctionExecutable, we can make them one MarkedBlock. 21 Since UnlinkedFunctionExecutable is allocated from IsoSubspace, we do not need to fit it to 22 one of size class. 23 24 This patch adds RareData to UnlinkedFunctionExecutable and move some rare datas into RareData. 25 And kill one MarkedBlock allocation in JSC initialization phase. 26 27 * bytecode/UnlinkedFunctionExecutable.cpp: 28 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 29 (JSC::UnlinkedFunctionExecutable::ensureRareDataSlow): 30 * bytecode/UnlinkedFunctionExecutable.h: 31 * debugger/DebuggerLocation.cpp: 32 (JSC::DebuggerLocation::DebuggerLocation): 33 * inspector/ScriptDebugServer.cpp: 34 (Inspector::ScriptDebugServer::dispatchDidParseSource): 35 * parser/Lexer.h: 36 (JSC::Lexer::sourceURLDirective const): 37 (JSC::Lexer::sourceMappingURLDirective const): 38 (JSC::Lexer::sourceURL const): Deleted. 39 (JSC::Lexer::sourceMappingURL const): Deleted. 40 * parser/Parser.h: 41 (JSC::Parser<LexerType>::parse): 42 * parser/SourceProvider.h: 43 (JSC::SourceProvider::sourceURLDirective const): 44 (JSC::SourceProvider::sourceMappingURLDirective const): 45 (JSC::SourceProvider::setSourceURLDirective): 46 (JSC::SourceProvider::setSourceMappingURLDirective): 47 (JSC::SourceProvider::sourceURL const): Deleted. We rename it from sourceURL to sourceURLDirective 48 since it is the correct name. 49 (JSC::SourceProvider::sourceMappingURL const): Deleted. We rename it from sourceMappingURL to 50 sourceMappingURLDirective since it is the correct name. 51 * runtime/CachedTypes.cpp: 52 (JSC::CachedSourceProviderShape::encode): 53 (JSC::CachedFunctionExecutableRareData::encode): 54 (JSC::CachedFunctionExecutableRareData::decode const): CachedFunctionExecutable did not have 55 sourceMappingURL to sourceMappingURLDirective. So this patch keeps the same logic. 56 (JSC::CachedFunctionExecutable::rareData const): 57 (JSC::CachedFunctionExecutable::encode): 58 (JSC::CachedFunctionExecutable::decode const): 59 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 60 * runtime/CodeCache.cpp: 61 (JSC::CodeCache::getUnlinkedGlobalCodeBlock): 62 (JSC::CodeCache::getUnlinkedGlobalFunctionExecutable): 63 * runtime/CodeCache.h: 64 (JSC::generateUnlinkedCodeBlockImpl): 65 * runtime/FunctionExecutable.h: 66 * runtime/SamplingProfiler.cpp: 67 (JSC::SamplingProfiler::StackFrame::url): 68 1 69 2019-02-15 Yusuke Suzuki <ysuzuki@apple.com> 2 70 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
r241571 r241645 43 43 namespace JSC { 44 44 45 static_assert(sizeof(UnlinkedFunctionExecutable) <= 1 60, "UnlinkedFunctionExecutable should fit in a 160-byte cell. If you increase the size of this class, consider making a size class that perfectly fits it.");45 static_assert(sizeof(UnlinkedFunctionExecutable) <= 128, "UnlinkedFunctionExecutable should fit in a 128-byte cell to keep allocated blocks count to only one after initializing JSGlobalObject."); 46 46 47 47 const ClassInfo UnlinkedFunctionExecutable::s_info = { "UnlinkedFunctionExecutable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(UnlinkedFunctionExecutable) }; … … 107 107 , m_ecmaName(node->ecmaName()) 108 108 , m_inferredName(node->inferredName()) 109 , m_classSource(node->classSource())110 109 , m_parentScopeTDZVariables(WTFMove(parentScopeTDZVariables)) 111 110 { … … 118 117 ASSERT(m_derivedContextType == static_cast<unsigned>(derivedContextType)); 119 118 ASSERT(!(m_isBuiltinDefaultClassConstructor && constructorKind() == ConstructorKind::None)); 119 if (!node->classSource().isNull()) 120 setClassSource(node->classSource()); 120 121 } 121 122 … … 244 245 } 245 246 247 UnlinkedFunctionExecutable::RareData& UnlinkedFunctionExecutable::ensureRareDataSlow() 248 { 249 ASSERT(!m_rareData); 250 m_rareData = std::make_unique<RareData>(); 251 return *m_rareData; 252 } 253 246 254 void UnlinkedFunctionExecutable::setInvalidTypeProfilingOffsets() 247 255 { -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
r241571 r241645 57 57 friend class CodeCache; 58 58 friend class VM; 59 friend CachedFunctionExecutable;59 friend class CachedFunctionExecutable; 60 60 61 61 typedef JSCell Base; … … 83 83 SourceParseMode parseMode() const { return static_cast<SourceParseMode>(m_sourceParseMode); }; 84 84 85 const SourceCode& classSource() const { return m_classSource; }; 86 void setClassSource(const SourceCode& source) { m_classSource = source; }; 85 SourceCode classSource() const 86 { 87 if (m_rareData) 88 return m_rareData->m_classSource; 89 return SourceCode(); 90 } 91 void setClassSource(const SourceCode& source) 92 { 93 ensureRareData().m_classSource = source; 94 } 87 95 88 96 bool isInStrictContext() const { return m_isInStrictContext; } … … 141 149 JSParserScriptMode scriptMode() const { return static_cast<JSParserScriptMode>(m_scriptMode); } 142 150 bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; } 151 bool isClass() const 152 { 153 if (!m_rareData) 154 return false; 155 return !m_rareData->m_classSource.isNull(); 156 } 143 157 VariableEnvironment parentScopeTDZVariables() const { return m_parentScopeTDZVariables.environment().toVariableEnvironment(); } 144 158 … … 147 161 JSC::DerivedContextType derivedContextType() const {return static_cast<JSC::DerivedContextType>(m_derivedContextType); } 148 162 149 const String& sourceURLDirective() const { return m_sourceURLDirective; } 150 const String& sourceMappingURLDirective() const { return m_sourceMappingURLDirective; } 151 void setSourceURLDirective(const String& sourceURL) { m_sourceURLDirective = sourceURL; } 152 void setSourceMappingURLDirective(const String& sourceMappingURL) { m_sourceMappingURLDirective = sourceMappingURL; } 163 String sourceURLDirective() const 164 { 165 if (m_rareData) 166 return m_rareData->m_sourceURLDirective; 167 return String(); 168 } 169 String sourceMappingURLDirective() const 170 { 171 if (m_rareData) 172 return m_rareData->m_sourceMappingURLDirective; 173 return String(); 174 } 175 void setSourceURLDirective(const String& sourceURL) 176 { 177 ensureRareData().m_sourceURLDirective = sourceURL; 178 } 179 void setSourceMappingURLDirective(const String& sourceMappingURL) 180 { 181 ensureRareData().m_sourceMappingURLDirective = sourceMappingURL; 182 } 183 184 struct RareData { 185 WTF_MAKE_STRUCT_FAST_ALLOCATED; 186 187 SourceCode m_classSource; 188 String m_sourceURLDirective; 189 String m_sourceMappingURLDirective; 190 }; 153 191 154 192 private: … … 186 224 Identifier m_ecmaName; 187 225 Identifier m_inferredName; 188 SourceCode m_classSource; 189 190 String m_sourceURLDirective; 191 String m_sourceMappingURLDirective; 226 227 RareData& ensureRareData() 228 { 229 if (LIKELY(m_rareData)) 230 return *m_rareData; 231 return ensureRareDataSlow(); 232 } 233 RareData& ensureRareDataSlow(); 192 234 193 235 CompactVariableMap::Handle m_parentScopeTDZVariables; 236 std::unique_ptr<RareData> m_rareData; 194 237 195 238 protected: -
trunk/Source/JavaScriptCore/debugger/DebuggerLocation.cpp
r208063 r241645 41 41 url = executable->sourceURL(); 42 42 if (url.isEmpty()) 43 url = executable->source().provider()->sourceURL ();43 url = executable->source().provider()->sourceURLDirective(); 44 44 } 45 45 -
trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp
r228260 r241645 196 196 script.startColumn = sourceProvider->startPosition().m_column.zeroBasedInt(); 197 197 script.isContentScript = isContentScript; 198 script.sourceURL = sourceProvider->sourceURL ();199 script.sourceMappingURL = sourceProvider->sourceMappingURL ();198 script.sourceURL = sourceProvider->sourceURLDirective(); 199 script.sourceMappingURL = sourceProvider->sourceMappingURLDirective(); 200 200 201 201 int sourceLength = script.source.length(); -
trunk/Source/JavaScriptCore/parser/Lexer.h
r239427 r241645 88 88 String getErrorMessage() const { return m_lexErrorMessage; } 89 89 void setErrorMessage(const String& errorMessage) { m_lexErrorMessage = errorMessage; } 90 String sourceURL () const { return m_sourceURLDirective; }91 String sourceMappingURL () const { return m_sourceMappingURLDirective; }90 String sourceURLDirective() const { return m_sourceURLDirective; } 91 String sourceMappingURLDirective() const { return m_sourceMappingURLDirective; } 92 92 void clear(); 93 93 void setOffset(int offset, int lineStartOffset) -
trunk/Source/JavaScriptCore/parser/Parser.h
r240686 r241645 1939 1939 1940 1940 if (!isFunctionParseMode(parseMode)) { 1941 m_source->provider()->setSourceURLDirective(m_lexer->sourceURL ());1942 m_source->provider()->setSourceMappingURLDirective(m_lexer->sourceMappingURL ());1941 m_source->provider()->setSourceURLDirective(m_lexer->sourceURLDirective()); 1942 m_source->provider()->setSourceMappingURLDirective(m_lexer->sourceMappingURLDirective()); 1943 1943 } 1944 1944 } else { -
trunk/Source/JavaScriptCore/parser/SourceProvider.h
r241612 r241645 126 126 const SourceOrigin& sourceOrigin() const { return m_sourceOrigin; } 127 127 const URL& url() const { return m_url; } 128 const String& sourceURL () const { return m_sourceURLDirective; }129 const String& sourceMappingURL () const { return m_sourceMappingURLDirective; }128 const String& sourceURLDirective() const { return m_sourceURLDirective; } 129 const String& sourceMappingURLDirective() const { return m_sourceMappingURLDirective; } 130 130 131 131 TextPosition startPosition() const { return m_startPosition; } … … 139 139 } 140 140 141 void setSourceURLDirective(const String& sourceURL ) { m_sourceURLDirective = sourceURL; }142 void setSourceMappingURLDirective(const String& sourceMappingURL ) { m_sourceMappingURLDirective = sourceMappingURL; }141 void setSourceURLDirective(const String& sourceURLDirective) { m_sourceURLDirective = sourceURLDirective; } 142 void setSourceMappingURLDirective(const String& sourceMappingURLDirective) { m_sourceMappingURLDirective = sourceMappingURLDirective; } 143 143 144 144 private: -
trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp
r241550 r241645 1267 1267 m_sourceOrigin.encode(encoder, sourceProvider.sourceOrigin()); 1268 1268 m_url.encode(encoder, sourceProvider.url()); 1269 m_sourceURLDirective.encode(encoder, sourceProvider.sourceURL ());1270 m_sourceMappingURLDirective.encode(encoder, sourceProvider.sourceMappingURL ());1269 m_sourceURLDirective.encode(encoder, sourceProvider.sourceURLDirective()); 1270 m_sourceMappingURLDirective.encode(encoder, sourceProvider.sourceMappingURLDirective()); 1271 1271 m_startPosition.encode(encoder, sourceProvider.startPosition()); 1272 1272 } … … 1430 1430 }; 1431 1431 1432 class CachedFunctionExecutableRareData : public CachedObject<UnlinkedFunctionExecutable::RareData> { 1433 public: 1434 void encode(Encoder& encoder, const UnlinkedFunctionExecutable::RareData& rareData) 1435 { 1436 m_classSource.encode(encoder, rareData.m_classSource); 1437 } 1438 1439 UnlinkedFunctionExecutable::RareData* decode(Decoder& decoder) const 1440 { 1441 UnlinkedFunctionExecutable::RareData* rareData = new UnlinkedFunctionExecutable::RareData { }; 1442 m_classSource.decode(decoder, rareData->m_classSource); 1443 return rareData; 1444 } 1445 1446 private: 1447 CachedSourceCode m_classSource; 1448 }; 1449 1432 1450 class CachedFunctionExecutable : public CachedObject<UnlinkedFunctionExecutable> { 1433 1451 public: … … 1464 1482 Identifier ecmaName(Decoder& decoder) const { return m_ecmaName.decode(decoder); } 1465 1483 Identifier inferredName(Decoder& decoder) const { return m_inferredName.decode(decoder); } 1484 1485 UnlinkedFunctionExecutable::RareData* rareData(Decoder& decoder) const { return m_rareData.decodeAsPtr(decoder); } 1466 1486 1467 1487 private: … … 1490 1510 unsigned m_derivedContextType: 2; 1491 1511 1492 Cached SourceCode m_classSource;1512 CachedOptional<CachedFunctionExecutableRareData> m_rareData; 1493 1513 1494 1514 CachedIdentifier m_name; … … 1825 1845 m_derivedContextType = executable.m_derivedContextType; 1826 1846 1827 m_ classSource.encode(encoder, executable.m_classSource);1847 m_rareData.encode(encoder, executable.m_rareData); 1828 1848 1829 1849 m_name.encode(encoder, executable.name()); … … 1845 1865 executable->finishCreation(decoder.vm()); 1846 1866 1847 m_classSource.decode(decoder, executable->m_classSource);1848 1867 m_unlinkedCodeBlockForCall.decode(decoder, executable->m_unlinkedCodeBlockForCall, executable); 1849 1868 m_unlinkedCodeBlockForConstruct.decode(decoder, executable->m_unlinkedCodeBlockForConstruct, executable); … … 1883 1902 1884 1903 , m_parentScopeTDZVariables(decoder.vm().m_compactVariableMap->get(parentScopeTDZVariables)) 1904 1905 , m_rareData(cachedExecutable.rareData(decoder)) 1885 1906 { 1886 1907 } -
trunk/Source/JavaScriptCore/runtime/CodeCache.cpp
r241612 r241645 71 71 unsigned endColumn = unlinkedCodeBlock->endColumn() + (endColumnIsOnStartLine ? startColumn : 1); 72 72 executable->recordParse(unlinkedCodeBlock->codeFeatures(), unlinkedCodeBlock->hasCapturedVariables(), source.firstLine().oneBasedInt() + lineCount, endColumn); 73 source.provider()->setSourceURLDirective(unlinkedCodeBlock->sourceURLDirective()); 74 source.provider()->setSourceMappingURLDirective(unlinkedCodeBlock->sourceMappingURLDirective()); 73 if (!unlinkedCodeBlock->sourceURLDirective().isNull()) 74 source.provider()->setSourceURLDirective(unlinkedCodeBlock->sourceURLDirective()); 75 if (!unlinkedCodeBlock->sourceMappingURLDirective().isNull()) 76 source.provider()->setSourceMappingURLDirective(unlinkedCodeBlock->sourceMappingURLDirective()); 75 77 return unlinkedCodeBlock; 76 78 } … … 116 118 UnlinkedFunctionExecutable* executable = m_sourceCode.findCacheAndUpdateAge<UnlinkedFunctionExecutable>(vm, key); 117 119 if (executable && Options::useCodeCache()) { 118 source.provider()->setSourceURLDirective(executable->sourceURLDirective()); 119 source.provider()->setSourceMappingURLDirective(executable->sourceMappingURLDirective()); 120 if (!executable->sourceURLDirective().isNull()) 121 source.provider()->setSourceURLDirective(executable->sourceURLDirective()); 122 if (!executable->sourceMappingURLDirective().isNull()) 123 source.provider()->setSourceMappingURLDirective(executable->sourceMappingURLDirective()); 120 124 return executable; 121 125 } … … 150 154 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, constructAbility, JSParserScriptMode::Classic, vm.m_compactVariableMap->get(emptyTDZVariables), DerivedContextType::None); 151 155 152 functionExecutable->setSourceURLDirective(source.provider()->sourceURL()); 153 functionExecutable->setSourceMappingURLDirective(source.provider()->sourceMappingURL()); 156 if (!source.provider()->sourceURLDirective().isNull()) 157 functionExecutable->setSourceURLDirective(source.provider()->sourceURLDirective()); 158 if (!source.provider()->sourceMappingURLDirective().isNull()) 159 functionExecutable->setSourceMappingURLDirective(source.provider()->sourceMappingURLDirective()); 154 160 155 161 if (Options::useCodeCache()) -
trunk/Source/JavaScriptCore/runtime/CodeCache.h
r241612 r241645 298 298 UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executableInfo, debuggerMode); 299 299 unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), lineCount, unlinkedEndColumn); 300 unlinkedCodeBlock->setSourceURLDirective(source.provider()->sourceURL()); 301 unlinkedCodeBlock->setSourceMappingURLDirective(source.provider()->sourceMappingURL()); 300 if (!source.provider()->sourceURLDirective().isNull()) 301 unlinkedCodeBlock->setSourceURLDirective(source.provider()->sourceURLDirective()); 302 if (!source.provider()->sourceMappingURLDirective().isNull()) 303 unlinkedCodeBlock->setSourceMappingURLDirective(source.provider()->sourceMappingURLDirective()); 302 304 303 305 error = BytecodeGenerator::generate(vm, rootNode.get(), source, unlinkedCodeBlock, debuggerMode, variablesUnderTDZ); -
trunk/Source/JavaScriptCore/runtime/FunctionExecutable.h
r240965 r241645 133 133 bool isBuiltinFunction() const { return m_unlinkedExecutable->isBuiltinFunction(); } 134 134 ConstructAbility constructAbility() const { return m_unlinkedExecutable->constructAbility(); } 135 bool isClass() const { return !classSource().isNull(); }135 bool isClass() const { return m_unlinkedExecutable->isClass(); } 136 136 bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; } 137 137 bool isGetter() const { return parseMode() == SourceParseMode::GetterMode; } … … 166 166 SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); } 167 167 JSParserScriptMode scriptMode() const { return m_unlinkedExecutable->scriptMode(); } 168 const SourceCode&classSource() const { return m_unlinkedExecutable->classSource(); }168 SourceCode classSource() const { return m_unlinkedExecutable->classSource(); } 169 169 170 170 static void visitChildren(JSCell*, SlotVisitor&); -
trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp
r241615 r241645 864 864 String url = static_cast<ScriptExecutable*>(executable)->sourceURL(); 865 865 if (url.isEmpty()) 866 return static_cast<ScriptExecutable*>(executable)->source().provider()->sourceURL (); // Fall back to sourceURL directive.866 return static_cast<ScriptExecutable*>(executable)->source().provider()->sourceURLDirective(); // Fall back to sourceURL directive. 867 867 return url; 868 868 }
Note: See TracChangeset
for help on using the changeset viewer.