Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WebIDL] Eagerly allocate element wrappers onto a butterfly storage of a static NodeList #3902

Merged

Commits on Sep 1, 2022

  1. [WebIDL] Eagerly allocate element wrappers onto a butterfly storage o…

    …f a static NodeList
    
    https://bugs.webkit.org/show_bug.cgi?id=234538
    
    Reviewed by Yusuke Suzuki and Saam Barati.
    
    This is a re-land of r253946 with a suggestedArrayStorageTransition() fixed, debug
    assertions adjusted, and tests performing less iterations to avoid timeouts.
    
    This change greatly speeds up iterating static NodeList iteration (including via
    Array.prototype.indexOf), making it on par with JSArray. It preserves current
    (weird) NodeList semantics, including cases of transitioning to slow put array storage
    mode, and is future-proof against aligning internal methods of DOM collections with
    other browsers (http://webkit.org/b/218849).
    
    There was no way to achieve that with existing indexing types: put_by_val compiled
    for NonArrayWithContiguous emits only indexing type check, thus incorrectly mutating
    a NodeList instead of calling put() override. NonArrayWithSlowPutArrayStorage could
    be semantically correct alternative only if all its elements are onto a sparse map,
    which won't be much faster.
    
    Two viable approaches were either introducing a new Contiguous-like indexing type,
    or doing something similar to IndexedDirectArgumentsLoad. This change does the former
    to reuse existing logic for DFG::ArrayMode refining and ArrayIndexOf compilation.
    
    Another tricky part is that NodeList's "length" is a configurable getter on prototype,
    unlike own non-configurable JSArray's "length", and we need to ensure that both the
    NodeList structure is original (inherits from NodeList.prototype) and the "length"
    getter wasn't deleted / overriden.
    
    For the static NodeList to leverage fast compiled get_by_val, it needs to have original
    getOwnPropertySlotByIndex() method, so SlowPutArrayStorageVectorPropertiesAreReadOnly
    out-of-line type info flag is added to reliably preserve ReadOnly attributes of its
    indices as per spec [1].
    
    This change is a locally confirmed 2% progression on all three Speedometer2/VanillaJS subtests.
    
    [1] https://webidl.spec.whatwg.org/#LegacyPlatformObjectGetOwnProperty (step 1.2.7)
    
    * .gitignore:
    * Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
    * Source/JavaScriptCore/bytecode/AccessCase.cpp:
    (JSC::AccessCase::create):
    (JSC::AccessCase::guardedByStructureCheckSkippingConstantIdentifierCheck const):
    (JSC::AccessCase::requiresIdentifierNameMatch const):
    (JSC::AccessCase::requiresInt32PropertyCheck const):
    (JSC::AccessCase::needsScratchFPR const):
    (JSC::AccessCase::forEachDependentCell const):
    (JSC::AccessCase::doesCalls const):
    (JSC::AccessCase::canReplace const):
    (JSC::AccessCase::generateWithGuard):
    (JSC::AccessCase::generateImpl):
    (JSC::AccessCase::canBeShared):
    * Source/JavaScriptCore/bytecode/AccessCase.h:
    * Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp:
    * Source/JavaScriptCore/bytecode/AdaptiveInferredPropertyValueWatchpointBase.h:
    * Source/JavaScriptCore/bytecode/ArrayProfile.cpp:
    (JSC::dumpArrayModes):
    (JSC::ArrayProfile::computeUpdatedPrediction):
    * Source/JavaScriptCore/bytecode/ArrayProfile.h:
    (JSC::shouldUseAlwaysSlowPutContiguous):
    * Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp:
    (WTF::printInternal):
    * Source/JavaScriptCore/bytecode/Repatch.cpp:
    (JSC::tryCacheArrayGetByVal):
    * Source/JavaScriptCore/bytecode/Watchpoint.h:
    * Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
    * Source/JavaScriptCore/dfg/DFGArrayMode.cpp:
    (JSC::DFG::ArrayMode::fromObserved):
    (JSC::DFG::ArrayMode::refine const):
    (JSC::DFG::ArrayMode::alreadyChecked const):
    (JSC::DFG::arrayTypeToString):
    (JSC::DFG::toIndexingShape):
    (JSC::DFG::permitsBoundsCheckLowering):
    * Source/JavaScriptCore/dfg/DFGArrayMode.h:
    (JSC::DFG::ArrayMode::usesButterfly const):
    (JSC::DFG::ArrayMode::isSlowPut const):
    (JSC::DFG::ArrayMode::isAnyKindOfContiguous const):
    (JSC::DFG::ArrayMode::lengthNeedsStorage const):
    (JSC::DFG::ArrayMode::modeForPut const):
    (JSC::DFG::ArrayMode::supportsSelfLength const):
    (JSC::DFG::ArrayMode::arrayModesThatPassFiltering const):
    * Source/JavaScriptCore/dfg/DFGArrayifySlowPathGenerator.h:
    * Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
    (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
    * Source/JavaScriptCore/dfg/DFGClobberize.h:
    (JSC::DFG::clobberize):
    * Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
    (JSC::DFG::FixupPhase::attemptToMakeGetArrayLength):
    (JSC::DFG::FixupPhase::attemptToMakeGetArrayLengthForAlwaysSlowPutContiguous):
    (JSC::DFG::FixupPhase::fixupArrayIndexOf):
    * Source/JavaScriptCore/dfg/DFGOperations.cpp:
    (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
    * Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
    (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode):
    (JSC::DFG::SpeculativeJIT::checkArray):
    (JSC::DFG::SpeculativeJIT::compilePutByVal):
    * Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
    (JSC::DFG::SpeculativeJIT::compileGetByVal):
    * Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h:
    (JSC::FTL::AbstractHeapRepository::forArrayType):
    * Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
    (JSC::FTL::DFG::LowerDFGToB3::compileArrayify):
    (JSC::FTL::DFG::LowerDFGToB3::compileGetArrayLength):
    (JSC::FTL::DFG::LowerDFGToB3::compileGetByValImpl):
    (JSC::FTL::DFG::LowerDFGToB3::compilePutByVal):
    (JSC::FTL::DFG::LowerDFGToB3::compileArrayIndexOf):
    (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
    * Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:
    (JSC::LLInt::performLLIntGetByID):
    * Source/JavaScriptCore/llint/LowLevelInterpreter.asm:
    * Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm:
    * Source/JavaScriptCore/llint/LowLevelInterpreter64.asm:
    * Source/JavaScriptCore/runtime/ArrayPrototype.cpp:
    (JSC::JSC_DEFINE_HOST_FUNCTION):
    (JSC::tryFastIndexOf):
    (JSC::fastIndexOf): Deleted.
    * Source/JavaScriptCore/runtime/IndexingType.cpp:
    (JSC::dumpIndexingType):
    * Source/JavaScriptCore/runtime/IndexingType.h:
    (JSC::hasAlwaysSlowPutContiguous):
    (JSC::hasAnyContiguous):
    * Source/JavaScriptCore/runtime/JSArray.cpp:
    (JSC::JSArray::fastSlice):
    * Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
    (JSC::JSGlobalObject::init):
    (JSC::JSGlobalObject::initAlwaysSlowPutContiguousWatchpointSet):
    (JSC::JSGlobalObject::recordOriginalAlwaysSlowPutContiguousStructure):
    * Source/JavaScriptCore/runtime/JSGlobalObject.h:
    (JSC::JSGlobalObject::alwaysSlowPutContiguousWatchpointSet):
    (JSC::JSGlobalObject::isOriginalSlowPutContigiousStructure):
    (JSC::JSGlobalObject::originalAlwaysSlowPutContiguousStructures const):
    * Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h:
    (JSC::JSGlobalObject::alwaysSlowPutContiguousPrototypeChainIsSane):
    * Source/JavaScriptCore/runtime/JSObject.cpp:
    (JSC::JSObject::getOwnPropertySlotByIndex):
    (JSC::JSObject::convertContiguousToArrayStorage):
    (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode):
    (JSC::JSObject::switchToSlowPutArrayStorage):
    (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
    * Source/JavaScriptCore/runtime/JSObject.h:
    (JSC::JSObject::trySetIndexQuickly):
    (JSC::JSObject::setIndexQuickly):
    (JSC::JSObject::tryMakeWritableContiguous):
    * Source/JavaScriptCore/runtime/JSObjectInlines.h:
    (JSC::JSObject::canDoFastIndexedAccess):
    * Source/JavaScriptCore/runtime/JSTypeInfo.h:
    (JSC::TypeInfo::arrayStorageVectorPropertiesAreReadOnly const):
    * Source/JavaScriptCore/runtime/StructureTransitionTable.h:
    (JSC::newIndexingType):
    * Source/JavaScriptCore/tools/JSDollarVM.cpp:
    (JSC::createAlwaysSlowPutContiguousObject):
    (JSC::JSC_DEFINE_HOST_FUNCTION):
    (JSC::JSDollarVM::finishCreation):
    * Source/WTF/wtf/Vector.h:
    (WTF::Malloc>::every const):
    * Source/WebCore/WebCore.xcodeproj/project.pbxproj:
    * Source/WebCore/bindings/js/JSDOMWindowBase.cpp:
    (WebCore::JSDOMWindowBase::finishCreation):
    (WebCore::JSDOMWindowBase::installAlwaysSlowPutContiguousWatchpoints):
    * Source/WebCore/bindings/js/JSDOMWindowBase.h:
    * Source/WebCore/bindings/js/JSNodeListCustom.cpp:
    (WebCore::JSStaticNodeList::createPrototype):
    (WebCore::JSStaticNodeList::JSStaticNodeList):
    (WebCore::JSStaticNodeList::finishCreation):
    (WebCore::createWrapper):
    * Source/WebCore/bindings/js/JSNodeListCustom.h:
    (WebCore::JSStaticNodeList::create):
    (WebCore::JSStaticNodeList::createStructure):
    * Source/WebCore/dom/NodeList.h:
    (WebCore::NodeList::isStaticNodeList const):
    * Source/WebCore/dom/StaticNodeList.h:
    
    Canonical link: https://commits.webkit.org/254036@main
    shvaikalesh authored and Alexey Shvayka committed Sep 1, 2022
    Copy the full SHA
    de4790b View commit details
    Browse the repository at this point in the history