Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 18d37d9fc2a08b00884449570d8d1011f0df2e95
https://github.com/WebKit/WebKit/commit/18d37d9fc2a08b00884449570d8d1011f0df2e95
Author: Yusuke Suzuki <[email protected]>
Date: 2023-04-10 (Mon, 10 Apr 2023)
Changed paths:
A JSTests/microbenchmarks/megamorphic-miss.js
A JSTests/microbenchmarks/megamorphic-own-load.js
A JSTests/microbenchmarks/megamorphic-prototype-load.js
M Source/JavaScriptCore/CMakeLists.txt
M Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
M Source/JavaScriptCore/Sources.txt
M Source/JavaScriptCore/bytecode/AccessCase.cpp
M Source/JavaScriptCore/bytecode/AccessCase.h
M Source/JavaScriptCore/bytecode/CheckPrivateBrandStatus.cpp
M Source/JavaScriptCore/bytecode/DeleteByStatus.cpp
M Source/JavaScriptCore/bytecode/GetByStatus.cpp
M Source/JavaScriptCore/bytecode/InByStatus.h
M Source/JavaScriptCore/bytecode/InlineCacheCompiler.cpp
M Source/JavaScriptCore/bytecode/InlineCacheCompiler.h
M Source/JavaScriptCore/bytecode/InstanceOfStatus.h
M Source/JavaScriptCore/bytecode/PutByStatus.cpp
M Source/JavaScriptCore/bytecode/Repatch.cpp
M Source/JavaScriptCore/bytecode/Repatch.h
M Source/JavaScriptCore/bytecode/SetPrivateBrandStatus.cpp
M Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
M Source/JavaScriptCore/bytecode/StructureStubInfo.h
M Source/JavaScriptCore/bytecode/StubInfoSummary.cpp
M Source/JavaScriptCore/bytecode/StubInfoSummary.h
M Source/JavaScriptCore/dfg/DFGOperations.cpp
M Source/JavaScriptCore/heap/Heap.cpp
M Source/JavaScriptCore/jit/JITOperations.cpp
M Source/JavaScriptCore/jit/JITOperations.h
M Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
M Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
M Source/JavaScriptCore/runtime/HasOwnPropertyCache.h
M Source/JavaScriptCore/runtime/JSGlobalObject.cpp
M Source/JavaScriptCore/runtime/JSObject.cpp
M Source/JavaScriptCore/runtime/JSObject.h
M Source/JavaScriptCore/runtime/JSObjectInlines.h
A Source/JavaScriptCore/runtime/MegamorphicCache.cpp
A Source/JavaScriptCore/runtime/MegamorphicCache.h
M Source/JavaScriptCore/runtime/ObjectPrototype.cpp
M Source/JavaScriptCore/runtime/Structure.cpp
M Source/JavaScriptCore/runtime/Structure.h
M Source/JavaScriptCore/runtime/StructureCache.cpp
M Source/JavaScriptCore/runtime/StructureInlines.h
M Source/JavaScriptCore/runtime/StructureTransitionTable.h
M Source/JavaScriptCore/runtime/VM.cpp
M Source/JavaScriptCore/runtime/VM.h
M Source/WebCore/bindings/js/JSDOMAsyncIterator.h
M Source/WebCore/bindings/js/JSDOMBuiltinConstructor.h
M Source/WebCore/bindings/js/JSDOMConstructor.h
M Source/WebCore/bindings/js/JSDOMConstructorNotCallable.h
M Source/WebCore/bindings/js/JSDOMConstructorNotConstructable.h
M Source/WebCore/bindings/js/JSDOMIterator.h
M Source/WebCore/bindings/js/JSWindowProxy.cpp
M Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
M Source/WebCore/bindings/scripts/test/JS/JSExposedStar.cpp
M Source/WebCore/bindings/scripts/test/JS/JSExposedToWorkerAndWindow.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestAsyncIterable.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestAsyncKeyValueIterable.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestCEReactions.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestCEReactionsStringifier.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestClassWithJSBuiltinConstructor.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestConditionalIncludes.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestConditionallyReadWrite.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestDOMJIT.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestDefaultToJSON.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestDefaultToJSONFilteredByExposed.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestDefaultToJSONIndirectInheritance.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestDefaultToJSONInherit.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestDefaultToJSONInheritFinal.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestDelegateToSharedSyntheticAttribute.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestDomainSecurity.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestEnabledBySetting.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestEnabledForContext.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestEventConstructor.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestEventTarget.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestException.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestGenerateAddOpaqueRoot.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestGenerateIsReachable.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterNoIdentifier.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterThrowingException.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestIndexedSetterWithIdentifier.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestInterfaceLeadingUnderscore.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestIterable.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestJSBuiltinConstructor.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestLegacyFactoryFunction.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestLegacyNoInterfaceObject.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestLegacyOverrideBuiltIns.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestMapLike.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestMapLikeWithOverriddenOperations.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterNoIdentifier.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterThrowingException.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedAndIndexedSetterWithIdentifier.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterNoIdentifier.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterThrowingException.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterWithIdentifier.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedDeleterWithIndexedGetter.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterCallWith.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterNoIdentifier.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedGetterWithIdentifier.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterNoIdentifier.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterThrowingException.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIdentifier.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetter.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithIndexedGetterAndSetter.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithLegacyOverrideBuiltIns.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithLegacyUnforgeableProperties.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestNamedSetterWithLegacyUnforgeablePropertiesAndLegacyOverrideBuiltIns.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestOperationConditional.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructors.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestOverloadedConstructorsWithSequence.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestPluginInterface.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestPromiseRejectionEvent.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestReadOnlyMapLike.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestReadOnlySetLike.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestReportExtraMemoryCost.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestSerializedScriptValueInterface.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestSetLike.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestSetLikeWithOverriddenOperations.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestStringifier.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestStringifierAnonymousOperation.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestStringifierNamedOperation.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestStringifierOperationImplementedAs.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestStringifierOperationNamedToString.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestStringifierReadOnlyAttribute.cpp
M
Source/WebCore/bindings/scripts/test/JS/JSTestStringifierReadWriteAttribute.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestTaggedWrapper.cpp
M Source/WebCore/bindings/scripts/test/JS/JSTestTypedefs.cpp
M Source/WebCore/bindings/scripts/test/JS/JSWorkerGlobalScope.cpp
M Source/WebCore/bindings/scripts/test/JS/JSWorkletGlobalScope.cpp
M Source/WebCore/workers/WorkerOrWorkletScriptController.cpp
Log Message:
-----------
[JSC] Add megamorphic cache
https://bugs.webkit.org/show_bug.cgi?id=255060
rdar://problem/107683366
Reviewed by Justin Michaud.
This patch adds megamorphic load cache finally, which exists in SpiderMonkey
and V8. Our plan is adding megamorphic store cache next.
1. We move mayBePrototype bit from object cell to Structure. This allows us to
disable IC setup for prototype objects by observing Structure.
(And this is extremely rare). And every time we do some modification of the
object, we can check `mayBePrototype()` and we can invalidate
megamorphic cache integrity (VM::invalidateStructureChainIntegrity). This
bit & transition happens automatically when an object gets used as a prototype.
But we mark all DOM prototypes and constructors a priori since they become
prototype objects.
2. We integrate megamorphic load cache, which is 2-level hash table with 2
different hash functions. Primary table has 2048 entries and secondaryHash
table has 512 entries, which is derived number from V8's megamorphic cache
implementation. Our megamorphic cache's entry is StructureID +
UniquedStringImpl.
And the result is holder object and offset. Holder is null if property is
missed. And holder is special marker (0x2) if it is own property.
Every time objects used for prototype gets changed, whole megamorphic cache
gets invalidated by incrementing epoch. This is surprisingly rare since
we do not modify objects used for prototype after creating instances (And
once the page gets stable state, we do not modify prototype objects).
We use 2-level cache with 2 completely different hash functions to make it
work well for various StructureID + UniquedStringImpl* pair.
3. We increment epoch of megamorphic cache when GC happens. So we do not keep
entries valid over GC.
This change roughly offers 2-3x performance improvement for megamorphic access.
ToT Patched
megamorphic-own-load 99.3922+-1.9842 ^ 41.2465+-0.0893
^ definitely 2.4097x faster
megamorphic-load 14.8899+-0.0635 ^ 5.0489+-0.0328
^ definitely 2.9491x faster
megamorphic-prototype-load 136.9894+-0.6358 ^ 38.1426+-0.0790
^ definitely 3.5915x faster
megamorphic-miss 98.3712+-1.6652 ^ 31.9041+-0.0640
^ definitely 3.0833x faster
* JSTests/microbenchmarks/megamorphic-miss.js: Added.
(f):
* JSTests/microbenchmarks/megamorphic-own-load.js: Added.
(f):
* JSTests/microbenchmarks/megamorphic-prototype-load.js: Added.
(f):
* Source/JavaScriptCore/CMakeLists.txt:
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/Sources.txt:
* 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::runWithDowncast):
(JSC::AccessCase::canBeShared):
* Source/JavaScriptCore/bytecode/AccessCase.h:
* Source/JavaScriptCore/bytecode/CheckPrivateBrandStatus.cpp:
(JSC::CheckPrivateBrandStatus::CheckPrivateBrandStatus):
* Source/JavaScriptCore/bytecode/DeleteByStatus.cpp:
(JSC::DeleteByStatus::DeleteByStatus):
* Source/JavaScriptCore/bytecode/GetByStatus.cpp:
(JSC::GetByStatus::GetByStatus):
* Source/JavaScriptCore/bytecode/InByStatus.h:
* Source/JavaScriptCore/bytecode/InlineCacheCompiler.cpp:
(JSC::InlineCacheCompiler::generateWithGuard):
(JSC::InlineCacheCompiler::generateImpl):
(JSC::InlineCacheCompiler::regenerate):
(WTF::printInternal):
* Source/JavaScriptCore/bytecode/InlineCacheCompiler.h:
(JSC::AccessGenerationResult::AccessGenerationResult):
(JSC::AccessGenerationResult::generatedMegamorphicCode const):
(JSC::AccessGenerationResult::generatedSomeCode const):
* Source/JavaScriptCore/bytecode/InstanceOfStatus.h:
* Source/JavaScriptCore/bytecode/PutByStatus.cpp:
(JSC::PutByStatus::PutByStatus):
(JSC::PutByStatus::computeFor):
* Source/JavaScriptCore/bytecode/Repatch.cpp:
(JSC::tryCacheGetBy):
(JSC::repatchGetBy):
(JSC::repatchGetBySlowPathCall):
(JSC::tryCachePutBy):
(JSC::tryCacheDeleteBy):
* Source/JavaScriptCore/bytecode/Repatch.h:
* Source/JavaScriptCore/bytecode/SetPrivateBrandStatus.cpp:
(JSC::SetPrivateBrandStatus::SetPrivateBrandStatus):
* Source/JavaScriptCore/bytecode/StructureStubInfo.cpp:
(JSC::StructureStubInfo::summary const):
* Source/JavaScriptCore/bytecode/StructureStubInfo.h:
(JSC::StructureStubInfo::considerCachingGeneric):
(JSC::StructureStubInfo::considerCachingBy):
(JSC::StructureStubInfo::considerCachingMegamorphic):
(JSC::StructureStubInfo::considerCachingImpl):
(JSC::StructureStubInfo::considerCaching): Deleted.
* Source/JavaScriptCore/bytecode/StubInfoSummary.cpp:
(WTF::printInternal):
* Source/JavaScriptCore/bytecode/StubInfoSummary.h:
(JSC::isInlineable):
(JSC::slowVersion):
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/heap/Heap.cpp:
(JSC::Heap::finalize):
* Source/JavaScriptCore/jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/jit/JITOperations.h:
* Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* Source/JavaScriptCore/runtime/CommonSlowPaths.cpp:
(JSC::JSC_DEFINE_COMMON_SLOW_PATH):
* Source/JavaScriptCore/runtime/HasOwnPropertyCache.h:
(JSC::VM::ensureHasOwnPropertyCache):
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* Source/JavaScriptCore/runtime/JSObject.cpp:
(JSC::JSObject::setPrototypeDirect):
(JSC::JSObject::deleteProperty):
* Source/JavaScriptCore/runtime/JSObject.h:
* Source/JavaScriptCore/runtime/JSObjectInlines.h:
(JSC::JSObject::prepareToPutDirectWithoutTransition):
(JSC::JSObject::putDirectInternal):
(JSC::JSObject::mayBePrototype const):
(JSC::JSObject::didBecomePrototype):
* Source/JavaScriptCore/runtime/MegamorphicCache.cpp: Copied from
Source/JavaScriptCore/bytecode/StubInfoSummary.cpp.
(JSC::MegamorphicCache::age):
(JSC::MegamorphicCache::clearEntries):
* Source/JavaScriptCore/runtime/MegamorphicCache.h: Added.
(JSC::MegamorphicCache::Entry::offsetOfUid):
(JSC::MegamorphicCache::Entry::offsetOfStructureID):
(JSC::MegamorphicCache::Entry::offsetOfEpoch):
(JSC::MegamorphicCache::Entry::offsetOfOffset):
(JSC::MegamorphicCache::Entry::offsetOfHolder):
(JSC::MegamorphicCache::Entry::initAsMiss):
(JSC::MegamorphicCache::Entry::initAsHit):
(JSC::MegamorphicCache::offsetOfPrimaryEntries):
(JSC::MegamorphicCache::offsetOfSecondaryEntries):
(JSC::MegamorphicCache::offsetOfEpoch):
(JSC::MegamorphicCache::primaryHash):
(JSC::MegamorphicCache::secondaryHash):
(JSC::MegamorphicCache::initAsMiss):
(JSC::MegamorphicCache::initAsHit):
(JSC::MegamorphicCache::epoch const):
(JSC::MegamorphicCache::bumpEpoch):
* Source/JavaScriptCore/runtime/ObjectPrototype.cpp:
(JSC::objectPrototypeHasOwnProperty):
* Source/JavaScriptCore/runtime/Structure.cpp:
(JSC::Structure::Structure):
(JSC::Structure::becomePrototypeTransition):
(JSC::Structure::nonPropertyTransitionSlow):
* Source/JavaScriptCore/runtime/Structure.h:
* Source/JavaScriptCore/runtime/StructureCache.cpp:
(JSC::StructureCache::createEmptyStructure):
* Source/JavaScriptCore/runtime/StructureInlines.h:
(JSC::Structure::create):
(JSC::Structure::nonPropertyTransition):
* Source/JavaScriptCore/runtime/StructureTransitionTable.h:
* Source/JavaScriptCore/runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::ensureMegamorphicCacheSlow):
(JSC::VM::invalidateStructureChainIntegrity):
* Source/JavaScriptCore/runtime/VM.h:
(JSC::VM::megamorphicCache):
(JSC::VM::ensureMegamorphicCache):
* Source/WebCore/bindings/js/JSDOMAsyncIterator.h:
(WebCore::JSDOMAsyncIteratorBase::createPrototype):
* Source/WebCore/bindings/js/JSDOMBuiltinConstructor.h:
(WebCore::JSDOMBuiltinConstructor<JSClass>::createStructure):
* Source/WebCore/bindings/js/JSDOMConstructor.h:
(WebCore::JSDOMConstructor<JSClass>::createStructure):
* Source/WebCore/bindings/js/JSDOMConstructorNotCallable.h:
(WebCore::JSDOMConstructorNotCallable<JSClass>::createStructure):
* Source/WebCore/bindings/js/JSDOMConstructorNotConstructable.h:
(WebCore::JSDOMConstructorNotConstructable<JSClass>::createStructure):
* Source/WebCore/bindings/js/JSDOMIterator.h:
(WebCore::JSDOMIteratorBase::createPrototype):
* Source/WebCore/bindings/js/JSWindowProxy.cpp:
(WebCore::JSWindowProxy::setWindow):
* Source/WebCore/bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
* Source/WebCore/workers/WorkerOrWorkletScriptController.cpp:
(WebCore::WorkerOrWorkletScriptController::initScriptWithSubclass):
Canonical link: https://commits.webkit.org/262808@main
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes