[wasm] Experimentally allow modules >1GB

Add an experimental flag to allow modules up to a size slightly below
2GB, to make sure that we don't run into integer overflows.
Modules this large are not tested at all currently, hence the explicit
"experimental" in the flag name.

Drive-by: Fix one comparison to use ">" instead of ">=".

R=ahaas@chromium.org
CC=​bmeurer@chromium.org

Bug: v8:10642
Change-Id: I91cfc290c262b9b81750e3c8af5358c1cd2572b1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2266535
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68547}
This commit is contained in:
Clemens Backes 2020-06-25 16:14:32 +02:00 committed by Commit Bot
parent 33376bdf1d
commit 490971092c
6 changed files with 19 additions and 6 deletions

View File

@ -823,6 +823,9 @@ DEFINE_BOOL(stress_wasm_code_gc, false,
DEFINE_INT(wasm_max_initial_code_space_reservation, 0,
"maximum size of the initial wasm code space reservation (in MB)")
DEFINE_BOOL(experimental_wasm_allow_huge_modules, false,
"allow wasm modules bigger than 1GB, but below ~2GB")
// Profiler flags.
DEFINE_INT(frame_count, 1, "number of stack frames inspected by the profiler")

View File

@ -2049,9 +2049,10 @@ ModuleResult DecodeWasmModule(const WasmFeatures& enabled,
AccountingAllocator* allocator) {
size_t size = module_end - module_start;
CHECK_LE(module_start, module_end);
if (size >= kV8MaxWasmModuleSize) {
return ModuleResult{WasmError{0, "size > maximum module size (%zu): %zu",
kV8MaxWasmModuleSize, size}};
size_t max_size = max_module_size();
if (size > max_size) {
return ModuleResult{
WasmError{0, "size > maximum module size (%zu): %zu", max_size, size}};
}
// TODO(bradnelson): Improve histogram handling of size_t.
auto size_counter =

View File

@ -410,7 +410,7 @@ class AsyncStreamingDecoder::DecodeSectionID : public DecodingState {
class AsyncStreamingDecoder::DecodeSectionLength : public DecodeVarInt32 {
public:
explicit DecodeSectionLength(uint8_t id, uint32_t module_offset)
: DecodeVarInt32(kV8MaxWasmModuleSize, "section length"),
: DecodeVarInt32(max_module_size(), "section length"),
section_id_(id),
module_offset_(module_offset) {}

View File

@ -1417,6 +1417,13 @@ uint32_t max_table_init_entries() {
FLAG_wasm_max_table_size);
}
// {max_module_size} is declared in wasm-limits.h.
size_t max_module_size() {
return FLAG_experimental_wasm_allow_huge_modules
? RoundDown<kSystemPointerSize>(size_t{kMaxInt})
: kV8MaxWasmModuleSize;
}
#undef TRACE_CODE_GC
} // namespace wasm

View File

@ -214,9 +214,10 @@ i::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
if (length == 0) {
thrower->CompileError("BufferSource argument is empty");
}
if (length > i::wasm::kV8MaxWasmModuleSize) {
size_t max_length = i::wasm::max_module_size();
if (length > max_length) {
thrower->RangeError("buffer source exceeds maximum size of %zu (is %zu)",
i::wasm::kV8MaxWasmModuleSize, length);
max_length, length);
}
if (thrower->error()) return i::wasm::ModuleWireBytes(nullptr, nullptr);
return i::wasm::ModuleWireBytes(start, start + length);

View File

@ -65,6 +65,7 @@ constexpr uint64_t kWasmMaxHeapOffset =
V8_EXPORT_PRIVATE uint32_t max_initial_mem_pages();
V8_EXPORT_PRIVATE uint32_t max_maximum_mem_pages();
uint32_t max_table_init_entries();
size_t max_module_size();
inline uint64_t max_mem_bytes() {
return uint64_t{max_maximum_mem_pages()} * kWasmPageSize;