Commit 3dffdf03 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[wasm-gc] Liftoff support part 3: arrays

This adds support for the following instructions:
ref.eq, array.new_with_rtt, array.new_default_with_rtt,
array.get, array.set, array.len.

Bug: v8:7748
Change-Id: I93c4a6676acc8b0ac035dd50762be6a1cc545a57
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2593340
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71796}
parent 3650b365
......@@ -698,12 +698,15 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr,
}
void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
Register offset_reg,
int32_t offset_imm,
LiftoffRegister src,
LiftoffRegList pinned) {
STATIC_ASSERT(kTaggedSize == kInt32Size);
// Store the value.
MemOperand dst_op(dst_addr, offset_imm);
UseScratchRegisterScope temps(this);
MemOperand dst_op =
liftoff::GetMemOp(this, &temps, dst_addr, offset_reg, offset_imm);
str(src.gp(), dst_op);
// The write barrier.
Label write_barrier;
......
......@@ -405,11 +405,14 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr,
}
void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
Register offset_reg,
int32_t offset_imm,
LiftoffRegister src,
LiftoffRegList pinned) {
// Store the value.
MemOperand dst_op(dst_addr, offset_imm);
UseScratchRegisterScope temps(this);
MemOperand dst_op =
liftoff::GetMemOp(this, &temps, dst_addr, offset_reg, offset_imm);
StoreTaggedField(src.gp(), dst_op);
// The write barrier.
Label write_barrier;
......
......@@ -330,6 +330,7 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr,
}
void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
Register offset_reg,
int32_t offset_imm,
LiftoffRegister src,
LiftoffRegList pinned) {
......@@ -337,7 +338,9 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
DCHECK_LE(offset_imm, std::numeric_limits<int32_t>::max());
STATIC_ASSERT(kTaggedSize == kInt32Size);
Register scratch = pinned.set(GetUnusedRegister(kGpReg, pinned)).gp();
Operand dst_op = Operand(dst_addr, offset_imm);
Operand dst_op = offset_reg == no_reg
? Operand(dst_addr, offset_imm)
: Operand(dst_addr, offset_reg, times_1, offset_imm);
mov(dst_op, src.gp());
Label write_barrier;
......
......@@ -342,6 +342,19 @@ class LiftoffAssembler : public TurboAssembler {
return LoadToRegister(slot, pinned);
}
// Use this to pop a value into a register that has no other uses, so it
// can be modified.
LiftoffRegister PopToModifiableRegister(LiftoffRegList pinned = {}) {
ValueType type = cache_state_.stack_state.back().type();
LiftoffRegister reg = PopToRegister(pinned);
if (cache_state()->is_free(reg)) return reg;
pinned.set(reg);
LiftoffRegister new_reg = GetUnusedRegister(reg.reg_class(), pinned);
Move(new_reg, reg, type);
return new_reg;
}
// Returns the register which holds the value of stack slot {index}. If the
// value is not stored in a register yet, a register is allocated for it. The
// register is then assigned to the stack slot. The value stack height is not
......@@ -541,8 +554,9 @@ class LiftoffAssembler : public TurboAssembler {
inline void LoadTaggedPointer(Register dst, Register src_addr,
Register offset_reg, int32_t offset_imm,
LiftoffRegList pinned);
inline void StoreTaggedPointer(Register dst_addr, int32_t offset_imm,
LiftoffRegister src, LiftoffRegList pinned);
inline void StoreTaggedPointer(Register dst_addr, Register offset_reg,
int32_t offset_imm, LiftoffRegister src,
LiftoffRegList pinned);
inline void LoadFixedArrayLengthAsInt32(LiftoffRegister dst, Register array,
LiftoffRegList pinned) {
int offset = FixedArray::kLengthOffset - kHeapObjectTag;
......
This diff is collapsed.
......@@ -58,6 +58,8 @@ static inline constexpr RegClass reg_class_for(ValueType::Kind kind) {
case ValueType::kF32:
case ValueType::kF64:
return kFpReg;
case ValueType::kI8:
case ValueType::kI16:
case ValueType::kI32:
return kGpReg;
case ValueType::kI64:
......
......@@ -311,12 +311,13 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr,
}
void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
Register offset_reg,
int32_t offset_imm,
LiftoffRegister src,
LiftoffRegList pinned) {
DCHECK_GE(offset_imm, 0);
Register scratch = pinned.set(GetUnusedRegister(kGpReg, pinned)).gp();
Operand dst_op = liftoff::GetMemOp(this, dst_addr, no_reg,
Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg,
static_cast<uint32_t>(offset_imm));
StoreTaggedField(dst_op, src.gp());
......
......@@ -85,6 +85,7 @@ struct WasmModule;
V(I64ToBigInt) \
V(RecordWrite) \
V(ToNumber) \
V(WasmAllocateArrayWithRtt) \
V(WasmAllocateStructWithRtt)
// Sorted, disjoint and non-overlapping memory regions. A region is of the
......
......@@ -421,8 +421,9 @@ WASM_COMPILED_EXEC_TEST(BrOnCast) {
tester.CheckResult(kTypedAfterBranch, 42);
}
TEST(WasmRefEq) {
WasmGCTester tester;
WASM_COMPILED_EXEC_TEST(WasmRefEq) {
WasmGCTester tester(execution_tier);
FLAG_experimental_liftoff_extern_ref = true;
byte type_index = tester.DefineStruct({F(kWasmI32, true), F(kWasmI32, true)});
ValueType kRefTypes[] = {ref(type_index)};
ValueType kOptRefType = optref(type_index);
......@@ -460,8 +461,9 @@ TEST(WasmRefEq) {
tester.CheckResult(kFunc, 0b1001);
}
TEST(WasmPackedStructU) {
WasmGCTester tester;
WASM_COMPILED_EXEC_TEST(WasmPackedStructU) {
WasmGCTester tester(execution_tier);
FLAG_experimental_liftoff_extern_ref = true;
const byte type_index = tester.DefineStruct(
{F(kWasmI8, true), F(kWasmI16, true), F(kWasmI32, true)});
......@@ -497,8 +499,9 @@ TEST(WasmPackedStructU) {
tester.CheckResult(kF1, static_cast<uint16_t>(expected_output_1));
}
TEST(WasmPackedStructS) {
WasmGCTester tester;
WASM_COMPILED_EXEC_TEST(WasmPackedStructS) {
WasmGCTester tester(execution_tier);
FLAG_experimental_liftoff_extern_ref = true;
const byte type_index = tester.DefineStruct(
{F(kWasmI8, true), F(kWasmI16, true), F(kWasmI32, true)});
......@@ -594,8 +597,10 @@ TEST(WasmLetInstruction) {
tester.CheckResult(kLetTestErase, 0);
}
TEST(WasmBasicArray) {
WasmGCTester tester;
WASM_COMPILED_EXEC_TEST(WasmBasicArray) {
WasmGCTester tester(execution_tier);
FLAG_experimental_liftoff_extern_ref = true;
const byte type_index = tester.DefineArray(wasm::kWasmI32, true);
ValueType kRefTypes[] = {ref(type_index)};
FunctionSig sig_q_v(1, 0, kRefTypes);
......@@ -668,8 +673,9 @@ TEST(WasmBasicArray) {
tester.CheckHasThrown(kAllocateTooLarge);
}
TEST(WasmPackedArrayU) {
WasmGCTester tester;
WASM_COMPILED_EXEC_TEST(WasmPackedArrayU) {
WasmGCTester tester(execution_tier);
FLAG_experimental_liftoff_extern_ref = true;
const byte array_index = tester.DefineArray(kWasmI8, true);
ValueType array_type = optref(array_index);
......@@ -703,8 +709,9 @@ TEST(WasmPackedArrayU) {
tester.CheckResult(kF, static_cast<uint8_t>(expected_output_3), 3);
}
TEST(WasmPackedArrayS) {
WasmGCTester tester;
WASM_COMPILED_EXEC_TEST(WasmPackedArrayS) {
WasmGCTester tester(execution_tier);
FLAG_experimental_liftoff_extern_ref = true;
const byte array_index = tester.DefineArray(kWasmI16, true);
ValueType array_type = optref(array_index);
......
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