v8/test/mjsunit/wasm/many-modules.js
Clemens Hammacher 87287908b3 [wasm] Add test for creating 10k modules in one process
With --wasm-far-jump-table, it will be possible to create 10k (and
more) modules in one process. So far, we hit the virtual address space
limit around 1k modules, because each module makes a reservation of
{kMaxWasmCodeMemory} upfront. After this change, each module will only
reserve the estimated needed code size (if --wasm-far-jump-table is
set).

The test is carefully optimized to not execute too much code in the
loop, so it can still run in simulators in reasonable time. Note that
the time for actually compiling the module is spent in C++, which is
fast in simulator builds.

R=mstarzinger@chromium.org

Bug: v8:9477, v8:9651
Change-Id: If74a825d272a65b82ca5433cb648b6a2271872e8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1811038
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63903}
2019-09-20 09:34:34 +00:00

46 lines
2.0 KiB
JavaScript

// 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.
// No reason to stress-opt this; save some time.
// Flags: --wasm-far-jump-table --no-stress-opt
load('test/mjsunit/wasm/wasm-module-builder.js');
// We generate the module bytes once to make this test more efficient,
// especially on simulator builds. The bytes contain a sentinel which is later
// patched to different constants. This makes the modules distinct and forces
// the engine to create different code for them.
// This is the sentinel placed in the bytes. It's a 5 byte LEB-encoded integer.
const sentinel = wasmSignedLeb(0x12345678);
assertEquals(5, sentinel.length);
const builder = new WasmModuleBuilder();
builder.addFunction('f', kSig_i_i).addBody([kExprI32Const, ...sentinel]);
const module_bytes = builder.toBuffer();
// Checks whether {module_bytes[i .. i+sentinel.length]} matches {sentinel}.
const has_sentinel = (i, k = 0) => module_bytes[i + k] == sentinel[k] &&
(k == sentinel.length - 1 || has_sentinel(i, k + 1));
// Now find the sentinel.
const find_sentinel = i =>
module_bytes.slice(i).findIndex((e, i) => has_sentinel(i));
const sentinel_position = find_sentinel(0);
assertTrue(has_sentinel(sentinel_position), 'found sentinel');
assertEquals(-1, find_sentinel(sentinel_position + 1), 'exactly one sentinel');
// Generating {num_modules} modules should not run out of memory, since the code
// space needed per module is quite low.
const num_modules = 10000;
// Keep all generated modules alive.
const modules = [];
// Reset sentinel section to nops so that shorter LEBs will just be followed by
// nops. This resion will be patched in the loop with values of increasing size.
module_bytes.set(Array(sentinel.length).fill(_ => kExprNop), sentinel_position);
for (let i = 0; i < num_modules; ++i) {
if (i % 50 == 0) print(i);
module_bytes.set(wasmSignedLeb(i), sentinel_position);
modules.push(new WebAssembly.Module(module_bytes));
}