[wasm] Make wasm::ValueType independent of the MachineRepresentation

R=clemensh@chromium.org
CC=​titzer@chromium.org

Change-Id: I4951bf7ffc8baf51225e7bef60349186811b9f76
Reviewed-on: https://chromium-review.googlesource.com/1024037
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53020}
This commit is contained in:
Andreas Haas 2018-05-07 13:02:21 +02:00 committed by Commit Bot
parent 08bfc14b68
commit 6380476c71
20 changed files with 225 additions and 133 deletions

View File

@ -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<size_t>(
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<MachineRepresentation> 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<MachineRepresentation>* CreateMachineSignature(
Zone* zone, wasm::FunctionSig* sig) {
Signature<MachineRepresentation>::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<int>(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<int>(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);
}

View File

@ -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);

View File

@ -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

View File

@ -2108,7 +2108,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
unsigned SimdExtractLane(WasmOpcode opcode, ValueType type) {
SimdLaneImmediate<validate> 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<validate> {
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<validate> {
unsigned SimdShiftOp(WasmOpcode opcode) {
SimdShiftImmediate<validate> 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<validate> {
unsigned Simd8x16ShuffleOp() {
Simd8x16ShuffleImmediate<validate> 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<validate> {
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<validate> {
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<validate> {
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 {

View File

@ -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,

View File

@ -7,7 +7,7 @@
#include <map>
#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<ValueType>;
// A signature map canonicalizes signatures into a range of indices so that

View File

@ -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:

View File

@ -177,7 +177,8 @@ class InterpreterHandle {
ScopedVector<WasmValue> 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<uint32_t>(
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<ctype>(arg_buffer, ret_val.to<ctype>()); \
#define CASE_RET_TYPE(type, ctype) \
case type: \
DCHECK_EQ(ValueTypes::ElementSizeInBytes(sig->GetReturn(0)), \
sizeof(ctype)); \
WriteUnalignedValue<ctype>(arg_buffer, ret_val.to<ctype>()); \
break;
switch (sig->GetReturn(0)) {
CASE_RET_TYPE(kWasmI32, uint32_t)

View File

@ -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);

View File

@ -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;

View File

@ -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();
}

View File

@ -633,7 +633,7 @@ MaybeHandle<WasmGlobalObject> WasmGlobalObject::New(
auto global_obj = Handle<WasmGlobalObject>::cast(
isolate->factory()->NewJSObject(global_ctor));
uint32_t type_size = TypeSize(type);
uint32_t type_size = wasm::ValueTypes::ElementSizeInBytes(type);
Handle<JSArrayBuffer> buffer;
if (!maybe_buffer.ToHandle(&buffer)) {

View File

@ -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<ValueType>;
} // namespace wasm
@ -250,8 +250,7 @@ class WasmGlobalObject : public JSObject {
Isolate* isolate, MaybeHandle<JSArrayBuffer> 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();

View File

@ -570,6 +570,7 @@ enum TrapReason {
kTrapCount
#undef DECLARE_ENUM
};
// A collection of opcode-related static methods.
class V8_EXPORT_PRIVATE WasmOpcodes {
public:

View File

@ -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());
}

View File

@ -321,7 +321,7 @@ WASM_COMPILED_EXEC_TEST(WasmSimpleStepping) {
WASM_COMPILED_EXEC_TEST(WasmStepInAndOut) {
WasmRunner<int, int> runner(execution_mode);
WasmFunctionCompiler& f2 = runner.NewFunction<void>();
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<void, int> 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

View File

@ -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:

View File

@ -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());

View File

@ -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<MachineRepresentation>::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<MachineRepresentation>::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());

View File

@ -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) {