Commit ec8e7e65 authored by Deepti Gandluri's avatar Deepti Gandluri Committed by Commit Bot

[wasm] Add Atomic Load, Store Ops to the interpreter

Bug: v8:6532
Change-Id: I2ae9c2a2d2b6a02826a50cd150cb8008841f55e4
Reviewed-on: https://chromium-review.googlesource.com/804212
Commit-Queue: Deepti Gandluri <gdeepti@chromium.org>
Reviewed-by: 's avatarEric Holk <eholk@chromium.org>
Reviewed-by: 's avatarBen Smith <binji@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49807}
parent 6c830b48
......@@ -1026,9 +1026,6 @@ class WasmDecoder : public Decoder {
std::pair<uint32_t, uint32_t> StackEffect(const byte* pc) {
WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
if (WasmOpcodes::IsPrefixOpcode(opcode)) {
opcode = static_cast<WasmOpcode>(opcode << 8 | *(pc + 1));
}
// Handle "simple" opcodes with a fixed signature first.
FunctionSig* sig = WasmOpcodes::Signature(opcode);
if (!sig) sig = WasmOpcodes::AsmjsSignature(opcode);
......@@ -1039,10 +1036,8 @@ class WasmDecoder : public Decoder {
switch (opcode) {
case kExprSelect:
return {3, 1};
case kExprS128StoreMem:
FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
return {2, 0};
case kExprS128LoadMem:
FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
case kExprTeeLocal:
case kExprGrowMemory:
......@@ -1083,6 +1078,23 @@ class WasmDecoder : public Decoder {
case kExprReturn:
case kExprUnreachable:
return {0, 0};
case kAtomicPrefix:
case kSimdPrefix: {
opcode = static_cast<WasmOpcode>(opcode << 8 | *(pc + 1));
switch (opcode) {
case kExprI32AtomicStore:
case kExprI32AtomicStore8U:
case kExprI32AtomicStore16U:
case kExprS128StoreMem:
return {2, 0};
default: {
sig = WasmOpcodes::Signature(opcode);
if (sig) {
return {sig->parameter_count(), sig->return_count()};
}
}
}
}
default:
V8_Fatal(__FILE__, __LINE__, "unimplemented opcode: %x (%s)", opcode,
WasmOpcodes::OpcodeName(opcode));
......
......@@ -1540,12 +1540,12 @@ class ThreadImpl {
}
template <typename type>
bool ExtractAtomicBinOpParams(Decoder* decoder, InterpreterCode* code,
Address& address, pc_t pc, type& val,
int& len) {
bool ExtractAtomicOpParams(Decoder* decoder, InterpreterCode* code,
Address& address, pc_t pc, int& len,
type* val = nullptr) {
MemoryAccessOperand<Decoder::kNoValidate> operand(decoder, code->at(pc + 1),
sizeof(type));
val = Pop().to<uint32_t>();
if (val) *val = Pop().to<uint32_t>();
uint32_t index = Pop().to<uint32_t>();
if (!BoundsCheck<type>(wasm_context_->mem_size, operand.offset, index)) {
DoTrap(kTrapMemOutOfBounds, pc);
......@@ -1560,19 +1560,20 @@ class ThreadImpl {
InterpreterCode* code, pc_t pc, int& len) {
WasmValue result;
switch (opcode) {
#define ATOMIC_BINOP_CASE(name, type, operation) \
case kExpr##name: { \
type val; \
Address addr; \
if (!ExtractAtomicBinOpParams<type>(decoder, code, addr, pc, val, len)) { \
return false; \
} \
static_assert(sizeof(std::atomic<type>) == sizeof(type), \
"Size mismatch for types std::atomic<" #type \
">, and " #type); \
result = WasmValue( \
std::operation(reinterpret_cast<std::atomic<type>*>(addr), val)); \
break; \
#define ATOMIC_BINOP_CASE(name, type, operation) \
case kExpr##name: { \
type val; \
Address addr; \
if (!ExtractAtomicOpParams<type>(decoder, code, addr, pc, len, &val)) { \
return false; \
} \
static_assert(sizeof(std::atomic<type>) == sizeof(type), \
"Size mismatch for types std::atomic<" #type \
">, and " #type); \
result = WasmValue( \
std::operation(reinterpret_cast<std::atomic<type>*>(addr), val)); \
Push(result); \
break; \
}
ATOMIC_BINOP_CASE(I32AtomicAdd, uint32_t, atomic_fetch_add);
ATOMIC_BINOP_CASE(I32AtomicAdd8U, uint8_t, atomic_fetch_add);
......@@ -1593,10 +1594,44 @@ class ThreadImpl {
ATOMIC_BINOP_CASE(I32AtomicExchange8U, uint8_t, atomic_exchange);
ATOMIC_BINOP_CASE(I32AtomicExchange16U, uint16_t, atomic_exchange);
#undef ATOMIC_BINOP_CASE
#define ATOMIC_LOAD_CASE(name, type, operation) \
case kExpr##name: { \
Address addr; \
if (!ExtractAtomicOpParams<type>(decoder, code, addr, pc, len)) { \
return false; \
} \
static_assert(sizeof(std::atomic<type>) == sizeof(type), \
"Size mismatch for types std::atomic<" #type \
">, and " #type); \
result = \
WasmValue(std::operation(reinterpret_cast<std::atomic<type>*>(addr))); \
Push(result); \
break; \
}
ATOMIC_LOAD_CASE(I32AtomicLoad, uint32_t, atomic_load);
ATOMIC_LOAD_CASE(I32AtomicLoad8U, uint8_t, atomic_load);
ATOMIC_LOAD_CASE(I32AtomicLoad16U, uint16_t, atomic_load);
#undef ATOMIC_LOAD_CASE
#define ATOMIC_STORE_CASE(name, type, operation) \
case kExpr##name: { \
type val; \
Address addr; \
if (!ExtractAtomicOpParams<type>(decoder, code, addr, pc, len, &val)) { \
return false; \
} \
static_assert(sizeof(std::atomic<type>) == sizeof(type), \
"Size mismatch for types std::atomic<" #type \
">, and " #type); \
std::operation(reinterpret_cast<std::atomic<type>*>(addr), val); \
break; \
}
ATOMIC_STORE_CASE(I32AtomicStore, uint32_t, atomic_store);
ATOMIC_STORE_CASE(I32AtomicStore8U, uint8_t, atomic_store);
ATOMIC_STORE_CASE(I32AtomicStore16U, uint16_t, atomic_store);
#undef ATOMIC_STORE_CASE
default:
return false;
}
Push(result);
return true;
}
......
......@@ -234,7 +234,7 @@ WASM_COMPILED_EXEC_TEST(I32AtomicCompareExchange8U) {
}
}
WASM_COMPILED_EXEC_TEST(I32AtomicLoad) {
WASM_EXEC_TEST(I32AtomicLoad) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t> r(execution_mode);
r.builder().SetHasSharedMemory();
......@@ -249,7 +249,7 @@ WASM_COMPILED_EXEC_TEST(I32AtomicLoad) {
}
}
WASM_COMPILED_EXEC_TEST(I32AtomicLoad16U) {
WASM_EXEC_TEST(I32AtomicLoad16U) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t> r(execution_mode);
r.builder().SetHasSharedMemory();
......@@ -264,7 +264,7 @@ WASM_COMPILED_EXEC_TEST(I32AtomicLoad16U) {
}
}
WASM_COMPILED_EXEC_TEST(I32AtomicLoad8U) {
WASM_EXEC_TEST(I32AtomicLoad8U) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t> r(execution_mode);
r.builder().SetHasSharedMemory();
......@@ -279,7 +279,7 @@ WASM_COMPILED_EXEC_TEST(I32AtomicLoad8U) {
}
}
WASM_COMPILED_EXEC_TEST(I32AtomicStoreLoad) {
WASM_EXEC_TEST(I32AtomicStoreLoad) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t, uint32_t> r(execution_mode);
r.builder().SetHasSharedMemory();
......@@ -298,7 +298,7 @@ WASM_COMPILED_EXEC_TEST(I32AtomicStoreLoad) {
}
}
WASM_COMPILED_EXEC_TEST(I32AtomicStoreLoad16U) {
WASM_EXEC_TEST(I32AtomicStoreLoad16U) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t, uint32_t> r(execution_mode);
r.builder().SetHasSharedMemory();
......@@ -318,7 +318,7 @@ WASM_COMPILED_EXEC_TEST(I32AtomicStoreLoad16U) {
}
}
WASM_COMPILED_EXEC_TEST(I32AtomicStoreLoad8U) {
WASM_EXEC_TEST(I32AtomicStoreLoad8U) {
EXPERIMENTAL_FLAG_SCOPE(threads);
WasmRunner<uint32_t, uint32_t> r(execution_mode);
r.builder().SetHasSharedMemory();
......
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