Skip to content

[JSC] Add IC/DFG/FTL intrinsic for %TypedArray%.prototype.buffer getter - #77421

Draft
sosukesuzuki wants to merge 1 commit into
WebKit:mainfrom
sosukesuzuki:eng/add-ic-dfg-ftl-intrinsic-for-typed-array-prototype-buffer-getter
Draft

sosukesuzuki wants to merge 1 commit into
WebKit:mainfrom
sosukesuzuki:eng/add-ic-dfg-ftl-intrinsic-for-typed-array-prototype-buffer-getter

Conversation

@sosukesuzuki

@sosukesuzuki sosukesuzuki commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

26f72c1

[JSC] Add IC/DFG/FTL intrinsic for `%TypedArray%.prototype.buffer` getter
https://bugs.webkit.org/show_bug.cgi?id=327976

Reviewed by NOBODY (OOPS!).

`typedArray.buffer` always called the C++ getter, even when the typed array
already has an ArrayBuffer and its JSArrayBuffer wrapper exists, as in

    new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)

This patch adds TypedArrayBufferIntrinsic. If the typed array has an
ArrayBuffer and ArrayBuffer::m_wrapper is live, IC, DFG (new node
GetTypedArrayBuffer), and FTL load the wrapper without a call. Otherwise
they call operationGetTypedArrayBuffer.

                                      Baseline                  Patched

typed-array-buffer-to-data-view  209.2541+-3.6939     ^    177.0420+-2.5226        ^ definitely 1.1819x faster
typed-array-buffer               174.2531+-2.5504     ^     45.6432+-0.6428        ^ definitely 3.8177x faster

Tests: JSTests/microbenchmarks/typed-array-buffer-to-data-view.js
       JSTests/microbenchmarks/typed-array-buffer.js
       JSTests/stress/typed-array-buffer-intrinsic.js

* JSTests/microbenchmarks/typed-array-buffer-to-data-view.js: Added.
(test):
* JSTests/microbenchmarks/typed-array-buffer.js: Added.
(test):
* JSTests/stress/typed-array-buffer-intrinsic.js: Added.
(shouldBe):
(shouldThrow):
(testViewOverBuffer.get for):
(testStorageAfterConversion.writeAround):
(testStorageAfterConversion.readAround):
(testStorageAfterConversion.namedPropertiesAround):
(testStorageAfterConversion):
(get testResizableAndShared.get const):
(get testResizableAndShared.get resizable):
(get testSubclassAndOtherRealm.Bytes):
(get testOtherReceivers.get const):
(get testLiveValuesAroundAccess.get const):
(get testLiveValuesAroundAccess):
(get testGetterCall.call):
(get testGetterCall):
(testUnusedResult.touch):
* Source/JavaScriptCore/b3/B3AbstractHeapRepository.cpp:
* Source/JavaScriptCore/b3/B3AbstractHeapRepository.h:
* Source/JavaScriptCore/bytecode/InlineCacheCompiler.cpp:
(JSC::InlineCacheCompiler::canEmitIntrinsicGetter):
(JSC::InlineCacheCompiler::emitIntrinsicGetter):
* Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp:
(JSC::IntrinsicGetterAccessCase::doesCalls const):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGCloneHelper.h:
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetTypedArrayBuffer):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetPrototypeOf):
(JSC::FTL::DFG::LowerDFGToB3::compileGetTypedArrayBuffer):
* Source/JavaScriptCore/jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::loadTypedArrayBufferWrapper):
* Source/JavaScriptCore/jit/AssemblyHelpers.h:
* Source/JavaScriptCore/jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/jit/JITOperations.h:
* Source/JavaScriptCore/runtime/ArrayBuffer.h:
* Source/JavaScriptCore/runtime/Intrinsic.h:
* Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp:
(JSC::JSTypedArrayViewPrototype::finishCreation):
* Source/JavaScriptCore/runtime/SimpleTypedArrayController.h:
* Source/JavaScriptCore/runtime/TypedArrayController.h:
(JSC::TypedArrayController::isWrapperCachedInArrayBuffer const):

26f72c1

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win
✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 win-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ⏳ 🧪 api-mac-debug ✅ 🧪 jsc-wpe
✅ 🧪 jsc-x86-64 loading 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk3-gcc
✅ 🛠 🧪 jsc-debug-arm64 ❌ 🛠 ios-safer-cpp loading 🧪 mac-AS-debug-wk2 ✅ 🛠 gtk
✅ 🛠 vision ✅ 🧪 gtk-wk2
✅ 🛠 vision-sim ⏳ 🧪 mac-intel-wk2 ✅ 🧪 api-gtk
✅ 🧪 vision-wk2 ❌ 🛠 mac-safer-cpp ✅ 🛠 playstation
✅ 🛠 tv ✅ 🧪 mac-site-isolation
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

…tter

https://bugs.webkit.org/show_bug.cgi?id=327976

Reviewed by NOBODY (OOPS!).

`typedArray.buffer` always called the C++ getter, even when the typed array
already has an ArrayBuffer and its JSArrayBuffer wrapper exists, as in

    new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)

This patch adds TypedArrayBufferIntrinsic. If the typed array has an
ArrayBuffer and ArrayBuffer::m_wrapper is live, IC, DFG (new node
GetTypedArrayBuffer), and FTL load the wrapper without a call. Otherwise
they call operationGetTypedArrayBuffer.

                                      Baseline                  Patched

typed-array-buffer-to-data-view  209.2541+-3.6939     ^    177.0420+-2.5226        ^ definitely 1.1819x faster
typed-array-buffer               174.2531+-2.5504     ^     45.6432+-0.6428        ^ definitely 3.8177x faster

Tests: JSTests/microbenchmarks/typed-array-buffer-to-data-view.js
       JSTests/microbenchmarks/typed-array-buffer.js
       JSTests/stress/typed-array-buffer-intrinsic.js

* JSTests/microbenchmarks/typed-array-buffer-to-data-view.js: Added.
(test):
* JSTests/microbenchmarks/typed-array-buffer.js: Added.
(test):
* JSTests/stress/typed-array-buffer-intrinsic.js: Added.
(shouldBe):
(shouldThrow):
(testViewOverBuffer.get for):
(testStorageAfterConversion.writeAround):
(testStorageAfterConversion.readAround):
(testStorageAfterConversion.namedPropertiesAround):
(testStorageAfterConversion):
(get testResizableAndShared.get const):
(get testResizableAndShared.get resizable):
(get testSubclassAndOtherRealm.Bytes):
(get testOtherReceivers.get const):
(get testLiveValuesAroundAccess.get const):
(get testLiveValuesAroundAccess):
(get testGetterCall.call):
(get testGetterCall):
(testUnusedResult.touch):
* Source/JavaScriptCore/b3/B3AbstractHeapRepository.cpp:
* Source/JavaScriptCore/b3/B3AbstractHeapRepository.h:
* Source/JavaScriptCore/bytecode/InlineCacheCompiler.cpp:
(JSC::InlineCacheCompiler::canEmitIntrinsicGetter):
(JSC::InlineCacheCompiler::emitIntrinsicGetter):
* Source/JavaScriptCore/bytecode/IntrinsicGetterAccessCase.cpp:
(JSC::IntrinsicGetterAccessCase::doesCalls const):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGCloneHelper.h:
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetTypedArrayBuffer):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileGetPrototypeOf):
(JSC::FTL::DFG::LowerDFGToB3::compileGetTypedArrayBuffer):
* Source/JavaScriptCore/jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::loadTypedArrayBufferWrapper):
* Source/JavaScriptCore/jit/AssemblyHelpers.h:
* Source/JavaScriptCore/jit/JITOperations.cpp:
(JSC::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/jit/JITOperations.h:
* Source/JavaScriptCore/runtime/ArrayBuffer.h:
* Source/JavaScriptCore/runtime/Intrinsic.h:
* Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp:
(JSC::JSTypedArrayViewPrototype::finishCreation):
* Source/JavaScriptCore/runtime/SimpleTypedArrayController.h:
* Source/JavaScriptCore/runtime/TypedArrayController.h:
(JSC::TypedArrayController::isWrapperCachedInArrayBuffer const):
@sosukesuzuki sosukesuzuki self-assigned this Oct 18, 2026
@sosukesuzuki sosukesuzuki added the JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. label Oct 18, 2026
@webkit-ews-buildbot

Copy link
Copy Markdown
Collaborator

iOS Safer C++ Build #60555 (26f72c1)

❌ Found 1 failing file with 1 issue. Please address these issues before landing. See WebKit Guidelines for Safer C++ Programming.
(cc @rniwa)

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Oct 18, 2026
@webkit-ews-buildbot

Copy link
Copy Markdown
Collaborator

macOS Safer C++ Build #140690 (26f72c1)

❌ Found 1 failing file with 1 issue. Please address these issues before landing. See WebKit Guidelines for Safer C++ Programming.
(cc @rniwa)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. merging-blocked Applied to prevent a change from being merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants