diff options
Diffstat (limited to 'js/src/jit/WarpCacheIRTranspiler.cpp')
-rw-r--r-- | js/src/jit/WarpCacheIRTranspiler.cpp | 506 |
1 files changed, 397 insertions, 109 deletions
diff --git a/js/src/jit/WarpCacheIRTranspiler.cpp b/js/src/jit/WarpCacheIRTranspiler.cpp index 7654232ecd..9a99e0f5c3 100644 --- a/js/src/jit/WarpCacheIRTranspiler.cpp +++ b/js/src/jit/WarpCacheIRTranspiler.cpp @@ -11,8 +11,6 @@ #include "jsmath.h" -#include "builtin/DataViewObject.h" -#include "builtin/MapObject.h" #include "jit/AtomicOp.h" #include "jit/CacheIR.h" #include "jit/CacheIRCompiler.h" @@ -26,7 +24,6 @@ #include "jit/WarpBuilderShared.h" #include "jit/WarpSnapshot.h" #include "js/ScalarType.h" // js::Scalar::Type -#include "vm/ArgumentsObject.h" #include "vm/BytecodeLocation.h" #include "wasm/WasmCode.h" @@ -52,7 +49,8 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared { // Array mapping call arguments to OperandId. using ArgumentKindArray = - mozilla::EnumeratedArray<ArgumentKind, ArgumentKind::NumKinds, OperandId>; + mozilla::EnumeratedArray<ArgumentKind, OperandId, + size_t(ArgumentKind::NumKinds)>; ArgumentKindArray argumentOperandIds_; void setArgumentId(ArgumentKind kind, OperandId id) { @@ -255,14 +253,20 @@ class MOZ_RAII WarpCacheIRTranspiler : public WarpBuilderShared { ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId, uint32_t newShapeOffset); - void addDataViewData(MDefinition* obj, Scalar::Type type, - MDefinition** offset, MInstruction** elements); + MInstruction* emitTypedArrayLength(ArrayBufferViewKind viewKind, + MDefinition* obj); - [[nodiscard]] bool emitAtomicsBinaryOp(ObjOperandId objId, - IntPtrOperandId indexId, - uint32_t valueId, - Scalar::Type elementType, - bool forEffect, AtomicOp op); + MInstruction* emitDataViewLength(ArrayBufferViewKind viewKind, + MDefinition* obj); + + void addDataViewData(ArrayBufferViewKind viewKind, MDefinition* obj, + Scalar::Type type, MDefinition** offset, + MInstruction** elements); + + [[nodiscard]] bool emitAtomicsBinaryOp( + ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, + Scalar::Type elementType, bool forEffect, ArrayBufferViewKind viewKind, + AtomicOp op); [[nodiscard]] bool emitLoadArgumentSlot(ValOperandId resultId, uint32_t slotIndex); @@ -347,9 +351,14 @@ bool WarpCacheIRTranspiler::transpile( // Effectful instructions should have a resume point. MIonToWasmCall is an // exception: we can attach the resume point to the MInt64ToBigInt instruction - // instead. + // instead. Other exceptions are MResizableTypedArrayLength and + // MResizableDataViewByteLength, and MGrowableSharedArrayBufferByteLength, + // which add the resume point to MPostIntPtrConversion. MOZ_ASSERT_IF(effectful_, - effectful_->resumePoint() || effectful_->isIonToWasmCall()); + effectful_->resumePoint() || effectful_->isIonToWasmCall() || + effectful_->isResizableTypedArrayLength() || + effectful_->isResizableDataViewByteLength() || + effectful_->isGrowableSharedArrayBufferByteLength()); return true; } @@ -385,31 +394,44 @@ bool WarpCacheIRTranspiler::emitGuardClass(ObjOperandId objId, return true; } +bool WarpCacheIRTranspiler::emitGuardEitherClass(ObjOperandId objId, + GuardClassKind kind1, + GuardClassKind kind2) { + MDefinition* def = getOperand(objId); + + // We don't yet need this case, so it's unsupported for now. + MOZ_ASSERT(kind1 != GuardClassKind::JSFunction && + kind2 != GuardClassKind::JSFunction); + + const JSClass* classp1 = classForGuardClassKind(kind1); + const JSClass* classp2 = classForGuardClassKind(kind2); + auto* ins = MGuardToEitherClass::New(alloc(), def, classp1, classp2); + + add(ins); + + setOperand(objId, ins); + return true; +} + const JSClass* WarpCacheIRTranspiler::classForGuardClassKind( GuardClassKind kind) { switch (kind) { case GuardClassKind::Array: - return &ArrayObject::class_; case GuardClassKind::PlainObject: - return &PlainObject::class_; case GuardClassKind::FixedLengthArrayBuffer: - return &FixedLengthArrayBufferObject::class_; + case GuardClassKind::ResizableArrayBuffer: case GuardClassKind::FixedLengthSharedArrayBuffer: - return &FixedLengthSharedArrayBufferObject::class_; + case GuardClassKind::GrowableSharedArrayBuffer: case GuardClassKind::FixedLengthDataView: - return &FixedLengthDataViewObject::class_; + case GuardClassKind::ResizableDataView: case GuardClassKind::MappedArguments: - return &MappedArgumentsObject::class_; case GuardClassKind::UnmappedArguments: - return &UnmappedArgumentsObject::class_; - case GuardClassKind::WindowProxy: - return mirGen().runtime->maybeWindowProxyClass(); case GuardClassKind::Set: - return &SetObject::class_; case GuardClassKind::Map: - return &MapObject::class_; case GuardClassKind::BoundFunction: - return &BoundFunctionObject::class_; + return ClassFor(kind); + case GuardClassKind::WindowProxy: + return mirGen().runtime->maybeWindowProxyClass(); case GuardClassKind::JSFunction: break; } @@ -830,6 +852,16 @@ bool WarpCacheIRTranspiler::emitGuardIsFixedLengthTypedArray( return true; } +bool WarpCacheIRTranspiler::emitGuardIsResizableTypedArray(ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* ins = MGuardIsResizableTypedArray::New(alloc(), obj); + add(ins); + + setOperand(objId, ins); + return true; +} + bool WarpCacheIRTranspiler::emitGuardHasProxyHandler(ObjOperandId objId, uint32_t handlerOffset) { MDefinition* obj = getOperand(objId); @@ -2121,13 +2153,35 @@ bool WarpCacheIRTranspiler::emitCallObjectHasSparseElementResult( return true; } +MInstruction* WarpCacheIRTranspiler::emitTypedArrayLength( + ArrayBufferViewKind viewKind, MDefinition* obj) { + if (viewKind == ArrayBufferViewKind::FixedLength) { + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); + + return length; + } + + // Bounds check doesn't require a memory barrier. See IsValidIntegerIndex + // abstract operation which reads the underlying buffer byte length using + // "unordered" memory order. + auto barrier = MemoryBarrierRequirement::NotRequired; + + // Movable and removable because no memory barrier is needed. + auto* length = MResizableTypedArrayLength::New(alloc(), obj, barrier); + length->setMovable(); + length->setNotGuard(); + add(length); + + return length; +} + bool WarpCacheIRTranspiler::emitLoadTypedArrayElementExistsResult( - ObjOperandId objId, IntPtrOperandId indexId) { + ObjOperandId objId, IntPtrOperandId indexId, ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* index = getOperand(indexId); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* length = emitTypedArrayLength(viewKind, obj); // Unsigned comparison to catch negative indices. auto* ins = MCompare::New(alloc(), index, length, JSOp::Lt, @@ -2165,27 +2219,29 @@ static MIRType MIRTypeForArrayBufferViewRead(Scalar::Type arrayType, bool WarpCacheIRTranspiler::emitLoadTypedArrayElementResult( ObjOperandId objId, IntPtrOperandId indexId, Scalar::Type elementType, - bool handleOOB, bool forceDoubleForUint32) { + bool handleOOB, bool forceDoubleForUint32, ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* index = getOperand(indexId); + auto* length = emitTypedArrayLength(viewKind, obj); + + if (!handleOOB) { + // MLoadTypedArrayElementHole does the bounds checking. + index = addBoundsCheck(index, length); + } + + auto* elements = MArrayBufferViewElements::New(alloc(), obj); + add(elements); + if (handleOOB) { auto* load = MLoadTypedArrayElementHole::New( - alloc(), obj, index, elementType, forceDoubleForUint32); + alloc(), elements, index, length, elementType, forceDoubleForUint32); add(load); pushResult(load); return true; } - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); - - index = addBoundsCheck(index, length); - - auto* elements = MArrayBufferViewElements::New(alloc(), obj); - add(elements); - auto* load = MLoadUnboxedScalar::New(alloc(), elements, index, elementType); load->setResultType( MIRTypeForArrayBufferViewRead(elementType, forceDoubleForUint32)); @@ -2717,17 +2773,14 @@ bool WarpCacheIRTranspiler::emitStoreDenseElementHole(ObjOperandId objId, return resumeAfter(store); } -bool WarpCacheIRTranspiler::emitStoreTypedArrayElement(ObjOperandId objId, - Scalar::Type elementType, - IntPtrOperandId indexId, - uint32_t rhsId, - bool handleOOB) { +bool WarpCacheIRTranspiler::emitStoreTypedArrayElement( + ObjOperandId objId, Scalar::Type elementType, IntPtrOperandId indexId, + uint32_t rhsId, bool handleOOB, ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* index = getOperand(indexId); MDefinition* rhs = getOperand(ValOperandId(rhsId)); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* length = emitTypedArrayLength(viewKind, obj); if (!handleOOB) { // MStoreTypedArrayElementHole does the bounds checking. @@ -2749,11 +2802,34 @@ bool WarpCacheIRTranspiler::emitStoreTypedArrayElement(ObjOperandId objId, return resumeAfter(store); } -void WarpCacheIRTranspiler::addDataViewData(MDefinition* obj, Scalar::Type type, +MInstruction* WarpCacheIRTranspiler::emitDataViewLength( + ArrayBufferViewKind viewKind, MDefinition* obj) { + if (viewKind == ArrayBufferViewKind::FixedLength) { + auto* length = MArrayBufferViewLength::New(alloc(), obj); + add(length); + + return length; + } + + // Bounds check doesn't require a memory barrier. See GetViewValue and + // SetViewValue abstract operations which read the underlying buffer byte + // length using "unordered" memory order. + auto barrier = MemoryBarrierRequirement::NotRequired; + + // Movable and removable because no memory barrier is needed. + auto* length = MResizableDataViewByteLength::New(alloc(), obj, barrier); + length->setMovable(); + length->setNotGuard(); + add(length); + + return length; +} + +void WarpCacheIRTranspiler::addDataViewData(ArrayBufferViewKind viewKind, + MDefinition* obj, Scalar::Type type, MDefinition** offset, MInstruction** elements) { - MInstruction* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* length = emitDataViewLength(viewKind, obj); // Adjust the length to account for accesses near the end of the dataview. if (size_t byteSize = Scalar::byteSize(type); byteSize > 1) { @@ -2773,14 +2849,14 @@ void WarpCacheIRTranspiler::addDataViewData(MDefinition* obj, Scalar::Type type, bool WarpCacheIRTranspiler::emitLoadDataViewValueResult( ObjOperandId objId, IntPtrOperandId offsetId, BooleanOperandId littleEndianId, Scalar::Type elementType, - bool forceDoubleForUint32) { + bool forceDoubleForUint32, ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* offset = getOperand(offsetId); MDefinition* littleEndian = getOperand(littleEndianId); // Add bounds check and get the DataViewObject's elements. MInstruction* elements; - addDataViewData(obj, elementType, &offset, &elements); + addDataViewData(viewKind, obj, elementType, &offset, &elements); // Load the element. MInstruction* load; @@ -2802,7 +2878,8 @@ bool WarpCacheIRTranspiler::emitLoadDataViewValueResult( bool WarpCacheIRTranspiler::emitStoreDataViewValueResult( ObjOperandId objId, IntPtrOperandId offsetId, uint32_t valueId, - BooleanOperandId littleEndianId, Scalar::Type elementType) { + BooleanOperandId littleEndianId, Scalar::Type elementType, + ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* offset = getOperand(offsetId); MDefinition* value = getOperand(ValOperandId(valueId)); @@ -2810,7 +2887,7 @@ bool WarpCacheIRTranspiler::emitStoreDataViewValueResult( // Add bounds check and get the DataViewObject's elements. MInstruction* elements; - addDataViewData(obj, elementType, &offset, &elements); + addDataViewData(viewKind, obj, elementType, &offset, &elements); // Store the element. MInstruction* store; @@ -4067,6 +4144,78 @@ bool WarpCacheIRTranspiler::emitArrayBufferViewByteOffsetDoubleResult( return true; } +bool WarpCacheIRTranspiler:: + emitResizableTypedArrayByteOffsetMaybeOutOfBoundsInt32Result( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* byteOffset = + MResizableTypedArrayByteOffsetMaybeOutOfBounds::New(alloc(), obj); + add(byteOffset); + + auto* byteOffsetInt32 = MNonNegativeIntPtrToInt32::New(alloc(), byteOffset); + add(byteOffsetInt32); + + pushResult(byteOffsetInt32); + return true; +} + +bool WarpCacheIRTranspiler:: + emitResizableTypedArrayByteOffsetMaybeOutOfBoundsDoubleResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* byteOffset = + MResizableTypedArrayByteOffsetMaybeOutOfBounds::New(alloc(), obj); + add(byteOffset); + + auto* byteOffsetDouble = MIntPtrToDouble::New(alloc(), byteOffset); + add(byteOffsetDouble); + + pushResult(byteOffsetDouble); + return true; +} + +bool WarpCacheIRTranspiler::emitResizableTypedArrayLengthInt32Result( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + // Explicit |length| accesses are seq-consistent atomic loads. + auto barrier = MemoryBarrierRequirement::Required; + + auto* length = MResizableTypedArrayLength::New(alloc(), obj, barrier); + addEffectful(length); + + auto* lengthInt32 = MNonNegativeIntPtrToInt32::New(alloc(), length); + add(lengthInt32); + + auto* postConversion = MPostIntPtrConversion::New(alloc(), lengthInt32); + add(postConversion); + + pushResult(postConversion); + return resumeAfterUnchecked(postConversion); +} + +bool WarpCacheIRTranspiler::emitResizableTypedArrayLengthDoubleResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + // Explicit |length| accesses are seq-consistent atomic loads. + auto barrier = MemoryBarrierRequirement::Required; + + auto* length = MResizableTypedArrayLength::New(alloc(), obj, barrier); + addEffectful(length); + + auto* lengthDouble = MIntPtrToDouble::New(alloc(), length); + add(lengthDouble); + + auto* postConversion = MPostIntPtrConversion::New(alloc(), lengthDouble); + add(postConversion); + + pushResult(postConversion); + return resumeAfterUnchecked(postConversion); +} + bool WarpCacheIRTranspiler::emitTypedArrayByteLengthInt32Result( ObjOperandId objId) { MDefinition* obj = getOperand(objId); @@ -4112,6 +4261,63 @@ bool WarpCacheIRTranspiler::emitTypedArrayByteLengthDoubleResult( return true; } +bool WarpCacheIRTranspiler::emitResizableTypedArrayByteLengthInt32Result( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + // Explicit |byteLength| accesses are seq-consistent atomic loads. + auto barrier = MemoryBarrierRequirement::Required; + + auto* length = MResizableTypedArrayLength::New(alloc(), obj, barrier); + addEffectful(length); + + auto* lengthInt32 = MNonNegativeIntPtrToInt32::New(alloc(), length); + add(lengthInt32); + + auto* size = MTypedArrayElementSize::New(alloc(), obj); + add(size); + + auto* mul = MMul::New(alloc(), lengthInt32, size, MIRType::Int32); + mul->setCanBeNegativeZero(false); + add(mul); + + auto* postConversion = MPostIntPtrConversion::New(alloc(), mul); + add(postConversion); + + pushResult(postConversion); + return resumeAfterUnchecked(postConversion); +} + +bool WarpCacheIRTranspiler::emitResizableTypedArrayByteLengthDoubleResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + // Explicit |byteLength| accesses are seq-consistent atomic loads. + auto barrier = MemoryBarrierRequirement::Required; + + auto* length = MResizableTypedArrayLength::New(alloc(), obj, barrier); + addEffectful(length); + + auto* lengthDouble = MIntPtrToDouble::New(alloc(), length); + add(lengthDouble); + + auto* size = MTypedArrayElementSize::New(alloc(), obj); + add(size); + + auto* sizeDouble = MToDouble::New(alloc(), size); + add(sizeDouble); + + auto* mul = MMul::New(alloc(), lengthDouble, sizeDouble, MIRType::Double); + mul->setCanBeNegativeZero(false); + add(mul); + + auto* postConversion = MPostIntPtrConversion::New(alloc(), mul); + add(postConversion); + + pushResult(postConversion); + return resumeAfterUnchecked(postConversion); +} + bool WarpCacheIRTranspiler::emitTypedArrayElementSizeResult( ObjOperandId objId) { MDefinition* obj = getOperand(objId); @@ -4123,6 +4329,80 @@ bool WarpCacheIRTranspiler::emitTypedArrayElementSizeResult( return true; } +bool WarpCacheIRTranspiler::emitResizableDataViewByteLengthInt32Result( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + // Explicit |byteLength| accesses are seq-consistent atomic loads. + auto barrier = MemoryBarrierRequirement::Required; + + auto* length = MResizableDataViewByteLength::New(alloc(), obj, barrier); + addEffectful(length); + + auto* lengthInt32 = MNonNegativeIntPtrToInt32::New(alloc(), length); + add(lengthInt32); + + auto* postConversion = MPostIntPtrConversion::New(alloc(), lengthInt32); + add(postConversion); + + pushResult(postConversion); + return resumeAfterUnchecked(postConversion); +} + +bool WarpCacheIRTranspiler::emitResizableDataViewByteLengthDoubleResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + // Explicit |byteLength| accesses are seq-consistent atomic loads. + auto barrier = MemoryBarrierRequirement::Required; + + auto* length = MResizableDataViewByteLength::New(alloc(), obj, barrier); + addEffectful(length); + + auto* lengthDouble = MIntPtrToDouble::New(alloc(), length); + add(lengthDouble); + + auto* postConversion = MPostIntPtrConversion::New(alloc(), lengthDouble); + add(postConversion); + + pushResult(postConversion); + return resumeAfterUnchecked(postConversion); +} + +bool WarpCacheIRTranspiler::emitGrowableSharedArrayBufferByteLengthInt32Result( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* length = MGrowableSharedArrayBufferByteLength::New(alloc(), obj); + addEffectful(length); + + auto* lengthInt32 = MNonNegativeIntPtrToInt32::New(alloc(), length); + add(lengthInt32); + + auto* postConversion = MPostIntPtrConversion::New(alloc(), lengthInt32); + add(postConversion); + + pushResult(postConversion); + return resumeAfterUnchecked(postConversion); +} + +bool WarpCacheIRTranspiler::emitGrowableSharedArrayBufferByteLengthDoubleResult( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* length = MGrowableSharedArrayBufferByteLength::New(alloc(), obj); + addEffectful(length); + + auto* lengthDouble = MIntPtrToDouble::New(alloc(), length); + add(lengthDouble); + + auto* postConversion = MPostIntPtrConversion::New(alloc(), lengthDouble); + add(postConversion); + + pushResult(postConversion); + return resumeAfterUnchecked(postConversion); +} + bool WarpCacheIRTranspiler::emitGuardHasAttachedArrayBuffer( ObjOperandId objId) { MDefinition* obj = getOperand(objId); @@ -4134,6 +4414,29 @@ bool WarpCacheIRTranspiler::emitGuardHasAttachedArrayBuffer( return true; } +bool WarpCacheIRTranspiler::emitGuardResizableArrayBufferViewInBounds( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* ins = MGuardResizableArrayBufferViewInBounds::New(alloc(), obj); + add(ins); + + setOperand(objId, ins); + return true; +} + +bool WarpCacheIRTranspiler::emitGuardResizableArrayBufferViewInBoundsOrDetached( + ObjOperandId objId) { + MDefinition* obj = getOperand(objId); + + auto* ins = + MGuardResizableArrayBufferViewInBoundsOrDetached::New(alloc(), obj); + add(ins); + + setOperand(objId, ins); + return true; +} + bool WarpCacheIRTranspiler::emitIsTypedArrayConstructorResult( ObjOperandId objId) { MDefinition* obj = getOperand(objId); @@ -4318,14 +4621,14 @@ bool WarpCacheIRTranspiler::emitNewTypedArrayFromArrayResult( bool WarpCacheIRTranspiler::emitAtomicsCompareExchangeResult( ObjOperandId objId, IntPtrOperandId indexId, uint32_t expectedId, - uint32_t replacementId, Scalar::Type elementType) { + uint32_t replacementId, Scalar::Type elementType, + ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* index = getOperand(indexId); MDefinition* expected = getOperand(ValOperandId(expectedId)); MDefinition* replacement = getOperand(ValOperandId(replacementId)); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* length = emitTypedArrayLength(viewKind, obj); index = addBoundsCheck(index, length); @@ -4347,13 +4650,12 @@ bool WarpCacheIRTranspiler::emitAtomicsCompareExchangeResult( bool WarpCacheIRTranspiler::emitAtomicsExchangeResult( ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, - Scalar::Type elementType) { + Scalar::Type elementType, ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* index = getOperand(indexId); MDefinition* value = getOperand(ValOperandId(valueId)); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* length = emitTypedArrayLength(viewKind, obj); index = addBoundsCheck(index, length); @@ -4373,17 +4675,15 @@ bool WarpCacheIRTranspiler::emitAtomicsExchangeResult( return resumeAfter(exchange); } -bool WarpCacheIRTranspiler::emitAtomicsBinaryOp(ObjOperandId objId, - IntPtrOperandId indexId, - uint32_t valueId, - Scalar::Type elementType, - bool forEffect, AtomicOp op) { +bool WarpCacheIRTranspiler::emitAtomicsBinaryOp( + ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, + Scalar::Type elementType, bool forEffect, ArrayBufferViewKind viewKind, + AtomicOp op) { MDefinition* obj = getOperand(objId); MDefinition* index = getOperand(indexId); MDefinition* value = getOperand(ValOperandId(valueId)); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* length = emitTypedArrayLength(viewKind, obj); index = addBoundsCheck(index, length); @@ -4409,59 +4709,48 @@ bool WarpCacheIRTranspiler::emitAtomicsBinaryOp(ObjOperandId objId, return resumeAfter(binop); } -bool WarpCacheIRTranspiler::emitAtomicsAddResult(ObjOperandId objId, - IntPtrOperandId indexId, - uint32_t valueId, - Scalar::Type elementType, - bool forEffect) { +bool WarpCacheIRTranspiler::emitAtomicsAddResult( + ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, + Scalar::Type elementType, bool forEffect, ArrayBufferViewKind viewKind) { return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, forEffect, - AtomicFetchAddOp); + viewKind, AtomicOp::Add); } -bool WarpCacheIRTranspiler::emitAtomicsSubResult(ObjOperandId objId, - IntPtrOperandId indexId, - uint32_t valueId, - Scalar::Type elementType, - bool forEffect) { +bool WarpCacheIRTranspiler::emitAtomicsSubResult( + ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, + Scalar::Type elementType, bool forEffect, ArrayBufferViewKind viewKind) { return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, forEffect, - AtomicFetchSubOp); + viewKind, AtomicOp::Sub); } -bool WarpCacheIRTranspiler::emitAtomicsAndResult(ObjOperandId objId, - IntPtrOperandId indexId, - uint32_t valueId, - Scalar::Type elementType, - bool forEffect) { +bool WarpCacheIRTranspiler::emitAtomicsAndResult( + ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, + Scalar::Type elementType, bool forEffect, ArrayBufferViewKind viewKind) { return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, forEffect, - AtomicFetchAndOp); + viewKind, AtomicOp::And); } -bool WarpCacheIRTranspiler::emitAtomicsOrResult(ObjOperandId objId, - IntPtrOperandId indexId, - uint32_t valueId, - Scalar::Type elementType, - bool forEffect) { +bool WarpCacheIRTranspiler::emitAtomicsOrResult( + ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, + Scalar::Type elementType, bool forEffect, ArrayBufferViewKind viewKind) { return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, forEffect, - AtomicFetchOrOp); + viewKind, AtomicOp::Or); } -bool WarpCacheIRTranspiler::emitAtomicsXorResult(ObjOperandId objId, - IntPtrOperandId indexId, - uint32_t valueId, - Scalar::Type elementType, - bool forEffect) { +bool WarpCacheIRTranspiler::emitAtomicsXorResult( + ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, + Scalar::Type elementType, bool forEffect, ArrayBufferViewKind viewKind) { return emitAtomicsBinaryOp(objId, indexId, valueId, elementType, forEffect, - AtomicFetchXorOp); + viewKind, AtomicOp::Xor); } -bool WarpCacheIRTranspiler::emitAtomicsLoadResult(ObjOperandId objId, - IntPtrOperandId indexId, - Scalar::Type elementType) { +bool WarpCacheIRTranspiler::emitAtomicsLoadResult( + ObjOperandId objId, IntPtrOperandId indexId, Scalar::Type elementType, + ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* index = getOperand(indexId); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* length = emitTypedArrayLength(viewKind, obj); index = addBoundsCheck(index, length); @@ -4473,7 +4762,7 @@ bool WarpCacheIRTranspiler::emitAtomicsLoadResult(ObjOperandId objId, MIRTypeForArrayBufferViewRead(elementType, forceDoubleForUint32); auto* load = MLoadUnboxedScalar::New(alloc(), elements, index, elementType, - DoesRequireMemoryBarrier); + MemoryBarrierRequirement::Required); load->setResultType(knownType); addEffectful(load); @@ -4481,24 +4770,23 @@ bool WarpCacheIRTranspiler::emitAtomicsLoadResult(ObjOperandId objId, return resumeAfter(load); } -bool WarpCacheIRTranspiler::emitAtomicsStoreResult(ObjOperandId objId, - IntPtrOperandId indexId, - uint32_t valueId, - Scalar::Type elementType) { +bool WarpCacheIRTranspiler::emitAtomicsStoreResult( + ObjOperandId objId, IntPtrOperandId indexId, uint32_t valueId, + Scalar::Type elementType, ArrayBufferViewKind viewKind) { MDefinition* obj = getOperand(objId); MDefinition* index = getOperand(indexId); MDefinition* value = getOperand(ValOperandId(valueId)); - auto* length = MArrayBufferViewLength::New(alloc(), obj); - add(length); + auto* length = emitTypedArrayLength(viewKind, obj); index = addBoundsCheck(index, length); auto* elements = MArrayBufferViewElements::New(alloc(), obj); add(elements); - auto* store = MStoreUnboxedScalar::New(alloc(), elements, index, value, - elementType, DoesRequireMemoryBarrier); + auto* store = + MStoreUnboxedScalar::New(alloc(), elements, index, value, elementType, + MemoryBarrierRequirement::Required); addEffectful(store); pushResult(value); |