Commit 65060353 authored by peterwmwong's avatar peterwmwong Committed by Commit Bot

[typedarray] Port AttachBuffer to Torque.

Change-Id: I96935cd8e16715ce729a9830c00357c740696b3b
Reviewed-on: https://chromium-review.googlesource.com/c/1470445
Commit-Queue: Peter Wong <peter.wm.wong@gmail.com>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarSimon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59808}
parent b3d8eeb6
...@@ -172,10 +172,17 @@ extern class JSBoundFunction extends JSObject { ...@@ -172,10 +172,17 @@ extern class JSBoundFunction extends JSObject {
} }
type Callable = JSFunction | JSBoundFunction | JSProxy; type Callable = JSFunction | JSBoundFunction | JSProxy;
type FixedTypedArrayBase extends FixedArrayBase
generates 'TNode<FixedTypedArrayBase>'; extern class FixedTypedArrayBase extends FixedArrayBase {
base_pointer: Smi;
external_pointer: RawPtr;
}
extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength(
FixedArrayBase): intptr;
type FixedTypedArray extends FixedTypedArrayBase type FixedTypedArray extends FixedTypedArrayBase
generates 'TNode<FixedTypedArray>'; generates 'TNode<FixedTypedArray>';
extern class SloppyArgumentsElements extends FixedArray {} extern class SloppyArgumentsElements extends FixedArray {}
type NumberDictionary extends HeapObject type NumberDictionary extends HeapObject
generates 'TNode<NumberDictionary>'; generates 'TNode<NumberDictionary>';
...@@ -220,7 +227,34 @@ extern class JSArrayBufferView extends JSObject { ...@@ -220,7 +227,34 @@ extern class JSArrayBufferView extends JSObject {
byte_length: uintptr; byte_length: uintptr;
} }
extern class JSTypedArray extends JSArrayBufferView {} extern class JSTypedArray extends JSArrayBufferView {
AttachOffHeapBuffer(
buffer: JSArrayBuffer, map: Map, length: PositiveSmi,
byteOffset: uintptr): void {
const basePointer: Smi = 0;
// The max byteOffset is 8 * MaxSmi on the particular platform. 32 bit
// platforms are self-limiting, because we can't allocate an array bigger
// than our 32-bit arithmetic range anyway. 64 bit platforms could
// theoretically have an offset up to 2^35 - 1.
const backingStore = buffer.backing_store;
const externalPointer = backingStore + Convert<intptr>(byteOffset);
// Assert no overflow has occurred. Only assert if the mock array buffer
// allocator is NOT used. When the mock array buffer is used, impossibly
// large allocations are allowed that would erroneously cause an overflow
// and this assertion to fail.
assert(
IsMockArrayBufferAllocatorFlag() ||
Convert<uintptr>(externalPointer) >= Convert<uintptr>(backingStore));
this.buffer = buffer;
this.elements = new
FixedTypedArrayBase{map, length, basePointer, externalPointer};
}
length: Smi;
}
type JSDataView extends JSArrayBufferView generates 'TNode<JSDataView>'; type JSDataView extends JSArrayBufferView generates 'TNode<JSDataView>';
...@@ -517,6 +551,8 @@ extern runtime ThrowInvalidStringLength(Context): never; ...@@ -517,6 +551,8 @@ extern runtime ThrowInvalidStringLength(Context): never;
extern operator '==' macro WordEqual(RawPtr, RawPtr): bool; extern operator '==' macro WordEqual(RawPtr, RawPtr): bool;
extern operator '!=' macro WordNotEqual(RawPtr, RawPtr): bool; extern operator '!=' macro WordNotEqual(RawPtr, RawPtr): bool;
extern operator '+' macro RawPtrAdd(RawPtr, intptr): RawPtr;
extern operator '+' macro RawPtrAdd(intptr, RawPtr): RawPtr;
extern operator '<' macro Int32LessThan(int32, int32): bool; extern operator '<' macro Int32LessThan(int32, int32): bool;
extern operator '<' macro Uint32LessThan(uint32, uint32): bool; extern operator '<' macro Uint32LessThan(uint32, uint32): bool;
...@@ -1238,6 +1274,7 @@ extern macro IsArrayIteratorProtectorCellInvalid(): bool; ...@@ -1238,6 +1274,7 @@ extern macro IsArrayIteratorProtectorCellInvalid(): bool;
extern macro IsArraySpeciesProtectorCellInvalid(): bool; extern macro IsArraySpeciesProtectorCellInvalid(): bool;
extern macro IsTypedArraySpeciesProtectorCellInvalid(): bool; extern macro IsTypedArraySpeciesProtectorCellInvalid(): bool;
extern macro IsPromiseSpeciesProtectorCellInvalid(): bool; extern macro IsPromiseSpeciesProtectorCellInvalid(): bool;
extern macro IsMockArrayBufferAllocatorFlag(): bool;
extern operator '.data_ptr' macro TypedArrayBuiltinsAssembler::LoadDataPtr( extern operator '.data_ptr' macro TypedArrayBuiltinsAssembler::LoadDataPtr(
JSTypedArray): RawPtr; JSTypedArray): RawPtr;
...@@ -1246,11 +1283,8 @@ extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind; ...@@ -1246,11 +1283,8 @@ extern operator '.elements_kind' macro LoadMapElementsKind(Map): ElementsKind;
extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray): extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray):
ElementsKind; ElementsKind;
extern operator '.length' macro LoadJSTypedArrayLength(JSTypedArray): Smi;
extern operator '.length' macro LoadFastJSArrayLength(FastJSArray): Smi; extern operator '.length' macro LoadFastJSArrayLength(FastJSArray): Smi;
extern operator '.length_intptr' macro LoadAndUntagFixedArrayBaseLength(
FixedArrayBase): intptr;
extern operator '.objects[]' macro LoadFixedArrayElement( extern operator '.objects[]' macro LoadFixedArrayElement(
FixedArray, intptr): Object; FixedArray, intptr): Object;
extern operator '.objects[]' macro LoadFixedArrayElement( extern operator '.objects[]' macro LoadFixedArrayElement(
......
...@@ -44,41 +44,6 @@ TNode<Map> TypedArrayBuiltinsAssembler::LoadMapForType( ...@@ -44,41 +44,6 @@ TNode<Map> TypedArrayBuiltinsAssembler::LoadMapForType(
return var_typed_map.value(); return var_typed_map.value();
} }
TNode<BoolT> TypedArrayBuiltinsAssembler::IsMockArrayBufferAllocatorFlag() {
TNode<Word32T> flag_value = UncheckedCast<Word32T>(Load(
MachineType::Uint8(),
ExternalConstant(
ExternalReference::address_of_mock_arraybuffer_allocator_flag())));
return Word32NotEqual(Word32And(flag_value, Int32Constant(0xFF)),
Int32Constant(0));
}
// The byte_offset can be higher than Smi range, in which case to perform the
// pointer arithmetic necessary to calculate external_pointer, converting
// byte_offset to an intptr is more difficult. The max byte_offset is 8 * MaxSmi
// on the particular platform. 32 bit platforms are self-limiting, because we
// can't allocate an array bigger than our 32-bit arithmetic range anyway. 64
// bit platforms could theoretically have an offset up to 2^35 - 1, so we may
// need to convert the float heap number to an intptr.
TNode<UintPtrT> TypedArrayBuiltinsAssembler::CalculateExternalPointer(
TNode<UintPtrT> backing_store, TNode<UintPtrT> byte_offset) {
TNode<UintPtrT> external_pointer = UintPtrAdd(backing_store, byte_offset);
#ifdef DEBUG
// Assert no overflow has occurred. Only assert if the mock array buffer
// allocator is NOT used. When the mock array buffer is used, impossibly
// large allocations are allowed that would erroneously cause an overflow and
// this assertion to fail.
Label next(this);
GotoIf(IsMockArrayBufferAllocatorFlag(), &next);
CSA_ASSERT(this, UintPtrGreaterThanOrEqual(external_pointer, backing_store));
Goto(&next);
BIND(&next);
#endif // DEBUG
return external_pointer;
}
// Setup the TypedArray which is under construction. // Setup the TypedArray which is under construction.
// - Set the length. // - Set the length.
// - Set the byte_offset. // - Set the byte_offset.
...@@ -102,33 +67,6 @@ void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder, ...@@ -102,33 +67,6 @@ void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder,
} }
} }
// Attach an off-heap buffer to a TypedArray.
void TypedArrayBuiltinsAssembler::AttachBuffer(TNode<JSTypedArray> holder,
TNode<JSArrayBuffer> buffer,
TNode<Map> map,
TNode<Smi> length,
TNode<UintPtrT> byte_offset) {
CSA_ASSERT(this, TaggedIsPositiveSmi(length));
StoreObjectField(holder, JSArrayBufferView::kBufferOffset, buffer);
Node* elements = Allocate(FixedTypedArrayBase::kHeaderSize);
StoreMapNoWriteBarrier(elements, map);
StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, length);
StoreObjectFieldNoWriteBarrier(
elements, FixedTypedArrayBase::kBasePointerOffset, SmiConstant(0));
TNode<UintPtrT> backing_store =
LoadObjectField<UintPtrT>(buffer, JSArrayBuffer::kBackingStoreOffset);
TNode<UintPtrT> external_pointer =
CalculateExternalPointer(backing_store, byte_offset);
StoreObjectFieldNoWriteBarrier(
elements, FixedTypedArrayBase::kExternalPointerOffset, external_pointer,
MachineType::PointerRepresentation());
StoreObjectField(holder, JSObject::kElementsOffset, elements);
}
// Allocate a new ArrayBuffer and initialize it with empty properties and // Allocate a new ArrayBuffer and initialize it with empty properties and
// elements. // elements.
TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer( TNode<JSArrayBuffer> TypedArrayBuiltinsAssembler::AllocateEmptyOnHeapBuffer(
......
...@@ -18,8 +18,6 @@ namespace typed_array_createtypedarray { ...@@ -18,8 +18,6 @@ namespace typed_array_createtypedarray {
bool; bool;
extern macro TypedArrayBuiltinsAssembler::SetupTypedArray( extern macro TypedArrayBuiltinsAssembler::SetupTypedArray(
JSTypedArray, Smi, uintptr, uintptr): void; JSTypedArray, Smi, uintptr, uintptr): void;
extern macro TypedArrayBuiltinsAssembler::AttachBuffer(
JSTypedArray, JSArrayBuffer, Map, Smi, uintptr): void;
extern runtime ThrowInvalidTypedArrayAlignment(implicit context: Context)( extern runtime ThrowInvalidTypedArrayAlignment(implicit context: Context)(
Map, String): never; Map, String): never;
...@@ -43,7 +41,7 @@ namespace typed_array_createtypedarray { ...@@ -43,7 +41,7 @@ namespace typed_array_createtypedarray {
try { try {
if (bufferConstructor != defaultConstructor) { if (bufferConstructor != defaultConstructor) {
goto AttachBuffer(ConstructWithTarget( goto AttachOffHeapBuffer(ConstructWithTarget(
defaultConstructor, bufferConstructor, byteLengthNum)); defaultConstructor, bufferConstructor, byteLengthNum));
} }
...@@ -64,16 +62,17 @@ namespace typed_array_createtypedarray { ...@@ -64,16 +62,17 @@ namespace typed_array_createtypedarray {
} }
label AllocateOffHeap { label AllocateOffHeap {
if constexpr (initialize) { if constexpr (initialize) {
goto AttachBuffer(Construct(defaultConstructor, byteLengthNum)); goto AttachOffHeapBuffer(Construct(defaultConstructor, byteLengthNum));
} else { } else {
goto AttachBuffer(Call( goto AttachOffHeapBuffer(Call(
context, GetArrayBufferNoInitFunction(), Undefined, byteLengthNum)); context, GetArrayBufferNoInitFunction(), Undefined, byteLengthNum));
} }
} }
label AttachBuffer(bufferObj: Object) { label AttachOffHeapBuffer(bufferObj: Object) {
const buffer = Cast<JSArrayBuffer>(bufferObj) otherwise unreachable; const buffer = Cast<JSArrayBuffer>(bufferObj) otherwise unreachable;
const byteOffset: uintptr = 0; const byteOffset: uintptr = 0;
AttachBuffer(typedArray, buffer, elementsInfo.map, length, byteOffset); typedArray.AttachOffHeapBuffer(
buffer, elementsInfo.map, length, byteOffset);
} }
const byteOffset: uintptr = 0; const byteOffset: uintptr = 0;
...@@ -236,7 +235,8 @@ namespace typed_array_createtypedarray { ...@@ -236,7 +235,8 @@ namespace typed_array_createtypedarray {
} }
SetupTypedArray(typedArray, newLength, offset, newByteLength); SetupTypedArray(typedArray, newLength, offset, newByteLength);
AttachBuffer(typedArray, buffer, elementsInfo.map, newLength, offset); typedArray.AttachOffHeapBuffer(
buffer, elementsInfo.map, newLength, offset);
} }
label IfInvalidAlignment(problemString: String) deferred { label IfInvalidAlignment(problemString: String) deferred {
ThrowInvalidTypedArrayAlignment(typedArray.map, problemString); ThrowInvalidTypedArrayAlignment(typedArray.map, problemString);
......
...@@ -2205,6 +2205,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -2205,6 +2205,15 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsRegExpSpeciesProtectorCellInvalid(); TNode<BoolT> IsRegExpSpeciesProtectorCellInvalid();
TNode<BoolT> IsPromiseSpeciesProtectorCellInvalid(); TNode<BoolT> IsPromiseSpeciesProtectorCellInvalid();
TNode<BoolT> IsMockArrayBufferAllocatorFlag() {
TNode<Word32T> flag_value = UncheckedCast<Word32T>(Load(
MachineType::Uint8(),
ExternalConstant(
ExternalReference::address_of_mock_arraybuffer_allocator_flag())));
return Word32NotEqual(Word32And(flag_value, Int32Constant(0xFF)),
Int32Constant(0));
}
// True iff |object| is a Smi or a HeapNumber. // True iff |object| is a Smi or a HeapNumber.
TNode<BoolT> IsNumber(SloppyTNode<Object> object); TNode<BoolT> IsNumber(SloppyTNode<Object> object);
// True iff |object| is a Smi or a HeapNumber or a BigInt. // True iff |object| is a Smi or a HeapNumber or a BigInt.
......
...@@ -1089,6 +1089,12 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -1089,6 +1089,12 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return Unsigned( return Unsigned(
IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right))); IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right)));
} }
TNode<RawPtrT> RawPtrAdd(TNode<RawPtrT> left, TNode<IntPtrT> right) {
return ReinterpretCast<RawPtrT>(IntPtrAdd(left, right));
}
TNode<RawPtrT> RawPtrAdd(TNode<IntPtrT> left, TNode<RawPtrT> right) {
return ReinterpretCast<RawPtrT>(IntPtrAdd(left, right));
}
TNode<WordT> WordShl(SloppyTNode<WordT> value, int shift); TNode<WordT> WordShl(SloppyTNode<WordT> value, int shift);
TNode<WordT> WordShr(SloppyTNode<WordT> value, int shift); TNode<WordT> WordShr(SloppyTNode<WordT> value, int shift);
......
...@@ -590,15 +590,9 @@ class FixedTypedArrayBase : public FixedArrayBase { ...@@ -590,15 +590,9 @@ class FixedTypedArrayBase : public FixedArrayBase {
// Dispatched behavior. // Dispatched behavior.
DECL_CAST(FixedTypedArrayBase) DECL_CAST(FixedTypedArrayBase)
#define FIXED_TYPED_ARRAY_BASE_FIELDS(V) \
V(kBasePointerOffset, kTaggedSize) \
V(kExternalPointerOffset, kSystemPointerSize) \
/* Header size. */ \
V(kHeaderSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(FixedArrayBase::kHeaderSize, DEFINE_FIELD_OFFSET_CONSTANTS(FixedArrayBase::kHeaderSize,
FIXED_TYPED_ARRAY_BASE_FIELDS) FIXED_TYPED_ARRAY_BASE_FIELDS)
#undef FIXED_TYPED_ARRAY_BASE_FIELDS static const int kHeaderSize = kSize;
STATIC_ASSERT(IsAligned(kHeaderSize, kDoubleAlignment)); STATIC_ASSERT(IsAligned(kHeaderSize, kDoubleAlignment));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment