Skip to content
Permalink
Browse files
[JSC] Implement growable SharedArrayBuffer part 1
https://bugs.webkit.org/show_bug.cgi?id=247541
rdar://102006760

Reviewed by Mark Lam.

This patch adds first patch for growable SharedArrayBuffer. This patch does
not add TypedArray's length tracking (when backing ArrayBuffer is resized,
then TypedArray's length needs to be changed too).

1. We extract Wasm::MemoryHandle to runtime to use it for non wasm. This offers
   growable memory infrastructure since it was used for growable shared Wasm::Memory.
   This also requires moving MemoryMode, MemorySharingMode, and PageCount from wasm to runtime.
2. We add resizable TypedArrayTypes, and currently DFG does OSR exit when we encounter it.
   We also change it from uint32_t to uint8_t to make room in TypedArray to have more information.
3. This patch adds growable SharedArrayBuffer's methods.
4. We add OSAllocator::protect to make (1) work on Windows too.

* JSTests/test262/config.yaml:
* JSTests/test262/expectations.yaml:
* JSTests/wasm/stress/shared-wasm-memory-buffer.js:
* Source/JavaScriptCore/CMakeLists.txt:
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/Sources.txt:
* Source/JavaScriptCore/bytecode/AccessCase.cpp:
(JSC::AccessCase::generateWithGuard):
* Source/JavaScriptCore/bytecode/ExitKind.cpp:
(JSC::exitKindToString):
* Source/JavaScriptCore/bytecode/ExitKind.h:
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::newTypedArrayWithSize):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::jumpForTypedArrayOutOfBounds):
(JSC::DFG::SpeculativeJIT::jumpForTypedArrayIsDetachedIfOutOfBounds):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileGetTypedArrayLengthAsInt52):
(JSC::DFG::SpeculativeJIT::compileGetTypedArrayByteOffsetAsInt52):
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h:
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::emitGetTypedArrayByteOffsetExceptSettingResult):
(JSC::FTL::DFG::LowerDFGToB3::compileGetArrayLength):
(JSC::FTL::DFG::LowerDFGToB3::compileGetTypedArrayLengthAsInt52):
(JSC::FTL::DFG::LowerDFGToB3::emitNewTypedArrayWithSize):
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
* Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp:
(JSC::StructureMemoryManager::commitBlock):
(JSC::StructureMemoryManager::decommitBlock):
* Source/JavaScriptCore/jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::branchIfFastTypedArray):
(JSC::AssemblyHelpers::branchIfNotFastTypedArray):
* Source/JavaScriptCore/jit/IntrinsicEmitter.cpp:
(JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter):
* Source/JavaScriptCore/jsc.cpp:
(JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/llint/LowLevelInterpreter.asm:
* Source/JavaScriptCore/llint/WebAssembly.asm:
* Source/JavaScriptCore/runtime/ArrayBuffer.cpp:
(JSC::ArrayBufferContents::tryAllocate):
(JSC::ArrayBufferContents::makeShared):
(JSC::ArrayBufferContents::copyTo):
(JSC::ArrayBufferContents::shareWith):
(JSC::ArrayBuffer::createFromBytes):
(JSC::ArrayBuffer::createShared):
(JSC::ArrayBuffer::tryCreate):
(JSC::ArrayBuffer::grow):
(JSC::tryAllocate):
(JSC::ArrayBuffer::tryCreateShared):
(JSC::SharedArrayBufferContents::grow):
* Source/JavaScriptCore/runtime/ArrayBuffer.h:
(JSC::ArrayBuffer::byteLength const):
(JSC::ArrayBuffer::maxByteLength const):
(JSC::IdempotentArrayBufferByteLengthGetter::IdempotentArrayBufferByteLengthGetter):
(JSC::IdempotentArrayBufferByteLengthGetter::operator()):
* Source/JavaScriptCore/runtime/BufferMemoryHandle.cpp: Added.
(JSC::BufferMemoryHandle::fastMappedRedzoneBytes):
(JSC::BufferMemoryHandle::fastMappedBytes):
(JSC::BufferMemoryResult::toString):
(JSC::BufferMemoryResult::dump const):
(JSC::BufferMemoryManager::tryAllocateFastMemory):
(JSC::BufferMemoryManager::freeFastMemory):
(JSC::BufferMemoryManager::tryAllocateGrowableBoundsCheckingMemory):
(JSC::BufferMemoryManager::freeGrowableBoundsCheckingMemory):
(JSC::BufferMemoryManager::isInGrowableOrFastMemory):
(JSC::BufferMemoryManager::tryAllocatePhysicalBytes):
(JSC::BufferMemoryManager::freePhysicalBytes):
(JSC::BufferMemoryManager::dump const):
(JSC::BufferMemoryManager::singleton):
(JSC::BufferMemoryHandle::BufferMemoryHandle):
(JSC::BufferMemoryHandle::~BufferMemoryHandle):
(JSC::BufferMemoryHandle::memory const):
* Source/JavaScriptCore/runtime/BufferMemoryHandle.h: Added.
(JSC::BufferMemoryResult::BufferMemoryResult):
(JSC::BufferMemoryManager::memoryLimit const):
* Source/JavaScriptCore/runtime/CommonIdentifiers.h:
* Source/JavaScriptCore/runtime/JSArrayBufferConstructor.cpp:
(JSC::JSGenericArrayBufferConstructor<sharingMode>::constructImpl):
* Source/JavaScriptCore/runtime/JSArrayBufferPrototype.cpp:
(JSC::arrayBufferSlice):
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::JSArrayBufferPrototype::finishCreation):
* Source/JavaScriptCore/runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::ConstructionContext::ConstructionContext):
(JSC::JSArrayBufferView::JSArrayBufferView):
(JSC::JSArrayBufferView::finishCreation):
(JSC::JSArrayBufferView::detach):
(JSC::JSArrayBufferView::slowDownAndWasteMemory):
(JSC::isIntegerIndexedObjectOutOfBounds):
(JSC::integerIndexedObjectLength):
(JSC::integerIndexedObjectByteLength):
(WTF::printInternal):
* Source/JavaScriptCore/runtime/JSArrayBufferView.h:
(JSC::hasArrayBuffer):
(JSC::isResizable):
(JSC::JSArrayBufferView::ConstructionContext::vector const):
(JSC::JSArrayBufferView::ConstructionContext::maxByteLength const):
(JSC::JSArrayBufferView::ConstructionContext::maxByteLengthUnsafe const):
(JSC::JSArrayBufferView::vector const):
(JSC::JSArrayBufferView::maxByteLength const):
(JSC::JSArrayBufferView::offsetOfMaxByteLength):
* Source/JavaScriptCore/runtime/JSArrayBufferViewInlines.h:
(JSC::JSArrayBufferView::isShared):
(JSC::JSArrayBufferView::possiblySharedBufferImpl):
(JSC::JSArrayBufferView::existingBufferInButterfly):
* Source/JavaScriptCore/runtime/JSCJSValue.h:
* Source/JavaScriptCore/runtime/JSCJSValueInlines.h:
(JSC::JSValue::toTypedArrayIndex const):
* Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h:
* Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewWithArguments):
(JSC::constructGenericTypedArrayViewImpl):
* Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::deletePropertyByIndex):
(JSC::JSGenericTypedArrayView<Adaptor>::visitChildrenImpl):
* Source/JavaScriptCore/runtime/MemoryMode.cpp: Renamed from Source/JavaScriptCore/wasm/WasmMemoryMode.cpp.
(WTF::printInternal):
* Source/JavaScriptCore/runtime/MemoryMode.h: Renamed from Source/JavaScriptCore/wasm/WasmMemoryMode.h.
* Source/JavaScriptCore/runtime/OptionsList.h:
* Source/JavaScriptCore/runtime/PageCount.cpp: Renamed from Source/JavaScriptCore/wasm/WasmPageCount.cpp.
(JSC::PageCount::dump const):
* Source/JavaScriptCore/runtime/PageCount.h: Renamed from Source/JavaScriptCore/wasm/WasmPageCount.h.
(JSC::PageCount::PageCount):
(JSC::PageCount::bytes const):
(JSC::PageCount::pageCount const):
(JSC::PageCount::isValid):
(JSC::PageCount::isValid const):
(JSC::PageCount::fromBytes):
(JSC::PageCount::fromBytesWithRoundUp):
(JSC::PageCount::max):
(JSC::PageCount::operator bool const):
(JSC::PageCount::operator< const):
(JSC::PageCount::operator> const):
(JSC::PageCount::operator>= const):
(JSC::PageCount::operator== const):
(JSC::PageCount::operator!= const):
(JSC::PageCount::operator+ const):
* Source/JavaScriptCore/runtime/StructureInlines.h:
(JSC::Structure::hasIndexingHeader const):
* Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::addCurrentMemory):
* Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::addCurrentMemory):
* Source/JavaScriptCore/wasm/WasmCallee.h:
* Source/JavaScriptCore/wasm/WasmCalleeGroup.cpp:
(JSC::Wasm::CalleeGroup::isSafeToRun):
* Source/JavaScriptCore/wasm/WasmCalleeGroup.h:
* Source/JavaScriptCore/wasm/WasmFormat.h:
* Source/JavaScriptCore/wasm/WasmMemory.cpp:
(JSC::Wasm::Memory::Memory):
(JSC::Wasm::Memory::create):
(JSC::Wasm::Memory::createZeroSized):
(JSC::Wasm::Memory::tryCreate):
(JSC::Wasm::Memory::addressIsInGrowableOrFastMemory):
(JSC::Wasm::Memory::growShared):
(JSC::Wasm::Memory::grow):
(JSC::Wasm::Memory::dump const):
(JSC::Wasm::MemoryHandle::MemoryHandle): Deleted.
(JSC::Wasm::MemoryHandle::~MemoryHandle): Deleted.
(JSC::Wasm::MemoryHandle::memory const): Deleted.
(JSC::Wasm::Memory::fastMappedRedzoneBytes): Deleted.
(JSC::Wasm::Memory::fastMappedBytes): Deleted.
* Source/JavaScriptCore/wasm/WasmMemory.h:
(JSC::Wasm::Memory::maxFastMemoryCount): Deleted.
* Source/JavaScriptCore/wasm/WasmMemoryInformation.h:
* Source/JavaScriptCore/wasm/WasmModule.cpp:
(JSC::Wasm::Module::copyInitialCalleeGroupToAllMemoryModes):
* Source/JavaScriptCore/wasm/WasmModule.h:
* Source/JavaScriptCore/wasm/WasmOperations.cpp:
(JSC::Wasm::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::tryCreate):
* Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h:
* Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::buffer):
(JSC::JSWebAssemblyMemory::grow):
(JSC::JSWebAssemblyMemory::type):
(JSC::JSWebAssemblyMemory::growSuccessCallback):
* Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h:
* Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h:
* Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::calleeSaves const):
(JSC::WebAssemblyFunction::jsCallEntrypointSlow):
* Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::initializeImports):
* Source/WTF/wtf/OSAllocator.h:
* Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp:
(WTF::OSAllocator::protect):
* Source/WTF/wtf/win/OSAllocatorWin.cpp:
(WTF::OSAllocator::protect):
* Source/WebCore/bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneSerializer::dumpIfTerminal):
(WebCore::CloneDeserializer::readTerminal):
* Source/WebCore/bindings/js/SerializedScriptValue.h:

Canonical link: https://commits.webkit.org/256524@main
  • Loading branch information
Constellation committed Nov 10, 2022
1 parent 7c870a9 commit 7a292520f6b12e8d4d9001d1480474b5c83cb0f8
Show file tree
Hide file tree
Showing 67 changed files with 1,997 additions and 741 deletions.
@@ -13,13 +13,13 @@ flags:
ShadowRealm: useShadowRealm
import-assertions: useImportAssertion
json-modules: useImportAssertion
resizable-arraybuffer: useResizableArrayBuffer
skip:
features:
- Atomics.waitAsync
# https://bugs.webkit.org/show_bug.cgi?id=174931
- regexp-lookbehind
- regexp-v-flag
- resizable-arraybuffer
- callable-boundary-realms
- FinalizationRegistry.prototype.cleanupSome
- decorators

Large diffs are not rendered by default.

@@ -956,6 +956,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
runtime/BooleanObject.h
runtime/BooleanPrototype.h
runtime/BrandedStructure.h
runtime/BufferMemoryHandle.h
runtime/Butterfly.h
runtime/ButterflyInlines.h
runtime/BytecodeCacheError.h
@@ -1136,6 +1137,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
runtime/Lookup.h
runtime/MatchResult.h
runtime/MathCommon.h
runtime/MemoryMode.h
runtime/MemoryStatistics.h
runtime/Microtask.h
runtime/ModuleProgramExecutable.h
@@ -1152,6 +1154,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
runtime/Operations.h
runtime/Options.h
runtime/OptionsList.h
runtime/PageCount.h
runtime/ParseInt.h
runtime/PrivateFieldPutKind.h
runtime/PrivateName.h
@@ -1268,13 +1271,11 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
wasm/WasmLLIntTierUpCounter.h
wasm/WasmMemory.h
wasm/WasmMemoryInformation.h
wasm/WasmMemoryMode.h
wasm/WasmModule.h
wasm/WasmModuleInformation.h
wasm/WasmName.h
wasm/WasmNameSection.h
wasm/WasmOSREntryData.h
wasm/WasmPageCount.h
wasm/WasmSIMDOpcodes.h
wasm/WasmSections.h
wasm/WasmTypeDefinition.h

Large diffs are not rendered by default.

@@ -762,6 +762,7 @@ runtime/BooleanConstructor.cpp
runtime/BooleanObject.cpp
runtime/BooleanPrototype.cpp
runtime/BrandedStructure.cpp
runtime/BufferMemoryHandle.cpp
runtime/BytecodeCacheError.cpp
runtime/CallData.cpp
runtime/CachePayload.cpp
@@ -964,6 +965,7 @@ runtime/MapPrototype.cpp
runtime/MatchResult.cpp
runtime/MathCommon.cpp
runtime/MathObject.cpp
runtime/MemoryMode.cpp
runtime/MemoryStatistics.cpp
runtime/ModuleProgramExecutable.cpp
runtime/NarrowingNumberPredictionFuzzerAgent.cpp
@@ -981,6 +983,7 @@ runtime/ObjectInitializationScope.cpp
runtime/ObjectPrototype.cpp
runtime/Operations.cpp
runtime/Options.cpp
runtime/PageCount.cpp
runtime/PredictionFileCreatingFuzzerAgent.cpp
runtime/PrivateFieldPutKind.cpp
runtime/ProgramExecutable.cpp
@@ -1124,15 +1127,13 @@ wasm/WasmLLIntTierUpCounter.cpp
wasm/WasmMachineThreads.cpp
wasm/WasmMemory.cpp
wasm/WasmMemoryInformation.cpp
wasm/WasmMemoryMode.cpp
wasm/WasmModule.cpp
wasm/WasmModuleInformation.cpp
wasm/WasmNameSectionParser.cpp
wasm/WasmOMGPlan.cpp
wasm/WasmOSREntryPlan.cpp
wasm/WasmOpcodeOrigin.cpp
wasm/WasmOperations.cpp
wasm/WasmPageCount.cpp
wasm/WasmPlan.cpp
wasm/WasmSectionParser.cpp
wasm/WasmTypeDefinition.cpp
@@ -1237,9 +1237,9 @@ void AccessCase::generateWithGuard(
jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);

#if USE(LARGE_TYPED_ARRAYS)
jit.load64(addressOfLength, scratchGPR);
jit.load64(CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMaxByteLength()), scratchGPR);
#else
jit.load32(addressOfLength, scratchGPR);
jit.load32(CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMaxByteLength()), scratchGPR);
#endif
jit.loadPtr(CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfVector()), scratch2GPR);
jit.cageConditionallyAndUntag(Gigacage::Primitive, scratch2GPR, scratchGPR, scratchGPR, false);
@@ -1661,9 +1661,9 @@ void AccessCase::generateWithGuard(
jit, ScratchRegisterAllocator::ExtraStackSpace::NoExtraSpace);

#if USE(LARGE_TYPED_ARRAYS)
jit.load64(addressOfLength, scratchGPR);
jit.load64(CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMaxByteLength()), scratchGPR);
#else
jit.load32(addressOfLength, scratchGPR);
jit.load32(CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMaxByteLength()), scratchGPR);
#endif
jit.loadPtr(CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfVector()), scratch2GPR);
jit.cageConditionallyAndUntag(Gigacage::Primitive, scratch2GPR, scratchGPR, scratchGPR, false);
@@ -93,6 +93,8 @@ ASCIILiteral exitKindToString(ExitKind kind)
return "GenericUnwind"_s;
case BigInt32Overflow:
return "BigInt32Overflow"_s;
case UnexpectedResizableArrayBufferView:
return "UnexpectedResizableArrayBufferView"_s;
}
RELEASE_ASSERT_NOT_REACHED();
return "Unknown"_s;
@@ -59,6 +59,7 @@ enum ExitKind : uint8_t {
ExceptionCheck, // We exited because a direct exception check showed that we threw an exception from a C call.
GenericUnwind, // We exited because we arrived at this OSR exit from genericUnwind.
BigInt32Overflow, // We exited because of an BigInt32 overflow.
UnexpectedResizableArrayBufferView, // We exited because we made an incorrect assumption about what type of ArrayBufferView we would see.
};

ASCIILiteral exitKindToString(ExitKind);
@@ -195,7 +195,7 @@ char* newTypedArrayWithSize(JSGlobalObject* globalObject, VM& vm, Structure* str
size_t unsignedSize = static_cast<size_t>(size);

if (vector)
return bitwise_cast<char*>(ViewClass::createWithFastVector(globalObject, structure, unsignedSize, untagArrayPtr(vector, unsignedSize)));
return bitwise_cast<char*>(ViewClass::createWithFastVector(globalObject, structure, unsignedSize, untagArrayPtr(vector, unsignedSize * ViewClass::elementSize)));

RELEASE_AND_RETURN(scope, bitwise_cast<char*>(ViewClass::create(globalObject, structure, unsignedSize)));
}
@@ -3608,6 +3608,8 @@ JITCompiler::Jump SpeculativeJIT::jumpForTypedArrayOutOfBounds(Node* node, GPRRe
#endif
}

// FIXME: We should record UnexpectedResizableArrayBufferView in ArrayProfile, propagate it to DFG::ArrayMode, and accept it here.
speculationCheck(UnexpectedResizableArrayBufferView, JSValueSource::unboxedCell(baseGPR), node, m_jit.branch8(MacroAssembler::Equal, CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMode()), TrustedImm32(ResizableWastefulTypedArray)));
#if USE(LARGE_TYPED_ARRAYS)
m_jit.signExtend32ToPtr(indexGPR, scratchGPR);
return m_jit.branch64(
@@ -3638,10 +3640,12 @@ JITCompiler::Jump SpeculativeJIT::jumpForTypedArrayIsDetachedIfOutOfBounds(Node*
else {
outOfBounds.link(&m_jit);

JITCompiler::Jump notWasteful = m_jit.branch32(
MacroAssembler::NotEqual,
JITCompiler::Jump notWasteful = m_jit.branch8(
MacroAssembler::Below,
MacroAssembler::Address(base, JSArrayBufferView::offsetOfMode()),
TrustedImm32(WastefulTypedArray));
// FIXME: We should record UnexpectedResizableArrayBufferView in ArrayProfile, propagate it to DFG::ArrayMode, and accept it here.
speculationCheck(UnexpectedResizableArrayBufferView, JSValueSource::unboxedCell(base), node, m_jit.branch8(CCallHelpers::Equal, CCallHelpers::Address(base, JSArrayBufferView::offsetOfMode()), TrustedImm32(ResizableWastefulTypedArray)));

JITCompiler::Jump hasNullVector;
#if CPU(ARM64E)
@@ -8403,7 +8407,7 @@ void SpeculativeJIT::cageTypedArrayStorage(GPRReg baseReg, GPRReg storageReg, bo
{
auto untagArrayPtr = [&]() {
#if CPU(ARM64E)
m_jit.untagArrayPtrLength64(MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfLength()), storageReg, validateAuth);
m_jit.untagArrayPtrLength64(MacroAssembler::Address(baseReg, JSArrayBufferView::offsetOfMaxByteLength()), storageReg, validateAuth);
#else
UNUSED_PARAM(validateAuth);
UNUSED_PARAM(baseReg);
@@ -8483,10 +8487,12 @@ void SpeculativeJIT::compileGetTypedArrayByteOffset(Node* node)

GPRReg arrayBufferGPR = dataGPR;

JITCompiler::Jump emptyByteOffset = m_jit.branch32(
MacroAssembler::NotEqual,
JITCompiler::Jump emptyByteOffset = m_jit.branch8(
MacroAssembler::Below,
MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfMode()),
TrustedImm32(WastefulTypedArray));
// FIXME: We should record UnexpectedResizableArrayBufferView in ArrayProfile, propagate it to DFG::ArrayMode, and accept it here.
speculationCheck(UnexpectedResizableArrayBufferView, JSValueSource::unboxedCell(baseGPR), node, m_jit.branch8(MacroAssembler::Equal, CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMode()), TrustedImm32(ResizableWastefulTypedArray)));

m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfVector()), vectorGPR);

@@ -8791,6 +8797,8 @@ void SpeculativeJIT::compileGetArrayLength(Node* node)
GPRTemporary result(this);
GPRReg baseGPR = base.gpr();
GPRReg resultGPR = result.gpr();
// FIXME: We should record UnexpectedResizableArrayBufferView in ArrayProfile, propagate it to DFG::ArrayMode, and accept it here.
speculationCheck(UnexpectedResizableArrayBufferView, JSValueSource::unboxedCell(baseGPR), node, m_jit.branch8(MacroAssembler::Equal, CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMode()), TrustedImm32(ResizableWastefulTypedArray)));
#if USE(LARGE_TYPED_ARRAYS)
m_jit.load64(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfLength()), resultGPR);
speculationCheck(Overflow, JSValueSource(), nullptr, m_jit.branch64(MacroAssembler::Above, resultGPR, TrustedImm64(std::numeric_limits<int32_t>::max())));
@@ -11658,6 +11666,7 @@ void SpeculativeJIT::emitNewTypedArrayWithSizeInRegister(Node* node, TypedArrayT
#if CPU(ARM64E)
// sizeGPR is still boxed as a number and there is no 32-bit variant of the PAC instructions.
m_jit.zeroExtend32ToWord(sizeGPR, scratchGPR);
m_jit.lshift64(TrustedImm32(logElementSize(typedArrayType)), scratchGPR);
m_jit.tagArrayPtr(scratchGPR, storageGPR);
#endif

@@ -11684,12 +11693,18 @@ void SpeculativeJIT::emitNewTypedArrayWithSizeInRegister(Node* node, TypedArrayT
m_jit.store64(
sizeGPR,
MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfLength()));
m_jit.zeroExtend32ToWord(sizeGPR, scratchGPR);
m_jit.lshift64(TrustedImm32(logElementSize(typedArrayType)), scratchGPR);
m_jit.store64(scratchGPR, MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfMaxByteLength()));
#else
m_jit.store32(
sizeGPR,
MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfLength()));
m_jit.move(sizeGPR, scratchGPR);
m_jit.lshift32(TrustedImm32(logElementSize(typedArrayType)), scratchGPR);
m_jit.store32(scratchGPR, MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfMaxByteLength()));
#endif
m_jit.store32(
m_jit.store8(
TrustedImm32(FastTypedArray),
MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfMode()));

@@ -2944,6 +2944,8 @@ void SpeculativeJIT::compileGetTypedArrayLengthAsInt52(Node* node)
GPRTemporary result(this, Reuse, base);
GPRReg baseGPR = base.gpr();
GPRReg resultGPR = result.gpr();
// FIXME: We should record UnexpectedResizableArrayBufferView in ArrayProfile, propagate it to DFG::ArrayMode, and accept it here.
speculationCheck(UnexpectedResizableArrayBufferView, JSValueSource::unboxedCell(baseGPR), node, m_jit.branch8(MacroAssembler::Equal, CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMode()), TrustedImm32(ResizableWastefulTypedArray)));
m_jit.load64(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfLength()), resultGPR);
static_assert(MAX_ARRAY_BUFFER_SIZE < (1ull << 52), "there is a risk that the size of a typed array won't fit in an Int52");
strictInt52Result(resultGPR, node);
@@ -2961,10 +2963,11 @@ void SpeculativeJIT::compileGetTypedArrayByteOffsetAsInt52(Node* node)

GPRReg arrayBufferGPR = dataGPR;

JITCompiler::Jump emptyByteOffset = m_jit.branch32(
MacroAssembler::NotEqual,
JITCompiler::Jump emptyByteOffset = m_jit.branch8(
MacroAssembler::Below,
MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfMode()),
TrustedImm32(WastefulTypedArray));
speculationCheck(UnexpectedResizableArrayBufferView, JSValueSource::unboxedCell(baseGPR), node, m_jit.branch8(MacroAssembler::Equal, CCallHelpers::Address(baseGPR, JSArrayBufferView::offsetOfMode()), TrustedImm32(ResizableWastefulTypedArray)));

m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfVector()), vectorGPR);

@@ -5650,6 +5653,9 @@ void SpeculativeJIT::compile(Node* node)
isLittleEndianOperand.emplace(this, node->child3());
GPRReg isLittleEndianGPR = isLittleEndianOperand ? isLittleEndianOperand->gpr() : InvalidGPRReg;

// FIXME: We should record UnexpectedResizableArrayBufferView in ArrayProfile, propagate it to DFG::ArrayMode, and accept it here.
speculationCheck(UnexpectedResizableArrayBufferView, JSValueSource::unboxedCell(dataViewGPR), node, m_jit.branch8(MacroAssembler::Equal, CCallHelpers::Address(dataViewGPR, JSArrayBufferView::offsetOfMode()), TrustedImm32(ResizableDataViewMode)));

DataViewData data = node->dataViewData();

m_jit.zeroExtend32ToWord(indexGPR, t2);
@@ -5860,6 +5866,9 @@ void SpeculativeJIT::compile(Node* node)
isLittleEndianOperand.emplace(this, m_graph.varArgChild(node, 3));
GPRReg isLittleEndianGPR = isLittleEndianOperand ? isLittleEndianOperand->gpr() : InvalidGPRReg;

// FIXME: We should record UnexpectedResizableArrayBufferView in ArrayProfile, propagate it to DFG::ArrayMode, and accept it here.
speculationCheck(UnexpectedResizableArrayBufferView, JSValueSource::unboxedCell(dataViewGPR), node, m_jit.branch8(MacroAssembler::Equal, CCallHelpers::Address(dataViewGPR, JSArrayBufferView::offsetOfMode()), TrustedImm32(ResizableDataViewMode)));

m_jit.zeroExtend32ToWord(indexGPR, t2);
if (data.byteSize > 1)
m_jit.add64(TrustedImm32(data.byteSize - 1), t2);
@@ -88,6 +88,7 @@ namespace JSC { namespace FTL {
macro(GetterSetter_getter, GetterSetter::offsetOfGetter()) \
macro(GetterSetter_setter, GetterSetter::offsetOfSetter()) \
macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \
macro(JSArrayBufferView_maxByteLength, JSArrayBufferView::offsetOfMaxByteLength()) \
macro(JSArrayBufferView_mode, JSArrayBufferView::offsetOfMode()) \
macro(JSArrayBufferView_vector, JSArrayBufferView::offsetOfVector()) \
macro(JSBigInt_length, JSBigInt::offsetOfLength()) \

0 comments on commit 7a29252

Please sign in to comment.