diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index 52c1124bf5..9daa02a00f 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -185,8 +185,10 @@ Node* WasmGraphBuilder::Phi(wasm::ValueType type, unsigned count, Node** vals, DCHECK(IrOpcode::IsMergeOpcode(control->opcode())); Node** buf = Realloc(vals, count, count + 1); buf[count] = control; - return graph()->NewNode(jsgraph()->common()->Phi(type, count), count + 1, - buf); + return graph()->NewNode( + jsgraph()->common()->Phi(wasm::ValueTypes::MachineRepresentationFor(type), + count), + count + 1, buf); } Node* WasmGraphBuilder::EffectPhi(unsigned count, Node** effects, @@ -1058,7 +1060,7 @@ Node* WasmGraphBuilder::BuildChangeEndiannessStore( Node* result; Node* value = node; MachineOperatorBuilder* m = jsgraph()->machine(); - int valueSizeInBytes = 1 << ElementSizeLog2Of(wasmtype); + int valueSizeInBytes = wasm::ValueTypes::ElementSizeInBytes(wasmtype); int valueSizeInBits = 8 * valueSizeInBytes; bool isFloat = false; @@ -1093,7 +1095,7 @@ Node* WasmGraphBuilder::BuildChangeEndiannessStore( // In case we store lower part of WasmI64 expression, we can truncate // upper 32bits value = graph()->NewNode(m->TruncateInt64ToInt32(), value); - valueSizeInBytes = 1 << ElementSizeLog2Of(wasm::kWasmI32); + valueSizeInBytes = wasm::ValueTypes::ElementSizeInBytes(wasm::kWasmI32); valueSizeInBits = 8 * valueSizeInBytes; if (mem_rep == MachineRepresentation::kWord16) { value = @@ -1207,7 +1209,7 @@ Node* WasmGraphBuilder::BuildChangeEndiannessLoad(Node* node, Node* result; Node* value = node; MachineOperatorBuilder* m = jsgraph()->machine(); - int valueSizeInBytes = 1 << ElementSizeLog2Of(memtype.representation()); + int valueSizeInBytes = ElementSizeInBytes(memtype.representation()); int valueSizeInBits = 8 * valueSizeInBytes; bool isFloat = false; @@ -1834,7 +1836,7 @@ Node* WasmGraphBuilder::BuildCFuncInstruction(ExternalReference ref, // function, and after calling the C function we collect the return value from // the buffer. - const int type_size = 1 << ElementSizeLog2Of(type.representation()); + const int type_size = ElementSizeInBytes(type.representation()); const int stack_slot_bytes = (input1 == nullptr ? 1 : 2) * type_size; Node* stack_slot = graph()->NewNode(jsgraph()->machine()->StackSlot(stack_slot_bytes)); @@ -1891,8 +1893,8 @@ Node* WasmGraphBuilder::BuildIntToFloatConversionInstruction( MachineRepresentation parameter_representation, const MachineType result_type) { int stack_slot_size = - 1 << std::max(ElementSizeLog2Of(parameter_representation), - ElementSizeLog2Of(result_type.representation())); + std::max(ElementSizeInBytes(parameter_representation), + ElementSizeInBytes(result_type.representation())); Node* stack_slot = graph()->NewNode(jsgraph()->machine()->StackSlot(stack_slot_size)); const Operator* store_op = jsgraph()->machine()->Store( @@ -1940,9 +1942,8 @@ Node* WasmGraphBuilder::BuildCcallConvertFloat(Node* input, const MachineType int_ty = IntConvertType(opcode); const MachineType float_ty = FloatConvertType(opcode); ExternalReference call_ref = convert_ccall_ref(this, opcode); - int stack_slot_size = - 1 << std::max(ElementSizeLog2Of(int_ty.representation()), - ElementSizeLog2Of(float_ty.representation())); + int stack_slot_size = std::max(ElementSizeInBytes(int_ty.representation()), + ElementSizeInBytes(float_ty.representation())); Node* stack_slot = graph()->NewNode(jsgraph()->machine()->StackSlot(stack_slot_size)); const Operator* store_op = jsgraph()->machine()->Store( @@ -2012,7 +2013,8 @@ uint32_t WasmGraphBuilder::GetExceptionEncodedSize( const wasm::WasmExceptionSig* sig = exception->sig; uint32_t encoded_size = 0; for (size_t i = 0; i < sig->parameter_count(); ++i) { - size_t byte_size = size_t(1) << ElementSizeLog2Of(sig->GetParam(i)); + size_t byte_size = static_cast( + wasm::ValueTypes::ElementSizeInBytes(sig->GetParam(i))); DCHECK_EQ(byte_size % kBytesPerExceptionValuesArrayElement, 0); DCHECK_LE(1, byte_size / kBytesPerExceptionValuesArrayElement); encoded_size += byte_size / kBytesPerExceptionValuesArrayElement; @@ -3277,7 +3279,7 @@ void WasmGraphBuilder::BuildWasmInterpreterEntry(uint32_t func_index) { // Compute size for the argument buffer. int args_size_bytes = 0; for (wasm::ValueType type : sig_->parameters()) { - args_size_bytes += 1 << ElementSizeLog2Of(type); + args_size_bytes += wasm::ValueTypes::ElementSizeInBytes(type); } // The return value is also passed via this buffer: @@ -3285,7 +3287,9 @@ void WasmGraphBuilder::BuildWasmInterpreterEntry(uint32_t func_index) { // TODO(wasm): Handle multi-value returns. DCHECK_EQ(1, wasm::kV8MaxWasmFunctionReturns); int return_size_bytes = - sig_->return_count() == 0 ? 0 : 1 << ElementSizeLog2Of(sig_->GetReturn()); + sig_->return_count() == 0 + ? 0 + : wasm::ValueTypes::ElementSizeInBytes(sig_->GetReturn()); // Get a stack slot for the arguments. Node* arg_buffer = @@ -3303,7 +3307,7 @@ void WasmGraphBuilder::BuildWasmInterpreterEntry(uint32_t func_index) { *effect_ = graph()->NewNode(GetSafeStoreOperator(offset, type), arg_buffer, Int32Constant(offset), Param(i + 1), *effect_, *control_); - offset += 1 << ElementSizeLog2Of(type); + offset += wasm::ValueTypes::ElementSizeInBytes(type); } DCHECK_EQ(args_size_bytes, offset); @@ -3364,7 +3368,7 @@ void WasmGraphBuilder::BuildCWasmEntry() { Int32Constant(offset), *effect_, *control_); *effect_ = arg_load; args[pos++] = arg_load; - offset += 1 << ElementSizeLog2Of(type); + offset += wasm::ValueTypes::ElementSizeInBytes(type); } args[pos++] = *effect_; @@ -3381,7 +3385,9 @@ void WasmGraphBuilder::BuildCWasmEntry() { // Store the return value. DCHECK_GE(1, sig_->return_count()); if (sig_->return_count() == 1) { - StoreRepresentation store_rep(sig_->GetReturn(), kNoWriteBarrier); + StoreRepresentation store_rep( + wasm::ValueTypes::MachineRepresentationFor(sig_->GetReturn()), + kNoWriteBarrier); Node* store = graph()->NewNode(jsgraph()->machine()->Store(store_rep), arg_buffer, Int32Constant(0), call, *effect_, *control_); @@ -3396,7 +3402,7 @@ void WasmGraphBuilder::BuildCWasmEntry() { MachineRepresentation::kTagged, // arg0 (code) MachineRepresentation::kTagged // arg1 (buffer) }; - wasm::FunctionSig c_entry_sig(1, 2, sig_reps); + Signature c_entry_sig(1, 2, sig_reps); Int64Lowering r(jsgraph()->graph(), jsgraph()->machine(), jsgraph()->common(), jsgraph()->zone(), &c_entry_sig); r.LowerGraph(); @@ -3441,8 +3447,9 @@ void WasmGraphBuilder::InitInstanceCache( void WasmGraphBuilder::PrepareInstanceCacheForLoop( WasmInstanceCacheNodes* instance_cache, Node* control) { -#define INTRODUCE_PHI(field, rep) \ - instance_cache->field = Phi(rep, 1, &instance_cache->field, control); +#define INTRODUCE_PHI(field, rep) \ + instance_cache->field = graph()->NewNode(jsgraph()->common()->Phi(rep, 1), \ + instance_cache->field, control); INTRODUCE_PHI(mem_start, MachineType::PointerRepresentation()); INTRODUCE_PHI(mem_size, MachineRepresentation::kWord32); @@ -3456,10 +3463,10 @@ void WasmGraphBuilder::PrepareInstanceCacheForLoop( void WasmGraphBuilder::NewInstanceCacheMerge(WasmInstanceCacheNodes* to, WasmInstanceCacheNodes* from, Node* merge) { -#define INTRODUCE_PHI(field, rep) \ - if (to->field != from->field) { \ - Node* vals[] = {to->field, from->field}; \ - to->field = Phi(rep, 2, vals, merge); \ +#define INTRODUCE_PHI(field, rep) \ + if (to->field != from->field) { \ + Node* vals[] = {to->field, from->field, merge}; \ + to->field = graph()->NewNode(jsgraph()->common()->Phi(rep, 2), 3, vals); \ } INTRODUCE_PHI(mem_start, MachineType::PointerRepresentation()); @@ -3484,16 +3491,20 @@ void WasmGraphBuilder::MergeInstanceCacheInto(WasmInstanceCacheNodes* to, } } -Node* WasmGraphBuilder::CreateOrMergeIntoPhi(wasm::ValueType type, Node* merge, - Node* tnode, Node* fnode) { +Node* WasmGraphBuilder::CreateOrMergeIntoPhi(MachineRepresentation rep, + Node* merge, Node* tnode, + Node* fnode) { if (IsPhiWithMerge(tnode, merge)) { AppendToPhi(tnode, fnode); } else if (tnode != fnode) { uint32_t count = merge->InputCount(); - Node** vals = Buffer(count); + // + 1 for the merge node. + Node** vals = Buffer(count + 1); for (uint32_t j = 0; j < count - 1; j++) vals[j] = tnode; vals[count - 1] = fnode; - return Phi(type, count, vals, merge); + vals[count] = merge; + return graph()->NewNode(jsgraph()->common()->Phi(rep, count), count + 1, + vals); } return tnode; } @@ -3759,9 +3770,10 @@ Node* WasmGraphBuilder::BoundsCheckMem(uint8_t access_size, Node* index, const Operator* WasmGraphBuilder::GetSafeLoadOperator(int offset, wasm::ValueType type) { - int alignment = offset % (1 << ElementSizeLog2Of(type)); + int alignment = offset % (wasm::ValueTypes::ElementSizeInBytes(type)); MachineType mach_type = wasm::ValueTypes::MachineTypeFor(type); - if (alignment == 0 || jsgraph()->machine()->UnalignedLoadSupported(type)) { + if (alignment == 0 || jsgraph()->machine()->UnalignedLoadSupported( + wasm::ValueTypes::MachineRepresentationFor(type))) { return jsgraph()->machine()->Load(mach_type); } return jsgraph()->machine()->UnalignedLoad(mach_type); @@ -3769,13 +3781,14 @@ const Operator* WasmGraphBuilder::GetSafeLoadOperator(int offset, const Operator* WasmGraphBuilder::GetSafeStoreOperator(int offset, wasm::ValueType type) { - int alignment = offset % (1 << ElementSizeLog2Of(type)); - if (alignment == 0 || jsgraph()->machine()->UnalignedStoreSupported(type)) { - StoreRepresentation rep(type, WriteBarrierKind::kNoWriteBarrier); - return jsgraph()->machine()->Store(rep); + int alignment = offset % (wasm::ValueTypes::ElementSizeInBytes(type)); + MachineRepresentation rep = wasm::ValueTypes::MachineRepresentationFor(type); + if (alignment == 0 || jsgraph()->machine()->UnalignedStoreSupported(rep)) { + StoreRepresentation store_rep(rep, WriteBarrierKind::kNoWriteBarrier); + return jsgraph()->machine()->Store(store_rep); } - UnalignedStoreRepresentation rep(type); - return jsgraph()->machine()->UnalignedStore(rep); + UnalignedStoreRepresentation store_rep(rep); + return jsgraph()->machine()->UnalignedStore(store_rep); } Node* WasmGraphBuilder::TraceMemoryOperation(bool is_store, @@ -3843,7 +3856,7 @@ Node* WasmGraphBuilder::LoadMem(wasm::ValueType type, MachineType memtype, #endif if (type == wasm::kWasmI64 && - ElementSizeLog2Of(memtype.representation()) < 3) { + ElementSizeInBytes(memtype.representation()) < 8) { // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. if (memtype.IsSigned()) { // sign extend @@ -3869,7 +3882,7 @@ Node* WasmGraphBuilder::StoreMem(MachineRepresentation mem_rep, Node* index, wasm::ValueType type) { Node* store; - index = BoundsCheckMem(wasm::ValueTypes::MemSize(mem_rep), index, offset, + index = BoundsCheckMem(i::ElementSizeInBytes(mem_rep), index, offset, position, kCanOmitBoundsCheck); #if defined(V8_TARGET_BIG_ENDIAN) @@ -4020,15 +4033,33 @@ Node* WasmGraphBuilder::String(const char* string) { Graph* WasmGraphBuilder::graph() { return jsgraph()->graph(); } +namespace { +Signature* CreateMachineSignature( + Zone* zone, wasm::FunctionSig* sig) { + Signature::Builder builder(zone, sig->return_count(), + sig->parameter_count()); + for (auto ret : sig->returns()) { + builder.AddReturn(wasm::ValueTypes::MachineRepresentationFor(ret)); + } + + for (auto param : sig->parameters()) { + builder.AddParam(wasm::ValueTypes::MachineRepresentationFor(param)); + } + return builder.Build(); +} +} // namespace + void WasmGraphBuilder::LowerInt64() { if (jsgraph()->machine()->Is64()) return; Int64Lowering r(jsgraph()->graph(), jsgraph()->machine(), jsgraph()->common(), - jsgraph()->zone(), sig_); + jsgraph()->zone(), + CreateMachineSignature(jsgraph()->zone(), sig_)); r.LowerGraph(); } void WasmGraphBuilder::SimdScalarLoweringForTesting() { - SimdScalarLowering(jsgraph(), sig_).LowerGraph(); + SimdScalarLowering(jsgraph(), CreateMachineSignature(jsgraph()->zone(), sig_)) + .LowerGraph(); } void WasmGraphBuilder::SetSourcePosition(Node* node, @@ -4970,7 +5001,10 @@ SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction( if (builder.has_simd() && (!CpuFeatures::SupportsWasmSimd128() || wasm_unit_->lower_simd_)) { - SimdScalarLowering(jsgraph_, wasm_unit_->func_body_.sig).LowerGraph(); + SimdScalarLowering( + jsgraph_, + CreateMachineSignature(jsgraph_->zone(), wasm_unit_->func_body_.sig)) + .LowerGraph(); } if (wasm_unit_->func_index_ >= FLAG_trace_wasm_ast_start && @@ -5138,16 +5172,17 @@ class LinkageLocationAllocator { const DoubleRegister (&fp)[kNumFpRegs]) : allocator_(wasm::LinkageAllocator(gp, fp)) {} - LinkageLocation Next(wasm::ValueType type) { - MachineType mach_type = wasm::ValueTypes::MachineTypeFor(type); - if (type == wasm::kWasmF32 || type == wasm::kWasmF64) { + LinkageLocation Next(MachineRepresentation type) { + MachineType mach_type = MachineType::TypeForRepresentation(type); + if (type == MachineRepresentation::kFloat32 || + type == MachineRepresentation::kFloat64) { if (allocator_.has_more_fp_regs()) { DoubleRegister reg = allocator_.NextFpReg(); #if V8_TARGET_ARCH_ARM // Allocate floats using a double register, but modify the code to // reflect how ARM FP registers alias. // TODO(bbudge) Modify wasm linkage to allow use of all float regs. - if (type == wasm::kWasmF32) { + if (type == MachineRepresentation::kFloat32) { int float_reg_code = reg.code() * 2; DCHECK_GT(RegisterConfiguration::kMaxFPRegisters, float_reg_code); return LinkageLocation::ForRegister( @@ -5189,7 +5224,8 @@ CallDescriptor* GetWasmCallDescriptor(Zone* zone, wasm::FunctionSig* fsig, const int parameter_count = static_cast(fsig->parameter_count()); for (int i = 0; i < parameter_count; i++) { - wasm::ValueType param = fsig->GetParam(i); + MachineRepresentation param = + wasm::ValueTypes::MachineRepresentationFor(fsig->GetParam(i)); auto l = params.Next(param); locations.AddParam(l); } @@ -5201,7 +5237,8 @@ CallDescriptor* GetWasmCallDescriptor(Zone* zone, wasm::FunctionSig* fsig, const int return_count = static_cast(locations.return_count_); for (int i = 0; i < return_count; i++) { - wasm::ValueType ret = fsig->GetReturn(i); + MachineRepresentation ret = + wasm::ValueTypes::MachineRepresentationFor(fsig->GetReturn(i)); auto l = rets.Next(ret); locations.AddReturn(l); } diff --git a/src/compiler/wasm-compiler.h b/src/compiler/wasm-compiler.h index 5f330d9c20..b3b3f15344 100644 --- a/src/compiler/wasm-compiler.h +++ b/src/compiler/wasm-compiler.h @@ -176,8 +176,8 @@ class WasmGraphBuilder { Node* Terminate(Node* effect, Node* control); Node* Merge(unsigned count, Node** controls); Node* Phi(wasm::ValueType type, unsigned count, Node** vals, Node* control); - Node* CreateOrMergeIntoPhi(wasm::ValueType type, Node* merge, Node* tnode, - Node* fnode); + Node* CreateOrMergeIntoPhi(MachineRepresentation rep, Node* merge, + Node* tnode, Node* fnode); Node* CreateOrMergeIntoEffectPhi(Node* merge, Node* tnode, Node* fnode); Node* EffectPhi(unsigned count, Node** effects, Node* control); Node* NumberConstant(int32_t value); diff --git a/src/machine-type.h b/src/machine-type.h index e242e2821c..68db01a4ef 100644 --- a/src/machine-type.h +++ b/src/machine-type.h @@ -52,6 +52,8 @@ enum class MachineSemantic : uint8_t { V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep); +V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep); + class MachineType { public: constexpr MachineType() @@ -292,6 +294,10 @@ V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep) { UNREACHABLE(); } +V8_EXPORT_PRIVATE inline int ElementSizeInBytes(MachineRepresentation rep) { + return 1 << ElementSizeLog2Of(rep); +} + } // namespace internal } // namespace v8 diff --git a/src/wasm/function-body-decoder-impl.h b/src/wasm/function-body-decoder-impl.h index 89be64ad19..3cd310d3ec 100644 --- a/src/wasm/function-body-decoder-impl.h +++ b/src/wasm/function-body-decoder-impl.h @@ -2108,7 +2108,7 @@ class WasmFullDecoder : public WasmDecoder { unsigned SimdExtractLane(WasmOpcode opcode, ValueType type) { SimdLaneImmediate imm(this, this->pc_); if (this->Validate(this->pc_, opcode, imm)) { - Value inputs[] = {Pop(0, ValueType::kSimd128)}; + Value inputs[] = {Pop(0, kWasmS128)}; auto* result = Push(type); CALL_INTERFACE_IF_REACHABLE(SimdLaneOp, opcode, imm, ArrayVector(inputs), result); @@ -2121,8 +2121,8 @@ class WasmFullDecoder : public WasmDecoder { if (this->Validate(this->pc_, opcode, imm)) { Value inputs[2]; inputs[1] = Pop(1, type); - inputs[0] = Pop(0, ValueType::kSimd128); - auto* result = Push(ValueType::kSimd128); + inputs[0] = Pop(0, kWasmS128); + auto* result = Push(kWasmS128); CALL_INTERFACE_IF_REACHABLE(SimdLaneOp, opcode, imm, ArrayVector(inputs), result); } @@ -2132,8 +2132,8 @@ class WasmFullDecoder : public WasmDecoder { unsigned SimdShiftOp(WasmOpcode opcode) { SimdShiftImmediate imm(this, this->pc_); if (this->Validate(this->pc_, opcode, imm)) { - auto input = Pop(0, ValueType::kSimd128); - auto* result = Push(ValueType::kSimd128); + auto input = Pop(0, kWasmS128); + auto* result = Push(kWasmS128); CALL_INTERFACE_IF_REACHABLE(SimdShiftOp, opcode, imm, input, result); } return imm.length; @@ -2142,9 +2142,9 @@ class WasmFullDecoder : public WasmDecoder { unsigned Simd8x16ShuffleOp() { Simd8x16ShuffleImmediate imm(this, this->pc_); if (this->Validate(this->pc_, imm)) { - auto input1 = Pop(1, ValueType::kSimd128); - auto input0 = Pop(0, ValueType::kSimd128); - auto* result = Push(ValueType::kSimd128); + auto input1 = Pop(1, kWasmS128); + auto input0 = Pop(0, kWasmS128); + auto* result = Push(kWasmS128); CALL_INTERFACE_IF_REACHABLE(Simd8x16ShuffleOp, imm, input0, input1, result); } @@ -2155,23 +2155,23 @@ class WasmFullDecoder : public WasmDecoder { unsigned len = 0; switch (opcode) { case kExprF32x4ExtractLane: { - len = SimdExtractLane(opcode, ValueType::kFloat32); + len = SimdExtractLane(opcode, kWasmF32); break; } case kExprI32x4ExtractLane: case kExprI16x8ExtractLane: case kExprI8x16ExtractLane: { - len = SimdExtractLane(opcode, ValueType::kWord32); + len = SimdExtractLane(opcode, kWasmI32); break; } case kExprF32x4ReplaceLane: { - len = SimdReplaceLane(opcode, ValueType::kFloat32); + len = SimdReplaceLane(opcode, kWasmF32); break; } case kExprI32x4ReplaceLane: case kExprI16x8ReplaceLane: case kExprI8x16ReplaceLane: { - len = SimdReplaceLane(opcode, ValueType::kWord32); + len = SimdReplaceLane(opcode, kWasmI32); break; } case kExprI32x4Shl: @@ -2218,11 +2218,11 @@ class WasmFullDecoder : public WasmDecoder { if (sig != nullptr) { MachineType memtype; switch (opcode) { -#define CASE_ATOMIC_STORE_OP(Name, Type) \ - case kExpr##Name: { \ - memtype = MachineType::Type(); \ - ret_type = MachineRepresentation::kNone; \ - break; \ +#define CASE_ATOMIC_STORE_OP(Name, Type) \ + case kExpr##Name: { \ + memtype = MachineType::Type(); \ + ret_type = kWasmStmt; \ + break; \ } ATOMIC_STORE_OP_LIST(CASE_ATOMIC_STORE_OP) #undef CASE_ATOMIC_OP @@ -2242,9 +2242,7 @@ class WasmFullDecoder : public WasmDecoder { this, this->pc_ + 1, ElementSizeLog2Of(memtype.representation())); len += imm.length; PopArgs(sig); - auto result = ret_type == MachineRepresentation::kNone - ? nullptr - : Push(GetReturnType(sig)); + auto result = ret_type == kWasmStmt ? nullptr : Push(GetReturnType(sig)); CALL_INTERFACE_IF_REACHABLE(AtomicOp, opcode, vec2vec(args_), imm, result); } else { diff --git a/src/wasm/function-body-decoder.cc b/src/wasm/function-body-decoder.cc index 9afc7880ae..a4a38e5750 100644 --- a/src/wasm/function-body-decoder.cc +++ b/src/wasm/function-body-decoder.cc @@ -574,9 +574,9 @@ class WasmGraphBuildingInterface { try_info->exception = if_exception; } else { DCHECK_EQ(SsaEnv::kMerged, try_info->catch_env->state); - try_info->exception = - builder_->CreateOrMergeIntoPhi(kWasmI32, try_info->catch_env->control, - try_info->exception, if_exception); + try_info->exception = builder_->CreateOrMergeIntoPhi( + MachineRepresentation::kWord32, try_info->catch_env->control, + try_info->exception, if_exception); } SetEnv(success_env); @@ -618,7 +618,8 @@ class WasmGraphBuildingInterface { DCHECK(val.type == old.type || val.type == kWasmVar); old.node = first ? val.node : builder_->CreateOrMergeIntoPhi( - old.type, target->control, old.node, val.node); + ValueTypes::MachineRepresentationFor(old.type), + target->control, old.node, val.node); } } @@ -670,7 +671,8 @@ class WasmGraphBuildingInterface { // Merge locals. for (int i = decoder->NumLocals() - 1; i >= 0; i--) { to->locals[i] = builder_->CreateOrMergeIntoPhi( - decoder->GetLocalType(i), merge, to->locals[i], from->locals[i]); + ValueTypes::MachineRepresentationFor(decoder->GetLocalType(i)), + merge, to->locals[i], from->locals[i]); } // Merge the instance caches. builder_->MergeInstanceCacheInto(&to->instance_cache, diff --git a/src/wasm/signature-map.h b/src/wasm/signature-map.h index 25d8d2c576..3fab0fde16 100644 --- a/src/wasm/signature-map.h +++ b/src/wasm/signature-map.h @@ -7,7 +7,7 @@ #include -#include "src/machine-type.h" +#include "src/wasm/value-type.h" namespace v8 { namespace internal { @@ -17,7 +17,6 @@ class Signature; namespace wasm { -using ValueType = MachineRepresentation; using FunctionSig = Signature; // A signature map canonicalizes signatures into a range of indices so that diff --git a/src/wasm/value-type.h b/src/wasm/value-type.h index 3301c7b735..42b078aeac 100644 --- a/src/wasm/value-type.h +++ b/src/wasm/value-type.h @@ -12,17 +12,16 @@ namespace v8 { namespace internal { namespace wasm { -// We reuse the internal machine type to represent WebAssembly types. -// A typedef improves readability without adding a whole new type system. -using ValueType = MachineRepresentation; -constexpr ValueType kWasmStmt = MachineRepresentation::kNone; -constexpr ValueType kWasmI32 = MachineRepresentation::kWord32; -constexpr ValueType kWasmI64 = MachineRepresentation::kWord64; -constexpr ValueType kWasmF32 = MachineRepresentation::kFloat32; -constexpr ValueType kWasmF64 = MachineRepresentation::kFloat64; -constexpr ValueType kWasmS128 = MachineRepresentation::kSimd128; -constexpr ValueType kWasmAnyRef = MachineRepresentation::kTaggedPointer; -constexpr ValueType kWasmVar = MachineRepresentation::kTagged; +enum ValueType : uint8_t { + kWasmStmt, + kWasmI32, + kWasmI64, + kWasmF32, + kWasmF64, + kWasmS128, + kWasmAnyRef, + kWasmVar, +}; // TODO(clemensh): Compute memtype and size from ValueType once we have c++14 // constexpr support. @@ -126,7 +125,7 @@ class StoreType { constexpr unsigned size_log_2() const { return kStoreSizeLog2[val_]; } constexpr unsigned size() const { return 1 << size_log_2(); } constexpr ValueType value_type() const { return kValueType[val_]; } - constexpr ValueType mem_rep() const { return kMemRep[val_]; } + constexpr MachineRepresentation mem_rep() const { return kMemRep[val_]; } static StoreType ForValueType(ValueType type) { switch (type) { @@ -169,7 +168,37 @@ class StoreType { class V8_EXPORT_PRIVATE ValueTypes { public: static byte MemSize(MachineType type) { - return MemSize(type.representation()); + return 1 << i::ElementSizeLog2Of(type.representation()); + } + + static int ElementSizeInBytes(ValueType type) { + switch (type) { + case kWasmI32: + case kWasmF32: + return 4; + case kWasmI64: + case kWasmF64: + return 8; + case kWasmS128: + return 16; + default: + UNREACHABLE(); + } + } + + static int ElementSizeLog2Of(ValueType type) { + switch (type) { + case kWasmI32: + case kWasmF32: + return 2; + case kWasmI64: + case kWasmF64: + return 3; + case kWasmS128: + return 4; + default: + UNREACHABLE(); + } } static byte MemSize(ValueType type) { return 1 << ElementSizeLog2Of(type); } @@ -216,6 +245,27 @@ class V8_EXPORT_PRIVATE ValueTypes { } } + static MachineRepresentation MachineRepresentationFor(ValueType type) { + switch (type) { + case kWasmI32: + return MachineRepresentation::kWord32; + case kWasmI64: + return MachineRepresentation::kWord64; + case kWasmF32: + return MachineRepresentation::kFloat32; + case kWasmF64: + return MachineRepresentation::kFloat64; + case kWasmAnyRef: + return MachineRepresentation::kTaggedPointer; + case kWasmS128: + return MachineRepresentation::kSimd128; + case kWasmStmt: + return MachineRepresentation::kNone; + default: + UNREACHABLE(); + } + } + static ValueType ValueTypeFor(MachineType type) { switch (type.representation()) { case MachineRepresentation::kWord8: diff --git a/src/wasm/wasm-debug.cc b/src/wasm/wasm-debug.cc index c4a950c3f4..986819ffeb 100644 --- a/src/wasm/wasm-debug.cc +++ b/src/wasm/wasm-debug.cc @@ -177,7 +177,8 @@ class InterpreterHandle { ScopedVector wasm_args(num_params); Address arg_buf_ptr = arg_buffer; for (int i = 0; i < num_params; ++i) { - uint32_t param_size = 1 << ElementSizeLog2Of(sig->GetParam(i)); + uint32_t param_size = static_cast( + ValueTypes::ElementSizeInBytes(sig->GetParam(i))); #define CASE_ARG_TYPE(type, ctype) \ case type: \ DCHECK_EQ(param_size, sizeof(ctype)); \ @@ -240,10 +241,11 @@ class InterpreterHandle { DCHECK_EQ(1, kV8MaxWasmFunctionReturns); if (sig->return_count()) { WasmValue ret_val = thread->GetReturnValue(0); -#define CASE_RET_TYPE(type, ctype) \ - case type: \ - DCHECK_EQ(1 << ElementSizeLog2Of(sig->GetReturn(0)), sizeof(ctype)); \ - WriteUnalignedValue(arg_buffer, ret_val.to()); \ +#define CASE_RET_TYPE(type, ctype) \ + case type: \ + DCHECK_EQ(ValueTypes::ElementSizeInBytes(sig->GetReturn(0)), \ + sizeof(ctype)); \ + WriteUnalignedValue(arg_buffer, ret_val.to()); \ break; switch (sig->GetReturn(0)) { CASE_RET_TYPE(kWasmI32, uint32_t) diff --git a/src/wasm/wasm-interpreter.cc b/src/wasm/wasm-interpreter.cc index 86333e2bbc..79b5542150 100644 --- a/src/wasm/wasm-interpreter.cc +++ b/src/wasm/wasm-interpreter.cc @@ -2281,7 +2281,7 @@ class ThreadImpl { size_t offset = 0; WasmValue* wasm_args = sp_ - num_args; for (int i = 0; i < num_args; ++i) { - uint32_t param_size = 1 << ElementSizeLog2Of(sig->GetParam(i)); + int param_size = ValueTypes::ElementSizeInBytes(sig->GetParam(i)); if (arg_buffer.size() < offset + param_size) { arg_buffer.resize(std::max(2 * arg_buffer.size(), offset + param_size)); } @@ -2307,9 +2307,9 @@ class ThreadImpl { // Ensure that there is enough space in the arg_buffer to hold the return // value(s). - uint32_t return_size = 0; + size_t return_size = 0; for (ValueType t : sig->returns()) { - return_size += 1 << ElementSizeLog2Of(t); + return_size += ValueTypes::ElementSizeInBytes(t); } if (arg_buffer.size() < return_size) { arg_buffer.resize(return_size); diff --git a/src/wasm/wasm-linkage.h b/src/wasm/wasm-linkage.h index 761c18fe3a..65fc0a2600 100644 --- a/src/wasm/wasm-linkage.h +++ b/src/wasm/wasm-linkage.h @@ -139,14 +139,14 @@ class LinkageAllocator { // Stackslots are counted upwards starting from 0 (or the offset set by // {SetStackOffset}. - int NumStackSlots(ValueType type) { - return 1 << std::max(0, ElementSizeLog2Of(type) - kPointerSizeLog2); + int NumStackSlots(MachineRepresentation type) { + return std::max(1, ElementSizeInBytes(type) / kPointerSize); } // Stackslots are counted upwards starting from 0 (or the offset set by // {SetStackOffset}. If {type} needs more than // one stack slot, the lowest used stack slot is returned. - int NextStackSlot(ValueType type) { + int NextStackSlot(MachineRepresentation type) { int num_stack_slots = NumStackSlots(type); int offset = stack_offset_; stack_offset_ += num_stack_slots; diff --git a/src/wasm/wasm-objects-inl.h b/src/wasm/wasm-objects-inl.h index c1fbffdd74..8da7678414 100644 --- a/src/wasm/wasm-objects-inl.h +++ b/src/wasm/wasm-objects-inl.h @@ -71,17 +71,14 @@ BIT_FIELD_ACCESSORS(WasmGlobalObject, flags, type, WasmGlobalObject::TypeBits) BIT_FIELD_ACCESSORS(WasmGlobalObject, flags, is_mutable, WasmGlobalObject::IsMutableBit) -// static -uint32_t WasmGlobalObject::TypeSize(wasm::ValueType type) { - return 1U << ElementSizeLog2Of(type); +int WasmGlobalObject::type_size() const { + return wasm::ValueTypes::ElementSizeInBytes(type()); } -uint32_t WasmGlobalObject::type_size() const { return TypeSize(type()); } - Address WasmGlobalObject::address() const { uint32_t buffer_size = 0; DCHECK(array_buffer()->byte_length()->ToUint32(&buffer_size)); - DCHECK(offset() + type_size() <= buffer_size); + DCHECK_LE(offset() + type_size(), buffer_size); USE(buffer_size); return Address(array_buffer()->backing_store()) + offset(); } diff --git a/src/wasm/wasm-objects.cc b/src/wasm/wasm-objects.cc index b6add9a1cc..51886e8108 100644 --- a/src/wasm/wasm-objects.cc +++ b/src/wasm/wasm-objects.cc @@ -633,7 +633,7 @@ MaybeHandle WasmGlobalObject::New( auto global_obj = Handle::cast( isolate->factory()->NewJSObject(global_ctor)); - uint32_t type_size = TypeSize(type); + uint32_t type_size = wasm::ValueTypes::ElementSizeInBytes(type); Handle buffer; if (!maybe_buffer.ToHandle(&buffer)) { diff --git a/src/wasm/wasm-objects.h b/src/wasm/wasm-objects.h index 21a9769399..c941495e40 100644 --- a/src/wasm/wasm-objects.h +++ b/src/wasm/wasm-objects.h @@ -12,6 +12,7 @@ #include "src/objects.h" #include "src/objects/script.h" #include "src/signature.h" +#include "src/wasm/value-type.h" // Has to be the last include (doesn't have include guards) #include "src/objects/object-macros.h" @@ -28,7 +29,6 @@ struct WasmModule; class SignatureMap; class WireBytesRef; class WasmInterpreter; -using ValueType = MachineRepresentation; using FunctionSig = Signature; } // namespace wasm @@ -250,8 +250,7 @@ class WasmGlobalObject : public JSObject { Isolate* isolate, MaybeHandle buffer, wasm::ValueType type, int32_t offset, bool is_mutable); - static inline uint32_t TypeSize(wasm::ValueType); - inline uint32_t type_size() const; + inline int type_size() const; inline int32_t GetI32(); inline int64_t GetI64(); diff --git a/src/wasm/wasm-opcodes.h b/src/wasm/wasm-opcodes.h index 5e0cad0195..5faf715355 100644 --- a/src/wasm/wasm-opcodes.h +++ b/src/wasm/wasm-opcodes.h @@ -570,6 +570,7 @@ enum TrapReason { kTrapCount #undef DECLARE_ENUM }; + // A collection of opcode-related static methods. class V8_EXPORT_PRIVATE WasmOpcodes { public: diff --git a/test/cctest/compiler/test-multiple-return.cc b/test/cctest/compiler/test-multiple-return.cc index 2b322fa19e..7681722dde 100644 --- a/test/cctest/compiler/test-multiple-return.cc +++ b/test/cctest/compiler/test-multiple-return.cc @@ -35,11 +35,11 @@ CallDescriptor* CreateCallDescriptor(Zone* zone, int return_count, wasm::FunctionSig::Builder builder(zone, return_count, param_count); for (int i = 0; i < param_count; i++) { - builder.AddParam(type.representation()); + builder.AddParam(wasm::ValueTypes::ValueTypeFor(type)); } for (int i = 0; i < return_count; i++) { - builder.AddReturn(type.representation()); + builder.AddReturn(wasm::ValueTypes::ValueTypeFor(type)); } return compiler::GetWasmCallDescriptor(zone, builder.Build()); } diff --git a/test/cctest/wasm/test-wasm-breakpoints.cc b/test/cctest/wasm/test-wasm-breakpoints.cc index c2472bb029..ad5997dab5 100644 --- a/test/cctest/wasm/test-wasm-breakpoints.cc +++ b/test/cctest/wasm/test-wasm-breakpoints.cc @@ -321,7 +321,7 @@ WASM_COMPILED_EXEC_TEST(WasmSimpleStepping) { WASM_COMPILED_EXEC_TEST(WasmStepInAndOut) { WasmRunner runner(execution_mode); WasmFunctionCompiler& f2 = runner.NewFunction(); - f2.AllocateLocal(ValueType::kWord32); + f2.AllocateLocal(kWasmI32); // Call f2 via indirect call, because a direct call requires f2 to exist when // we compile main, but we need to compile main first so that the order of @@ -360,9 +360,9 @@ WASM_COMPILED_EXEC_TEST(WasmStepInAndOut) { WASM_COMPILED_EXEC_TEST(WasmGetLocalsAndStack) { WasmRunner runner(execution_mode); - runner.AllocateLocal(ValueType::kWord64); - runner.AllocateLocal(ValueType::kFloat32); - runner.AllocateLocal(ValueType::kFloat64); + runner.AllocateLocal(kWasmI64); + runner.AllocateLocal(kWasmF32); + runner.AllocateLocal(kWasmF64); BUILD(runner, // set [1] to 17 diff --git a/test/common/wasm/wasm-module-runner.cc b/test/common/wasm/wasm-module-runner.cc index 02630ebfaf..02d7185b71 100644 --- a/test/common/wasm/wasm-module-runner.cc +++ b/test/common/wasm/wasm-module-runner.cc @@ -74,16 +74,16 @@ bool InterpretWasmModuleForTesting(Isolate* isolate, // Fill the parameters up with default values. for (size_t i = argc; i < param_count; ++i) { switch (signature->GetParam(i)) { - case MachineRepresentation::kWord32: + case kWasmI32: arguments[i] = WasmValue(int32_t{0}); break; - case MachineRepresentation::kWord64: + case kWasmI64: arguments[i] = WasmValue(int64_t{0}); break; - case MachineRepresentation::kFloat32: + case kWasmF32: arguments[i] = WasmValue(0.0f); break; - case MachineRepresentation::kFloat64: + case kWasmF64: arguments[i] = WasmValue(0.0); break; default: diff --git a/test/fuzzer/multi-return.cc b/test/fuzzer/multi-return.cc index d6265c39d2..6da801866c 100644 --- a/test/fuzzer/multi-return.cc +++ b/test/fuzzer/multi-return.cc @@ -135,14 +135,14 @@ CallDescriptor* CreateRandomCallDescriptor(Zone* zone, size_t return_count, wasm::FunctionSig::Builder builder(zone, return_count, param_count); for (size_t i = 0; i < param_count; i++) { MachineType type = RandomType(input); - builder.AddParam(type.representation()); + builder.AddParam(wasm::ValueTypes::ValueTypeFor(type)); } // Read the end byte of the parameters. input->NextInt8(1); for (size_t i = 0; i < return_count; i++) { MachineType type = RandomType(input); - builder.AddReturn(type.representation()); + builder.AddReturn(wasm::ValueTypes::ValueTypeFor(type)); } return compiler::GetWasmCallDescriptor(zone, builder.Build()); diff --git a/test/unittests/compiler/int64-lowering-unittest.cc b/test/unittests/compiler/int64-lowering-unittest.cc index baf89f296f..5897187ae4 100644 --- a/test/unittests/compiler/int64-lowering-unittest.cc +++ b/test/unittests/compiler/int64-lowering-unittest.cc @@ -11,6 +11,7 @@ #include "src/compiler/wasm-compiler.h" #include "src/objects-inl.h" #include "src/signature.h" +#include "src/wasm/value-type.h" #include "src/wasm/wasm-module.h" #include "test/unittests/compiler/graph-unittest.h" #include "test/unittests/compiler/node-test-utils.h" @@ -330,8 +331,8 @@ TEST_F(Int64LoweringTest, CallI64Return) { int32_t function = 0x9999; Node* context_address = Int32Constant(0); - Signature::Builder sig_builder(zone(), 1, 0); - sig_builder.AddReturn(MachineRepresentation::kWord64); + wasm::FunctionSig::Builder sig_builder(zone(), 1, 0); + sig_builder.AddReturn(wasm::kWasmI64); auto call_descriptor = compiler::GetWasmCallDescriptor(zone(), sig_builder.Build()); @@ -360,11 +361,11 @@ TEST_F(Int64LoweringTest, CallI64Parameter) { int32_t function = 0x9999; Node* context_address = Int32Constant(0); - Signature::Builder sig_builder(zone(), 1, 3); - sig_builder.AddReturn(MachineRepresentation::kWord32); - sig_builder.AddParam(MachineRepresentation::kWord64); - sig_builder.AddParam(MachineRepresentation::kWord32); - sig_builder.AddParam(MachineRepresentation::kWord64); + wasm::FunctionSig::Builder sig_builder(zone(), 1, 3); + sig_builder.AddReturn(wasm::kWasmI32); + sig_builder.AddParam(wasm::kWasmI64); + sig_builder.AddParam(wasm::kWasmI32); + sig_builder.AddParam(wasm::kWasmI64); auto call_descriptor = compiler::GetWasmCallDescriptor(zone(), sig_builder.Build()); diff --git a/test/unittests/wasm/module-decoder-unittest.cc b/test/unittests/wasm/module-decoder-unittest.cc index 79ae8e578b..f0e98cf0a4 100644 --- a/test/unittests/wasm/module-decoder-unittest.cc +++ b/test/unittests/wasm/module-decoder-unittest.cc @@ -462,7 +462,7 @@ TEST_F(WasmModuleVerifyTest, OneI32Exception) { const WasmException& e0 = result.val->exceptions.front(); EXPECT_EQ(1u, e0.sig->parameter_count()); - EXPECT_EQ(MachineRepresentation::kWord32, e0.sig->GetParam(0)); + EXPECT_EQ(kWasmI32, e0.sig->GetParam(0)); } TEST_F(WasmModuleVerifyTest, TwoExceptions) { @@ -479,10 +479,10 @@ TEST_F(WasmModuleVerifyTest, TwoExceptions) { EXPECT_EQ(2u, result.val->exceptions.size()); const WasmException& e0 = result.val->exceptions.front(); EXPECT_EQ(2u, e0.sig->parameter_count()); - EXPECT_EQ(MachineRepresentation::kFloat32, e0.sig->GetParam(0)); - EXPECT_EQ(MachineRepresentation::kWord64, e0.sig->GetParam(1)); + EXPECT_EQ(kWasmF32, e0.sig->GetParam(0)); + EXPECT_EQ(kWasmI64, e0.sig->GetParam(1)); const WasmException& e1 = result.val->exceptions.back(); - EXPECT_EQ(MachineRepresentation::kWord32, e1.sig->GetParam(0)); + EXPECT_EQ(kWasmI32, e1.sig->GetParam(0)); } TEST_F(WasmModuleVerifyTest, Exception_invalid_type) {