summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/wasm')
-rw-r--r--deps/v8/test/cctest/wasm/OWNERS2
-rw-r--r--deps/v8/test/cctest/wasm/test-grow-memory.cc131
-rw-r--r--deps/v8/test/cctest/wasm/test-jump-table-assembler.cc24
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-64.cc4
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc104
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc2
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-module.cc162
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm-simd.cc416
-rw-r--r--deps/v8/test/cctest/wasm/test-run-wasm.cc31
-rw-r--r--deps/v8/test/cctest/wasm/test-streaming-compilation.cc40
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc182
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc4
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc42
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-serialization.cc30
-rw-r--r--deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc116
-rw-r--r--deps/v8/test/cctest/wasm/wasm-run-utils.cc34
16 files changed, 879 insertions, 445 deletions
diff --git a/deps/v8/test/cctest/wasm/OWNERS b/deps/v8/test/cctest/wasm/OWNERS
index dc68b39733..16b08f3b3b 100644
--- a/deps/v8/test/cctest/wasm/OWNERS
+++ b/deps/v8/test/cctest/wasm/OWNERS
@@ -1,5 +1,5 @@
ahaas@chromium.org
-clemensh@chromium.org
+clemensb@chromium.org
titzer@chromium.org
# COMPONENT: Blink>JavaScript>WebAssembly
diff --git a/deps/v8/test/cctest/wasm/test-grow-memory.cc b/deps/v8/test/cctest/wasm/test-grow-memory.cc
new file mode 100644
index 0000000000..a188707cae
--- /dev/null
+++ b/deps/v8/test/cctest/wasm/test-grow-memory.cc
@@ -0,0 +1,131 @@
+// Copyright 2019 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.
+
+#include "src/wasm/wasm-objects-inl.h"
+#include "src/wasm/wasm-opcodes.h"
+
+#include "src/wasm/wasm-module-builder.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/manually-externalized-buffer.h"
+#include "test/common/wasm/flag-utils.h"
+#include "test/common/wasm/test-signatures.h"
+#include "test/common/wasm/wasm-macro-gen.h"
+#include "test/common/wasm/wasm-module-runner.h"
+
+namespace v8 {
+namespace internal {
+namespace wasm {
+namespace test_grow_memory {
+
+using testing::CompileAndInstantiateForTesting;
+using v8::internal::testing::ManuallyExternalizedBuffer;
+
+namespace {
+void ExportAsMain(WasmFunctionBuilder* f) {
+ f->builder()->AddExport(CStrVector("main"), f);
+}
+#define EMIT_CODE_WITH_END(f, code) \
+ do { \
+ f->EmitCode(code, sizeof(code)); \
+ f->Emit(kExprEnd); \
+ } while (false)
+
+void Cleanup(Isolate* isolate = CcTest::InitIsolateOnce()) {
+ // By sending a low memory notifications, we will try hard to collect all
+ // garbage and will therefore also invoke all weak callbacks of actually
+ // unreachable persistent handles.
+ reinterpret_cast<v8::Isolate*>(isolate)->LowMemoryNotification();
+}
+} // namespace
+
+TEST(GrowMemDetaches) {
+ {
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ HandleScope scope(isolate);
+ Handle<WasmMemoryObject> memory_object =
+ WasmMemoryObject::New(isolate, 16, 100, SharedFlag::kNotShared)
+ .ToHandleChecked();
+ Handle<JSArrayBuffer> buffer(memory_object->array_buffer(), isolate);
+ int32_t result = WasmMemoryObject::Grow(isolate, memory_object, 0);
+ CHECK_EQ(16, result);
+ CHECK_NE(*buffer, memory_object->array_buffer());
+ CHECK(buffer->was_detached());
+ }
+ Cleanup();
+}
+
+TEST(Externalized_GrowMemMemSize) {
+ {
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ HandleScope scope(isolate);
+ Handle<WasmMemoryObject> memory_object =
+ WasmMemoryObject::New(isolate, 16, 100, SharedFlag::kNotShared)
+ .ToHandleChecked();
+ ManuallyExternalizedBuffer external(
+ handle(memory_object->array_buffer(), isolate));
+ int32_t result = WasmMemoryObject::Grow(isolate, memory_object, 0);
+ CHECK_EQ(16, result);
+ CHECK_NE(*external.buffer_, memory_object->array_buffer());
+ CHECK(external.buffer_->was_detached());
+ }
+ Cleanup();
+}
+
+TEST(Run_WasmModule_Buffer_Externalized_GrowMem) {
+ {
+ Isolate* isolate = CcTest::InitIsolateOnce();
+ HandleScope scope(isolate);
+ TestSignatures sigs;
+ v8::internal::AccountingAllocator allocator;
+ Zone zone(&allocator, ZONE_NAME);
+
+ WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
+ WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
+ ExportAsMain(f);
+ byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(6)), WASM_DROP,
+ WASM_MEMORY_SIZE};
+ EMIT_CODE_WITH_END(f, code);
+
+ ZoneBuffer buffer(&zone);
+ builder->WriteTo(&buffer);
+ testing::SetupIsolateForWasmModule(isolate);
+ ErrorThrower thrower(isolate, "Test");
+ const Handle<WasmInstanceObject> instance =
+ CompileAndInstantiateForTesting(
+ isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()))
+ .ToHandleChecked();
+ Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate);
+
+ // Fake the Embedder flow by externalizing the array buffer.
+ ManuallyExternalizedBuffer external1(
+ handle(memory_object->array_buffer(), isolate));
+
+ // Grow using the API.
+ uint32_t result = WasmMemoryObject::Grow(isolate, memory_object, 4);
+ CHECK_EQ(16, result);
+ CHECK(external1.buffer_->was_detached()); // growing always detaches
+ CHECK_EQ(0, external1.buffer_->byte_length());
+
+ CHECK_NE(*external1.buffer_, memory_object->array_buffer());
+
+ // Fake the Embedder flow by externalizing the array buffer.
+ ManuallyExternalizedBuffer external2(
+ handle(memory_object->array_buffer(), isolate));
+
+ // Grow using an internal WASM bytecode.
+ result = testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr);
+ CHECK_EQ(26, result);
+ CHECK(external2.buffer_->was_detached()); // growing always detaches
+ CHECK_EQ(0, external2.buffer_->byte_length());
+ CHECK_NE(*external2.buffer_, memory_object->array_buffer());
+ }
+ Cleanup();
+}
+
+} // namespace test_grow_memory
+} // namespace wasm
+} // namespace internal
+} // namespace v8
+
+#undef EMIT_CODE_WITH_END
diff --git a/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc b/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc
index 556d74daef..d3aa75a64e 100644
--- a/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc
+++ b/deps/v8/test/cctest/wasm/test-jump-table-assembler.cc
@@ -36,7 +36,7 @@ constexpr size_t kThunkBufferSize = AssemblerBase::kMinimalBufferSize;
#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64
constexpr uint32_t kAvailableBufferSlots =
- (kMaxWasmCodeMemory - kJumpTableSize) / kThunkBufferSize;
+ (kMaxWasmCodeSpaceSize - kJumpTableSize) / kThunkBufferSize;
constexpr uint32_t kBufferSlotStartOffset =
RoundUp<kThunkBufferSize>(kJumpTableSize);
#else
@@ -49,7 +49,7 @@ Address AllocateJumpTableThunk(
std::vector<std::unique_ptr<TestingAssemblerBuffer>>* thunk_buffers) {
#if V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_X64
// To guarantee that the branch range lies within the near-call range,
- // generate the thunk in the same (kMaxWasmCodeMemory-sized) buffer as the
+ // generate the thunk in the same (kMaxWasmCodeSpaceSize-sized) buffer as the
// jump_target itself.
//
// Allocate a slot that we haven't already used. This is necessary because
@@ -181,11 +181,13 @@ class JumpTablePatcher : public v8::base::Thread {
// Then, repeatedly patch the jump table to jump to one of the two thunks.
constexpr int kNumberOfPatchIterations = 64;
for (int i = 0; i < kNumberOfPatchIterations; ++i) {
- TRACE(" patcher %p patch slot " V8PRIxPTR_FMT " to thunk #%d\n", this,
- slot_address, i % 2);
+ TRACE(" patcher %p patch slot " V8PRIxPTR_FMT
+ " to thunk #%d (" V8PRIxPTR_FMT ")\n",
+ this, slot_address, i % 2, thunks_[i % 2]);
base::MutexGuard jump_table_guard(jump_table_mutex_);
JumpTableAssembler::PatchJumpTableSlot(
- slot_start_, slot_index_, thunks_[i % 2], WasmCode::kFlushICache);
+ slot_start_ + JumpTableAssembler::JumpSlotIndexToOffset(slot_index_),
+ kNullAddress, thunks_[i % 2]);
}
TRACE("Patcher %p is stopping ...\n", this);
}
@@ -219,11 +221,8 @@ TEST(JumpTablePatchingStress) {
// is not reliable enough to guarantee that we can always achieve this with
// separate allocations, so for Arm64 we generate all code in a single
// kMaxMasmCodeMemory-sized chunk.
- //
- // TODO(wasm): Currently {kMaxWasmCodeMemory} limits code sufficiently, so
- // that the jump table only supports {near_call} distances.
- STATIC_ASSERT(kMaxWasmCodeMemory >= kJumpTableSize);
- auto buffer = AllocateAssemblerBuffer(kMaxWasmCodeMemory);
+ STATIC_ASSERT(kMaxWasmCodeSpaceSize >= kJumpTableSize);
+ auto buffer = AllocateAssemblerBuffer(kMaxWasmCodeSpaceSize);
byte* thunk_slot_buffer = buffer->start() + kBufferSlotStartOffset;
#else
auto buffer = AllocateAssemblerBuffer(kJumpTableSize);
@@ -242,8 +241,9 @@ TEST(JumpTablePatchingStress) {
std::vector<std::unique_ptr<TestingAssemblerBuffer>> thunk_buffers;
// Patch the jump table slot to jump to itself. This will later be patched
// by the patchers.
- JumpTableAssembler::PatchJumpTableSlot(
- slot_start, slot, slot_start + slot_offset, WasmCode::kFlushICache);
+ Address slot_addr =
+ slot_start + JumpTableAssembler::JumpSlotIndexToOffset(slot);
+ JumpTableAssembler::PatchJumpTableSlot(slot_addr, kNullAddress, slot_addr);
// For each patcher, generate two thunks where this patcher can emit code
// which finally jumps back to {slot} in the jump table.
std::vector<Address> patcher_thunks;
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-64.cc b/deps/v8/test/cctest/wasm/test-run-wasm-64.cc
index 3f96f8720f..09d1eb7fda 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-64.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-64.cc
@@ -1502,7 +1502,7 @@ static void CompileCallIndirectMany(ExecutionTier tier, ValueType param) {
std::vector<byte> code;
for (byte p = 0; p < num_params; p++) {
- ADD_CODE(code, kExprGetLocal, p);
+ ADD_CODE(code, kExprLocalGet, p);
}
ADD_CODE(code, kExprI32Const, 0);
ADD_CODE(code, kExprCallIndirect, 1, TABLE_ZERO);
@@ -1563,7 +1563,7 @@ static void Run_WasmMixedCall_N(ExecutionTier execution_tier, int start) {
// Store the result in a local.
byte local_index = r.AllocateLocal(ValueTypes::ValueTypeFor(result));
- ADD_CODE(code, kExprSetLocal, local_index);
+ ADD_CODE(code, kExprLocalSet, local_index);
// Store the result in memory.
ADD_CODE(code,
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc b/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc
index e794c00ece..d2ac3434df 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-bulk-memory.cc
@@ -13,11 +13,10 @@ namespace wasm {
namespace test_run_wasm_bulk_memory {
namespace {
-void CheckMemoryEquals(
- TestingModuleBuilder& builder, // NOLINT(runtime/references)
- size_t index, const std::vector<byte>& expected) {
- const byte* mem_start = builder.raw_mem_start<byte>();
- const byte* mem_end = builder.raw_mem_end<byte>();
+void CheckMemoryEquals(TestingModuleBuilder* builder, size_t index,
+ const std::vector<byte>& expected) {
+ const byte* mem_start = builder->raw_mem_start<byte>();
+ const byte* mem_end = builder->raw_mem_end<byte>();
size_t mem_size = mem_end - mem_start;
CHECK_LE(index, mem_size);
CHECK_LE(index + expected.size(), mem_size);
@@ -26,11 +25,10 @@ void CheckMemoryEquals(
}
}
-void CheckMemoryEqualsZero(
- TestingModuleBuilder& builder, // NOLINT(runtime/references)
- size_t index, size_t length) {
- const byte* mem_start = builder.raw_mem_start<byte>();
- const byte* mem_end = builder.raw_mem_end<byte>();
+void CheckMemoryEqualsZero(TestingModuleBuilder* builder, size_t index,
+ size_t length) {
+ const byte* mem_start = builder->raw_mem_start<byte>();
+ const byte* mem_end = builder->raw_mem_end<byte>();
size_t mem_size = mem_end - mem_start;
CHECK_LE(index, mem_size);
CHECK_LE(index + length, mem_size);
@@ -39,12 +37,11 @@ void CheckMemoryEqualsZero(
}
}
-void CheckMemoryEqualsFollowedByZeroes(
- TestingModuleBuilder& builder, // NOLINT(runtime/references)
- const std::vector<byte>& expected) {
+void CheckMemoryEqualsFollowedByZeroes(TestingModuleBuilder* builder,
+ const std::vector<byte>& expected) {
CheckMemoryEquals(builder, 0, expected);
CheckMemoryEqualsZero(builder, expected.size(),
- builder.mem_size() - expected.size());
+ builder->mem_size() - expected.size());
}
} // namespace
@@ -60,24 +57,24 @@ WASM_EXEC_TEST(MemoryInit) {
kExprI32Const, 0);
// All zeroes.
- CheckMemoryEqualsZero(r.builder(), 0, kWasmPageSize);
+ CheckMemoryEqualsZero(&r.builder(), 0, kWasmPageSize);
// Copy all bytes from data segment 0, to memory at [10, 20).
CHECK_EQ(0, r.Call(10, 0, 10));
CheckMemoryEqualsFollowedByZeroes(
- r.builder(),
+ &r.builder(),
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
// Copy bytes in range [5, 10) from data segment 0, to memory at [0, 5).
CHECK_EQ(0, r.Call(0, 5, 5));
CheckMemoryEqualsFollowedByZeroes(
- r.builder(),
+ &r.builder(),
{5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
// Copy 0 bytes does nothing.
CHECK_EQ(0, r.Call(10, 1, 0));
CheckMemoryEqualsFollowedByZeroes(
- r.builder(),
+ &r.builder(),
{5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
// Copy 0 at end of memory region or data segment is OK.
@@ -100,12 +97,12 @@ WASM_EXEC_TEST(MemoryInitOutOfBoundsData) {
// Write all values up to the out-of-bounds write.
CHECK_EQ(0xDEADBEEF, r.Call(kWasmPageSize - 5, 0, 6));
- CheckMemoryEquals(r.builder(), last_5_bytes, {0, 1, 2, 3, 4});
+ CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 1, 2, 3, 4});
// Write all values up to the out-of-bounds read.
r.builder().BlankMemory();
CHECK_EQ(0xDEADBEEF, r.Call(0, 5, 6));
- CheckMemoryEqualsFollowedByZeroes(r.builder(), {5, 6, 7, 8, 9});
+ CheckMemoryEqualsFollowedByZeroes(&r.builder(), {5, 6, 7, 8, 9});
}
WASM_EXEC_TEST(MemoryInitOutOfBounds) {
@@ -155,13 +152,13 @@ WASM_EXEC_TEST(MemoryCopy) {
// Copy from [1, 8] to [10, 16].
CHECK_EQ(0, r.Call(10, 1, 8));
CheckMemoryEqualsFollowedByZeroes(
- r.builder(),
+ &r.builder(),
{0, 11, 22, 33, 44, 55, 66, 77, 0, 0, 11, 22, 33, 44, 55, 66, 77});
// Copy 0 bytes does nothing.
CHECK_EQ(0, r.Call(10, 2, 0));
CheckMemoryEqualsFollowedByZeroes(
- r.builder(),
+ &r.builder(),
{0, 11, 22, 33, 44, 55, 66, 77, 0, 0, 11, 22, 33, 44, 55, 66, 77});
// Copy 0 at end of memory region is OK.
@@ -184,12 +181,12 @@ WASM_EXEC_TEST(MemoryCopyOverlapping) {
// Copy from [0, 3] -> [2, 5]. The copy must not overwrite 30 before copying
// it (i.e. cannot copy forward in this case).
CHECK_EQ(0, r.Call(2, 0, 3));
- CheckMemoryEqualsFollowedByZeroes(r.builder(), {10, 20, 10, 20, 30});
+ CheckMemoryEqualsFollowedByZeroes(&r.builder(), {10, 20, 10, 20, 30});
// Copy from [2, 5] -> [0, 3]. The copy must not write the first 10 (i.e.
// cannot copy backward in this case).
CHECK_EQ(0, r.Call(0, 2, 3));
- CheckMemoryEqualsFollowedByZeroes(r.builder(), {10, 20, 30, 20, 30});
+ CheckMemoryEqualsFollowedByZeroes(&r.builder(), {10, 20, 30, 20, 30});
}
WASM_EXEC_TEST(MemoryCopyOutOfBoundsData) {
@@ -209,21 +206,21 @@ WASM_EXEC_TEST(MemoryCopyOutOfBoundsData) {
// Copy with source < destination. Copy would happen backwards,
// but the first byte to copy is out-of-bounds, so no data should be written.
CHECK_EQ(0xDEADBEEF, r.Call(last_5_bytes, 0, 6));
- CheckMemoryEquals(r.builder(), last_5_bytes, {0, 0, 0, 0, 0});
+ CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 0, 0, 0, 0});
// Copy overlapping with destination < source. Copy will happen forwards, up
// to the out-of-bounds access.
r.builder().BlankMemory();
memcpy(mem + last_5_bytes, data, 5);
CHECK_EQ(0xDEADBEEF, r.Call(0, last_5_bytes, kWasmPageSize));
- CheckMemoryEquals(r.builder(), 0, {11, 22, 33, 44, 55});
+ CheckMemoryEquals(&r.builder(), 0, {11, 22, 33, 44, 55});
// Copy overlapping with source < destination. Copy would happen backwards,
// but the first byte to copy is out-of-bounds, so no data should be written.
r.builder().BlankMemory();
memcpy(mem, data, 5);
CHECK_EQ(0xDEADBEEF, r.Call(last_5_bytes, 0, kWasmPageSize));
- CheckMemoryEquals(r.builder(), last_5_bytes, {0, 0, 0, 0, 0});
+ CheckMemoryEquals(&r.builder(), last_5_bytes, {0, 0, 0, 0, 0});
}
WASM_EXEC_TEST(MemoryCopyOutOfBounds) {
@@ -265,15 +262,15 @@ WASM_EXEC_TEST(MemoryFill) {
WASM_MEMORY_FILL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1), WASM_GET_LOCAL(2)),
kExprI32Const, 0);
CHECK_EQ(0, r.Call(1, 33, 5));
- CheckMemoryEqualsFollowedByZeroes(r.builder(), {0, 33, 33, 33, 33, 33});
+ CheckMemoryEqualsFollowedByZeroes(&r.builder(), {0, 33, 33, 33, 33, 33});
CHECK_EQ(0, r.Call(4, 66, 4));
- CheckMemoryEqualsFollowedByZeroes(r.builder(),
+ CheckMemoryEqualsFollowedByZeroes(&r.builder(),
{0, 33, 33, 33, 66, 66, 66, 66});
// Fill 0 bytes does nothing.
CHECK_EQ(0, r.Call(4, 66, 0));
- CheckMemoryEqualsFollowedByZeroes(r.builder(),
+ CheckMemoryEqualsFollowedByZeroes(&r.builder(),
{0, 33, 33, 33, 66, 66, 66, 66});
// Fill 0 at end of memory region is OK.
@@ -290,7 +287,7 @@ WASM_EXEC_TEST(MemoryFillValueWrapsToByte) {
kExprI32Const, 0);
CHECK_EQ(0, r.Call(0, 1000, 3));
const byte expected = 1000 & 255;
- CheckMemoryEqualsFollowedByZeroes(r.builder(),
+ CheckMemoryEqualsFollowedByZeroes(&r.builder(),
{expected, expected, expected});
}
@@ -304,7 +301,7 @@ WASM_EXEC_TEST(MemoryFillOutOfBoundsData) {
kExprI32Const, 0);
const byte v = 123;
CHECK_EQ(0xDEADBEEF, r.Call(kWasmPageSize - 5, v, 999));
- CheckMemoryEquals(r.builder(), kWasmPageSize - 6, {0, v, v, v, v, v});
+ CheckMemoryEquals(&r.builder(), kWasmPageSize - 6, {0, v, v, v, v, v});
}
WASM_EXEC_TEST(MemoryFillOutOfBounds) {
@@ -408,14 +405,13 @@ void CheckTable(Isolate* isolate, Handle<WasmTableObject> table, Args... args) {
template <typename WasmRunner, typename... Args>
void CheckTableCall(Isolate* isolate, Handle<WasmTableObject> table,
- WasmRunner& r, // NOLINT(runtime/references)
- uint32_t function_index, Args... args) {
+ WasmRunner* r, uint32_t function_index, Args... args) {
uint32_t args_length = static_cast<uint32_t>(sizeof...(args));
CHECK_EQ(table->current_length(), args_length);
double expected[] = {args...};
for (uint32_t i = 0; i < args_length; ++i) {
Handle<Object> buffer[] = {isolate->factory()->NewNumber(i)};
- r.CheckCallApplyViaJS(expected[i], function_index, buffer, 1);
+ r->CheckCallApplyViaJS(expected[i], function_index, buffer, 1);
}
}
} // namespace
@@ -462,7 +458,7 @@ void TestTableInitElems(ExecutionTier execution_tier, int table_index) {
isolate);
const double null = 0xDEADBEEF;
- CheckTableCall(isolate, table, r, call_index, null, null, null, null, null);
+ CheckTableCall(isolate, table, &r, call_index, null, null, null, null, null);
// 0 count is ok in bounds, and at end of regions.
r.CheckCallViaJS(0, 0, 0, 0);
@@ -471,19 +467,19 @@ void TestTableInitElems(ExecutionTier execution_tier, int table_index) {
// Test actual writes.
r.CheckCallViaJS(0, 0, 0, 1);
- CheckTableCall(isolate, table, r, call_index, 0, null, null, null, null);
+ CheckTableCall(isolate, table, &r, call_index, 0, null, null, null, null);
r.CheckCallViaJS(0, 0, 0, 2);
- CheckTableCall(isolate, table, r, call_index, 0, 1, null, null, null);
+ CheckTableCall(isolate, table, &r, call_index, 0, 1, null, null, null);
r.CheckCallViaJS(0, 0, 0, 3);
- CheckTableCall(isolate, table, r, call_index, 0, 1, 2, null, null);
+ CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, null, null);
r.CheckCallViaJS(0, 3, 0, 2);
- CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 0, 1);
+ CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 0, 1);
r.CheckCallViaJS(0, 3, 1, 2);
- CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 1, 2);
+ CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 1, 2);
r.CheckCallViaJS(0, 3, 2, 2);
- CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 2, 3);
+ CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 2, 3);
r.CheckCallViaJS(0, 3, 3, 2);
- CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4);
+ CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4);
}
WASM_EXEC_TEST(TableInitElems0) { TestTableInitElems(execution_tier, 0); }
@@ -534,15 +530,15 @@ void TestTableInitOob(ExecutionTier execution_tier, int table_index) {
isolate);
const double null = 0xDEADBEEF;
- CheckTableCall(isolate, table, r, call_index, null, null, null, null, null);
+ CheckTableCall(isolate, table, &r, call_index, null, null, null, null, null);
// Write all values up to the out-of-bounds write.
r.CheckCallViaJS(0xDEADBEEF, 3, 0, 3);
- CheckTableCall(isolate, table, r, call_index, null, null, null, 0, 1);
+ CheckTableCall(isolate, table, &r, call_index, null, null, null, 0, 1);
// Write all values up to the out-of-bounds read.
r.CheckCallViaJS(0xDEADBEEF, 0, 3, 3);
- CheckTableCall(isolate, table, r, call_index, 3, 4, null, 0, 1);
+ CheckTableCall(isolate, table, &r, call_index, 3, 4, null, 0, 1);
// 0-count is never oob.
r.CheckCallViaJS(0, kTableSize + 1, 0, 0);
@@ -696,21 +692,21 @@ void TestTableCopyCalls(ExecutionTier execution_tier, int table_dst,
isolate);
if (table_dst == table_src) {
- CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4);
+ CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4);
r.CheckCallViaJS(0, 0, 1, 1);
- CheckTableCall(isolate, table, r, call_index, 1, 1, 2, 3, 4);
+ CheckTableCall(isolate, table, &r, call_index, 1, 1, 2, 3, 4);
r.CheckCallViaJS(0, 0, 1, 2);
- CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 3, 4);
+ CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 3, 4);
r.CheckCallViaJS(0, 3, 0, 2);
- CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 1, 2);
+ CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 1, 2);
} else {
- CheckTableCall(isolate, table, r, call_index, 0, 1, 2, 3, 4);
+ CheckTableCall(isolate, table, &r, call_index, 0, 1, 2, 3, 4);
r.CheckCallViaJS(0, 0, 1, 1);
- CheckTableCall(isolate, table, r, call_index, 1, 1, 2, 3, 4);
+ CheckTableCall(isolate, table, &r, call_index, 1, 1, 2, 3, 4);
r.CheckCallViaJS(0, 0, 1, 2);
- CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 3, 4);
+ CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 3, 4);
r.CheckCallViaJS(0, 3, 0, 2);
- CheckTableCall(isolate, table, r, call_index, 1, 2, 2, 0, 1);
+ CheckTableCall(isolate, table, &r, call_index, 1, 2, 2, 0, 1);
}
}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc b/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc
index 4c1842b537..1b64135cb8 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-interpreter.cc
@@ -278,7 +278,7 @@ TEST(Breakpoint_I32Add) {
static const int kNumBreakpoints = 3;
byte code[] = {WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))};
std::unique_ptr<int[]> offsets =
- Find(code, sizeof(code), kNumBreakpoints, kExprGetLocal, kExprGetLocal,
+ Find(code, sizeof(code), kNumBreakpoints, kExprLocalGet, kExprLocalGet,
kExprI32Add);
WasmRunner<int32_t, uint32_t, uint32_t> r(ExecutionTier::kInterpreter);
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
index 51d97650d4..5f70ab6c7b 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
@@ -11,7 +11,6 @@
#include "src/utils/version.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-memory.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
@@ -943,154 +942,6 @@ TEST(MemoryWithOOBEmptyDataSegment) {
Cleanup();
}
-// Utility to free the allocated memory for a buffer that is manually
-// externalized in a test.
-struct ManuallyExternalizedBuffer {
- Isolate* isolate_;
- Handle<JSArrayBuffer> buffer_;
- void* allocation_base_;
- size_t allocation_length_;
- bool const should_free_;
-
- ManuallyExternalizedBuffer(JSArrayBuffer buffer, Isolate* isolate)
- : isolate_(isolate),
- buffer_(buffer, isolate),
- allocation_base_(buffer.allocation_base()),
- allocation_length_(buffer.allocation_length()),
- should_free_(!isolate_->wasm_engine()->memory_tracker()->IsWasmMemory(
- buffer.backing_store())) {
- if (!isolate_->wasm_engine()->memory_tracker()->IsWasmMemory(
- buffer.backing_store())) {
- v8::Utils::ToLocal(buffer_)->Externalize();
- }
- }
- ~ManuallyExternalizedBuffer() {
- if (should_free_) {
- buffer_->FreeBackingStoreFromMainThread();
- }
- }
-};
-
-TEST(Run_WasmModule_Buffer_Externalized_GrowMem) {
- {
- Isolate* isolate = CcTest::InitIsolateOnce();
- HandleScope scope(isolate);
- TestSignatures sigs;
- v8::internal::AccountingAllocator allocator;
- Zone zone(&allocator, ZONE_NAME);
-
- WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
- WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
- ExportAsMain(f);
- byte code[] = {WASM_GROW_MEMORY(WASM_I32V_1(6)), WASM_DROP,
- WASM_MEMORY_SIZE};
- EMIT_CODE_WITH_END(f, code);
-
- ZoneBuffer buffer(&zone);
- builder->WriteTo(&buffer);
- testing::SetupIsolateForWasmModule(isolate);
- ErrorThrower thrower(isolate, "Test");
- const Handle<WasmInstanceObject> instance =
- CompileAndInstantiateForTesting(
- isolate, &thrower, ModuleWireBytes(buffer.begin(), buffer.end()))
- .ToHandleChecked();
- Handle<WasmMemoryObject> memory_object(instance->memory_object(), isolate);
-
- // Fake the Embedder flow by externalizing the array buffer.
- ManuallyExternalizedBuffer buffer1(memory_object->array_buffer(), isolate);
-
- // Grow using the API.
- uint32_t result = WasmMemoryObject::Grow(isolate, memory_object, 4);
- CHECK_EQ(16, result);
- CHECK(buffer1.buffer_->was_detached()); // growing always detaches
- CHECK_EQ(0, buffer1.buffer_->byte_length());
-
- CHECK_NE(*buffer1.buffer_, memory_object->array_buffer());
-
- // Fake the Embedder flow by externalizing the array buffer.
- ManuallyExternalizedBuffer buffer2(memory_object->array_buffer(), isolate);
-
- // Grow using an internal WASM bytecode.
- result = testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr);
- CHECK_EQ(26, result);
- CHECK(buffer2.buffer_->was_detached()); // growing always detaches
- CHECK_EQ(0, buffer2.buffer_->byte_length());
- CHECK_NE(*buffer2.buffer_, memory_object->array_buffer());
- }
- Cleanup();
-}
-
-TEST(Run_WasmModule_Buffer_Externalized_GrowMemMemSize) {
- {
- Isolate* isolate = CcTest::InitIsolateOnce();
- HandleScope scope(isolate);
- Handle<JSArrayBuffer> buffer;
- CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer));
- Handle<WasmMemoryObject> mem_obj =
- WasmMemoryObject::New(isolate, buffer, 100);
- auto const contents = v8::Utils::ToLocal(buffer)->Externalize();
- int32_t result = WasmMemoryObject::Grow(isolate, mem_obj, 0);
- CHECK_EQ(16, result);
- constexpr bool is_wasm_memory = true;
- const JSArrayBuffer::Allocation allocation{contents.AllocationBase(),
- contents.AllocationLength(),
- contents.Data(), is_wasm_memory};
- JSArrayBuffer::FreeBackingStore(isolate, allocation);
- }
- Cleanup();
-}
-
-TEST(Run_WasmModule_Buffer_Externalized_Detach) {
- {
- // Regression test for
- // https://bugs.chromium.org/p/chromium/issues/detail?id=731046
- Isolate* isolate = CcTest::InitIsolateOnce();
- HandleScope scope(isolate);
- Handle<JSArrayBuffer> buffer;
- CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer));
- auto const contents = v8::Utils::ToLocal(buffer)->Externalize();
- wasm::DetachMemoryBuffer(isolate, buffer, true);
- constexpr bool is_wasm_memory = true;
- const JSArrayBuffer::Allocation allocation{contents.AllocationBase(),
- contents.AllocationLength(),
- contents.Data(), is_wasm_memory};
- JSArrayBuffer::FreeBackingStore(isolate, allocation);
- }
- Cleanup();
-}
-
-TEST(Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree) {
- // Regresion test for https://crbug.com/813876
- Isolate* isolate = CcTest::InitIsolateOnce();
- HandleScope scope(isolate);
- Handle<JSArrayBuffer> buffer;
- CHECK(wasm::NewArrayBuffer(isolate, 16 * kWasmPageSize).ToHandle(&buffer));
- Handle<WasmMemoryObject> mem = WasmMemoryObject::New(isolate, buffer, 128);
- auto contents = v8::Utils::ToLocal(buffer)->Externalize();
- WasmMemoryObject::Grow(isolate, mem, 0);
- constexpr bool is_wasm_memory = true;
- JSArrayBuffer::FreeBackingStore(
- isolate, JSArrayBuffer::Allocation(contents.AllocationBase(),
- contents.AllocationLength(),
- contents.Data(), is_wasm_memory));
- // Make sure we can write to the buffer without crashing
- uint32_t* int_buffer =
- reinterpret_cast<uint32_t*>(mem->array_buffer().backing_store());
- int_buffer[0] = 0;
-}
-
-#if V8_TARGET_ARCH_64_BIT
-TEST(Run_WasmModule_Reclaim_Memory) {
- // Make sure we can allocate memories without running out of address space.
- Isolate* isolate = CcTest::InitIsolateOnce();
- Handle<JSArrayBuffer> buffer;
- for (int i = 0; i < 256; ++i) {
- HandleScope scope(isolate);
- CHECK(NewArrayBuffer(isolate, kWasmPageSize).ToHandle(&buffer));
- }
-}
-#endif
-
TEST(AtomicOpDisassembly) {
{
EXPERIMENTAL_FLAG_SCOPE(threads);
@@ -1118,12 +969,15 @@ TEST(AtomicOpDisassembly) {
ErrorThrower thrower(isolate, "Test");
auto enabled_features = WasmFeaturesFromIsolate(isolate);
- MaybeHandle<WasmModuleObject> module_object =
- isolate->wasm_engine()->SyncCompile(
- isolate, enabled_features, &thrower,
- ModuleWireBytes(buffer.begin(), buffer.end()));
+ Handle<WasmModuleObject> module_object =
+ isolate->wasm_engine()
+ ->SyncCompile(isolate, enabled_features, &thrower,
+ ModuleWireBytes(buffer.begin(), buffer.end()))
+ .ToHandleChecked();
+ NativeModule* native_module = module_object->native_module();
+ ModuleWireBytes wire_bytes(native_module->wire_bytes());
- module_object.ToHandleChecked()->DisassembleFunction(0);
+ DisassembleWasmFunction(native_module->module(), wire_bytes, 0);
}
Cleanup();
}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
index b48321df40..d76c4c3643 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
@@ -184,13 +184,20 @@ T UnsignedGreaterEqual(T a, T b) {
template <typename T>
T LogicalShiftLeft(T a, int shift) {
using UnsignedT = typename std::make_unsigned<T>::type;
- return static_cast<UnsignedT>(a) << shift;
+ return static_cast<UnsignedT>(a) << (shift % (sizeof(T) * 8));
}
template <typename T>
T LogicalShiftRight(T a, int shift) {
using UnsignedT = typename std::make_unsigned<T>::type;
- return static_cast<UnsignedT>(a) >> shift;
+ return static_cast<UnsignedT>(a) >> (shift % (sizeof(T) * 8));
+}
+
+// Define our own ArithmeticShiftRight instead of using the one from utils.h
+// because the shift amount needs to be taken modulo lane width.
+template <typename T>
+T ArithmeticShiftRight(T a, int shift) {
+ return a >> (shift % (sizeof(T) * 8));
}
template <typename T>
@@ -279,7 +286,7 @@ T Sqrt(T a) {
return std::sqrt(a);
}
-#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32
// only used for F64x2 tests below
int64_t Equal(double a, double b) { return a == b ? -1 : 0; }
@@ -292,14 +299,106 @@ int64_t GreaterEqual(double a, double b) { return a >= b ? -1 : 0; }
int64_t Less(double a, double b) { return a < b ? -1 : 0; }
int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; }
+
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+// Only used for qfma and qfms tests below.
+
+// FMOperation holds the params (a, b, c) for a Multiply-Add or
+// Multiply-Subtract operation, and the expected result if the operation was
+// fused, rounded only once for the entire operation, or unfused, rounded after
+// multiply and again after add/subtract.
+template <typename T>
+struct FMOperation {
+ const T a;
+ const T b;
+ const T c;
+ const T fused_result;
+ const T unfused_result;
+};
+
+// large_n is large number that overflows T when multiplied by itself, this is a
+// useful constant to test fused/unfused behavior.
+template <typename T>
+constexpr T large_n = T(0);
+
+template <>
+constexpr double large_n<double> = 1e200;
+
+template <>
+constexpr float large_n<float> = 1e20;
+
+// Fused Multiply-Add performs a + b * c.
+template <typename T>
+static constexpr FMOperation<T> qfma_array[] = {
+ {1.0f, 2.0f, 3.0f, 7.0f, 7.0f},
+ // fused: a + b * c = -inf + (positive overflow) = -inf
+ // unfused: a + b * c = -inf + inf = NaN
+ {-std::numeric_limits<T>::infinity(), large_n<T>, large_n<T>,
+ -std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()},
+ // fused: a + b * c = inf + (negative overflow) = inf
+ // unfused: a + b * c = inf + -inf = NaN
+ {std::numeric_limits<T>::infinity(), -large_n<T>, large_n<T>,
+ std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()},
+ // NaN
+ {std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f,
+ std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()},
+ // -NaN
+ {-std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f,
+ std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}};
+
+template <typename T>
+static constexpr Vector<const FMOperation<T>> qfma_vector() {
+ return ArrayVector(qfma_array<T>);
+}
+
+// Fused Multiply-Subtract performs a - b * c.
+template <typename T>
+static constexpr FMOperation<T> qfms_array[]{
+ {1.0f, 2.0f, 3.0f, -5.0f, -5.0f},
+ // fused: a - b * c = inf - (positive overflow) = inf
+ // unfused: a - b * c = inf - inf = NaN
+ {std::numeric_limits<T>::infinity(), large_n<T>, large_n<T>,
+ std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()},
+ // fused: a - b * c = -inf - (negative overflow) = -inf
+ // unfused: a - b * c = -inf - -inf = NaN
+ {-std::numeric_limits<T>::infinity(), -large_n<T>, large_n<T>,
+ -std::numeric_limits<T>::infinity(), std::numeric_limits<T>::quiet_NaN()},
+ // NaN
+ {std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f,
+ std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()},
+ // -NaN
+ {-std::numeric_limits<T>::quiet_NaN(), 2.0f, 3.0f,
+ std::numeric_limits<T>::quiet_NaN(), std::numeric_limits<T>::quiet_NaN()}};
+
+template <typename T>
+static constexpr Vector<const FMOperation<T>> qfms_vector() {
+ return ArrayVector(qfms_array<T>);
+}
+
+// Fused results only when fma3 feature is enabled, and running on TurboFan.
+bool ExpectFused(ExecutionTier tier) {
+#ifdef V8_TARGET_ARCH_X64
+ return CpuFeatures::IsSupported(FMA3) && (tier == ExecutionTier::kTurbofan);
+#else
+ return (tier == ExecutionTier::kTurbofan);
+#endif
+}
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32
} // namespace
-#define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \
- WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \
- WASM_SIMD_##TYPE##_EXTRACT_LANE( \
- lane_index, WASM_GET_LOCAL(value))), \
+#define WASM_SIMD_CHECK_LANE_S(TYPE, value, LANE_TYPE, lane_value, lane_index) \
+ WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \
+ WASM_SIMD_##TYPE##_EXTRACT_LANE( \
+ lane_index, WASM_GET_LOCAL(value))), \
+ WASM_RETURN1(WASM_ZERO))
+
+// Unsigned Extracts are only available for I8x16, I16x8 types
+#define WASM_SIMD_CHECK_LANE_U(TYPE, value, LANE_TYPE, lane_value, lane_index) \
+ WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \
+ WASM_SIMD_##TYPE##_EXTRACT_LANE_U( \
+ lane_index, WASM_GET_LOCAL(value))), \
WASM_RETURN1(WASM_ZERO))
#define TO_BYTE(val) static_cast<byte>(val)
@@ -338,13 +437,17 @@ int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; }
#define WASM_SIMD_I16x8_SPLAT(x) WASM_SIMD_SPLAT(I16x8, x)
#define WASM_SIMD_I16x8_EXTRACT_LANE(lane, x) \
- x, WASM_SIMD_OP(kExprI16x8ExtractLane), TO_BYTE(lane)
+ x, WASM_SIMD_OP(kExprI16x8ExtractLaneS), TO_BYTE(lane)
+#define WASM_SIMD_I16x8_EXTRACT_LANE_U(lane, x) \
+ x, WASM_SIMD_OP(kExprI16x8ExtractLaneU), TO_BYTE(lane)
#define WASM_SIMD_I16x8_REPLACE_LANE(lane, x, y) \
x, y, WASM_SIMD_OP(kExprI16x8ReplaceLane), TO_BYTE(lane)
#define WASM_SIMD_I8x16_SPLAT(x) WASM_SIMD_SPLAT(I8x16, x)
#define WASM_SIMD_I8x16_EXTRACT_LANE(lane, x) \
- x, WASM_SIMD_OP(kExprI8x16ExtractLane), TO_BYTE(lane)
+ x, WASM_SIMD_OP(kExprI8x16ExtractLaneS), TO_BYTE(lane)
+#define WASM_SIMD_I8x16_EXTRACT_LANE_U(lane, x) \
+ x, WASM_SIMD_OP(kExprI8x16ExtractLaneU), TO_BYTE(lane)
#define WASM_SIMD_I8x16_REPLACE_LANE(lane, x, y) \
x, y, WASM_SIMD_OP(kExprI8x16ReplaceLane), TO_BYTE(lane)
@@ -357,8 +460,17 @@ int64_t LessEqual(double a, double b) { return a <= b ? -1 : 0; }
#define WASM_SIMD_LOAD_MEM(index) \
index, WASM_SIMD_OP(kExprS128LoadMem), ZERO_ALIGNMENT, ZERO_OFFSET
+#define WASM_SIMD_LOAD_MEM_OFFSET(offset, index) \
+ index, WASM_SIMD_OP(kExprS128LoadMem), ZERO_ALIGNMENT, offset
#define WASM_SIMD_STORE_MEM(index, val) \
index, val, WASM_SIMD_OP(kExprS128StoreMem), ZERO_ALIGNMENT, ZERO_OFFSET
+#define WASM_SIMD_STORE_MEM_OFFSET(offset, index, val) \
+ index, val, WASM_SIMD_OP(kExprS128StoreMem), ZERO_ALIGNMENT, offset
+
+#define WASM_SIMD_F64x2_QFMA(a, b, c) a, b, c, WASM_SIMD_OP(kExprF64x2Qfma)
+#define WASM_SIMD_F64x2_QFMS(a, b, c) a, b, c, WASM_SIMD_OP(kExprF64x2Qfms)
+#define WASM_SIMD_F32x4_QFMA(a, b, c) a, b, c, WASM_SIMD_OP(kExprF32x4Qfma)
+#define WASM_SIMD_F32x4_QFMS(a, b, c) a, b, c, WASM_SIMD_OP(kExprF32x4Qfms)
// Runs tests of compiled code, using the interpreter as a reference.
#define WASM_SIMD_COMPILED_TEST(name) \
@@ -589,10 +701,15 @@ void RunF32x4UnOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WASM_SIMD_TEST(F32x4Abs) {
RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Abs, std::abs);
}
+
WASM_SIMD_TEST(F32x4Neg) {
RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Neg, Negate);
}
+WASM_SIMD_TEST(F32x4Sqrt) {
+ RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4Sqrt, Sqrt);
+}
+
WASM_SIMD_TEST(F32x4RecipApprox) {
RunF32x4UnOpTest(execution_tier, lower_simd, kExprF32x4RecipApprox,
base::Recip, false /* !exact */);
@@ -725,6 +842,57 @@ WASM_SIMD_TEST(F32x4Le) {
}
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+WASM_SIMD_TEST_NO_LOWERING(F32x4Qfma) {
+ WasmRunner<int32_t, float, float, float> r(execution_tier, lower_simd);
+ // Set up global to hold mask output.
+ float* g = r.builder().AddGlobal<float>(kWasmS128);
+ // Build fn to splat test values, perform compare op, and write the result.
+ byte value1 = 0, value2 = 1, value3 = 2;
+ BUILD(r,
+ WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_QFMA(
+ WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value1)),
+ WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value2)),
+ WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value3)))),
+ WASM_ONE);
+
+ for (FMOperation<float> x : qfma_vector<float>()) {
+ r.Call(x.a, x.b, x.c);
+ float expected =
+ ExpectFused(execution_tier) ? x.fused_result : x.unfused_result;
+ for (int i = 0; i < 4; i++) {
+ float actual = ReadLittleEndianValue<float>(&g[i]);
+ CheckFloatResult(x.a, x.b, expected, actual, true /* exact */);
+ }
+ }
+}
+
+WASM_SIMD_TEST_NO_LOWERING(F32x4Qfms) {
+ WasmRunner<int32_t, float, float, float> r(execution_tier, lower_simd);
+ // Set up global to hold mask output.
+ float* g = r.builder().AddGlobal<float>(kWasmS128);
+ // Build fn to splat test values, perform compare op, and write the result.
+ byte value1 = 0, value2 = 1, value3 = 2;
+ BUILD(r,
+ WASM_SET_GLOBAL(0, WASM_SIMD_F32x4_QFMS(
+ WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value1)),
+ WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value2)),
+ WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(value3)))),
+ WASM_ONE);
+
+ for (FMOperation<float> x : qfms_vector<float>()) {
+ r.Call(x.a, x.b, x.c);
+ float expected =
+ ExpectFused(execution_tier) ? x.fused_result : x.unfused_result;
+ for (int i = 0; i < 4; i++) {
+ float actual = ReadLittleEndianValue<float>(&g[i]);
+ CheckFloatResult(x.a, x.b, expected, actual, true /* exact */);
+ }
+ }
+}
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
WASM_SIMD_TEST_NO_LOWERING(I64x2Splat) {
WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd);
// Set up a global to hold output vector.
@@ -803,7 +971,8 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2Neg) {
void RunI64x2ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int64ShiftOp expected_op) {
- for (int shift = 1; shift < 64; shift++) {
+ // Intentionally shift by 64, should be no-op.
+ for (int shift = 1; shift <= 64; shift++) {
WasmRunner<int32_t, int64_t> r(execution_tier, lower_simd);
int64_t* g = r.builder().AddGlobal<int64_t>(kWasmS128);
byte value = 0;
@@ -918,6 +1087,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2GeU) {
RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2GeU,
UnsignedGreaterEqual);
}
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) {
WasmRunner<int32_t, double> r(execution_tier, lower_simd);
@@ -941,6 +1111,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Splat) {
}
}
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLaneWithI64x2) {
WasmRunner<int64_t> r(execution_tier, lower_simd);
BUILD(r, WASM_IF_ELSE_L(
@@ -950,6 +1121,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLaneWithI64x2) {
WASM_I64V(1), WASM_I64V(0)));
CHECK_EQ(1, r.Call());
}
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) {
WasmRunner<double, double> r(execution_tier, lower_simd);
@@ -973,6 +1145,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2ExtractLane) {
}
}
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractWithF64x2) {
WasmRunner<int64_t> r(execution_tier, lower_simd);
BUILD(r, WASM_IF_ELSE_L(
@@ -982,6 +1155,7 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2ExtractWithF64x2) {
WASM_I64V(1), WASM_I64V(0)));
CHECK_EQ(1, r.Call());
}
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
WASM_SIMD_TEST_NO_LOWERING(F64x2ReplaceLane) {
WasmRunner<int32_t> r(execution_tier, lower_simd);
@@ -1124,6 +1298,10 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Neg) {
RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Neg, Negate);
}
+WASM_SIMD_TEST_NO_LOWERING(F64x2Sqrt) {
+ RunF64x2UnOpTest(execution_tier, lower_simd, kExprF64x2Sqrt, Sqrt);
+}
+
void RunF64x2BinOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, DoubleBinOp expected_op) {
WasmRunner<int32_t, double, double> r(execution_tier, lower_simd);
@@ -1249,12 +1427,14 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Max) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Max, JSMax);
}
-#if V8_TARGET_ARCH_X64
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
WASM_SIMD_TEST_NO_LOWERING(I64x2Mul) {
RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2Mul,
base::MulWithWraparound);
}
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+#if V8_TARGET_ARCH_X64
WASM_SIMD_TEST_NO_LOWERING(I64x2MinS) {
RunI64x2BinOpTest(execution_tier, lower_simd, kExprI64x2MinS, Minimum);
}
@@ -1273,7 +1453,57 @@ WASM_SIMD_TEST_NO_LOWERING(I64x2MaxU) {
UnsignedMaximum);
}
#endif // V8_TARGET_ARCH_X64
+
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+WASM_SIMD_TEST_NO_LOWERING(F64x2Qfma) {
+ WasmRunner<int32_t, double, double, double> r(execution_tier, lower_simd);
+ // Set up global to hold mask output.
+ double* g = r.builder().AddGlobal<double>(kWasmS128);
+ // Build fn to splat test values, perform compare op, and write the result.
+ byte value1 = 0, value2 = 1, value3 = 2;
+ BUILD(r,
+ WASM_SET_GLOBAL(0, WASM_SIMD_F64x2_QFMA(
+ WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value1)),
+ WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value2)),
+ WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value3)))),
+ WASM_ONE);
+
+ for (FMOperation<double> x : qfma_vector<double>()) {
+ r.Call(x.a, x.b, x.c);
+ double expected =
+ ExpectFused(execution_tier) ? x.fused_result : x.unfused_result;
+ for (int i = 0; i < 2; i++) {
+ double actual = ReadLittleEndianValue<double>(&g[i]);
+ CheckDoubleResult(x.a, x.b, expected, actual, true /* exact */);
+ }
+ }
+}
+
+WASM_SIMD_TEST_NO_LOWERING(F64x2Qfms) {
+ WasmRunner<int32_t, double, double, double> r(execution_tier, lower_simd);
+ // Set up global to hold mask output.
+ double* g = r.builder().AddGlobal<double>(kWasmS128);
+ // Build fn to splat test values, perform compare op, and write the result.
+ byte value1 = 0, value2 = 1, value3 = 2;
+ BUILD(r,
+ WASM_SET_GLOBAL(0, WASM_SIMD_F64x2_QFMS(
+ WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value1)),
+ WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value2)),
+ WASM_SIMD_F64x2_SPLAT(WASM_GET_LOCAL(value3)))),
+ WASM_ONE);
+
+ for (FMOperation<double> x : qfms_vector<double>()) {
+ r.Call(x.a, x.b, x.c);
+ double expected =
+ ExpectFused(execution_tier) ? x.fused_result : x.unfused_result;
+ for (int i = 0; i < 2; i++) {
+ double actual = ReadLittleEndianValue<double>(&g[i]);
+ CheckDoubleResult(x.a, x.b, expected, actual, true /* exact */);
+ }
+ }
+}
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32
WASM_SIMD_TEST(I32x4Splat) {
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
@@ -1652,7 +1882,8 @@ WASM_SIMD_TEST(I32x4GeU) {
void RunI32x4ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int32ShiftOp expected_op) {
- for (int shift = 1; shift < 32; shift++) {
+ // Intentionally shift by 32, should be no-op.
+ for (int shift = 1; shift <= 32; shift++) {
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
int32_t* g = r.builder().AddGlobal<int32_t>(kWasmS128);
byte value = 0;
@@ -1902,7 +2133,8 @@ WASM_SIMD_TEST(I16x8LeU) {
void RunI16x8ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int16ShiftOp expected_op) {
- for (int shift = 1; shift < 16; shift++) {
+ // Intentionally shift by 16, should be no-op.
+ for (int shift = 1; shift <= 16; shift++) {
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
int16_t* g = r.builder().AddGlobal<int16_t>(kWasmS128);
byte value = 0;
@@ -1917,7 +2149,7 @@ void RunI16x8ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
FOR_INT16_INPUTS(x) {
r.Call(x);
- float expected = expected_op(x, shift);
+ int16_t expected = expected_op(x, shift);
for (int i = 0; i < 8; i++) {
CHECK_EQ(expected, ReadLittleEndianValue<int16_t>(&g[i]));
}
@@ -2118,7 +2350,8 @@ WASM_SIMD_TEST(I8x16Mul) {
void RunI8x16ShiftOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, Int8ShiftOp expected_op) {
- for (int shift = 1; shift < 8; shift++) {
+ // Intentionally shift by 8, should be no-op.
+ for (int shift = 1; shift <= 8; shift++) {
WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd);
int8_t* g = r.builder().AddGlobal<int8_t>(kWasmS128);
byte value = 0;
@@ -2184,10 +2417,10 @@ WASM_SIMD_TEST_NO_LOWERING(I8x16ShrU) {
format, WASM_GET_LOCAL(src1), WASM_GET_LOCAL(src2), \
WASM_SIMD_BINOP(kExprI##format##Ne, WASM_GET_LOCAL(mask), \
WASM_GET_LOCAL(zero)))), \
- WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \
- WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 1), \
- WASM_SIMD_CHECK_LANE(I##format, mask, I32, val1, 2), \
- WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \
+ WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 0), \
+ WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val1, 1), \
+ WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val1, 2), \
+ WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 3), WASM_ONE); \
\
CHECK_EQ(1, r.Call(0x12, 0x34)); \
}
@@ -2222,10 +2455,10 @@ WASM_SIMD_SELECT_TEST(8x16)
WASM_SET_LOCAL(mask, WASM_SIMD_SELECT(format, WASM_GET_LOCAL(src1), \
WASM_GET_LOCAL(src2), \
WASM_GET_LOCAL(mask))), \
- WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 0), \
- WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 1), \
- WASM_SIMD_CHECK_LANE(I##format, mask, I32, combined, 2), \
- WASM_SIMD_CHECK_LANE(I##format, mask, I32, val2, 3), WASM_ONE); \
+ WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 0), \
+ WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, combined, 1), \
+ WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, combined, 2), \
+ WASM_SIMD_CHECK_LANE_S(I##format, mask, I32, val2, 3), WASM_ONE); \
\
CHECK_EQ(1, r.Call(0x12, 0x34, 0x32)); \
}
@@ -2454,6 +2687,62 @@ WASM_SIMD_TEST(S8x16Concat) {
}
}
+#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64
+struct SwizzleTestArgs {
+ const Shuffle input;
+ const Shuffle indices;
+ const Shuffle expected;
+};
+
+static constexpr SwizzleTestArgs swizzle_test_args[] = {
+ {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
+ {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
+ {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
+ {15, 0, 14, 1, 13, 2, 12, 3, 11, 4, 10, 5, 9, 6, 8, 7},
+ {0, 15, 1, 14, 2, 13, 3, 12, 4, 11, 5, 10, 6, 9, 7, 8}},
+ {{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
+ {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30},
+ {15, 13, 11, 9, 7, 5, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0}},
+ // all indices are out of range
+ {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
+ {16, 17, 18, 19, 20, 124, 125, 126, 127, -1, -2, -3, -4, -5, -6, -7},
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}};
+
+static constexpr Vector<const SwizzleTestArgs> swizzle_test_vector =
+ ArrayVector(swizzle_test_args);
+
+WASM_SIMD_TEST(S8x16Swizzle) {
+ // RunBinaryLaneOpTest set up the two globals to be consecutive integers,
+ // [0-15] and [16-31]. Using [0-15] as the indices will not sufficiently test
+ // swizzle since the expected result is a no-op, using [16-31] will result in
+ // all 0s.
+ WasmRunner<int32_t> r(execution_tier, lower_simd);
+ static const int kElems = kSimd128Size / sizeof(uint8_t);
+ uint8_t* dst = r.builder().AddGlobal<uint8_t>(kWasmS128);
+ uint8_t* src0 = r.builder().AddGlobal<uint8_t>(kWasmS128);
+ uint8_t* src1 = r.builder().AddGlobal<uint8_t>(kWasmS128);
+ BUILD(
+ r,
+ WASM_SET_GLOBAL(0, WASM_SIMD_BINOP(kExprS8x16Swizzle, WASM_GET_GLOBAL(1),
+ WASM_GET_GLOBAL(2))),
+ WASM_ONE);
+
+ for (SwizzleTestArgs si : swizzle_test_vector) {
+ for (int i = 0; i < kElems; i++) {
+ WriteLittleEndianValue<uint8_t>(&src0[i], si.input[i]);
+ WriteLittleEndianValue<uint8_t>(&src1[i], si.indices[i]);
+ }
+
+ CHECK_EQ(1, r.Call());
+
+ for (int i = 0; i < kElems; i++) {
+ CHECK_EQ(ReadLittleEndianValue<uint8_t>(&dst[i]), si.expected[i]);
+ }
+ }
+}
+#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64
+
// Combine 3 shuffles a, b, and c by applying both a and b and then applying c
// to those two results.
Shuffle Combine(const Shuffle& a, const Shuffle& b, const Shuffle& c) {
@@ -2487,7 +2776,7 @@ void AppendShuffle(const Shuffle& shuffle, std::vector<byte>* buffer) {
for (size_t i = 0; i < kSimd128Size; ++i) buffer->push_back((shuffle[i]));
}
-void BuildShuffle(std::vector<Shuffle>& shuffles, // NOLINT(runtime/references)
+void BuildShuffle(const std::vector<Shuffle>& shuffles,
std::vector<byte>* buffer) {
// Perform the leaf shuffles on globals 0 and 1.
size_t row_index = (shuffles.size() - 1) / 2;
@@ -2504,7 +2793,7 @@ void BuildShuffle(std::vector<Shuffle>& shuffles, // NOLINT(runtime/references)
}
row_index /= 2;
} while (row_index != 0);
- byte epilog[] = {kExprSetGlobal, static_cast<byte>(0), WASM_ONE};
+ byte epilog[] = {kExprGlobalSet, static_cast<byte>(0), WASM_ONE};
for (size_t j = 0; j < arraysize(epilog); ++j) buffer->push_back(epilog[j]);
}
@@ -2895,11 +3184,34 @@ WASM_SIMD_TEST(SimdLoadStoreLoad) {
r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t));
// Load memory, store it, then reload it and extract the first lane. Use a
// non-zero offset into the memory of 1 lane (4 bytes) to test indexing.
- BUILD(r, WASM_SIMD_STORE_MEM(WASM_I32V(4), WASM_SIMD_LOAD_MEM(WASM_I32V(4))),
- WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_LOAD_MEM(WASM_I32V(4))));
+ BUILD(r, WASM_SIMD_STORE_MEM(WASM_I32V(8), WASM_SIMD_LOAD_MEM(WASM_I32V(4))),
+ WASM_SIMD_I32x4_EXTRACT_LANE(0, WASM_SIMD_LOAD_MEM(WASM_I32V(8))));
+
+ FOR_INT32_INPUTS(i) {
+ int32_t expected = i;
+ r.builder().WriteMemory(&memory[1], expected);
+ CHECK_EQ(expected, r.Call());
+ }
+}
+
+WASM_SIMD_TEST(SimdLoadStoreLoadMemargOffset) {
+ WasmRunner<int32_t> r(execution_tier, lower_simd);
+ int32_t* memory =
+ r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t));
+ constexpr byte offset_1 = 4;
+ constexpr byte offset_2 = 8;
+ // Load from memory at offset_1, store to offset_2, load from offset_2, and
+ // extract first lane. We use non-zero memarg offsets to test offset decoding.
+ BUILD(
+ r,
+ WASM_SIMD_STORE_MEM_OFFSET(
+ offset_2, WASM_ZERO, WASM_SIMD_LOAD_MEM_OFFSET(offset_1, WASM_ZERO)),
+ WASM_SIMD_I32x4_EXTRACT_LANE(
+ 0, WASM_SIMD_LOAD_MEM_OFFSET(offset_2, WASM_ZERO)));
FOR_INT32_INPUTS(i) {
int32_t expected = i;
+ // Index 1 of memory (int32_t) will be bytes 4 to 8.
r.builder().WriteMemory(&memory[1], expected);
CHECK_EQ(expected, r.Call());
}
@@ -3040,8 +3352,48 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) {
UnsignedGreater);
}
+#define WASM_EXTRACT_I16x8_TEST(Sign, Type) \
+ WASM_SIMD_TEST(I16X8ExtractLane##Sign) { \
+ WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); \
+ byte int_val = r.AllocateLocal(kWasmI32); \
+ byte simd_val = r.AllocateLocal(kWasmS128); \
+ BUILD(r, \
+ WASM_SET_LOCAL(simd_val, \
+ WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(int_val))), \
+ WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 0), \
+ WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 2), \
+ WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 4), \
+ WASM_SIMD_CHECK_LANE_U(I16x8, simd_val, I32, int_val, 6), WASM_ONE); \
+ FOR_##Type##_INPUTS(x) { CHECK_EQ(1, r.Call(x)); } \
+ }
+WASM_EXTRACT_I16x8_TEST(S, UINT16) WASM_EXTRACT_I16x8_TEST(I, INT16)
+#undef WASM_EXTRACT_I16x8_TEST
+
+#define WASM_EXTRACT_I8x16_TEST(Sign, Type) \
+ WASM_SIMD_TEST(I8x16ExtractLane##Sign) { \
+ WasmRunner<int32_t, int32_t> r(execution_tier, lower_simd); \
+ byte int_val = r.AllocateLocal(kWasmI32); \
+ byte simd_val = r.AllocateLocal(kWasmS128); \
+ BUILD(r, \
+ WASM_SET_LOCAL(simd_val, \
+ WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(int_val))), \
+ WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 1), \
+ WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 3), \
+ WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 5), \
+ WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 7), \
+ WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 9), \
+ WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 10), \
+ WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 11), \
+ WASM_SIMD_CHECK_LANE_U(I8x16, simd_val, I32, int_val, 13), \
+ WASM_ONE); \
+ FOR_##Type##_INPUTS(x) { CHECK_EQ(1, r.Call(x)); } \
+ }
+ WASM_EXTRACT_I8x16_TEST(S, UINT8) WASM_EXTRACT_I8x16_TEST(I, INT8)
+#undef WASM_EXTRACT_I8x16_TEST
+
#undef WASM_SIMD_TEST
-#undef WASM_SIMD_CHECK_LANE
+#undef WASM_SIMD_CHECK_LANE_S
+#undef WASM_SIMD_CHECK_LANE_U
#undef TO_BYTE
#undef WASM_SIMD_OP
#undef WASM_SIMD_SPLAT
@@ -3064,13 +3416,17 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) {
#undef WASM_SIMD_I32x4_REPLACE_LANE
#undef WASM_SIMD_I16x8_SPLAT
#undef WASM_SIMD_I16x8_EXTRACT_LANE
+#undef WASM_SIMD_I16x8_EXTRACT_LANE_U
#undef WASM_SIMD_I16x8_REPLACE_LANE
#undef WASM_SIMD_I8x16_SPLAT
#undef WASM_SIMD_I8x16_EXTRACT_LANE
+#undef WASM_SIMD_I8x16_EXTRACT_LANE_U
#undef WASM_SIMD_I8x16_REPLACE_LANE
#undef WASM_SIMD_S8x16_SHUFFLE_OP
#undef WASM_SIMD_LOAD_MEM
+#undef WASM_SIMD_LOAD_MEM_OFFSET
#undef WASM_SIMD_STORE_MEM
+#undef WASM_SIMD_STORE_MEM_OFFSET
#undef WASM_SIMD_SELECT_TEST
#undef WASM_SIMD_NON_CANONICAL_SELECT_TEST
#undef WASM_SIMD_COMPILED_TEST
@@ -3078,6 +3434,10 @@ WASM_SIMD_TEST_NO_LOWERING(I16x8GtUMixed) {
#undef WASM_SIMD_TEST_NO_LOWERING
#undef WASM_SIMD_ANYTRUE_TEST
#undef WASM_SIMD_ALLTRUE_TEST
+#undef WASM_SIMD_F64x2_QFMA
+#undef WASM_SIMD_F64x2_QFMS
+#undef WASM_SIMD_F32x4_QFMA
+#undef WASM_SIMD_F32x4_QFMS
} // namespace test_run_wasm_simd
} // namespace wasm
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm.cc b/deps/v8/test/cctest/wasm/test-run-wasm.cc
index 26df61ceb8..aa6195b8b3 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm.cc
@@ -49,8 +49,8 @@ WASM_EXEC_TEST(Int32Const_many) {
WASM_EXEC_TEST(GraphTrimming) {
// This WebAssembly code requires graph trimming in the TurboFan compiler.
WasmRunner<int32_t, int32_t> r(execution_tier);
- BUILD(r, kExprGetLocal, 0, kExprGetLocal, 0, kExprGetLocal, 0, kExprI32RemS,
- kExprI32Eq, kExprGetLocal, 0, kExprI32DivS, kExprUnreachable);
+ BUILD(r, kExprLocalGet, 0, kExprLocalGet, 0, kExprLocalGet, 0, kExprI32RemS,
+ kExprI32Eq, kExprLocalGet, 0, kExprI32DivS, kExprUnreachable);
r.Call(1);
}
@@ -1810,18 +1810,18 @@ WASM_EXEC_TEST(CheckMachIntsZero) {
BUILD(r, // --
/**/ kExprLoop, kLocalVoid, // --
- /* */ kExprGetLocal, 0, // --
+ /* */ kExprLocalGet, 0, // --
/* */ kExprIf, kLocalVoid, // --
- /* */ kExprGetLocal, 0, // --
+ /* */ kExprLocalGet, 0, // --
/* */ kExprI32LoadMem, 0, 0, // --
/* */ kExprIf, kLocalVoid, // --
/* */ kExprI32Const, 127, // --
/* */ kExprReturn, // --
/* */ kExprEnd, // --
- /* */ kExprGetLocal, 0, // --
+ /* */ kExprLocalGet, 0, // --
/* */ kExprI32Const, 4, // --
/* */ kExprI32Sub, // --
- /* */ kExprTeeLocal, 0, // --
+ /* */ kExprLocalTee, 0, // --
/* */ kExprBr, DEPTH_0, // --
/* */ kExprEnd, // --
/**/ kExprEnd, // --
@@ -2012,16 +2012,16 @@ static void TestBuildGraphForSimpleExpression(WasmOpcode opcode) {
FunctionSig* sig = WasmOpcodes::Signature(opcode);
if (sig->parameter_count() == 1) {
- byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode),
+ byte code[] = {WASM_NO_LOCALS, kExprLocalGet, 0, static_cast<byte>(opcode),
WASM_END};
TestBuildingGraph(&zone, &jsgraph, nullptr, sig, nullptr, code,
code + arraysize(code));
} else {
CHECK_EQ(2, sig->parameter_count());
byte code[] = {WASM_NO_LOCALS,
- kExprGetLocal,
+ kExprLocalGet,
0,
- kExprGetLocal,
+ kExprLocalGet,
1,
static_cast<byte>(opcode),
WASM_END};
@@ -2667,7 +2667,7 @@ static void Run_WasmMixedCall_N(ExecutionTier execution_tier, int start) {
// Store the result in a local.
byte local_index = r.AllocateLocal(ValueTypes::ValueTypeFor(result));
- ADD_CODE(code, kExprSetLocal, local_index);
+ ADD_CODE(code, kExprLocalSet, local_index);
// Store the result in memory.
ADD_CODE(code,
@@ -2761,10 +2761,11 @@ void RunMultiReturnSelect(ExecutionTier execution_tier, const T* inputs) {
WASM_GET_LOCAL(3)),
WASM_DROP);
} else {
- BUILD(r, WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0),
- WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
- WASM_GET_LOCAL(3)),
- kExprSetLocal, 0, WASM_DROP, WASM_GET_LOCAL(0));
+ BUILD(r,
+ WASM_CALL_FUNCTION(r1.function_index(), WASM_GET_LOCAL(0),
+ WASM_GET_LOCAL(1), WASM_GET_LOCAL(2),
+ WASM_GET_LOCAL(3)),
+ kExprLocalSet, 0, WASM_DROP, WASM_GET_LOCAL(0));
}
T expected = inputs[k == 0 ? i : j];
@@ -3330,7 +3331,7 @@ static void CompileCallIndirectMany(ExecutionTier tier, ValueType param) {
std::vector<byte> code;
for (byte p = 0; p < num_params; ++p) {
- ADD_CODE(code, kExprGetLocal, p);
+ ADD_CODE(code, kExprLocalGet, p);
}
ADD_CODE(code, kExprI32Const, 0);
ADD_CODE(code, kExprCallIndirect, 1, TABLE_ZERO);
diff --git a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
index 795fa30e72..f9089b7821 100644
--- a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
+++ b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
@@ -194,17 +194,17 @@ ZoneBuffer GetValidModuleBytes(Zone* zone) {
WasmModuleBuilder builder(zone);
{
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
- uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
+ uint8_t code[] = {kExprLocalGet, 0, kExprEnd};
f->EmitCode(code, arraysize(code));
}
{
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
- uint8_t code[] = {kExprGetLocal, 1, kExprEnd};
+ uint8_t code[] = {kExprLocalGet, 1, kExprEnd};
f->EmitCode(code, arraysize(code));
}
{
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
- uint8_t code[] = {kExprGetLocal, 2, kExprEnd};
+ uint8_t code[] = {kExprLocalGet, 2, kExprEnd};
f->EmitCode(code, arraysize(code));
}
builder.WriteTo(&buffer);
@@ -317,17 +317,17 @@ ZoneBuffer GetModuleWithInvalidSection(Zone* zone) {
WasmInitExpr(WasmInitExpr::kGlobalIndex, 12));
{
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
- uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
+ uint8_t code[] = {kExprLocalGet, 0, kExprEnd};
f->EmitCode(code, arraysize(code));
}
{
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
- uint8_t code[] = {kExprGetLocal, 1, kExprEnd};
+ uint8_t code[] = {kExprLocalGet, 1, kExprEnd};
f->EmitCode(code, arraysize(code));
}
{
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
- uint8_t code[] = {kExprGetLocal, 2, kExprEnd};
+ uint8_t code[] = {kExprLocalGet, 2, kExprEnd};
f->EmitCode(code, arraysize(code));
}
builder.WriteTo(&buffer);
@@ -442,7 +442,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByModuleDecoder) {
uint8_t code[] = {
U32V_1(4), // body size
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
@@ -481,7 +481,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByStreamingDecoder) {
uint8_t code[] = {
U32V_1(26), // !!! invalid body size !!!
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
@@ -520,7 +520,7 @@ STREAM_TEST(TestErrorInCodeSectionDetectedByCompiler) {
uint8_t code[] = {
U32V_1(4), // !!! invalid body size !!!
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
uint8_t invalid_code[] = {
@@ -679,7 +679,7 @@ STREAM_TEST(TestAbortAfterFunctionGotCompiled1) {
uint8_t code[] = {
U32V_1(4), // !!! invalid body size !!!
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
@@ -713,7 +713,7 @@ STREAM_TEST(TestAbortAfterFunctionGotCompiled2) {
uint8_t code[] = {
U32V_1(4), // !!! invalid body size !!!
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
@@ -745,7 +745,7 @@ STREAM_TEST(TestAbortAfterCodeSection1) {
uint8_t code[] = {
U32V_1(4), // body size
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
@@ -781,7 +781,7 @@ STREAM_TEST(TestAbortAfterCodeSection2) {
uint8_t code[] = {
U32V_1(4), // body size
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
@@ -815,7 +815,7 @@ STREAM_TEST(TestAbortAfterCompilationError1) {
uint8_t code[] = {
U32V_1(4), // !!! invalid body size !!!
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
uint8_t invalid_code[] = {
@@ -857,7 +857,7 @@ STREAM_TEST(TestAbortAfterCompilationError2) {
uint8_t code[] = {
U32V_1(4), // !!! invalid body size !!!
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
uint8_t invalid_code[] = {
@@ -934,7 +934,7 @@ STREAM_TEST(TestModuleWithMultipleFunctions) {
uint8_t code[] = {
U32V_1(4), // body size
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
@@ -970,7 +970,7 @@ STREAM_TEST(TestModuleWithDataSection) {
uint8_t code[] = {
U32V_1(4), // body size
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
@@ -1016,7 +1016,7 @@ STREAM_TEST(TestModuleWithImportedFunction) {
builder.AddImport(ArrayVector("Test"), sigs.i_iii());
{
WasmFunctionBuilder* f = builder.AddFunction(sigs.i_iii());
- uint8_t code[] = {kExprGetLocal, 0, kExprEnd};
+ uint8_t code[] = {kExprLocalGet, 0, kExprEnd};
f->EmitCode(code, arraysize(code));
}
builder.WriteTo(&buffer);
@@ -1047,7 +1047,7 @@ STREAM_TEST(TestModuleWithErrorAfterDataSection) {
U32V_1(1), // functions count
U32V_1(4), // body size
U32V_1(0), // locals count
- kExprGetLocal, // some code
+ kExprLocalGet, // some code
0, // some code
kExprEnd, // some code
kDataSectionCode, // section code
@@ -1133,7 +1133,7 @@ STREAM_TEST(TestSetModuleCompiledCallback) {
uint8_t code[] = {
U32V_1(4), // body size
U32V_1(0), // locals count
- kExprGetLocal, 0, kExprEnd // body
+ kExprLocalGet, 0, kExprEnd // body
};
const uint8_t bytes[] = {
diff --git a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
index e287b1139e..798e1d46da 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
@@ -22,10 +22,11 @@ namespace wasm {
namespace {
void CheckLocations(
- WasmModuleObject module_object, debug::Location start, debug::Location end,
+ NativeModule* native_module, debug::Location start, debug::Location end,
std::initializer_list<debug::Location> expected_locations_init) {
std::vector<debug::BreakLocation> locations;
- bool success = module_object.GetPossibleBreakpoints(start, end, &locations);
+ bool success = WasmModuleObject::GetPossibleBreakpoints(native_module, start,
+ end, &locations);
CHECK(success);
printf("got %d locations: ", static_cast<int>(locations.size()));
@@ -45,10 +46,11 @@ void CheckLocations(
}
}
-void CheckLocationsFail(WasmModuleObject module_object, debug::Location start,
+void CheckLocationsFail(NativeModule* native_module, debug::Location start,
debug::Location end) {
std::vector<debug::BreakLocation> locations;
- bool success = module_object.GetPossibleBreakpoints(start, end, &locations);
+ bool success = WasmModuleObject::GetPossibleBreakpoints(native_module, start,
+ end, &locations);
CHECK(!success);
}
@@ -63,8 +65,12 @@ class BreakHandler : public debug::DebugDelegate {
struct BreakPoint {
int position;
Action action;
+ std::function<void(void)> pre_action;
BreakPoint(int position, Action action)
- : position(position), action(action) {}
+ : position(position), action(action), pre_action([]() {}) {}
+ BreakPoint(int position, Action action,
+ std::function<void(void)> pre_action)
+ : position(position), action(action), pre_action(pre_action) {}
};
explicit BreakHandler(Isolate* isolate,
@@ -96,6 +102,7 @@ class BreakHandler : public debug::DebugDelegate {
auto summ = FrameSummary::GetTop(frame_it.frame()).AsWasmInterpreted();
CHECK_EQ(expected_breaks_[count_].position, summ.byte_offset());
+ expected_breaks_[count_].pre_action();
Action next_action = expected_breaks_[count_].action;
switch (next_action) {
case Continue:
@@ -112,22 +119,21 @@ class BreakHandler : public debug::DebugDelegate {
}
};
-void SetBreakpoint(WasmRunnerBase& runner, // NOLINT(runtime/references)
- int function_index, int byte_offset,
- int expected_set_byte_offset = -1) {
+Handle<BreakPoint> SetBreakpoint(WasmRunnerBase* runner, int function_index,
+ int byte_offset,
+ int expected_set_byte_offset = -1) {
int func_offset =
- runner.builder().GetFunctionAt(function_index)->code.offset();
+ runner->builder().GetFunctionAt(function_index)->code.offset();
int code_offset = func_offset + byte_offset;
if (expected_set_byte_offset == -1) expected_set_byte_offset = byte_offset;
- Handle<WasmInstanceObject> instance = runner.builder().instance_object();
- Handle<WasmModuleObject> module_object(instance->module_object(),
- runner.main_isolate());
+ Handle<WasmInstanceObject> instance = runner->builder().instance_object();
+ Handle<Script> script(instance->module_object().script(),
+ runner->main_isolate());
static int break_index = 0;
Handle<BreakPoint> break_point =
- runner.main_isolate()->factory()->NewBreakPoint(
- break_index++, runner.main_isolate()->factory()->empty_string());
- CHECK(WasmModuleObject::SetBreakPoint(module_object, &code_offset,
- break_point));
+ runner->main_isolate()->factory()->NewBreakPoint(
+ break_index++, runner->main_isolate()->factory()->empty_string());
+ CHECK(WasmModuleObject::SetBreakPoint(script, &code_offset, break_point));
int set_byte_offset = code_offset - func_offset;
CHECK_EQ(expected_set_byte_offset, set_byte_offset);
// Also set breakpoint on the debug info of the instance directly, since the
@@ -135,6 +141,24 @@ void SetBreakpoint(WasmRunnerBase& runner, // NOLINT(runtime/references)
Handle<WasmDebugInfo> debug_info =
WasmInstanceObject::GetOrCreateDebugInfo(instance);
WasmDebugInfo::SetBreakpoint(debug_info, function_index, set_byte_offset);
+
+ return break_point;
+}
+
+void ClearBreakpoint(WasmRunnerBase* runner, int function_index,
+ int byte_offset, Handle<BreakPoint> break_point) {
+ int func_offset =
+ runner->builder().GetFunctionAt(function_index)->code.offset();
+ int code_offset = func_offset + byte_offset;
+ Handle<WasmInstanceObject> instance = runner->builder().instance_object();
+ Handle<Script> script(instance->module_object().script(),
+ runner->main_isolate());
+ CHECK(WasmModuleObject::ClearBreakPoint(script, code_offset, break_point));
+ // Also clear breakpoint on the debug info of the instance directly, since the
+ // instance chain is not setup properly in tests.
+ Handle<WasmDebugInfo> debug_info =
+ WasmInstanceObject::GetOrCreateDebugInfo(instance);
+ WasmDebugInfo::ClearBreakpoint(debug_info, function_index, byte_offset);
}
// Wrapper with operator<<.
@@ -247,25 +271,25 @@ WASM_COMPILED_EXEC_TEST(WasmCollectPossibleBreakpoints) {
BUILD(runner, WASM_NOP, WASM_I32_ADD(WASM_ZERO, WASM_ONE));
WasmInstanceObject instance = *runner.builder().instance_object();
- WasmModuleObject module_object = instance.module_object();
+ NativeModule* native_module = instance.module_object().native_module();
std::vector<debug::Location> locations;
// Check all locations for function 0.
- CheckLocations(module_object, {0, 0}, {1, 0},
+ CheckLocations(native_module, {0, 0}, {1, 0},
{{0, 1}, {0, 2}, {0, 4}, {0, 6}, {0, 7}});
// Check a range ending at an instruction.
- CheckLocations(module_object, {0, 2}, {0, 4}, {{0, 2}});
+ CheckLocations(native_module, {0, 2}, {0, 4}, {{0, 2}});
// Check a range ending one behind an instruction.
- CheckLocations(module_object, {0, 2}, {0, 5}, {{0, 2}, {0, 4}});
+ CheckLocations(native_module, {0, 2}, {0, 5}, {{0, 2}, {0, 4}});
// Check a range starting at an instruction.
- CheckLocations(module_object, {0, 7}, {0, 8}, {{0, 7}});
+ CheckLocations(native_module, {0, 7}, {0, 8}, {{0, 7}});
// Check from an instruction to beginning of next function.
- CheckLocations(module_object, {0, 7}, {1, 0}, {{0, 7}});
+ CheckLocations(native_module, {0, 7}, {1, 0}, {{0, 7}});
// Check from end of one function (no valid instruction position) to beginning
// of next function. Must be empty, but not fail.
- CheckLocations(module_object, {0, 8}, {1, 0}, {});
+ CheckLocations(native_module, {0, 8}, {1, 0}, {});
// Check from one after the end of the function. Must fail.
- CheckLocationsFail(module_object, {0, 9}, {1, 0});
+ CheckLocationsFail(native_module, {0, 9}, {1, 0});
}
WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) {
@@ -276,7 +300,7 @@ WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) {
Handle<JSFunction> main_fun_wrapper =
runner.builder().WrapCode(runner.function_index());
- SetBreakpoint(runner, runner.function_index(), 4, 4);
+ SetBreakpoint(&runner, runner.function_index(), 4, 4);
BreakHandler count_breaks(isolate, {{4, BreakHandler::Continue}});
@@ -298,7 +322,7 @@ WASM_COMPILED_EXEC_TEST(WasmSimpleStepping) {
runner.builder().WrapCode(runner.function_index());
// Set breakpoint at the first I32Const.
- SetBreakpoint(runner, runner.function_index(), 1, 1);
+ SetBreakpoint(&runner, runner.function_index(), 1, 1);
BreakHandler count_breaks(isolate,
{
@@ -340,12 +364,12 @@ WASM_COMPILED_EXEC_TEST(WasmStepInAndOut) {
Handle<JSFunction> main_fun_wrapper =
runner.builder().WrapCode(f2.function_index());
- // Set first breakpoint on the GetLocal (offset 19) before the Call.
- SetBreakpoint(runner, f2.function_index(), 19, 19);
+ // Set first breakpoint on the LocalGet (offset 19) before the Call.
+ SetBreakpoint(&runner, f2.function_index(), 19, 19);
BreakHandler count_breaks(isolate,
{
- {19, BreakHandler::StepIn}, // GetLocal
+ {19, BreakHandler::StepIn}, // LocalGet
{21, BreakHandler::StepIn}, // Call
{1, BreakHandler::StepOut}, // in f2
{23, BreakHandler::Continue} // After Call
@@ -377,7 +401,7 @@ WASM_COMPILED_EXEC_TEST(WasmGetLocalsAndStack) {
// Set breakpoint at the first instruction (7 bytes for local decls: num
// entries + 3x<count, type>).
- SetBreakpoint(runner, runner.function_index(), 7, 7);
+ SetBreakpoint(&runner, runner.function_index(), 7, 7);
CollectValuesBreakHandler break_handler(
isolate,
@@ -401,6 +425,104 @@ WASM_COMPILED_EXEC_TEST(WasmGetLocalsAndStack) {
CHECK(!Execution::Call(isolate, main_fun_wrapper, global, 1, args).is_null());
}
+WASM_COMPILED_EXEC_TEST(WasmRemoveBreakPoint) {
+ WasmRunner<int> runner(execution_tier);
+ Isolate* isolate = runner.main_isolate();
+
+ BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP,
+ WASM_I32V_1(14));
+
+ Handle<JSFunction> main_fun_wrapper =
+ runner.builder().WrapCode(runner.function_index());
+
+ SetBreakpoint(&runner, runner.function_index(), 1, 1);
+ SetBreakpoint(&runner, runner.function_index(), 2, 2);
+ Handle<BreakPoint> to_delete =
+ SetBreakpoint(&runner, runner.function_index(), 3, 3);
+ SetBreakpoint(&runner, runner.function_index(), 4, 4);
+
+ BreakHandler count_breaks(isolate, {{1, BreakHandler::Continue},
+ {2, BreakHandler::Continue,
+ [&runner, &to_delete]() {
+ ClearBreakpoint(
+ &runner, runner.function_index(),
+ 3, to_delete);
+ }},
+ {4, BreakHandler::Continue}});
+
+ Handle<Object> global(isolate->context().global_object(), isolate);
+ MaybeHandle<Object> retval =
+ Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
+ CHECK(!retval.is_null());
+ int result;
+ CHECK(retval.ToHandleChecked()->ToInt32(&result));
+ CHECK_EQ(14, result);
+}
+
+WASM_COMPILED_EXEC_TEST(WasmRemoveLastBreakPoint) {
+ WasmRunner<int> runner(execution_tier);
+ Isolate* isolate = runner.main_isolate();
+
+ BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP,
+ WASM_I32V_1(14));
+
+ Handle<JSFunction> main_fun_wrapper =
+ runner.builder().WrapCode(runner.function_index());
+
+ SetBreakpoint(&runner, runner.function_index(), 1, 1);
+ SetBreakpoint(&runner, runner.function_index(), 2, 2);
+ Handle<BreakPoint> to_delete =
+ SetBreakpoint(&runner, runner.function_index(), 3, 3);
+
+ BreakHandler count_breaks(
+ isolate, {{1, BreakHandler::Continue},
+ {2, BreakHandler::Continue, [&runner, &to_delete]() {
+ ClearBreakpoint(&runner, runner.function_index(), 3,
+ to_delete);
+ }}});
+
+ Handle<Object> global(isolate->context().global_object(), isolate);
+ MaybeHandle<Object> retval =
+ Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
+ CHECK(!retval.is_null());
+ int result;
+ CHECK(retval.ToHandleChecked()->ToInt32(&result));
+ CHECK_EQ(14, result);
+}
+
+WASM_COMPILED_EXEC_TEST(WasmRemoveAllBreakPoint) {
+ WasmRunner<int> runner(execution_tier);
+ Isolate* isolate = runner.main_isolate();
+
+ BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP,
+ WASM_I32V_1(14));
+
+ Handle<JSFunction> main_fun_wrapper =
+ runner.builder().WrapCode(runner.function_index());
+
+ Handle<BreakPoint> bp1 =
+ SetBreakpoint(&runner, runner.function_index(), 1, 1);
+ Handle<BreakPoint> bp2 =
+ SetBreakpoint(&runner, runner.function_index(), 2, 2);
+ Handle<BreakPoint> bp3 =
+ SetBreakpoint(&runner, runner.function_index(), 3, 3);
+
+ BreakHandler count_breaks(
+ isolate, {{1, BreakHandler::Continue, [&runner, &bp1, &bp2, &bp3]() {
+ ClearBreakpoint(&runner, runner.function_index(), 1, bp1);
+ ClearBreakpoint(&runner, runner.function_index(), 3, bp3);
+ ClearBreakpoint(&runner, runner.function_index(), 2, bp2);
+ }}});
+
+ Handle<Object> global(isolate->context().global_object(), isolate);
+ MaybeHandle<Object> retval =
+ Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
+ CHECK(!retval.is_null());
+ int result;
+ CHECK(retval.ToHandleChecked()->ToInt32(&result));
+ CHECK_EQ(14, result);
+}
+
} // namespace wasm
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc b/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc
index 299c039698..15267215e1 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-import-wrapper-cache.cc
@@ -22,10 +22,8 @@ std::shared_ptr<NativeModule> NewModule(Isolate* isolate) {
std::shared_ptr<WasmModule> module(new WasmModule);
bool can_request_more = false;
size_t size = 16384;
- auto native_module = isolate->wasm_engine()->NewNativeModule(
+ return isolate->wasm_engine()->NewNativeModule(
isolate, kAllWasmFeatures, size, can_request_more, std::move(module));
- native_module->SetRuntimeStubs(isolate);
- return native_module;
}
TEST(CacheHit) {
diff --git a/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc b/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc
index 736475ff55..75e927fafe 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-interpreter-entry.cc
@@ -32,28 +32,27 @@ namespace {
template <typename T>
class ArgPassingHelper {
public:
- ArgPassingHelper(
- WasmRunnerBase& runner, // NOLINT(runtime/references)
- WasmFunctionCompiler& inner_compiler, // NOLINT(runtime/references)
- std::initializer_list<uint8_t> bytes_inner_function,
- std::initializer_list<uint8_t> bytes_outer_function,
- const T& expected_lambda)
- : isolate_(runner.main_isolate()),
+ ArgPassingHelper(WasmRunnerBase* runner, WasmFunctionCompiler* inner_compiler,
+ std::initializer_list<uint8_t> bytes_inner_function,
+ std::initializer_list<uint8_t> bytes_outer_function,
+ const T& expected_lambda)
+ : isolate_(runner->main_isolate()),
expected_lambda_(expected_lambda),
debug_info_(WasmInstanceObject::GetOrCreateDebugInfo(
- runner.builder().instance_object())) {
+ runner->builder().instance_object())) {
std::vector<uint8_t> inner_code{bytes_inner_function};
- inner_compiler.Build(inner_code.data(),
- inner_code.data() + inner_code.size());
+ inner_compiler->Build(inner_code.data(),
+ inner_code.data() + inner_code.size());
std::vector<uint8_t> outer_code{bytes_outer_function};
- runner.Build(outer_code.data(), outer_code.data() + outer_code.size());
+ runner->Build(outer_code.data(), outer_code.data() + outer_code.size());
- int funcs_to_redict[] = {static_cast<int>(inner_compiler.function_index())};
- runner.builder().SetExecutable();
+ int funcs_to_redict[] = {
+ static_cast<int>(inner_compiler->function_index())};
+ runner->builder().SetExecutable();
WasmDebugInfo::RedirectToInterpreter(debug_info_,
ArrayVector(funcs_to_redict));
- main_fun_wrapper_ = runner.builder().WrapCode(runner.function_index());
+ main_fun_wrapper_ = runner->builder().WrapCode(runner->function_index());
}
template <typename... Args>
@@ -82,8 +81,7 @@ class ArgPassingHelper {
template <typename T>
static ArgPassingHelper<T> GetHelper(
- WasmRunnerBase& runner, // NOLINT(runtime/references)
- WasmFunctionCompiler& inner_compiler, // NOLINT(runtime/references)
+ WasmRunnerBase* runner, WasmFunctionCompiler* inner_compiler,
std::initializer_list<uint8_t> bytes_inner_function,
std::initializer_list<uint8_t> bytes_outer_function,
const T& expected_lambda) {
@@ -99,7 +97,7 @@ TEST(TestArgumentPassing_int32) {
WasmFunctionCompiler& f2 = runner.NewFunction<int32_t, int32_t>();
auto helper = GetHelper(
- runner, f2,
+ &runner, &f2,
{// Return 2*<0> + 1.
WASM_I32_ADD(WASM_I32_MUL(WASM_I32V_1(2), WASM_GET_LOCAL(0)), WASM_ONE)},
{// Call f2 with param <0>.
@@ -117,7 +115,7 @@ TEST(TestArgumentPassing_double_int64) {
WasmFunctionCompiler& f2 = runner.NewFunction<double, int64_t>();
auto helper = GetHelper(
- runner, f2,
+ &runner, &f2,
{// Return (double)<0>.
WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(0))},
{// Call f2 with param (<0> | (<1> << 32)).
@@ -150,7 +148,7 @@ TEST(TestArgumentPassing_int64_double) {
WasmFunctionCompiler& f2 = runner.NewFunction<int64_t, double>();
auto helper = GetHelper(
- runner, f2,
+ &runner, &f2,
{// Return (int64_t)<0>.
WASM_I64_SCONVERT_F64(WASM_GET_LOCAL(0))},
{// Call f2 with param <0>, convert returned value back to double.
@@ -169,7 +167,7 @@ TEST(TestArgumentPassing_float_double) {
WasmFunctionCompiler& f2 = runner.NewFunction<double, float>();
auto helper = GetHelper(
- runner, f2,
+ &runner, &f2,
{// Return 2*(double)<0> + 1.
WASM_F64_ADD(
WASM_F64_MUL(WASM_F64(2), WASM_F64_CONVERT_F32(WASM_GET_LOCAL(0))),
@@ -186,7 +184,7 @@ TEST(TestArgumentPassing_double_double) {
WasmRunner<double, double, double> runner(ExecutionTier::kTurbofan);
WasmFunctionCompiler& f2 = runner.NewFunction<double, double, double>();
- auto helper = GetHelper(runner, f2,
+ auto helper = GetHelper(&runner, &f2,
{// Return <0> + <1>.
WASM_F64_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))},
{// Call f2 with params <0>, <1>.
@@ -208,7 +206,7 @@ TEST(TestArgumentPassing_AllTypes) {
runner.NewFunction<double, int32_t, int64_t, float, double>();
auto helper = GetHelper(
- runner, f2,
+ &runner, &f2,
{
// Convert all arguments to double, add them and return the sum.
WASM_F64_ADD( // <0+1+2> + <3>
diff --git a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
index 1ff2a899ad..c6486650ef 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
@@ -11,7 +11,6 @@
#include "src/utils/version.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-memory.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
@@ -272,9 +271,8 @@ TEST(BlockWasmCodeGenAtDeserialization) {
Cleanup();
}
-namespace {
-
-void TestTransferrableWasmModules(bool should_share) {
+UNINITIALIZED_TEST(CompiledWasmModulesTransfer) {
+ FlagScope<bool> flag_scope_engine(&FLAG_wasm_shared_engine, true);
i::wasm::WasmEngine::InitializeOncePerProcess();
v8::internal::AccountingAllocator allocator;
Zone zone(&allocator, ZONE_NAME);
@@ -285,7 +283,7 @@ void TestTransferrableWasmModules(bool should_share) {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* from_isolate = v8::Isolate::New(create_params);
- std::vector<v8::WasmModuleObject::TransferrableModule> store;
+ std::vector<v8::CompiledWasmModule> store;
std::shared_ptr<NativeModule> original_native_module;
{
v8::HandleScope scope(from_isolate);
@@ -293,7 +291,7 @@ void TestTransferrableWasmModules(bool should_share) {
Isolate* from_i_isolate = reinterpret_cast<Isolate*>(from_isolate);
testing::SetupIsolateForWasmModule(from_i_isolate);
- ErrorThrower thrower(from_i_isolate, "TestTransferrableWasmModules");
+ ErrorThrower thrower(from_i_isolate, "TestCompiledWasmModulesTransfer");
auto enabled_features = WasmFeaturesFromIsolate(from_i_isolate);
MaybeHandle<WasmModuleObject> maybe_module_object =
from_i_isolate->wasm_engine()->SyncCompile(
@@ -304,7 +302,7 @@ void TestTransferrableWasmModules(bool should_share) {
v8::Local<v8::WasmModuleObject> v8_module =
v8::Local<v8::WasmModuleObject>::Cast(
v8::Utils::ToLocal(Handle<JSObject>::cast(module_object)));
- store.push_back(v8_module->GetTransferrableModule());
+ store.push_back(v8_module->GetCompiledModule());
original_native_module = module_object->shared_native_module();
}
@@ -315,14 +313,13 @@ void TestTransferrableWasmModules(bool should_share) {
LocalContext env(to_isolate);
v8::MaybeLocal<v8::WasmModuleObject> transferred_module =
- v8::WasmModuleObject::FromTransferrableModule(to_isolate, store[0]);
+ v8::WasmModuleObject::FromCompiledModule(to_isolate, store[0]);
CHECK(!transferred_module.IsEmpty());
Handle<WasmModuleObject> module_object = Handle<WasmModuleObject>::cast(
v8::Utils::OpenHandle(*transferred_module.ToLocalChecked()));
std::shared_ptr<NativeModule> transferred_native_module =
module_object->shared_native_module();
- bool is_sharing = (original_native_module == transferred_native_module);
- CHECK_EQ(should_share, is_sharing);
+ CHECK_EQ(original_native_module, transferred_native_module);
}
to_isolate->Dispose();
}
@@ -330,19 +327,6 @@ void TestTransferrableWasmModules(bool should_share) {
from_isolate->Dispose();
}
-} // namespace
-
-UNINITIALIZED_TEST(TransferrableWasmModulesCloned) {
- FlagScope<bool> flag_scope_code(&FLAG_wasm_shared_code, false);
- TestTransferrableWasmModules(false);
-}
-
-UNINITIALIZED_TEST(TransferrableWasmModulesShared) {
- FlagScope<bool> flag_scope_engine(&FLAG_wasm_shared_engine, true);
- FlagScope<bool> flag_scope_code(&FLAG_wasm_shared_code, true);
- TestTransferrableWasmModules(true);
-}
-
#undef EMIT_CODE_WITH_END
} // namespace test_wasm_serialization
diff --git a/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc b/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc
index b5bacf57d4..2d6e930397 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-shared-engine.cc
@@ -27,7 +27,7 @@ namespace test_wasm_shared_engine {
class SharedEngine {
public:
explicit SharedEngine(size_t max_committed = kMaxWasmCodeMemory)
- : wasm_engine_(base::make_unique<WasmEngine>()) {}
+ : wasm_engine_(std::make_unique<WasmEngine>()) {}
~SharedEngine() {
// Ensure no remaining uses exist.
CHECK(wasm_engine_.unique());
@@ -112,19 +112,19 @@ class SharedEngineIsolate {
class SharedEngineThread : public v8::base::Thread {
public:
SharedEngineThread(SharedEngine* engine,
- std::function<void(SharedEngineIsolate&)> callback)
+ std::function<void(SharedEngineIsolate*)> callback)
: Thread(Options("SharedEngineThread")),
engine_(engine),
callback_(callback) {}
void Run() override {
SharedEngineIsolate isolate(engine_);
- callback_(isolate);
+ callback_(&isolate);
}
private:
SharedEngine* engine_;
- std::function<void(SharedEngineIsolate&)> callback_;
+ std::function<void(SharedEngineIsolate*)> callback_;
};
namespace {
@@ -159,43 +159,39 @@ class MockInstantiationResolver : public InstantiationResultResolver {
class MockCompilationResolver : public CompilationResultResolver {
public:
- MockCompilationResolver(
- SharedEngineIsolate& isolate, // NOLINT(runtime/references)
- Handle<Object>* out_instance)
+ MockCompilationResolver(SharedEngineIsolate* isolate,
+ Handle<Object>* out_instance)
: isolate_(isolate), out_instance_(out_instance) {}
void OnCompilationSucceeded(Handle<WasmModuleObject> result) override {
- isolate_.isolate()->wasm_engine()->AsyncInstantiate(
- isolate_.isolate(),
- base::make_unique<MockInstantiationResolver>(out_instance_), result,
- {});
+ isolate_->isolate()->wasm_engine()->AsyncInstantiate(
+ isolate_->isolate(),
+ std::make_unique<MockInstantiationResolver>(out_instance_), result, {});
}
void OnCompilationFailed(Handle<Object> error_reason) override {
UNREACHABLE();
}
private:
- SharedEngineIsolate& isolate_;
+ SharedEngineIsolate* isolate_;
Handle<Object>* out_instance_;
};
-void PumpMessageLoop(
- SharedEngineIsolate& isolate) { // NOLINT(runtime/references)
+void PumpMessageLoop(SharedEngineIsolate* isolate) {
v8::platform::PumpMessageLoop(i::V8::GetCurrentPlatform(),
- isolate.v8_isolate(),
+ isolate->v8_isolate(),
platform::MessageLoopBehavior::kWaitForWork);
- isolate.isolate()->default_microtask_queue()->RunMicrotasks(
- isolate.isolate());
+ isolate->isolate()->default_microtask_queue()->RunMicrotasks(
+ isolate->isolate());
}
Handle<WasmInstanceObject> CompileAndInstantiateAsync(
- SharedEngineIsolate& isolate, // NOLINT(runtime/references)
- ZoneBuffer* buffer) {
- Handle<Object> maybe_instance = handle(Smi::kZero, isolate.isolate());
- auto enabled_features = WasmFeaturesFromIsolate(isolate.isolate());
+ SharedEngineIsolate* isolate, ZoneBuffer* buffer) {
+ Handle<Object> maybe_instance = handle(Smi::kZero, isolate->isolate());
+ auto enabled_features = WasmFeaturesFromIsolate(isolate->isolate());
constexpr const char* kAPIMethodName = "Test.CompileAndInstantiateAsync";
- isolate.isolate()->wasm_engine()->AsyncCompile(
- isolate.isolate(), enabled_features,
- base::make_unique<MockCompilationResolver>(isolate, &maybe_instance),
+ isolate->isolate()->wasm_engine()->AsyncCompile(
+ isolate->isolate(), enabled_features,
+ std::make_unique<MockCompilationResolver>(isolate, &maybe_instance),
ModuleWireBytes(buffer->begin(), buffer->end()), true, kAPIMethodName);
while (!maybe_instance->IsWasmInstanceObject()) PumpMessageLoop(isolate);
Handle<WasmInstanceObject> instance =
@@ -261,17 +257,19 @@ TEST(SharedEngineRunImported) {
TEST(SharedEngineRunThreadedBuildingSync) {
SharedEngine engine;
- SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) {
- HandleScope scope(isolate.isolate());
- ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23);
- Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer);
- CHECK_EQ(23, isolate.Run(instance));
+ SharedEngineThread thread1(&engine, [](SharedEngineIsolate* isolate) {
+ HandleScope scope(isolate->isolate());
+ ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23);
+ Handle<WasmInstanceObject> instance =
+ isolate->CompileAndInstantiate(buffer);
+ CHECK_EQ(23, isolate->Run(instance));
});
- SharedEngineThread thread2(&engine, [](SharedEngineIsolate& isolate) {
- HandleScope scope(isolate.isolate());
- ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42);
- Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer);
- CHECK_EQ(42, isolate.Run(instance));
+ SharedEngineThread thread2(&engine, [](SharedEngineIsolate* isolate) {
+ HandleScope scope(isolate->isolate());
+ ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42);
+ Handle<WasmInstanceObject> instance =
+ isolate->CompileAndInstantiate(buffer);
+ CHECK_EQ(42, isolate->Run(instance));
});
CHECK(thread1.Start());
CHECK(thread2.Start());
@@ -281,19 +279,19 @@ TEST(SharedEngineRunThreadedBuildingSync) {
TEST(SharedEngineRunThreadedBuildingAsync) {
SharedEngine engine;
- SharedEngineThread thread1(&engine, [](SharedEngineIsolate& isolate) {
- HandleScope scope(isolate.isolate());
- ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 23);
+ SharedEngineThread thread1(&engine, [](SharedEngineIsolate* isolate) {
+ HandleScope scope(isolate->isolate());
+ ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 23);
Handle<WasmInstanceObject> instance =
CompileAndInstantiateAsync(isolate, buffer);
- CHECK_EQ(23, isolate.Run(instance));
+ CHECK_EQ(23, isolate->Run(instance));
});
- SharedEngineThread thread2(&engine, [](SharedEngineIsolate& isolate) {
- HandleScope scope(isolate.isolate());
- ZoneBuffer* buffer = BuildReturnConstantModule(isolate.zone(), 42);
+ SharedEngineThread thread2(&engine, [](SharedEngineIsolate* isolate) {
+ HandleScope scope(isolate->isolate());
+ ZoneBuffer* buffer = BuildReturnConstantModule(isolate->zone(), 42);
Handle<WasmInstanceObject> instance =
CompileAndInstantiateAsync(isolate, buffer);
- CHECK_EQ(42, isolate.Run(instance));
+ CHECK_EQ(42, isolate->Run(instance));
});
CHECK(thread1.Start());
CHECK(thread2.Start());
@@ -311,15 +309,15 @@ TEST(SharedEngineRunThreadedExecution) {
Handle<WasmInstanceObject> instance = isolate.CompileAndInstantiate(buffer);
module = isolate.ExportInstance(instance);
}
- SharedEngineThread thread1(&engine, [module](SharedEngineIsolate& isolate) {
- HandleScope scope(isolate.isolate());
- Handle<WasmInstanceObject> instance = isolate.ImportInstance(module);
- CHECK_EQ(23, isolate.Run(instance));
+ SharedEngineThread thread1(&engine, [module](SharedEngineIsolate* isolate) {
+ HandleScope scope(isolate->isolate());
+ Handle<WasmInstanceObject> instance = isolate->ImportInstance(module);
+ CHECK_EQ(23, isolate->Run(instance));
});
- SharedEngineThread thread2(&engine, [module](SharedEngineIsolate& isolate) {
- HandleScope scope(isolate.isolate());
- Handle<WasmInstanceObject> instance = isolate.ImportInstance(module);
- CHECK_EQ(23, isolate.Run(instance));
+ SharedEngineThread thread2(&engine, [module](SharedEngineIsolate* isolate) {
+ HandleScope scope(isolate->isolate());
+ Handle<WasmInstanceObject> instance = isolate->ImportInstance(module);
+ CHECK_EQ(23, isolate->Run(instance));
});
CHECK(thread1.Start());
CHECK(thread2.Start());
@@ -340,23 +338,23 @@ TEST(SharedEngineRunThreadedTierUp) {
constexpr int kNumberOfThreads = 5;
std::list<SharedEngineThread> threads;
for (int i = 0; i < kNumberOfThreads; ++i) {
- threads.emplace_back(&engine, [module](SharedEngineIsolate& isolate) {
+ threads.emplace_back(&engine, [module](SharedEngineIsolate* isolate) {
constexpr int kNumberOfIterations = 100;
- HandleScope scope(isolate.isolate());
- Handle<WasmInstanceObject> instance = isolate.ImportInstance(module);
+ HandleScope scope(isolate->isolate());
+ Handle<WasmInstanceObject> instance = isolate->ImportInstance(module);
for (int j = 0; j < kNumberOfIterations; ++j) {
- CHECK_EQ(23, isolate.Run(instance));
+ CHECK_EQ(23, isolate->Run(instance));
}
});
}
- threads.emplace_back(&engine, [module](SharedEngineIsolate& isolate) {
- HandleScope scope(isolate.isolate());
- Handle<WasmInstanceObject> instance = isolate.ImportInstance(module);
+ threads.emplace_back(&engine, [module](SharedEngineIsolate* isolate) {
+ HandleScope scope(isolate->isolate());
+ Handle<WasmInstanceObject> instance = isolate->ImportInstance(module);
WasmFeatures detected = kNoWasmFeatures;
WasmCompilationUnit::CompileWasmFunction(
- isolate.isolate(), module.get(), &detected,
+ isolate->isolate(), module.get(), &detected,
&module->module()->functions[0], ExecutionTier::kTurbofan);
- CHECK_EQ(23, isolate.Run(instance));
+ CHECK_EQ(23, isolate->Run(instance));
});
for (auto& thread : threads) CHECK(thread.Start());
for (auto& thread : threads) thread.Join();
diff --git a/deps/v8/test/cctest/wasm/wasm-run-utils.cc b/deps/v8/test/cctest/wasm/wasm-run-utils.cc
index 528d71f53c..09d64e5d97 100644
--- a/deps/v8/test/cctest/wasm/wasm-run-utils.cc
+++ b/deps/v8/test/cctest/wasm/wasm-run-utils.cc
@@ -10,7 +10,6 @@
#include "src/wasm/graph-builder-interface.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/wasm-import-wrapper-cache.h"
-#include "src/wasm/wasm-memory.h"
#include "src/wasm/wasm-objects-inl.h"
namespace v8 {
@@ -75,29 +74,23 @@ byte* TestingModuleBuilder::AddMemory(uint32_t size, SharedFlag shared) {
CHECK_NULL(mem_start_);
CHECK_EQ(0, mem_size_);
DCHECK(!instance_object_->has_memory_object());
- DCHECK_IMPLIES(test_module_->origin == kWasmOrigin,
- size % kWasmPageSize == 0);
+ uint32_t initial_pages = RoundUp(size, kWasmPageSize) / kWasmPageSize;
+ uint32_t maximum_pages = (test_module_->maximum_pages != 0)
+ ? test_module_->maximum_pages
+ : initial_pages;
test_module_->has_memory = true;
- uint32_t max_size =
- (test_module_->maximum_pages != 0) ? test_module_->maximum_pages : size;
- uint32_t alloc_size = RoundUp(size, kWasmPageSize);
- Handle<JSArrayBuffer> new_buffer;
- if (shared == SharedFlag::kShared) {
- CHECK(NewSharedArrayBuffer(isolate_, alloc_size, max_size)
- .ToHandle(&new_buffer));
- } else {
- CHECK(NewArrayBuffer(isolate_, alloc_size).ToHandle(&new_buffer));
- }
- CHECK(!new_buffer.is_null());
- mem_start_ = reinterpret_cast<byte*>(new_buffer->backing_store());
- mem_size_ = size;
- CHECK(size == 0 || mem_start_);
- memset(mem_start_, 0, size);
// Create the WasmMemoryObject.
Handle<WasmMemoryObject> memory_object =
- WasmMemoryObject::New(isolate_, new_buffer, max_size);
+ WasmMemoryObject::New(isolate_, initial_pages, maximum_pages, shared)
+ .ToHandleChecked();
instance_object_->set_memory_object(*memory_object);
+
+ mem_start_ =
+ reinterpret_cast<byte*>(memory_object->array_buffer().backing_store());
+ mem_size_ = size;
+ CHECK(size == 0 || mem_start_);
+
WasmMemoryObject::AddInstance(isolate_, memory_object, instance_object_);
// TODO(wasm): Delete the following two lines when test-run-wasm will use a
// multiple of kPageSize as memory size. At the moment, the effect of these
@@ -328,7 +321,6 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
auto native_module = isolate_->wasm_engine()->NewNativeModule(
isolate_, enabled_features_, test_module_);
native_module->SetWireBytes(OwnedVector<const uint8_t>());
- native_module->SetRuntimeStubs(isolate_);
Handle<WasmModuleObject> module_object =
WasmModuleObject::New(isolate_, std::move(native_module), script);
@@ -487,7 +479,7 @@ Handle<Code> WasmFunctionWrapper::GetWrapperCode() {
CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
OFStream os(tracing_scope.file());
- code->Disassemble("wasm wrapper", os);
+ code->Disassemble("wasm wrapper", os, isolate);
}
#endif
}