Commit bd4f1a61 authored by Bill Budge's avatar Bill Budge Committed by Commit Bot

[wasm] Torqueify more builtins.

- Rewrites the following builtins using Torque:
  WasmAtomicNotify
  WasmI32AtomicWait64
  WasmI64AtomicWait64
  WasmAllocateStruct
- Adds some helper builtins to reduce the size of the Atomics builtins.
  These do multiple conversions and CSA inlines all of this code. As
  these are runtime calls, the call overhead should be negligible.
  WasmInt32ToNumber
  WasmUint32ToNumber

Change-Id: Ie15e15a965dc383c54ae50164d83bce211178888
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2176895Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67785}
parent 81290c48
......@@ -842,12 +842,8 @@ namespace internal {
TFC(WasmFloat32ToNumber, WasmFloat32ToNumber) \
TFC(WasmFloat64ToNumber, WasmFloat64ToNumber) \
TFS(WasmAllocateArray, kMapIndex, kLength, kElementSize) \
TFS(WasmAllocateStruct, kMapIndex) \
TFC(WasmAtomicNotify, WasmAtomicNotify) \
TFC(WasmI32AtomicWait32, WasmI32AtomicWait32) \
TFC(WasmI32AtomicWait64, WasmI32AtomicWait64) \
TFC(WasmI64AtomicWait32, WasmI64AtomicWait32) \
TFC(WasmI64AtomicWait64, WasmI64AtomicWait64) \
TFC(WasmTableInit, WasmTableInit) \
TFC(WasmTableCopy, WasmTableCopy) \
\
......
......@@ -37,6 +37,12 @@ TNode<FixedArray> WasmBuiltinsAssembler::LoadExternalFunctionsFromInstance(
instance, WasmInstanceObject::kWasmExternalFunctionsOffset);
}
TNode<FixedArray> WasmBuiltinsAssembler::LoadManagedObjectMapsFromInstance(
TNode<WasmInstanceObject> instance) {
return LoadObjectField<FixedArray>(
instance, WasmInstanceObject::kManagedObjectMapsOffset);
}
TNode<Smi> WasmBuiltinsAssembler::SmiFromUint32WithSaturation(
TNode<Uint32T> value, uint32_t max) {
DCHECK_LE(max, static_cast<uint32_t>(Smi::kMaxValue));
......@@ -55,22 +61,6 @@ TF_BUILTIN(WasmFloat64ToNumber, WasmBuiltinsAssembler) {
Return(ChangeFloat64ToTagged(val));
}
TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) {
TNode<Uint32T> address =
UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
TNode<Uint32T> count = UncheckedCast<Uint32T>(Parameter(Descriptor::kCount));
TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
TNode<Number> address_number = ChangeUint32ToTagged(address);
TNode<Number> count_number = ChangeUint32ToTagged(count);
TNode<Context> context = LoadContextFromInstance(instance);
TNode<Smi> result_smi =
CAST(CallRuntime(Runtime::kWasmAtomicNotify, context, instance,
address_number, count_number));
Return(Unsigned(SmiToInt32(result_smi)));
}
TF_BUILTIN(WasmI32AtomicWait32, WasmBuiltinsAssembler) {
if (!Is32()) {
Unreachable();
......@@ -100,33 +90,6 @@ TF_BUILTIN(WasmI32AtomicWait32, WasmBuiltinsAssembler) {
Return(Unsigned(SmiToInt32(result_smi)));
}
TF_BUILTIN(WasmI32AtomicWait64, WasmBuiltinsAssembler) {
if (!Is64()) {
Unreachable();
return;
}
TNode<Uint32T> address =
UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
TNode<Number> address_number = ChangeUint32ToTagged(address);
TNode<Int32T> expected_value =
UncheckedCast<Int32T>(Parameter(Descriptor::kExpectedValue));
TNode<Number> expected_value_number = ChangeInt32ToTagged(expected_value);
TNode<IntPtrT> timeout_raw =
UncheckedCast<IntPtrT>(Parameter(Descriptor::kTimeout));
TNode<BigInt> timeout = BigIntFromInt64(timeout_raw);
TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
TNode<Context> context = LoadContextFromInstance(instance);
TNode<Smi> result_smi =
CAST(CallRuntime(Runtime::kWasmI32AtomicWait, context, instance,
address_number, expected_value_number, timeout));
Return(Unsigned(SmiToInt32(result_smi)));
}
TF_BUILTIN(WasmI64AtomicWait32, WasmBuiltinsAssembler) {
if (!Is32()) {
Unreachable();
......@@ -159,33 +122,6 @@ TF_BUILTIN(WasmI64AtomicWait32, WasmBuiltinsAssembler) {
Return(Unsigned(SmiToInt32(result_smi)));
}
TF_BUILTIN(WasmI64AtomicWait64, WasmBuiltinsAssembler) {
if (!Is64()) {
Unreachable();
return;
}
TNode<Uint32T> address =
UncheckedCast<Uint32T>(Parameter(Descriptor::kAddress));
TNode<Number> address_number = ChangeUint32ToTagged(address);
TNode<IntPtrT> expected_value_raw =
UncheckedCast<IntPtrT>(Parameter(Descriptor::kExpectedValue));
TNode<BigInt> expected_value = BigIntFromInt64(expected_value_raw);
TNode<IntPtrT> timeout_raw =
UncheckedCast<IntPtrT>(Parameter(Descriptor::kTimeout));
TNode<BigInt> timeout = BigIntFromInt64(timeout_raw);
TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
TNode<Context> context = LoadContextFromInstance(instance);
TNode<Smi> result_smi =
CAST(CallRuntime(Runtime::kWasmI64AtomicWait, context, instance,
address_number, expected_value, timeout));
Return(Unsigned(SmiToInt32(result_smi)));
}
TF_BUILTIN(WasmTableInit, WasmBuiltinsAssembler) {
TNode<Uint32T> dst_raw =
UncheckedCast<Uint32T>(Parameter(Descriptor::kDestination));
......@@ -270,18 +206,5 @@ TF_BUILTIN(WasmAllocateArray, WasmBuiltinsAssembler) {
Return(result);
}
TF_BUILTIN(WasmAllocateStruct, WasmBuiltinsAssembler) {
TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
TNode<Smi> map_index = CAST(Parameter(Descriptor::kMapIndex));
TNode<FixedArray> maps_list = LoadObjectField<FixedArray>(
instance, WasmInstanceObject::kManagedObjectMapsOffset);
TNode<Map> map = CAST(LoadFixedArrayElement(maps_list, map_index));
TNode<IntPtrT> instance_size =
TimesTaggedSize(LoadMapInstanceSizeInWords(map));
TNode<WasmStruct> result = UncheckedCast<WasmStruct>(Allocate(instance_size));
StoreMap(result, map);
Return(result);
}
} // namespace internal
} // namespace v8
......@@ -25,6 +25,9 @@ class WasmBuiltinsAssembler : public CodeStubAssembler {
TNode<FixedArray> LoadExternalFunctionsFromInstance(
TNode<WasmInstanceObject> instance);
TNode<FixedArray> LoadManagedObjectMapsFromInstance(
TNode<WasmInstanceObject> instance);
protected:
TNode<Smi> SmiFromUint32WithSaturation(TNode<Uint32T> value, uint32_t max);
};
......
......@@ -17,6 +17,17 @@ extern runtime ReThrow(Context, Object): JSAny;
extern runtime WasmStackGuard(Context): JSAny;
extern runtime ThrowWasmStackOverflow(Context): JSAny;
extern runtime WasmTraceMemory(Context, Smi): JSAny;
extern runtime WasmAtomicNotify(
Context, WasmInstanceObject, Number, Number): Smi;
extern runtime WasmI32AtomicWait(
Context, WasmInstanceObject, Number, Number, BigInt): Smi;
extern runtime WasmI64AtomicWait(
Context, WasmInstanceObject, Number, BigInt, BigInt): Smi;
}
namespace unsafe {
extern macro TimesTaggedSize(intptr): intptr;
extern macro Allocate(intptr): HeapObject;
}
namespace wasm {
......@@ -33,6 +44,8 @@ extern macro WasmBuiltinsAssembler::LoadTablesFromInstance(WasmInstanceObject):
FixedArray;
extern macro WasmBuiltinsAssembler::LoadExternalFunctionsFromInstance(
WasmInstanceObject): FixedArray;
extern macro WasmBuiltinsAssembler::LoadManagedObjectMapsFromInstance(
WasmInstanceObject): FixedArray;
macro LoadContextFromFrame(): NativeContext {
return LoadContextFromInstance(LoadInstanceFromFrame());
......@@ -166,6 +179,64 @@ builtin WasmAllocateJSArray(implicit context: Context)(size: Smi): JSArray {
return AllocateJSArray(ElementsKind::PACKED_ELEMENTS, map, size, size);
}
builtin WasmAllocateStruct(implicit context: Context)(mapIndex: Smi):
HeapObject {
const instance: WasmInstanceObject = LoadInstanceFromFrame();
const maps: FixedArray = LoadManagedObjectMapsFromInstance(instance);
const map: Map = %RawDownCast<Map>(LoadFixedArrayElement(maps, mapIndex));
const instanceSize: intptr =
unsafe::TimesTaggedSize(Convert<intptr>(map.instance_size_in_words));
const result: HeapObject = unsafe::Allocate(instanceSize);
* UnsafeConstCast(& result.map) = map;
return result;
}
builtin WasmInt32ToNumber(value: int32): Number {
return ChangeInt32ToTagged(value);
}
builtin WasmUint32ToNumber(value: uint32): Number {
return ChangeUint32ToTagged(value);
}
extern builtin I64ToBigInt(intptr): BigInt;
builtin WasmAtomicNotify(address: uint32, count: uint32): uint32 {
const instance: WasmInstanceObject = LoadInstanceFromFrame();
const result: Smi = runtime::WasmAtomicNotify(
LoadContextFromInstance(instance), instance, WasmUint32ToNumber(address),
WasmUint32ToNumber(count));
return Unsigned(SmiToInt32(result));
}
builtin WasmI32AtomicWait64(
address: uint32, expectedValue: int32, timeout: intptr): uint32 {
if constexpr (Is64()) {
const instance: WasmInstanceObject = LoadInstanceFromFrame();
const result: Smi = runtime::WasmI32AtomicWait(
LoadContextFromInstance(instance), instance,
WasmUint32ToNumber(address), WasmInt32ToNumber(expectedValue),
I64ToBigInt(timeout));
return Unsigned(SmiToInt32(result));
} else {
unreachable;
}
}
builtin WasmI64AtomicWait64(
address: uint32, expectedValue: intptr, timeout: intptr): uint32 {
if constexpr (Is64()) {
const instance: WasmInstanceObject = LoadInstanceFromFrame();
const result: Smi = runtime::WasmI64AtomicWait(
LoadContextFromInstance(instance), instance,
WasmUint32ToNumber(address), I64ToBigInt(expectedValue),
I64ToBigInt(timeout));
return Unsigned(SmiToInt32(result));
} else {
unreachable;
}
}
extern macro TryHasOwnProperty(HeapObject, Map, InstanceType, Name): never
labels Found, NotFound, Bailout;
type OnNonExistent constexpr 'OnNonExistent';
......
......@@ -403,32 +403,17 @@ void WasmTableCopyDescriptor::InitializePlatformSpecific(
kParameterCount - kStackArgumentsCount);
}
void WasmAtomicNotifyDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data, kParameterCount);
}
#if !defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64)
void WasmI32AtomicWait32Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data, kParameterCount);
}
void WasmI32AtomicWait64Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data, kParameterCount);
}
void WasmI64AtomicWait32Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data,
kParameterCount - kStackArgumentsCount);
}
void WasmI64AtomicWait64Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
DefaultInitializePlatformSpecific(data, kParameterCount);
}
#endif
void CloneObjectWithVectorDescriptor::InitializePlatformSpecific(
......
......@@ -95,13 +95,10 @@ namespace internal {
V(Typeof) \
V(UnaryOp_WithFeedback) \
V(Void) \
V(WasmAtomicNotify) \
V(WasmFloat32ToNumber) \
V(WasmFloat64ToNumber) \
V(WasmI32AtomicWait32) \
V(WasmI32AtomicWait64) \
V(WasmI64AtomicWait32) \
V(WasmI64AtomicWait64) \
V(WasmTableInit) \
V(WasmTableCopy) \
BUILTIN_LIST_TFS(V) \
......@@ -1414,15 +1411,6 @@ class V8_EXPORT_PRIVATE BigIntToI32PairDescriptor final
DECLARE_DESCRIPTOR(BigIntToI32PairDescriptor, CallInterfaceDescriptor)
};
class WasmAtomicNotifyDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kCount)
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(), // result 1
MachineType::Uint32(), // kAddress
MachineType::Uint32()) // kCount
DECLARE_DESCRIPTOR(WasmAtomicNotifyDescriptor, CallInterfaceDescriptor)
};
class WasmI32AtomicWait32Descriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeoutLow,
......@@ -1461,26 +1449,6 @@ class WasmI64AtomicWait32Descriptor final : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(WasmI64AtomicWait32Descriptor, CallInterfaceDescriptor)
};
class WasmI32AtomicWait64Descriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeout)
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(), // result 1
MachineType::Uint32(), // kAddress
MachineType::Int32(), // kExpectedValue
MachineType::Uint64()) // kTimeout
DECLARE_DESCRIPTOR(WasmI32AtomicWait64Descriptor, CallInterfaceDescriptor)
};
class WasmI64AtomicWait64Descriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kAddress, kExpectedValue, kTimeout)
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::Uint32(), // result 1
MachineType::Uint32(), // kAddress
MachineType::Uint64(), // kExpectedValue
MachineType::Uint64()) // kTimeout
DECLARE_DESCRIPTOR(WasmI64AtomicWait64Descriptor, CallInterfaceDescriptor)
};
class CloneObjectWithVectorDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kSource, kFlags, kSlot, kVector)
......
......@@ -39,14 +39,6 @@ void WasmI32AtomicWait32Descriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
}
void WasmI32AtomicWait64Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
const Register default_stub_registers[] = {a0, a1, a2};
CHECK_EQ(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
}
void WasmI64AtomicWait32Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
const Register default_stub_registers[] = {a0, a1, a2, a3, t0};
......@@ -56,14 +48,6 @@ void WasmI64AtomicWait32Descriptor::InitializePlatformSpecific(
default_stub_registers);
}
void WasmI64AtomicWait64Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
const Register default_stub_registers[] = {a0, a1, a2};
CHECK_EQ(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
}
void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
const Register default_stub_registers[] = {a0, a1, a2, a3, kReturnRegister0};
......
......@@ -39,14 +39,6 @@ void WasmI32AtomicWait32Descriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
}
void WasmI32AtomicWait64Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
const Register default_stub_registers[] = {a0, a1, a2};
CHECK_EQ(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
}
void WasmI64AtomicWait32Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
const Register default_stub_registers[] = {a0, a1, a2, a3, a4};
......@@ -56,14 +48,6 @@ void WasmI64AtomicWait32Descriptor::InitializePlatformSpecific(
default_stub_registers);
}
void WasmI64AtomicWait64Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
const Register default_stub_registers[] = {a0, a1, a2};
CHECK_EQ(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
}
void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
const Register default_stub_registers[] = {a0, a1, a2, a3, kReturnRegister0};
......
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