Commit a8b7d477 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[wasm] Bring memory limits up to spec

Make sure the "initial pages" memory limit is enforced correctly and
throws a CompileError when exceeded.
Bump the "maximum pages" memory limit to 65536.
The --wasm-max-mem-pages flag now controls the "initial pages" limit;
the "maximum pages" limit is always 65536 as spec'ed.

This CL depends on https://github.com/WebAssembly/spec/pull/1121.

Bug: v8:7881, v8:8633
Change-Id: I68d07cef56633b8b8ce3b3d047c14e1096daf547
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2035876Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66400}
parent 38b4f19b
...@@ -330,7 +330,7 @@ inline bool IsValidAsmjsMemorySize(size_t size) { ...@@ -330,7 +330,7 @@ inline bool IsValidAsmjsMemorySize(size_t size) {
// Enforce asm.js spec minimum size. // Enforce asm.js spec minimum size.
if (size < (1u << 12u)) return false; if (size < (1u << 12u)) return false;
// Enforce engine-limited and flag-limited maximum allocation size. // Enforce engine-limited and flag-limited maximum allocation size.
if (size > wasm::max_mem_pages() * uint64_t{wasm::kWasmPageSize}) { if (size > wasm::max_initial_mem_pages() * uint64_t{wasm::kWasmPageSize}) {
return false; return false;
} }
// Enforce power-of-2 sizes for 2^12 - 2^24. // Enforce power-of-2 sizes for 2^12 - 2^24.
......
...@@ -116,7 +116,7 @@ class V8_EXPORT_PRIVATE TypeCache final { ...@@ -116,7 +116,7 @@ class V8_EXPORT_PRIVATE TypeCache final {
Type const kJSArrayBufferViewByteOffsetType = kJSArrayBufferByteLengthType; Type const kJSArrayBufferViewByteOffsetType = kJSArrayBufferByteLengthType;
// The JSTypedArray::length property always contains an untagged number in // The JSTypedArray::length property always contains an untagged number in
// the range [0, kMaxSmiValue]. // the range [0, JSTypedArray::kMaxLength].
Type const kJSTypedArrayLengthType = Type const kJSTypedArrayLengthType =
CreateRange(0.0, JSTypedArray::kMaxLength); CreateRange(0.0, JSTypedArray::kMaxLength);
......
...@@ -671,9 +671,12 @@ DEFINE_BOOL(wasm_async_compilation, true, ...@@ -671,9 +671,12 @@ DEFINE_BOOL(wasm_async_compilation, true,
"enable actual asynchronous compilation for WebAssembly.compile") "enable actual asynchronous compilation for WebAssembly.compile")
DEFINE_BOOL(wasm_test_streaming, false, DEFINE_BOOL(wasm_test_streaming, false,
"use streaming compilation instead of async compilation for tests") "use streaming compilation instead of async compilation for tests")
// TODO(4153): Set this back to v8::internal::wasm::kV8MaxWasmMemoryPages DEFINE_UINT(wasm_max_mem_pages,
DEFINE_UINT(wasm_max_mem_pages, 32767, v8::internal::wasm::kSpecMaxWasmInitialMemoryPages,
"maximum number of 64KiB memory pages of a wasm instance") "maximum initial number of 64KiB memory pages of a wasm instance")
DEFINE_UINT(wasm_max_mem_pages_growth,
v8::internal::wasm::kSpecMaxWasmMaximumMemoryPages,
"maximum number of 64KiB pages a Wasm memory can grow to")
DEFINE_UINT(wasm_max_table_size, v8::internal::wasm::kV8MaxWasmTableSize, DEFINE_UINT(wasm_max_table_size, v8::internal::wasm::kV8MaxWasmTableSize,
"maximum table size of a wasm instance") "maximum table size of a wasm instance")
DEFINE_UINT(wasm_max_code_space, v8::internal::kMaxWasmCodeMB, DEFINE_UINT(wasm_max_code_space, v8::internal::kMaxWasmCodeMB,
......
...@@ -313,7 +313,7 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateWasmMemory( ...@@ -313,7 +313,7 @@ std::unique_ptr<BackingStore> BackingStore::TryAllocateWasmMemory(
// Compute size of reserved memory. // Compute size of reserved memory.
size_t engine_max_pages = wasm::max_mem_pages(); size_t engine_max_pages = wasm::max_initial_mem_pages();
size_t byte_capacity = size_t byte_capacity =
std::min(engine_max_pages, maximum_pages) * wasm::kWasmPageSize; std::min(engine_max_pages, maximum_pages) * wasm::kWasmPageSize;
size_t reservation_size = GetReservationSize(guards, byte_capacity); size_t reservation_size = GetReservationSize(guards, byte_capacity);
...@@ -408,7 +408,7 @@ std::unique_ptr<BackingStore> BackingStore::AllocateWasmMemory( ...@@ -408,7 +408,7 @@ std::unique_ptr<BackingStore> BackingStore::AllocateWasmMemory(
DCHECK_EQ(0, wasm::kWasmPageSize % AllocatePageSize()); DCHECK_EQ(0, wasm::kWasmPageSize % AllocatePageSize());
// Enforce engine limitation on the maximum number of pages. // Enforce engine limitation on the maximum number of pages.
if (initial_pages > wasm::max_mem_pages()) return nullptr; if (initial_pages > wasm::max_initial_mem_pages()) return nullptr;
auto backing_store = auto backing_store =
TryAllocateWasmMemory(isolate, initial_pages, maximum_pages, shared); TryAllocateWasmMemory(isolate, initial_pages, maximum_pages, shared);
......
...@@ -1879,11 +1879,13 @@ auto Memory::make(Store* store_abs, const MemoryType* type) -> own<Memory> { ...@@ -1879,11 +1879,13 @@ auto Memory::make(Store* store_abs, const MemoryType* type) -> own<Memory> {
const Limits& limits = type->limits(); const Limits& limits = type->limits();
uint32_t minimum = limits.min; uint32_t minimum = limits.min;
if (minimum > i::wasm::max_mem_pages()) return nullptr; // The max_initial_mem_pages limit is only spec'ed for JS embeddings,
// so we'll directly use the maximum pages limit here.
if (minimum > i::wasm::kSpecMaxWasmMaximumMemoryPages) return nullptr;
uint32_t maximum = limits.max; uint32_t maximum = limits.max;
if (maximum != Limits(0).max) { if (maximum != Limits(0).max) {
if (maximum < minimum) return nullptr; if (maximum < minimum) return nullptr;
if (maximum > i::wasm::kSpecMaxWasmMemoryPages) return nullptr; if (maximum > i::wasm::kSpecMaxWasmMaximumMemoryPages) return nullptr;
} }
// TODO(wasm+): Support shared memory. // TODO(wasm+): Support shared memory.
i::SharedFlag shared = i::SharedFlag::kNotShared; i::SharedFlag shared = i::SharedFlag::kNotShared;
......
...@@ -76,7 +76,7 @@ struct CompilationEnv { ...@@ -76,7 +76,7 @@ struct CompilationEnv {
: 0), : 0),
max_memory_size((module && module->has_maximum_pages max_memory_size((module && module->has_maximum_pages
? module->maximum_pages ? module->maximum_pages
: max_mem_pages()) * : max_initial_mem_pages()) *
uint64_t{kWasmPageSize}), uint64_t{kWasmPageSize}),
enabled_features(enabled_features), enabled_features(enabled_features),
lower_simd(lower_simd), lower_simd(lower_simd),
......
...@@ -584,9 +584,9 @@ class ModuleDecoderImpl : public Decoder { ...@@ -584,9 +584,9 @@ class ModuleDecoderImpl : public Decoder {
if (!AddMemory(module_.get())) break; if (!AddMemory(module_.get())) break;
uint8_t flags = validate_memory_flags(&module_->has_shared_memory); uint8_t flags = validate_memory_flags(&module_->has_shared_memory);
consume_resizable_limits( consume_resizable_limits(
"memory", "pages", kSpecMaxWasmMemoryPages, "memory", "pages", max_initial_mem_pages(),
&module_->initial_pages, &module_->has_maximum_pages, &module_->initial_pages, &module_->has_maximum_pages,
kSpecMaxWasmMemoryPages, &module_->maximum_pages, flags); max_maximum_mem_pages(), &module_->maximum_pages, flags);
break; break;
} }
case kExternalGlobal: { case kExternalGlobal: {
...@@ -676,8 +676,8 @@ class ModuleDecoderImpl : public Decoder { ...@@ -676,8 +676,8 @@ class ModuleDecoderImpl : public Decoder {
if (!AddMemory(module_.get())) break; if (!AddMemory(module_.get())) break;
uint8_t flags = validate_memory_flags(&module_->has_shared_memory); uint8_t flags = validate_memory_flags(&module_->has_shared_memory);
consume_resizable_limits( consume_resizable_limits(
"memory", "pages", kSpecMaxWasmMemoryPages, &module_->initial_pages, "memory", "pages", max_initial_mem_pages(), &module_->initial_pages,
&module_->has_maximum_pages, kSpecMaxWasmMemoryPages, &module_->has_maximum_pages, max_maximum_mem_pages(),
&module_->maximum_pages, flags); &module_->maximum_pages, flags);
} }
} }
......
...@@ -1402,10 +1402,11 @@ void InstanceBuilder::InitGlobals(Handle<WasmInstanceObject> instance) { ...@@ -1402,10 +1402,11 @@ void InstanceBuilder::InitGlobals(Handle<WasmInstanceObject> instance) {
// Allocate memory for a module instance as a new JSArrayBuffer. // Allocate memory for a module instance as a new JSArrayBuffer.
bool InstanceBuilder::AllocateMemory() { bool InstanceBuilder::AllocateMemory() {
auto initial_pages = module_->initial_pages; uint32_t initial_pages = module_->initial_pages;
auto maximum_pages = module_->has_maximum_pages ? module_->maximum_pages uint32_t maximum_pages = module_->has_maximum_pages
: wasm::max_mem_pages(); ? module_->maximum_pages
if (initial_pages > max_mem_pages()) { : wasm::max_initial_mem_pages();
if (initial_pages > max_initial_mem_pages()) {
thrower_->RangeError("Out of memory: wasm memory too large"); thrower_->RangeError("Out of memory: wasm memory too large");
return false; return false;
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "src/base/functional.h" #include "src/base/functional.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/common/globals.h"
#include "src/diagnostics/code-tracer.h" #include "src/diagnostics/code-tracer.h"
#include "src/diagnostics/compilation-statistics.h" #include "src/diagnostics/compilation-statistics.h"
#include "src/execution/frames.h" #include "src/execution/frames.h"
...@@ -21,6 +22,7 @@ ...@@ -21,6 +22,7 @@
#include "src/wasm/module-decoder.h" #include "src/wasm/module-decoder.h"
#include "src/wasm/module-instantiate.h" #include "src/wasm/module-instantiate.h"
#include "src/wasm/streaming-decoder.h" #include "src/wasm/streaming-decoder.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-objects-inl.h"
#ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING #ifdef V8_ENABLE_WASM_GDB_REMOTE_DEBUGGING
...@@ -1168,12 +1170,18 @@ std::shared_ptr<WasmEngine> WasmEngine::GetWasmEngine() { ...@@ -1168,12 +1170,18 @@ std::shared_ptr<WasmEngine> WasmEngine::GetWasmEngine() {
return *GetSharedWasmEngine(); return *GetSharedWasmEngine();
} }
// {max_mem_pages} is declared in wasm-limits.h. // {max_initial_mem_pages} is declared in wasm-limits.h.
uint32_t max_mem_pages() { uint32_t max_initial_mem_pages() {
STATIC_ASSERT(kV8MaxWasmMemoryPages <= kMaxUInt32); STATIC_ASSERT(kV8MaxWasmMemoryPages <= kMaxUInt32);
return std::min(uint32_t{kV8MaxWasmMemoryPages}, FLAG_wasm_max_mem_pages); return std::min(uint32_t{kV8MaxWasmMemoryPages}, FLAG_wasm_max_mem_pages);
} }
uint32_t max_maximum_mem_pages() {
STATIC_ASSERT(kV8MaxWasmMemoryPages <= kMaxUInt32);
return std::min(uint32_t{kV8MaxWasmMemoryPages},
FLAG_wasm_max_mem_pages_growth);
}
// {max_table_init_entries} is declared in wasm-limits.h. // {max_table_init_entries} is declared in wasm-limits.h.
uint32_t max_table_init_entries() { uint32_t max_table_init_entries() {
return std::min(uint32_t{kV8MaxWasmTableInitEntries}, return std::min(uint32_t{kV8MaxWasmTableInitEntries},
......
...@@ -1148,14 +1148,15 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -1148,14 +1148,15 @@ void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) {
int64_t initial = 0; int64_t initial = 0;
if (!GetInitialOrMinimumProperty(isolate, &thrower, context, descriptor, if (!GetInitialOrMinimumProperty(isolate, &thrower, context, descriptor,
&initial, 0, i::wasm::max_mem_pages())) { &initial, 0,
i::wasm::max_initial_mem_pages())) {
return; return;
} }
// The descriptor's 'maximum'. // The descriptor's 'maximum'.
int64_t maximum = -1; int64_t maximum = -1;
if (!GetOptionalIntegerProperty(isolate, &thrower, context, descriptor, if (!GetOptionalIntegerProperty(isolate, &thrower, context, descriptor,
v8_str(isolate, "maximum"), nullptr, &maximum, v8_str(isolate, "maximum"), nullptr, &maximum,
initial, i::wasm::kSpecMaxWasmMemoryPages)) { initial, i::wasm::max_maximum_mem_pages())) {
return; return;
} }
...@@ -1697,8 +1698,8 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -1697,8 +1698,8 @@ void WebAssemblyMemoryGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
} }
uint64_t max_size64 = receiver->maximum_pages(); uint64_t max_size64 = receiver->maximum_pages();
if (max_size64 > uint64_t{i::wasm::max_mem_pages()}) { if (max_size64 > uint64_t{i::wasm::max_initial_mem_pages()}) {
max_size64 = i::wasm::max_mem_pages(); max_size64 = i::wasm::max_initial_mem_pages();
} }
i::Handle<i::JSArrayBuffer> old_buffer(receiver->array_buffer(), i_isolate); i::Handle<i::JSArrayBuffer> old_buffer(receiver->array_buffer(), i_isolate);
......
...@@ -9,13 +9,17 @@ ...@@ -9,13 +9,17 @@
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include "src/base/macros.h"
#include "src/wasm/wasm-constants.h" #include "src/wasm/wasm-constants.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace wasm { namespace wasm {
constexpr size_t kSpecMaxWasmMemoryPages = 65536; // These two constants are defined in the Wasm JS API spec and as such only
// concern JS embeddings.
constexpr size_t kSpecMaxWasmInitialMemoryPages = 32767;
constexpr size_t kSpecMaxWasmMaximumMemoryPages = 65536;
// The following limits are imposed by V8 on WebAssembly modules. // The following limits are imposed by V8 on WebAssembly modules.
// The limits are agreed upon with other engines for consistency. // The limits are agreed upon with other engines for consistency.
...@@ -27,7 +31,9 @@ constexpr size_t kV8MaxWasmGlobals = 1000000; ...@@ -27,7 +31,9 @@ constexpr size_t kV8MaxWasmGlobals = 1000000;
constexpr size_t kV8MaxWasmExceptions = 1000000; constexpr size_t kV8MaxWasmExceptions = 1000000;
constexpr size_t kV8MaxWasmExceptionTypes = 1000000; constexpr size_t kV8MaxWasmExceptionTypes = 1000000;
constexpr size_t kV8MaxWasmDataSegments = 100000; constexpr size_t kV8MaxWasmDataSegments = 100000;
// Don't use this limit directly, but use the value of {max_mem_pages()}. // This indicates the maximum memory size our implementation supports.
// Don't use this limit directly; use {max_initial_mem_pages()} instead
// to take the spec'ed limit as well as command line flag into account.
constexpr size_t kV8MaxWasmMemoryPages = 65536; // = 4 GiB constexpr size_t kV8MaxWasmMemoryPages = 65536; // = 4 GiB
constexpr size_t kV8MaxWasmStringSize = 100000; constexpr size_t kV8MaxWasmStringSize = 100000;
constexpr size_t kV8MaxWasmModuleSize = 1024 * 1024 * 1024; // = 1 GiB constexpr size_t kV8MaxWasmModuleSize = 1024 * 1024 * 1024; // = 1 GiB
...@@ -43,8 +49,6 @@ constexpr size_t kV8MaxWasmTableInitEntries = 10000000; ...@@ -43,8 +49,6 @@ constexpr size_t kV8MaxWasmTableInitEntries = 10000000;
constexpr size_t kV8MaxWasmTables = 1; constexpr size_t kV8MaxWasmTables = 1;
constexpr size_t kV8MaxWasmMemories = 1; constexpr size_t kV8MaxWasmMemories = 1;
static_assert(kV8MaxWasmMemoryPages <= kSpecMaxWasmMemoryPages,
"v8 should not be more permissive than the spec");
static_assert(kV8MaxWasmTableSize <= 4294967295, // 2^32 - 1 static_assert(kV8MaxWasmTableSize <= 4294967295, // 2^32 - 1
"v8 should not exceed WebAssembly's non-web embedding limits"); "v8 should not exceed WebAssembly's non-web embedding limits");
static_assert(kV8MaxWasmTableInitEntries <= kV8MaxWasmTableSize, static_assert(kV8MaxWasmTableInitEntries <= kV8MaxWasmTableSize,
...@@ -58,11 +62,12 @@ constexpr uint64_t kWasmMaxHeapOffset = ...@@ -58,11 +62,12 @@ constexpr uint64_t kWasmMaxHeapOffset =
// Defined in wasm-engine.cc. // Defined in wasm-engine.cc.
// TODO(wasm): Make this size_t for wasm64. Currently the --wasm-max-mem-pages // TODO(wasm): Make this size_t for wasm64. Currently the --wasm-max-mem-pages
// flag is only uint32_t. // flag is only uint32_t.
V8_EXPORT_PRIVATE uint32_t max_mem_pages(); V8_EXPORT_PRIVATE uint32_t max_initial_mem_pages();
V8_EXPORT_PRIVATE uint32_t max_maximum_mem_pages();
uint32_t max_table_init_entries(); uint32_t max_table_init_entries();
inline uint64_t max_mem_bytes() { inline uint64_t max_mem_bytes() {
return uint64_t{max_mem_pages()} * kWasmPageSize; return uint64_t{max_initial_mem_pages()} * kWasmPageSize;
} }
} // namespace wasm } // namespace wasm
......
...@@ -879,18 +879,18 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate, ...@@ -879,18 +879,18 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
if (old_buffer->is_asmjs_memory()) return -1; if (old_buffer->is_asmjs_memory()) return -1;
// Checks for maximum memory size. // Checks for maximum memory size.
uint32_t maximum_pages = wasm::max_mem_pages(); uint32_t maximum_pages = wasm::max_initial_mem_pages();
if (memory_object->has_maximum_pages()) { if (memory_object->has_maximum_pages()) {
maximum_pages = std::min( maximum_pages = std::min(
maximum_pages, static_cast<uint32_t>(memory_object->maximum_pages())); maximum_pages, static_cast<uint32_t>(memory_object->maximum_pages()));
} }
CHECK_GE(wasm::max_mem_pages(), maximum_pages); CHECK_GE(wasm::max_initial_mem_pages(), maximum_pages);
size_t old_size = old_buffer->byte_length(); size_t old_size = old_buffer->byte_length();
CHECK_EQ(0, old_size % wasm::kWasmPageSize); CHECK_EQ(0, old_size % wasm::kWasmPageSize);
size_t old_pages = old_size / wasm::kWasmPageSize; size_t old_pages = old_size / wasm::kWasmPageSize;
CHECK_GE(wasm::max_mem_pages(), old_pages); CHECK_GE(wasm::max_initial_mem_pages(), old_pages);
if ((pages > maximum_pages - old_pages) || // exceeds remaining if ((pages > maximum_pages - old_pages) || // exceeds remaining
(pages > wasm::max_mem_pages() - old_pages)) { // exceeds limit (pages > wasm::max_initial_mem_pages() - old_pages)) { // exceeds limit
return -1; return -1;
} }
std::shared_ptr<BackingStore> backing_store = old_buffer->GetBackingStore(); std::shared_ptr<BackingStore> backing_store = old_buffer->GetBackingStore();
......
...@@ -32,6 +32,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { ...@@ -32,6 +32,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// We reduce the maximum memory size and table size of WebAssembly instances // We reduce the maximum memory size and table size of WebAssembly instances
// to avoid OOMs in the fuzzer. // to avoid OOMs in the fuzzer.
i::FlagScope<uint32_t> max_mem_flag_scope(&i::FLAG_wasm_max_mem_pages, 32); i::FlagScope<uint32_t> max_mem_flag_scope(&i::FLAG_wasm_max_mem_pages, 32);
i::FlagScope<uint32_t> max_mem_growth_flag_scope(
&i::FLAG_wasm_max_mem_pages_growth, 32);
i::FlagScope<uint32_t> max_table_size_scope(&i::FLAG_wasm_max_table_size, i::FlagScope<uint32_t> max_table_size_scope(&i::FLAG_wasm_max_table_size,
100); 100);
v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get(); v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get();
......
...@@ -10,4 +10,4 @@ let builder = new WasmModuleBuilder(); ...@@ -10,4 +10,4 @@ let builder = new WasmModuleBuilder();
const num_pages = 49152; const num_pages = 49152;
builder.addMemory(num_pages, num_pages); builder.addMemory(num_pages, num_pages);
// num_pages * 64k (page size) > kMaxInt. // num_pages * 64k (page size) > kMaxInt.
assertThrows(() => builder.instantiate(), RangeError); assertThrows(() => builder.instantiate(), WebAssembly.CompileError);
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
[ [
[ALWAYS, { [ALWAYS, {
# https://bugs.chromium.org/p/v8/issues/detail?id=8633 # These are slow, and not useful to run for the proposals:
'limits': [SKIP],
'proposals/reference-types/limits': [SKIP], 'proposals/reference-types/limits': [SKIP],
'proposals/multi-value/limits': [SKIP], 'proposals/multi-value/limits': [SKIP],
'proposals/bulk-memory-operations/limits': [SKIP], 'proposals/bulk-memory-operations/limits': [SKIP],
...@@ -22,6 +21,11 @@ ...@@ -22,6 +21,11 @@
'constructor/instantiate': [SKIP], 'constructor/instantiate': [SKIP],
}], # 'arch == s390 or arch == s390x or system == aix' }], # 'arch == s390 or arch == s390x or system == aix'
['mode == debug or simulator_run or variant != default', {
# Slow, and we always have the same limits anyway.
'limits': [SKIP],
}], # mode == debug or simulator_run or variant != default
############################################################################## ##############################################################################
['lite_mode or variant == jitless', { ['lite_mode or variant == jitless', {
# TODO(v8:7777): Re-enable once wasm is supported in jitless mode. # TODO(v8:7777): Re-enable once wasm is supported in jitless mode.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment