Optimize the construction of a JSC::Identifier from an ASCIILiteral
https://bugs.webkit.org/show_bug.cgi?id=238552
Reviewed by Geoffrey Garen.
Source/JavaScriptCore:
There are two ways to construct a JSC::Identifier from a string literal and both
were sub-optimal:
- template<unsigned charactersCount> static Identifier fromString(VM&, const char (&characters)[charactersCount]):
Even though it knows the charactersCount at compile time, it doesn't leverage this information
at all. Also, it ends up calling AtomStringImpl::add() instead of AtomStringImpl::addLiteral()
which means we lose the knowledge that it was a string literal and the optimization that come
with it (e.g. not copying the characters over). In this patch, I am deprecating this function
in favor of fromString(ASCIILiteral) which is now more efficient. I'll remove it in a follow up.
- static Identifier fromString(VM&, ASCIILiteral):
It ended up calling the Identifier(VM&, String) constructor which meant that we were potentially constructing
a String/StringImpl unnecessarily before atomizing it since the string may already be in the
AtomString table. We also failed to use the smallStrings cache for literals whose length is 1,
which would happen when calling
fromString(VM&, const char (&characters)[charactersCount]) .
In this patch, I optimized fromString(VM&, ASCIILiteral) to leverage the smallStrings cache
when necessary and call AtomStringImpl::addLiteral() instead of AtomStringImpl::add(). I also
made sure to mark fromString(VM&, ASCIILiteral) and Identifier(VM&, ASCIILiteral) as
ALWAYS_INLINE to make sure the compiler can optimize out the strlen() calls.
According to A/B bots, this is a 1-1.5% progression on Speedometer and and a 1.3% progression on
JetStream on iMac 20,1 (Intel). Sadly, this is perf-neutral on those two benchmarks on Apple
Silicon.
- API/JSAPIGlobalObject.mm:
(JSC::JSAPIGlobalObject::moduleLoaderCreateImportMetaProperties):
(JSGetMemoryUsageStatistics):
(JSObjectMakeFunction):
- builtins/BuiltinNames.cpp:
(JSC::BuiltinNames::BuiltinNames):
- builtins/BuiltinUtils.h:
- dynbench.cpp:
- inspector/JSInjectedScriptHost.cpp:
(Inspector::JSInjectedScriptHost::functionDetails):
(Inspector::constructInternalProperty):
(Inspector::JSInjectedScriptHost::weakMapEntries):
(Inspector::JSInjectedScriptHost::weakSetEntries):
(Inspector::JSInjectedScriptHost::iteratorEntries):
- inspector/JSJavaScriptCallFrame.cpp:
(Inspector::valueForScopeLocation):
(Inspector::JSJavaScriptCallFrame::scopeDescriptions):
- inspector/ScriptCallStackFactory.cpp:
(Inspector::extractSourceInformationFromException):
- inspector/agents/InspectorAuditAgent.cpp:
(Inspector::InspectorAuditAgent::populateAuditObject):
(GlobalObject::moduleLoaderCreateImportMetaProperties):
(JSC_DEFINE_HOST_FUNCTION):
(dumpException):
- runtime/AbstractModuleRecord.cpp:
(JSC::AbstractModuleRecord::hostResolveImportedModule):
- runtime/AtomicsObject.cpp:
(JSC::AtomicsObject::finishCreation):
- runtime/CommonIdentifiers.cpp:
(JSC::CommonIdentifiers::CommonIdentifiers):
- runtime/FinalizationRegistryPrototype.cpp:
(JSC::FinalizationRegistryPrototype::finishCreation):
(JSC::Identifier::addLiteral):
(JSC::Identifier::Identifier):
- runtime/IdentifierInlines.h:
(JSC::Identifier::fromString):
(JSC::IntlLocale::textInfo):
(JSC::IntlLocale::weekInfo):
- runtime/IntlNumberFormat.cpp:
(JSC::IntlNumberFormat::initializeNumberFormat):
(JSC::IntlNumberFormat::resolvedOptions const):
(JSC::IntlNumberFormat::formatToPartsInternal):
- runtime/IntlPluralRules.cpp:
(JSC::IntlPluralRules::resolvedOptions const):
- runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::exposeDollarVM):
- runtime/JSModuleLoader.cpp:
(JSC::JSModuleLoader::finishCreation):
(JSC::MathObject::finishCreation):
- runtime/NumberConstructor.cpp:
(JSC::NumberConstructor::finishCreation):
- runtime/StringPrototype.cpp:
(JSC::StringPrototype::finishCreation):
- runtime/SymbolConstructor.cpp:
- tools/JSDollarVM.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSDollarVM::finishCreation):
- wasm/js/JSWebAssemblyGlobal.cpp:
(JSC::JSWebAssemblyGlobal::type):
- wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::type):
- wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::type):
- wasm/js/WebAssemblyGlobalConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
- wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
- wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
- wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
- wasm/js/WebAssemblyTagPrototype.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
Source/WebCore:
Adopt the JSC::Identifier constructor from an ASCIILiteral more widely.
- Modules/applepay-ams-ui/ApplePayAMSUIPaymentHandler.cpp:
(WebCore::ApplePayAMSUIPaymentHandler::finishSession):
- Modules/encryptedmedia/legacy/LegacyCDMSessionClearKey.cpp:
(WebCore::CDMSessionClearKey::update):
- Modules/webaudio/AudioWorkletGlobalScope.cpp:
(WebCore::AudioWorkletGlobalScope::registerProcessor):
- Modules/webaudio/AudioWorkletProcessor.cpp:
(WebCore::AudioWorkletProcessor::process):
- bindings/js/JSCustomElementRegistryCustom.cpp:
(WebCore::JSCustomElementRegistry::define):
- bindings/js/JSDOMWindowCustom.cpp:
(WebCore::DialogHandler::dialogCreated):
(WebCore::DialogHandler::returnValue const):
(WebCore::JSDOMWindow::setOpener):
(WebCore::JSDOMWindow::setOpenDatabase):
- bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
- bindings/js/JSImageDataCustom.cpp:
(WebCore::toJSNewlyCreated):
- bindings/js/ScriptModuleLoader.cpp:
(WebCore::ScriptModuleLoader::createImportMetaProperties):
- bindings/scripts/CodeGeneratorJS.pm:
(GenerateDictionaryImplementationContent):
(addUnscopableProperties):
(GenerateImplementation):
(GenerateAttributeSetterBodyDefinition):
(GenerateDefaultToJSONOperationDefinition):
(GenerateCallbackImplementationContent):
(GenerateConstructorHelperMethods):
- bindings/scripts/test/JS/JSExposedStar.cpp:
(WebCore::JSExposedStarPrototype::finishCreation):
- bindings/scripts/test/JS/JSExposedToWorkerAndWindow.cpp:
(WebCore::convertDictionary<ExposedToWorkerAndWindow::Dict>):
(WebCore::convertDictionaryToJS):
- bindings/scripts/test/JS/JSTestCEReactions.cpp:
(WebCore::setJSTestCEReactions_stringifierAttributeSetter):
(WebCore::setJSTestCEReactions_stringifierAttributeNotNeededSetter):
- bindings/scripts/test/JS/JSTestCallbackInterface.cpp:
(WebCore::convertDictionary<TestCallbackInterface::Dictionary>):
(WebCore::JSTestCallbackInterface::callbackWithNoParam):
(WebCore::JSTestCallbackInterface::callbackWithArrayParam):
(WebCore::JSTestCallbackInterface::callbackWithSerializedScriptValueParam):
(WebCore::JSTestCallbackInterface::callbackWithStringList):
(WebCore::JSTestCallbackInterface::callbackWithBoolean):
(WebCore::JSTestCallbackInterface::callbackRequiresThisToPass):
(WebCore::JSTestCallbackInterface::callbackWithAReturnValue):
(WebCore::JSTestCallbackInterface::callbackThatRethrowsExceptions):
(WebCore::JSTestCallbackInterface::callbackWithThisObject):
- bindings/scripts/test/JS/JSTestConditionalIncludes.cpp:
(WebCore::JSTestConditionalIncludesDOMConstructor::initializeProperties):
(WebCore::JSTestConditionalIncludesPrototype::finishCreation):
- bindings/scripts/test/JS/JSTestConditionallyReadWrite.cpp:
(WebCore::JSTestConditionallyReadWritePrototype::finishCreation):
- bindings/scripts/test/JS/JSTestDefaultToJSON.cpp:
(WebCore::JSTestDefaultToJSONPrototype::finishCreation):
(WebCore::jsTestDefaultToJSONPrototypeFunction_toJSONBody):
- bindings/scripts/test/JS/JSTestDefaultToJSONFilteredByExposed.cpp:
(WebCore::JSTestDefaultToJSONFilteredByExposedPrototype::finishCreation):
(WebCore::jsTestDefaultToJSONFilteredByExposedPrototypeFunction_toJSONBody):
- bindings/scripts/test/JS/JSTestDefaultToJSONInherit.cpp:
(WebCore::jsTestDefaultToJSONInheritPrototypeFunction_toJSONBody):
- bindings/scripts/test/JS/JSTestDefaultToJSONInheritFinal.cpp:
(WebCore::jsTestDefaultToJSONInheritFinalPrototypeFunction_toJSONBody):
- bindings/scripts/test/JS/JSTestDerivedDictionary.cpp:
(WebCore::convertDictionary<TestDerivedDictionary>):
(WebCore::convertDictionaryToJS):
- bindings/scripts/test/JS/JSTestDerivedDictionary2.cpp:
(WebCore::convertDictionary<TestDerivedDictionary2>):
(WebCore::convertDictionaryToJS):
(WebCore::convertDictionary<TestDerivedDictionary2::Dictionary>):
- bindings/scripts/test/JS/JSTestDictionary.cpp:
(WebCore::convertDictionary<TestDictionary>):
- bindings/scripts/test/JS/JSTestDictionaryWithOnlyConditionalMembers.cpp:
(WebCore::convertDictionary<TestDictionaryWithOnlyConditionalMembers>):
(WebCore::convertDictionaryToJS):
- bindings/scripts/test/JS/JSTestEnabledBySetting.cpp:
(WebCore::JSTestEnabledBySettingDOMConstructor::initializeProperties):
(WebCore::JSTestEnabledBySettingPrototype::finishCreation):
- bindings/scripts/test/JS/JSTestEventConstructor.cpp:
(WebCore::convertDictionary<TestEventConstructor::Init>):
- bindings/scripts/test/JS/JSTestGenerateIsReachable.cpp:
(WebCore::JSTestGenerateIsReachablePrototype::finishCreation):
- bindings/scripts/test/JS/JSTestInheritedDictionary.cpp:
(WebCore::convertDictionary<TestInheritedDictionary>):
(WebCore::convertDictionaryToJS):
- bindings/scripts/test/JS/JSTestInheritedDictionary2.cpp:
(WebCore::convertDictionary<TestInheritedDictionary2>):
(WebCore::convertDictionaryToJS):
- bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::JSTestInterfacePrototype::finishCreation):
- bindings/scripts/test/JS/JSTestNamespaceObject.cpp:
(WebCore::JSTestNamespaceObjectDOMConstructor::initializeProperties):
- bindings/scripts/test/JS/JSTestNode.cpp:
(WebCore::JSTestNodePrototype::finishCreation):
(WebCore::jsTestNodePrototypeFunction_toJSONBody):
- bindings/scripts/test/JS/JSTestObj.cpp:
(WebCore::convertDictionary<TestObj::Dictionary>):
(WebCore::convertDictionaryToJS):
(WebCore::convertDictionary<TestObj::DictionaryThatShouldNotTolerateNull>):
(WebCore::convertDictionary<TestObj::DictionaryThatShouldTolerateNull>):
(WebCore::convertDictionary<AlternateDictionaryName>):
(WebCore::convertDictionary<TestObj::ParentDictionary>):
(WebCore::convertDictionary<TestObj::ChildDictionary>):
(WebCore::convertDictionary<TestObj::ConditionalDictionaryA>):
(WebCore::convertDictionary<TestObj::ConditionalDictionaryB>):
(WebCore::convertDictionary<TestObj::ConditionalDictionaryC>):
(WebCore::JSTestObjDOMConstructor::initializeProperties):
(WebCore::JSTestObjPrototype::finishCreation):
(WebCore::setJSTestObj_putForwardsAttributeSetter):
(WebCore::setJSTestObj_putForwardsNullableAttributeSetter):
- bindings/scripts/test/JS/JSTestPromiseRejectionEvent.cpp:
(WebCore::convertDictionary<TestPromiseRejectionEvent::Init>):
- bindings/scripts/test/JS/JSTestStandaloneDictionary.cpp:
(WebCore::convertDictionary<DictionaryImplName>):
(WebCore::convertDictionaryToJS):
- html/HTMLMediaElement.cpp:
(WebCore::controllerJSValue):
(WebCore::HTMLMediaElement::updateCaptionContainer):
(WebCore::HTMLMediaElement::ensureMediaControlsInjectedScript):
(WebCore::HTMLMediaElement::didAddUserAgentShadowRoot):
(WebCore::HTMLMediaElement::updateMediaControlsAfterPresentationModeChange):
(WebCore::HTMLMediaElement::getCurrentMediaControlsStatus):
|