Changeset 245288 in webkit
- Timestamp:
- May 14, 2019 10:31:53 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r245249 r245288 1 2019-05-14 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Shrink sizeof(UnlinkedFunctionExecutable) more 4 https://bugs.webkit.org/show_bug.cgi?id=197833 5 6 Reviewed by Darin Adler. 7 8 * stress/generator-name.js: Added. 9 (shouldBe): 10 (gen): 11 (catch): 12 1 13 2019-05-13 Tadeu Zagallo <tzagallo@apple.com> 2 14 -
trunk/Source/JavaScriptCore/ChangeLog
r245270 r245288 1 2019-05-14 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Shrink sizeof(UnlinkedFunctionExecutable) more 4 https://bugs.webkit.org/show_bug.cgi?id=197833 5 6 Reviewed by Darin Adler. 7 8 It turns out that Gmail creates so many JSFunctions, FunctionExecutables, and UnlinkedFunctionExecutables. 9 So we should shrink size of them to save memory. As a first step, this patch reduces the sizeof(UnlinkedFunctionExecutable) more by 16 bytes. 10 11 1. We reorder some fields to get 8 bytes. And we use 31 bits for xxx offset things since their maximum size should be within 31 bits due to 12 String's length & int32_t representation in our parser. 13 14 2. We drop m_inferredName and prefer m_ecmaName. The inferred name is used to offer better function name when the function expression lacks 15 the name, but now ECMAScript has a specified semantics to name those functions with intuitive names. We should use ecmaName consistently, 16 and should not eat 8 bytes for inferred names in UnlinkedFunctionExecutable. 17 18 We also fix generator ecma name. 19 20 * bytecode/CodeBlock.cpp: 21 (JSC::CodeBlock::inferredName const): 22 * bytecode/InlineCallFrame.cpp: 23 (JSC::InlineCallFrame::inferredName const): 24 * bytecode/UnlinkedFunctionExecutable.cpp: 25 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 26 * bytecode/UnlinkedFunctionExecutable.h: 27 * parser/ASTBuilder.h: 28 (JSC::ASTBuilder::createAssignResolve): 29 (JSC::ASTBuilder::createGeneratorFunctionBody): 30 (JSC::ASTBuilder::createGetterOrSetterProperty): 31 (JSC::ASTBuilder::createProperty): 32 (JSC::ASTBuilder::tryInferNameInPatternWithIdentifier): 33 (JSC::ASTBuilder::makeAssignNode): 34 * parser/Nodes.cpp: 35 (JSC::FunctionMetadataNode::operator== const): 36 (JSC::FunctionMetadataNode::dump const): 37 * parser/Nodes.h: 38 * runtime/CachedTypes.cpp: 39 (JSC::CachedFunctionExecutable::ecmaName const): 40 (JSC::CachedFunctionExecutable::encode): 41 (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): 42 (JSC::CachedFunctionExecutable::inferredName const): Deleted. 43 * runtime/FunctionExecutable.h: 44 * runtime/FunctionExecutableDump.cpp: 45 (JSC::FunctionExecutableDump::dump const): 46 * runtime/JSFunction.cpp: 47 (JSC::JSFunction::calculatedDisplayName): 48 (JSC::getCalculatedDisplayName): 49 * runtime/SamplingProfiler.cpp: 50 (JSC::SamplingProfiler::StackFrame::displayName): 51 (JSC::SamplingProfiler::StackFrame::displayNameForJSONTests): 52 1 53 2019-05-13 Yusuke Suzuki <ysuzuki@apple.com> 2 54 -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r245239 r245288 123 123 return "<eval>"; 124 124 case FunctionCode: 125 return jsCast<FunctionExecutable*>(ownerExecutable())-> inferredName().utf8();125 return jsCast<FunctionExecutable*>(ownerExecutable())->ecmaName().utf8(); 126 126 case ModuleCode: 127 127 return "<module>"; -
trunk/Source/JavaScriptCore/bytecode/InlineCallFrame.cpp
r243232 r245288 57 57 CString InlineCallFrame::inferredName() const 58 58 { 59 return jsCast<FunctionExecutable*>(baselineCodeBlock->ownerExecutable())-> inferredName().utf8();59 return jsCast<FunctionExecutable*>(baselineCodeBlock->ownerExecutable())->ecmaName().utf8(); 60 60 } 61 61 -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
r245040 r245288 85 85 : Base(*vm, structure) 86 86 , m_firstLineOffset(node->firstLine() - parentSource.firstLine().oneBasedInt()) 87 , m_isInStrictContext(node->isInStrictContext()) 87 88 , m_lineCount(node->lastLine() - node->firstLine()) 89 , m_hasCapturedVariables(false) 88 90 , m_unlinkedFunctionNameStart(node->functionNameStart() - parentSource.startOffset()) 91 , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction) 89 92 , m_unlinkedBodyStartColumn(node->startColumn()) 93 , m_isBuiltinDefaultClassConstructor(isBuiltinDefaultClassConstructor) 90 94 , m_unlinkedBodyEndColumn(m_lineCount ? node->endColumn() : node->endColumn() - node->startColumn()) 95 , m_constructAbility(static_cast<unsigned>(constructAbility)) 91 96 , m_startOffset(node->source().startOffset() - parentSource.startOffset()) 97 , m_scriptMode(static_cast<unsigned>(scriptMode)) 92 98 , m_sourceLength(node->source().length()) 99 , m_superBinding(static_cast<unsigned>(node->superBinding())) 93 100 , m_parametersStartOffset(node->parametersStart()) 101 , m_isCached(false) 94 102 , m_typeProfilingStartOffset(node->functionKeywordStart()) 95 103 , m_typeProfilingEndOffset(node->startStartOffset() + node->source().length() - 1) … … 97 105 , m_features(0) 98 106 , m_sourceParseMode(node->parseMode()) 99 , m_isInStrictContext(node->isInStrictContext())100 , m_hasCapturedVariables(false)101 , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction)102 , m_isBuiltinDefaultClassConstructor(isBuiltinDefaultClassConstructor)103 , m_constructAbility(static_cast<unsigned>(constructAbility))104 107 , m_constructorKind(static_cast<unsigned>(node->constructorKind())) 105 108 , m_functionMode(static_cast<unsigned>(node->functionMode())) 106 , m_scriptMode(static_cast<unsigned>(scriptMode))107 , m_superBinding(static_cast<unsigned>(node->superBinding()))108 109 , m_derivedContextType(static_cast<unsigned>(derivedContextType)) 109 , m_isCached(false)110 110 , m_unlinkedCodeBlockForCall() 111 111 , m_unlinkedCodeBlockForConstruct() 112 112 , m_name(node->ident()) 113 113 , m_ecmaName(node->ecmaName()) 114 , m_inferredName(node->inferredName())115 114 { 116 115 // Make sure these bitfields are adequately wide. -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
r245040 r245288 82 82 const Identifier& ecmaName() const { return m_ecmaName; } 83 83 void setEcmaName(const Identifier& name) { m_ecmaName = name; } 84 const Identifier& inferredName() const { return m_inferredName; }85 84 unsigned parameterCount() const { return m_parameterCount; }; // Excluding 'this'! 86 85 SourceParseMode parseMode() const { return static_cast<SourceParseMode>(m_sourceParseMode); }; … … 206 205 void decodeCachedCodeBlocks(); 207 206 208 unsigned m_firstLineOffset; 209 unsigned m_lineCount; 210 unsigned m_unlinkedFunctionNameStart; 211 unsigned m_unlinkedBodyStartColumn; 212 unsigned m_unlinkedBodyEndColumn; 213 unsigned m_startOffset; 214 unsigned m_sourceLength; 215 unsigned m_parametersStartOffset; 207 unsigned m_firstLineOffset : 31; 208 unsigned m_isInStrictContext : 1; 209 unsigned m_lineCount : 31; 210 unsigned m_hasCapturedVariables : 1; 211 unsigned m_unlinkedFunctionNameStart : 31; 212 unsigned m_isBuiltinFunction : 1; 213 unsigned m_unlinkedBodyStartColumn : 31; 214 unsigned m_isBuiltinDefaultClassConstructor : 1; 215 unsigned m_unlinkedBodyEndColumn : 31; 216 unsigned m_constructAbility: 1; 217 unsigned m_startOffset : 31; 218 unsigned m_scriptMode: 1; // JSParserScriptMode 219 unsigned m_sourceLength : 31; 220 unsigned m_superBinding : 1; 221 unsigned m_parametersStartOffset : 31; 222 unsigned m_isCached : 1; 216 223 unsigned m_typeProfilingStartOffset; 217 224 unsigned m_typeProfilingEndOffset; … … 219 226 CodeFeatures m_features; 220 227 SourceParseMode m_sourceParseMode; 221 unsigned m_isInStrictContext : 1;222 unsigned m_hasCapturedVariables : 1;223 unsigned m_isBuiltinFunction : 1;224 unsigned m_isBuiltinDefaultClassConstructor : 1;225 unsigned m_constructAbility: 1;226 228 unsigned m_constructorKind : 2; 227 229 unsigned m_functionMode : 2; // FunctionMode 228 unsigned m_scriptMode: 1; // JSParserScriptMode229 unsigned m_superBinding : 1;230 230 unsigned m_derivedContextType: 2; 231 bool m_isCached : 1;232 231 233 232 union { … … 246 245 Identifier m_name; 247 246 Identifier m_ecmaName; 248 Identifier m_inferredName;249 247 250 248 RareData& ensureRareData() -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r245040 r245288 371 371 auto metadata = static_cast<BaseFuncExprNode*>(rhs)->metadata(); 372 372 metadata->setEcmaName(ident); 373 metadata->setInferredName(ident);374 373 } else if (rhs->isClassExprNode()) 375 374 static_cast<ClassExprNode*>(rhs)->setEcmaName(ident); … … 418 417 FuncExprNode* result = static_cast<FuncExprNode*>(createFunctionExpr(location, functionInfo)); 419 418 if (!name.isNull()) 420 result->metadata()->set InferredName(name);419 result->metadata()->setEcmaName(name); 421 420 return result; 422 421 } … … 476 475 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset); 477 476 functionInfo.body->setEcmaName(*name); 478 functionInfo.body->setInferredName(*name);479 477 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn); 480 478 MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm->propertyNames->nullIdentifier, functionInfo.body, source); … … 508 506 auto metadata = static_cast<BaseFuncExprNode*>(node)->metadata(); 509 507 metadata->setEcmaName(*propertyName); 510 metadata->setInferredName(*propertyName);511 508 } else if (node->isClassExprNode()) 512 509 static_cast<ClassExprNode*>(node)->setEcmaName(*propertyName); … … 1116 1113 auto metadata = static_cast<BaseFuncExprNode*>(defaultValue)->metadata(); 1117 1114 metadata->setEcmaName(ident); 1118 metadata->setInferredName(ident);1119 1115 } else if (defaultValue->isClassExprNode()) 1120 1116 static_cast<ClassExprNode*>(defaultValue)->setEcmaName(ident); … … 1481 1477 auto metadata = static_cast<BaseFuncExprNode*>(expr)->metadata(); 1482 1478 metadata->setEcmaName(resolve->identifier()); 1483 metadata->setInferredName(resolve->identifier());1484 1479 } else if (expr->isClassExprNode()) 1485 1480 static_cast<ClassExprNode*>(expr)->setEcmaName(resolve->identifier()); … … 1500 1495 ASSERT(loc->isDotAccessorNode()); 1501 1496 DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc); 1502 if (op == OpEqual) { 1503 if (expr->isBaseFuncExprNode()) { 1504 // We don't also set the ecma name here because ES6 specifies that the 1505 // function should not pick up the name of the dot->identifier(). 1506 static_cast<BaseFuncExprNode*>(expr)->metadata()->setInferredName(dot->identifier()); 1507 } 1497 if (op == OpEqual) 1508 1498 return new (m_parserArena) AssignDotNode(location, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), start, end); 1509 }1510 1499 1511 1500 ReadModifyDotNode* node = new (m_parserArena) ReadModifyDotNode(location, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, start, end); -
trunk/Source/JavaScriptCore/parser/Nodes.cpp
r240641 r245288 258 258 && m_ident == other.m_ident 259 259 && m_ecmaName == other.m_ecmaName 260 && m_inferredName == other.m_inferredName261 260 && m_functionMode== other.m_functionMode 262 261 && m_startColumn== other.m_startColumn … … 282 281 stream.println("m_ident ", m_ident); 283 282 stream.println("m_ecmaName ", m_ecmaName); 284 stream.println("m_inferredName ", m_inferredName);285 283 stream.println("m_functionMode ", static_cast<uint32_t>(m_functionMode)); 286 284 stream.println("m_startColumn ", m_startColumn); -
trunk/Source/JavaScriptCore/parser/Nodes.h
r242812 r245288 1995 1995 void setEcmaName(const Identifier& ecmaName) { m_ecmaName = ecmaName; } 1996 1996 const Identifier& ecmaName() { return m_ident.isEmpty() ? m_ecmaName : m_ident; } 1997 void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }1998 const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }1999 1997 2000 1998 FunctionMode functionMode() { return m_functionMode; } … … 2043 2041 Identifier m_ident; 2044 2042 Identifier m_ecmaName; 2045 Identifier m_inferredName;2046 2043 unsigned m_startColumn; 2047 2044 unsigned m_endColumn; -
trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp
r245064 r245288 1642 1642 Identifier name(Decoder& decoder) const { return m_name.decode(decoder); } 1643 1643 Identifier ecmaName(Decoder& decoder) const { return m_ecmaName.decode(decoder); } 1644 Identifier inferredName(Decoder& decoder) const { return m_inferredName.decode(decoder); }1645 1644 1646 1645 UnlinkedFunctionExecutable::RareData* rareData(Decoder& decoder) const { return m_rareData.decode(decoder); } … … 1652 1651 CachedFunctionExecutableMetadata m_mutableMetadata; 1653 1652 1654 unsigned m_firstLineOffset; 1655 unsigned m_lineCount; 1656 unsigned m_unlinkedFunctionNameStart; 1657 unsigned m_unlinkedBodyStartColumn; 1658 unsigned m_unlinkedBodyEndColumn; 1659 unsigned m_startOffset; 1660 unsigned m_sourceLength; 1661 unsigned m_parametersStartOffset; 1653 unsigned m_firstLineOffset : 31; 1654 unsigned m_isInStrictContext : 1; 1655 unsigned m_lineCount : 31; 1656 unsigned m_isBuiltinFunction : 1; 1657 unsigned m_unlinkedFunctionNameStart : 31; 1658 unsigned m_isBuiltinDefaultClassConstructor : 1; 1659 unsigned m_unlinkedBodyStartColumn : 31; 1660 unsigned m_constructAbility: 1; 1661 unsigned m_unlinkedBodyEndColumn : 31; 1662 unsigned m_startOffset : 31; 1663 unsigned m_scriptMode: 1; // JSParserScriptMode 1664 unsigned m_sourceLength : 31; 1665 unsigned m_superBinding : 1; 1666 unsigned m_parametersStartOffset : 31; 1662 1667 unsigned m_typeProfilingStartOffset; 1663 1668 unsigned m_typeProfilingEndOffset; 1664 1669 unsigned m_parameterCount; 1665 1670 SourceParseMode m_sourceParseMode; 1666 unsigned m_isInStrictContext : 1;1667 unsigned m_isBuiltinFunction : 1;1668 unsigned m_isBuiltinDefaultClassConstructor : 1;1669 unsigned m_constructAbility: 1;1670 1671 unsigned m_constructorKind : 2; 1671 1672 unsigned m_functionMode : 2; // FunctionMode 1672 unsigned m_scriptMode: 1; // JSParserScriptMode1673 unsigned m_superBinding : 1;1674 1673 unsigned m_derivedContextType: 2; 1675 1674 … … 1678 1677 CachedIdentifier m_name; 1679 1678 CachedIdentifier m_ecmaName; 1680 CachedIdentifier m_inferredName;1681 1679 1682 1680 CachedWriteBarrier<CachedFunctionCodeBlock, UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall; … … 2045 2043 m_name.encode(encoder, executable.name()); 2046 2044 m_ecmaName.encode(encoder, executable.ecmaName()); 2047 m_inferredName.encode(encoder, executable.inferredName());2048 2045 2049 2046 m_unlinkedCodeBlockForCall.encode(encoder, executable.m_unlinkedCodeBlockForCall); … … 2064 2061 : Base(decoder.vm(), decoder.vm().unlinkedFunctionExecutableStructure.get()) 2065 2062 , m_firstLineOffset(cachedExecutable.firstLineOffset()) 2063 , m_isInStrictContext(cachedExecutable.isInStrictContext()) 2066 2064 , m_lineCount(cachedExecutable.lineCount()) 2065 , m_hasCapturedVariables(cachedExecutable.hasCapturedVariables()) 2067 2066 , m_unlinkedFunctionNameStart(cachedExecutable.unlinkedFunctionNameStart()) 2067 , m_isBuiltinFunction(cachedExecutable.isBuiltinFunction()) 2068 2068 , m_unlinkedBodyStartColumn(cachedExecutable.unlinkedBodyStartColumn()) 2069 , m_isBuiltinDefaultClassConstructor(cachedExecutable.isBuiltinDefaultClassConstructor()) 2069 2070 , m_unlinkedBodyEndColumn(cachedExecutable.unlinkedBodyEndColumn()) 2071 , m_constructAbility(cachedExecutable.constructAbility()) 2070 2072 , m_startOffset(cachedExecutable.startOffset()) 2073 , m_scriptMode(cachedExecutable.scriptMode()) 2071 2074 , m_sourceLength(cachedExecutable.sourceLength()) 2075 , m_superBinding(cachedExecutable.superBinding()) 2072 2076 , m_parametersStartOffset(cachedExecutable.parametersStartOffset()) 2077 , m_isCached(false) 2073 2078 , m_typeProfilingStartOffset(cachedExecutable.typeProfilingStartOffset()) 2074 2079 , m_typeProfilingEndOffset(cachedExecutable.typeProfilingEndOffset()) … … 2076 2081 , m_features(cachedExecutable.features()) 2077 2082 , m_sourceParseMode(cachedExecutable.sourceParseMode()) 2078 , m_isInStrictContext(cachedExecutable.isInStrictContext())2079 , m_hasCapturedVariables(cachedExecutable.hasCapturedVariables())2080 , m_isBuiltinFunction(cachedExecutable.isBuiltinFunction())2081 , m_isBuiltinDefaultClassConstructor(cachedExecutable.isBuiltinDefaultClassConstructor())2082 , m_constructAbility(cachedExecutable.constructAbility())2083 2083 , m_constructorKind(cachedExecutable.constructorKind()) 2084 2084 , m_functionMode(cachedExecutable.functionMode()) 2085 , m_scriptMode(cachedExecutable.scriptMode())2086 , m_superBinding(cachedExecutable.superBinding())2087 2085 , m_derivedContextType(cachedExecutable.derivedContextType()) 2088 , m_isCached(false)2089 2086 , m_unlinkedCodeBlockForCall() 2090 2087 , m_unlinkedCodeBlockForConstruct() … … 2092 2089 , m_name(cachedExecutable.name(decoder)) 2093 2090 , m_ecmaName(cachedExecutable.ecmaName(decoder)) 2094 , m_inferredName(cachedExecutable.inferredName(decoder))2095 2091 2096 2092 , m_rareData(cachedExecutable.rareData(decoder)) -
trunk/Source/JavaScriptCore/runtime/FunctionExecutable.h
r245040 r245288 162 162 const Identifier& name() { return m_unlinkedExecutable->name(); } 163 163 const Identifier& ecmaName() { return m_unlinkedExecutable->ecmaName(); } 164 const Identifier& inferredName() { return m_unlinkedExecutable->inferredName(); }165 164 unsigned parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'! 166 165 SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); } -
trunk/Source/JavaScriptCore/runtime/FunctionExecutableDump.cpp
r208309 r245288 35 35 void FunctionExecutableDump::dump(PrintStream& out) const 36 36 { 37 out.print(m_executable-> inferredName().string(), "#");37 out.print(m_executable->ecmaName().string(), "#"); 38 38 if (m_executable->isGeneratedForCall()) 39 39 out.print(m_executable->codeBlockForCall()->hashAsStringIfPossible()); -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r243886 r245288 228 228 return actualName; 229 229 230 return jsExecutable()-> inferredName().string();230 return jsExecutable()->ecmaName().string(); 231 231 } 232 232 … … 652 652 return actualName; 653 653 654 return function->jsExecutable()-> inferredName().string();654 return function->jsExecutable()->ecmaName().string(); 655 655 } 656 656 if (auto* function = jsDynamicCast<InternalFunction*>(vm, object)) -
trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp
r244811 r245288 780 780 781 781 if (executable->isFunctionExecutable()) 782 return static_cast<FunctionExecutable*>(executable)-> inferredName().string();782 return static_cast<FunctionExecutable*>(executable)->ecmaName().string(); 783 783 if (executable->isProgramExecutable() || executable->isEvalExecutable()) 784 784 return "(program)"_s; … … 807 807 808 808 if (executable->isFunctionExecutable()) { 809 String result = static_cast<FunctionExecutable*>(executable)-> inferredName().string();809 String result = static_cast<FunctionExecutable*>(executable)->ecmaName().string(); 810 810 if (result.isEmpty()) 811 811 return "(anonymous function)"_s; -
trunk/Source/WebCore/ChangeLog
r245286 r245288 1 2019-05-14 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Shrink sizeof(UnlinkedFunctionExecutable) more 4 https://bugs.webkit.org/show_bug.cgi?id=197833 5 6 Reviewed by Darin Adler. 7 8 * testing/Internals.cpp: 9 (WebCore::Internals::parserMetaData): 10 1 11 2019-05-14 Antoine Quint <graouts@apple.com> 2 12 -
trunk/Source/WebCore/testing/Internals.cpp
r245280 r245288 2160 2160 if (executable->isFunctionExecutable()) { 2161 2161 FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable); 2162 String inferredName = funcExecutable-> inferredName().string();2162 String inferredName = funcExecutable->ecmaName().string(); 2163 2163 result.appendLiteral("function \""); 2164 2164 result.append(inferredName);
Note: See TracChangeset
for help on using the changeset viewer.