Status: Untriaged
Owner:
piotr...@google.comCC:
s...@chromium.org,
ad...@chromium.org,
ish...@chromium.org,
clem...@chromium.org Priority: 2
Type: Bug
New issue 12592 by
piotr...@google.com: Increase maximum number of Wasm stores (V8 isolates) to more than 256
https://bugs.chromium.org/p/v8/issues/detail?id=12592Version: 9.2 to 9.9, even worse in LKGR
OS: Linux
Architecture: x64
This is a regression in terms of scalability.
Prior to 9.2, one could easily create 10,000 isolates in a single process.
Since commit 1f504c36da9bab622072d65f80bbf819576c7d3f (which enabled v8_enable_pointer_compression_shared_cage, shipped in 9.2), the maximum number of isolates in a single process dropped drastically to 512.
Since commit 5351e0e805e6e7081250b5b9a015dcff8157d1dc (which enabled v8_enable_external_code_space, to be shipped in 10.0), the maximum number of isolates in a single process dropped even further to 256.
This is quite limiting for our use case (Proxy-Wasm in Envoy), where we create a separate isolate for each plugin on each worker thread (so with a dozen of plugins on a powerful edge server, this easily exceeds the current limits and results in a crash).
I can easily restore the ability to create 10,000 isolates if I disable both features (v8_enable_pointer_compression_shared_cage=false v8_enable_external_code_space=false), but since Sandbox features require v8_enable_pointer_compression_shared_cage, I'm not sure how future-proof this is.
Also, I'd like to verify that those limits are a conscious choice and not imposed by accident because of to the selected data structures.
What steps will reproduce the problem?
Build the following code that creates Wasm stores (V8 isolates) in a loop:
$ cat wee8stores.cc
#include <fstream>
#include <iostream>
#include "wasm.hh"
using wasm::ownvec;
using wasm::Engine;
using wasm::Store;
static const int kCount = 10000;
int main(int argc, const char* argv[]) {
ownvec<Store> stores = ownvec<Store>::make_uninitialized(kCount);
auto engine = Engine::make();
for (int i = 0; i < kCount; i++) {
stores[i] = Store::make(engine.get());
if (stores[i] != nullptr) {
std::ifstream stat("/proc/self/statm");
std::cout << "> Created WasmVM #" << (i + 1) << ": " << stat.rdbuf();
stat.close();
} else {
std::cout << "> Failed to create WasmVM #" << i + 1 << std::endl;
exit(1);
}
}
std::cout << "> Done." << std::endl;
exit(0);
}
$ clang++ -std=c++14 -lpthread -ldl -Iinclude/ -Ithird_party/wasm-api/ wee8stores.cc out/wee8/obj/libwee8.a -o wee8stores
What is the expected output?
$ ./wee8stores
> Created WasmVM #1: 1086927 3070 2697 3092 0 33334 0
[...]
> Created WasmVM #10000: 10486917884 2205422 2512 2883 0 4032903 0
> Done.
What do you see instead?
$ ./wee8stores
> Created WasmVM #1: 1086927 3070 2697 3092 0 33334 0
[...]
> Created WasmVM #256: 1143817 60076 2764 3155 0 131853 0
<--- Last few GCs --->
<--- JS stacktrace --->
#
# Fatal javascript OOM in GC during deserialization
#
Trace/breakpoint trap
--
You received this message because:
1. The project was configured to send all issue notifications to this address
You may adjust your notification preferences at:
https://bugs.chromium.org/hosting/settings