From e43ec59b4e95505fbb2e233390e7551891287cd3 Mon Sep 17 00:00:00 2001 From: Andreas Haas Date: Mon, 7 Sep 2020 18:27:31 +0200 Subject: [PATCH] [wasm][liftoff] Support for most externref globals With this CL we add support for all externref globals except for imported mutable globals. R=thibaudm@chromium.org Bug: v8:7581 Change-Id: I63cb26f8ad6f4b8fc1c276e223c5d45745122ebf Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2396086 Commit-Queue: Andreas Haas Reviewed-by: Thibaud Michaud Cr-Commit-Position: refs/heads/master@{#69741} --- src/wasm/baseline/arm/liftoff-assembler-arm.h | 9 ++++ .../baseline/arm64/liftoff-assembler-arm64.h | 11 ++++ .../baseline/ia32/liftoff-assembler-ia32.h | 10 ++++ src/wasm/baseline/liftoff-assembler.h | 3 ++ src/wasm/baseline/liftoff-compiler.cc | 52 +++++++++++++++++-- .../baseline/mips/liftoff-assembler-mips.h | 8 +++ .../mips64/liftoff-assembler-mips64.h | 8 +++ src/wasm/baseline/ppc/liftoff-assembler-ppc.h | 8 +++ .../baseline/s390/liftoff-assembler-s390.h | 8 +++ src/wasm/baseline/x64/liftoff-assembler-x64.h | 14 +++++ .../mjsunit/wasm/externref-globals-liftoff.js | 8 +++ 11 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 test/mjsunit/wasm/externref-globals-liftoff.js diff --git a/src/wasm/baseline/arm/liftoff-assembler-arm.h b/src/wasm/baseline/arm/liftoff-assembler-arm.h index cddc766f55..49fca78f27 100644 --- a/src/wasm/baseline/arm/liftoff-assembler-arm.h +++ b/src/wasm/baseline/arm/liftoff-assembler-arm.h @@ -659,6 +659,15 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, offset_imm, LoadType::kI32Load, pinned); } +void LiftoffAssembler::StoreTaggedPointer(Register dst_addr, + Register offset_reg, + int32_t offset_imm, + LiftoffRegister src, + LiftoffRegList pinned) { + STATIC_ASSERT(kTaggedSize == kInt32Size); + Store(dst_addr, offset_reg, offset_imm, src, StoreType::kI32Store, pinned); +} + void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned, diff --git a/src/wasm/baseline/arm64/liftoff-assembler-arm64.h b/src/wasm/baseline/arm64/liftoff-assembler-arm64.h index e042c6fbc3..81d7ab8ebc 100644 --- a/src/wasm/baseline/arm64/liftoff-assembler-arm64.h +++ b/src/wasm/baseline/arm64/liftoff-assembler-arm64.h @@ -338,6 +338,17 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, LoadTaggedPointerField(dst, src_op); } +void LiftoffAssembler::StoreTaggedPointer(Register dst_addr, + Register offset_reg, + int32_t offset_imm, + LiftoffRegister src, + LiftoffRegList pinned) { + UseScratchRegisterScope temps(this); + MemOperand dst_op = + liftoff::GetMemOp(this, &temps, dst_addr, offset_reg, offset_imm); + StoreTaggedField(src.gp(), dst_op); +} + void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned, diff --git a/src/wasm/baseline/ia32/liftoff-assembler-ia32.h b/src/wasm/baseline/ia32/liftoff-assembler-ia32.h index 42c92d5ee0..f8dadc1075 100644 --- a/src/wasm/baseline/ia32/liftoff-assembler-ia32.h +++ b/src/wasm/baseline/ia32/liftoff-assembler-ia32.h @@ -291,6 +291,16 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, static_cast(offset_imm), LoadType::kI32Load, pinned); } +void LiftoffAssembler::StoreTaggedPointer(Register dst_addr, + Register offset_reg, + int32_t offset_imm, + LiftoffRegister src, + LiftoffRegList pinned) { + DCHECK_GE(offset_imm, 0); + STATIC_ASSERT(kTaggedSize == kInt32Size); + Store(dst_addr, offset_reg, offset_imm, src, StoreType::kI32Store, pinned); +} + void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned, diff --git a/src/wasm/baseline/liftoff-assembler.h b/src/wasm/baseline/liftoff-assembler.h index 7ac7e2ac84..cd909af909 100644 --- a/src/wasm/baseline/liftoff-assembler.h +++ b/src/wasm/baseline/liftoff-assembler.h @@ -485,6 +485,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, Register offset_reg, + int32_t offset_imm, LiftoffRegister src, + LiftoffRegList pinned); inline void Load(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned, uint32_t* protected_load_pc = nullptr, diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index 47f3d1e6c0..f264df83af 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -1813,8 +1813,30 @@ class LiftoffCompiler { void GlobalGet(FullDecoder* decoder, Value* result, const GlobalIndexImmediate& imm) { const auto* global = &env_->module->globals[imm.index]; - if (!CheckSupportedType(decoder, kSupportedTypesWithoutRefs, global->type, - "global")) { + if (!CheckSupportedType(decoder, + FLAG_liftoff_extern_ref + ? kSupportedTypes + : kSupportedTypesWithoutRefs, + global->type, "global")) { + return; + } + + if (global->type.is_reference_type()) { + if (global->mutability && global->imported) { + unsupported(decoder, kRefTypes, "imported mutable globals"); + return; + } + + LiftoffRegList pinned; + Register globals_buffer = + pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp(); + LOAD_TAGGED_PTR_INSTANCE_FIELD(globals_buffer, TaggedGlobalsBuffer); + Register value = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp(); + __ LoadTaggedPointer(value, globals_buffer, no_reg, + wasm::ObjectAccess::ElementOffsetInTaggedFixedArray( + imm.global->offset), + pinned); + __ PushRegister(global->type, LiftoffRegister(value)); return; } LiftoffRegList pinned; @@ -1830,9 +1852,31 @@ class LiftoffCompiler { void GlobalSet(FullDecoder* decoder, const Value& value, const GlobalIndexImmediate& imm) { auto* global = &env_->module->globals[imm.index]; - if (!CheckSupportedType(decoder, kSupportedTypesWithoutRefs, global->type, - "global")) + if (!CheckSupportedType(decoder, + FLAG_liftoff_extern_ref + ? kSupportedTypes + : kSupportedTypesWithoutRefs, + global->type, "global")) { return; + } + + if (global->type.is_reference_type()) { + if (global->mutability && global->imported) { + unsupported(decoder, kRefTypes, "imported mutable globals"); + return; + } + + LiftoffRegList pinned; + Register globals_buffer = + pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp(); + LOAD_TAGGED_PTR_INSTANCE_FIELD(globals_buffer, TaggedGlobalsBuffer); + LiftoffRegister value = pinned.set(__ PopToRegister(pinned)); + __ StoreTaggedPointer(globals_buffer, no_reg, + wasm::ObjectAccess::ElementOffsetInTaggedFixedArray( + imm.global->offset), + value, pinned); + return; + } LiftoffRegList pinned; uint32_t offset = 0; Register addr = GetGlobalBaseAndOffset(global, &pinned, &offset); diff --git a/src/wasm/baseline/mips/liftoff-assembler-mips.h b/src/wasm/baseline/mips/liftoff-assembler-mips.h index 15771e033b..cdbcafde4b 100644 --- a/src/wasm/baseline/mips/liftoff-assembler-mips.h +++ b/src/wasm/baseline/mips/liftoff-assembler-mips.h @@ -391,6 +391,14 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, static_cast(offset_imm), LoadType::kI32Load, pinned); } +void LiftoffAssembler::StoreTaggedPointer(Register dst_addr, + Register offset_reg, + int32_t offset_imm, + LiftoffRegister src, + LiftoffRegList pinned) { + bailout(kRefTypes, "GlobalSet"); +} + void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned, diff --git a/src/wasm/baseline/mips64/liftoff-assembler-mips64.h b/src/wasm/baseline/mips64/liftoff-assembler-mips64.h index e67e629473..e17f34163a 100644 --- a/src/wasm/baseline/mips64/liftoff-assembler-mips64.h +++ b/src/wasm/baseline/mips64/liftoff-assembler-mips64.h @@ -355,6 +355,14 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, static_cast(offset_imm), LoadType::kI64Load, pinned); } +void LiftoffAssembler::StoreTaggedPointer(Register dst_addr, + Register offset_reg, + int32_t offset_imm, + LiftoffRegister src, + LiftoffRegList pinned) { + bailout(kRefTypes, "GlobalSet"); +} + void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned, diff --git a/src/wasm/baseline/ppc/liftoff-assembler-ppc.h b/src/wasm/baseline/ppc/liftoff-assembler-ppc.h index 6129a25e9f..a391b9cb3d 100644 --- a/src/wasm/baseline/ppc/liftoff-assembler-ppc.h +++ b/src/wasm/baseline/ppc/liftoff-assembler-ppc.h @@ -119,6 +119,14 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, bailout(kUnsupportedArchitecture, "LoadTaggedPointer"); } +void LiftoffAssembler::StoreTaggedPointer(Register dst_addr, + Register offset_reg, + int32_t offset_imm, + LiftoffRegister src, + LiftoffRegList pinned) { + bailout(kRefTypes, "GlobalSet"); +} + void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned, diff --git a/src/wasm/baseline/s390/liftoff-assembler-s390.h b/src/wasm/baseline/s390/liftoff-assembler-s390.h index d4dba5d182..a534f3c67e 100644 --- a/src/wasm/baseline/s390/liftoff-assembler-s390.h +++ b/src/wasm/baseline/s390/liftoff-assembler-s390.h @@ -118,6 +118,14 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, bailout(kUnsupportedArchitecture, "LoadTaggedPointer"); } +void LiftoffAssembler::StoreTaggedPointer(Register dst_addr, + Register offset_reg, + int32_t offset_imm, + LiftoffRegister src, + LiftoffRegList pinned) { + bailout(kRefTypes, "GlobalSet"); +} + void LiftoffAssembler::Load(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned, diff --git a/src/wasm/baseline/x64/liftoff-assembler-x64.h b/src/wasm/baseline/x64/liftoff-assembler-x64.h index 3b54a29b89..c6ef82c801 100644 --- a/src/wasm/baseline/x64/liftoff-assembler-x64.h +++ b/src/wasm/baseline/x64/liftoff-assembler-x64.h @@ -275,6 +275,20 @@ void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, LoadTaggedPointerField(dst, src_op); } +void LiftoffAssembler::StoreTaggedPointer(Register dst_addr, + Register offset_reg, + int32_t offset_imm, + LiftoffRegister src, + LiftoffRegList pinned) { + DCHECK_GE(offset_imm, 0); + if (emit_debug_code() && offset_reg != no_reg) { + AssertZeroExtended(offset_reg); + } + Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, + static_cast(offset_imm)); + StoreTaggedField(dst_op, src.gp()); +} + void LiftoffAssembler::AtomicLoad(LiftoffRegister dst, Register src_addr, Register offset_reg, uint32_t offset_imm, LoadType type, LiftoffRegList pinned) { diff --git a/test/mjsunit/wasm/externref-globals-liftoff.js b/test/mjsunit/wasm/externref-globals-liftoff.js new file mode 100644 index 0000000000..53fb6ea0ab --- /dev/null +++ b/test/mjsunit/wasm/externref-globals-liftoff.js @@ -0,0 +1,8 @@ +// Copyright 2020 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --experimental-wasm-reftypes --expose-gc --liftoff +// Flags: --no-wasm-tier-up --liftoff-extern-ref + +load("test/mjsunit/wasm/externref-globals.js");