[wasm] Do not store ModuleEnv

Instead, create it when needed and pass it down to the actual
compilation.
This saves memory by making the WasmCompilationUnit smaller and will
eventually allow us to implement the trap handler fallback correctly by
using an updated ModuleEnv in background compilation and tier up.

R=mstarzinger@chromium.org

Bug: v8:5277, v8:8343
Change-Id: I0dc3a37fb88e54eb4822dc99d58ff024f4b2a367
Reviewed-on: https://chromium-review.googlesource.com/c/1293953
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56896}
This commit is contained in:
Clemens Hammacher 2018-10-23 13:43:07 +02:00 committed by Commit Bot
parent 6d28125e1c
commit 9716f689b8
20 changed files with 122 additions and 160 deletions

View File

@ -5144,8 +5144,8 @@ TurbofanWasmCompilationUnit::TurbofanWasmCompilationUnit(
TurbofanWasmCompilationUnit::~TurbofanWasmCompilationUnit() = default;
SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction(
wasm::WasmFeatures* detected, double* decode_ms, MachineGraph* mcgraph,
NodeOriginTable* node_origins) {
wasm::ModuleEnv* env, wasm::WasmFeatures* detected, double* decode_ms,
MachineGraph* mcgraph, NodeOriginTable* node_origins) {
base::ElapsedTimer decode_timer;
if (FLAG_trace_wasm_decode_time) {
decode_timer.Start();
@ -5154,12 +5154,12 @@ SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction(
// Create a TF graph during decoding.
SourcePositionTable* source_position_table =
new (mcgraph->zone()) SourcePositionTable(mcgraph->graph());
WasmGraphBuilder builder(wasm_unit_->env_, mcgraph->zone(), mcgraph,
WasmGraphBuilder builder(env, mcgraph->zone(), mcgraph,
wasm_unit_->func_body_.sig, source_position_table);
wasm::VoidResult graph_construction_result = wasm::BuildTFGraph(
wasm_unit_->wasm_engine_->allocator(),
wasm_unit_->native_module_->enabled_features(), wasm_unit_->env_->module,
&builder, detected, wasm_unit_->func_body_, node_origins);
wasm_unit_->native_module_->enabled_features(), env->module, &builder,
detected, wasm_unit_->func_body_, node_origins);
if (graph_construction_result.failed()) {
if (FLAG_trace_wasm_compiler) {
StdoutStream{} << "Compilation failed: "
@ -5172,7 +5172,7 @@ SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction(
builder.LowerInt64();
if (builder.has_simd() &&
(!CpuFeatures::SupportsWasmSimd128() || wasm_unit_->env_->lower_simd)) {
(!CpuFeatures::SupportsWasmSimd128() || env->lower_simd)) {
SimdScalarLowering(
mcgraph,
CreateMachineSignature(mcgraph->zone(), wasm_unit_->func_body_.sig))
@ -5182,8 +5182,7 @@ SourcePositionTable* TurbofanWasmCompilationUnit::BuildGraphForWasmFunction(
if (wasm_unit_->func_index_ >= FLAG_trace_wasm_ast_start &&
wasm_unit_->func_index_ < FLAG_trace_wasm_ast_end) {
PrintRawWasmCode(wasm_unit_->wasm_engine_->allocator(),
wasm_unit_->func_body_, wasm_unit_->env_->module,
wasm::kPrintLocals);
wasm_unit_->func_body_, env->module, wasm::kPrintLocals);
}
if (FLAG_trace_wasm_decode_time) {
*decode_ms = decode_timer.Elapsed().InMillisecondsF();
@ -5207,7 +5206,7 @@ Vector<const char> GetDebugName(Zone* zone, int index) {
} // namespace
void TurbofanWasmCompilationUnit::ExecuteCompilation(
wasm::WasmFeatures* detected) {
wasm::ModuleEnv* env, wasm::WasmFeatures* detected) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"),
"ExecuteTurbofanCompilation");
double decode_ms = 0;
@ -5223,7 +5222,7 @@ void TurbofanWasmCompilationUnit::ExecuteCompilation(
OptimizedCompilationInfo info(GetDebugName(&zone, wasm_unit_->func_index_),
&zone, Code::WASM_FUNCTION);
if (wasm_unit_->env_->runtime_exception_support) {
if (env->runtime_exception_support) {
info.SetWasmRuntimeExceptionSupport();
}
@ -5236,8 +5235,8 @@ void TurbofanWasmCompilationUnit::ExecuteCompilation(
? new (&zone)
NodeOriginTable(mcgraph->graph())
: nullptr;
SourcePositionTable* source_positions =
BuildGraphForWasmFunction(detected, &decode_ms, mcgraph, node_origins);
SourcePositionTable* source_positions = BuildGraphForWasmFunction(
env, detected, &decode_ms, mcgraph, node_origins);
if (wasm_unit_->failed()) return;
@ -5261,9 +5260,8 @@ void TurbofanWasmCompilationUnit::ExecuteCompilation(
std::unique_ptr<OptimizedCompilationJob> job(Pipeline::NewWasmCompilationJob(
&info, wasm_unit_->wasm_engine_, mcgraph, call_descriptor,
source_positions, node_origins, wasm_unit_->func_body_,
const_cast<wasm::WasmModule*>(wasm_unit_->env_->module),
wasm_unit_->native_module_, wasm_unit_->func_index_,
wasm_unit_->env_->module->origin));
const_cast<wasm::WasmModule*>(env->module), wasm_unit_->native_module_,
wasm_unit_->func_index_, env->module->origin));
if (job->ExecuteJob() == CompilationJob::SUCCEEDED) {
wasm_unit_->SetResult(info.wasm_code());
}

View File

@ -50,12 +50,13 @@ class TurbofanWasmCompilationUnit {
explicit TurbofanWasmCompilationUnit(wasm::WasmCompilationUnit* wasm_unit);
~TurbofanWasmCompilationUnit();
SourcePositionTable* BuildGraphForWasmFunction(wasm::WasmFeatures* detected,
SourcePositionTable* BuildGraphForWasmFunction(wasm::ModuleEnv* env,
wasm::WasmFeatures* detected,
double* decode_ms,
MachineGraph* mcgraph,
NodeOriginTable* node_origins);
void ExecuteCompilation(wasm::WasmFeatures* detected);
void ExecuteCompilation(wasm::ModuleEnv* env, wasm::WasmFeatures* detected);
private:
wasm::WasmCompilationUnit* const wasm_unit_;

View File

@ -1872,7 +1872,8 @@ class LiftoffCompiler {
} // namespace
bool LiftoffCompilationUnit::ExecuteCompilation(WasmFeatures* detected) {
bool LiftoffCompilationUnit::ExecuteCompilation(ModuleEnv* env,
WasmFeatures* detected) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"),
"ExecuteLiftoffCompilation");
base::ElapsedTimer compile_timer;
@ -1881,15 +1882,14 @@ bool LiftoffCompilationUnit::ExecuteCompilation(WasmFeatures* detected) {
}
Zone zone(wasm_unit_->wasm_engine_->allocator(), "LiftoffCompilationZone");
const WasmModule* module =
wasm_unit_->env_ ? wasm_unit_->env_->module : nullptr;
const WasmModule* module = env ? env->module : nullptr;
auto call_descriptor =
compiler::GetWasmCallDescriptor(&zone, wasm_unit_->func_body_.sig);
base::Optional<TimedHistogramScope> liftoff_compile_time_scope(
base::in_place, wasm_unit_->counters_->liftoff_compile_time());
WasmFullDecoder<Decoder::kValidate, LiftoffCompiler> decoder(
&zone, module, wasm_unit_->native_module_->enabled_features(), detected,
wasm_unit_->func_body_, call_descriptor, wasm_unit_->env_, &zone);
wasm_unit_->func_body_, call_descriptor, env, &zone);
decoder.Decode();
liftoff_compile_time_scope.reset();
LiftoffCompiler* compiler = &decoder.interface();

View File

@ -11,17 +11,16 @@ namespace v8 {
namespace internal {
namespace wasm {
struct WasmFeatures;
class ErrorThrower;
class WasmCode;
struct ModuleEnv;
class WasmCompilationUnit;
struct WasmFeatures;
class LiftoffCompilationUnit final {
public:
explicit LiftoffCompilationUnit(WasmCompilationUnit* wasm_unit)
: wasm_unit_(wasm_unit) {}
bool ExecuteCompilation(WasmFeatures* detected);
bool ExecuteCompilation(ModuleEnv*, WasmFeatures* detected);
private:
WasmCompilationUnit* const wasm_unit_;

View File

@ -80,9 +80,7 @@ struct CompilationStateDeleter {
// Wrapper to create a CompilationState exists in order to avoid having
// the CompilationState in the header file.
std::unique_ptr<CompilationState, CompilationStateDeleter> NewCompilationState(
Isolate*, const ModuleEnv&);
ModuleEnv* GetModuleEnv(CompilationState* compilation_state);
Isolate*, NativeModule*);
} // namespace wasm
} // namespace internal

View File

@ -36,23 +36,22 @@ ExecutionTier WasmCompilationUnit::GetDefaultExecutionTier() {
}
WasmCompilationUnit::WasmCompilationUnit(WasmEngine* wasm_engine,
ModuleEnv* env,
NativeModule* native_module,
FunctionBody body, int index,
Counters* counters, ExecutionTier mode)
: env_(env),
wasm_engine_(wasm_engine),
: wasm_engine_(wasm_engine),
func_body_(body),
counters_(counters),
func_index_(index),
native_module_(native_module),
mode_(mode) {
DCHECK_GE(index, env->module->num_imported_functions);
DCHECK_LT(index, env->module->functions.size());
const WasmModule* module = native_module->module();
DCHECK_GE(index, module->num_imported_functions);
DCHECK_LT(index, module->functions.size());
// Always disable Liftoff for asm.js, for two reasons:
// 1) asm-specific opcodes are not implemented, and
// 2) tier-up does not work with lazy compilation.
if (env->module->origin == kAsmJsOrigin) mode = ExecutionTier::kOptimized;
if (module->origin == kAsmJsOrigin) mode = ExecutionTier::kOptimized;
if (V8_UNLIKELY(FLAG_wasm_tier_mask_for_testing) && index < 32 &&
(FLAG_wasm_tier_mask_for_testing & (1 << index))) {
mode = ExecutionTier::kOptimized;
@ -64,12 +63,14 @@ WasmCompilationUnit::WasmCompilationUnit(WasmEngine* wasm_engine,
// {TurbofanWasmCompilationUnit} can be opaque in the header file.
WasmCompilationUnit::~WasmCompilationUnit() = default;
void WasmCompilationUnit::ExecuteCompilation(WasmFeatures* detected) {
auto size_histogram = SELECT_WASM_COUNTER(counters_, env_->module->origin,
wasm, function_size_bytes);
void WasmCompilationUnit::ExecuteCompilation(ModuleEnv* env,
WasmFeatures* detected) {
const WasmModule* module = native_module_->module();
auto size_histogram =
SELECT_WASM_COUNTER(counters_, module->origin, wasm, function_size_bytes);
size_histogram->AddSample(
static_cast<int>(func_body_.end - func_body_.start));
auto timed_histogram = SELECT_WASM_COUNTER(counters_, env_->module->origin,
auto timed_histogram = SELECT_WASM_COUNTER(counters_, module->origin,
wasm_compile, function_time);
TimedHistogramScope wasm_compile_function_time_scope(timed_histogram);
@ -80,12 +81,12 @@ void WasmCompilationUnit::ExecuteCompilation(WasmFeatures* detected) {
switch (mode_) {
case ExecutionTier::kBaseline:
if (liftoff_unit_->ExecuteCompilation(detected)) break;
if (liftoff_unit_->ExecuteCompilation(env, detected)) break;
// Otherwise, fall back to turbofan.
SwitchMode(ExecutionTier::kOptimized);
V8_FALLTHROUGH;
case ExecutionTier::kOptimized:
turbofan_unit_->ExecuteCompilation(detected);
turbofan_unit_->ExecuteCompilation(env, detected);
break;
case ExecutionTier::kInterpreter:
UNREACHABLE(); // TODO(titzer): compile interpreter entry stub.
@ -136,17 +137,16 @@ void WasmCompilationUnit::SwitchMode(ExecutionTier new_mode) {
// static
WasmCode* WasmCompilationUnit::CompileWasmFunction(
Isolate* isolate, NativeModule* native_module, WasmFeatures* detected,
ErrorThrower* thrower, ModuleEnv* env, const WasmFunction* function,
ExecutionTier mode) {
ErrorThrower* thrower, const WasmFunction* function, ExecutionTier mode) {
ModuleWireBytes wire_bytes(native_module->wire_bytes());
FunctionBody function_body{function->sig, function->code.offset(),
wire_bytes.start() + function->code.offset(),
wire_bytes.start() + function->code.end_offset()};
WasmCompilationUnit unit(isolate->wasm_engine(), env, native_module,
function_body,
WasmCompilationUnit unit(isolate->wasm_engine(), native_module, function_body,
function->func_index, isolate->counters(), mode);
unit.ExecuteCompilation(detected);
ModuleEnv env = native_module->CreateModuleEnv();
unit.ExecuteCompilation(&env, detected);
if (unit.failed()) {
unit.ReportError(thrower);
return nullptr;

View File

@ -37,13 +37,12 @@ class WasmCompilationUnit final {
// typically means to hold a std::shared_ptr<Counters>).
// If used exclusively from a foreground thread, Isolate::counters() may be
// used by callers to pass Counters.
WasmCompilationUnit(WasmEngine* wasm_engine, ModuleEnv*, NativeModule*,
FunctionBody, int index, Counters*,
ExecutionTier = GetDefaultExecutionTier());
WasmCompilationUnit(WasmEngine*, NativeModule*, FunctionBody, int index,
Counters*, ExecutionTier = GetDefaultExecutionTier());
~WasmCompilationUnit();
void ExecuteCompilation(WasmFeatures* detected);
void ExecuteCompilation(ModuleEnv*, WasmFeatures* detected);
NativeModule* native_module() const { return native_module_; }
ExecutionTier mode() const { return mode_; }
@ -58,14 +57,13 @@ class WasmCompilationUnit final {
static WasmCode* CompileWasmFunction(
Isolate* isolate, NativeModule* native_module, WasmFeatures* detected,
ErrorThrower* thrower, ModuleEnv* env, const WasmFunction* function,
ErrorThrower* thrower, const WasmFunction* function,
ExecutionTier = GetDefaultExecutionTier());
private:
friend class LiftoffCompilationUnit;
friend class compiler::TurbofanWasmCompilationUnit;
ModuleEnv* env_;
WasmEngine* wasm_engine_;
FunctionBody func_body_;
Counters* counters_;

View File

@ -65,7 +65,7 @@ enum class CompileMode : uint8_t { kRegular, kTiering };
// compilation of functions.
class CompilationState {
public:
CompilationState(internal::Isolate*, const ModuleEnv&);
CompilationState(internal::Isolate*, NativeModule*);
~CompilationState();
// Set the number of compilations unit expected to be executed. Needs to be
@ -115,7 +115,6 @@ class CompilationState {
WasmEngine* wasm_engine() const { return wasm_engine_; }
CompileMode compile_mode() const { return compile_mode_; }
ModuleEnv* module_env() { return &module_env_; }
WasmFeatures* detected_features() { return &detected_features_; }
private:
@ -130,8 +129,7 @@ class CompilationState {
// can be shared across multiple Isolates.
Isolate* const isolate_;
WasmEngine* const wasm_engine_;
// TODO(clemensh): Remove ModuleEnv, generate it when needed.
ModuleEnv module_env_;
NativeModule* const native_module_;
const CompileMode compile_mode_;
bool baseline_compilation_finished_ = false;
@ -347,21 +345,20 @@ WasmCode* LazyCompileFunction(Isolate* isolate, NativeModule* native_module,
compilation_timer.Start();
ModuleEnv* module_env = native_module->compilation_state()->module_env();
TRACE_LAZY("Compiling wasm-function#%d.\n", func_index);
const uint8_t* module_start = native_module->wire_bytes().start();
const WasmFunction* func = &module_env->module->functions[func_index];
const WasmFunction* func = &native_module->module()->functions[func_index];
FunctionBody body{func->sig, func->code.offset(),
module_start + func->code.offset(),
module_start + func->code.end_offset()};
WasmCompilationUnit unit(isolate->wasm_engine(), module_env, native_module,
body, func_index, isolate->counters());
WasmCompilationUnit unit(isolate->wasm_engine(), native_module, body,
func_index, isolate->counters());
ModuleEnv env = native_module->CreateModuleEnv();
unit.ExecuteCompilation(
native_module->compilation_state()->detected_features());
&env, native_module->compilation_state()->detected_features());
// If there is a pending error, something really went wrong. The module was
// verified before starting execution with lazy compilation.
@ -449,8 +446,7 @@ class CompilationUnitBuilder {
Vector<const uint8_t> bytes,
ExecutionTier mode) {
return base::make_unique<WasmCompilationUnit>(
compilation_state_->wasm_engine(), compilation_state_->module_env(),
native_module_,
compilation_state_->wasm_engine(), native_module_,
FunctionBody{function->sig, buffer_offset, bytes.begin(), bytes.end()},
function->func_index,
compilation_state_->isolate()->async_counters().get(), mode);
@ -489,20 +485,12 @@ double MonotonicallyIncreasingTimeInMs() {
base::Time::kMillisecondsPerSecond;
}
ModuleEnv CreateDefaultModuleEnv(const WasmModule* module,
bool allow_trap_handler = true) {
UseTrapHandler use_trap_handler =
trap_handler::IsTrapHandlerEnabled() && allow_trap_handler
? kUseTrapHandler
: kNoTrapHandler;
return ModuleEnv(module, use_trap_handler, kRuntimeExceptionSupport);
}
// Run by each compilation task and by the main thread (i.e. in both
// foreground and background threads). The no_finisher_callback is called
// within the result_mutex_ lock when no finishing task is running, i.e. when
// the finisher_is_running_ flag is not set.
bool FetchAndExecuteCompilationUnit(CompilationState* compilation_state,
bool FetchAndExecuteCompilationUnit(ModuleEnv* env,
CompilationState* compilation_state,
WasmFeatures* detected) {
DisallowHeapAccess no_heap_access;
@ -516,7 +504,7 @@ bool FetchAndExecuteCompilationUnit(CompilationState* compilation_state,
// later as soon as Liftoff can compile any function. Then, we can directly
// access {unit->mode()} within {ScheduleUnitForFinishing()}.
ExecutionTier mode = unit->mode();
unit->ExecuteCompilation(detected);
unit->ExecuteCompilation(env, detected);
compilation_state->ScheduleUnitForFinishing(std::move(unit), mode);
return true;
@ -615,8 +603,9 @@ void CompileInParallel(Isolate* isolate, NativeModule* native_module,
// The foreground task bypasses waiting on memory threshold, because
// its results will immediately be converted to code (below).
WasmFeatures detected_features;
while (
FetchAndExecuteCompilationUnit(compilation_state, &detected_features) &&
ModuleEnv env = native_module->CreateModuleEnv();
while (FetchAndExecuteCompilationUnit(&env, compilation_state,
&detected_features) &&
!compilation_state->baseline_compilation_finished()) {
// 2.b) If {baseline_finish_units_} contains a compilation unit, the main
// thread dequeues it and finishes the compilation unit. Compilation
@ -652,11 +641,11 @@ void CompileInParallel(Isolate* isolate, NativeModule* native_module,
}
void CompileSequentially(Isolate* isolate, NativeModule* native_module,
ModuleEnv* module_env, ErrorThrower* thrower) {
ErrorThrower* thrower) {
DCHECK(!thrower->error());
ModuleWireBytes wire_bytes(native_module->wire_bytes());
const WasmModule* module = module_env->module;
const WasmModule* module = native_module->module();
WasmFeatures detected = kNoWasmFeatures;
for (uint32_t i = 0; i < module->functions.size(); ++i) {
const WasmFunction& func = module->functions[i];
@ -664,7 +653,7 @@ void CompileSequentially(Isolate* isolate, NativeModule* native_module,
// Compile the function.
WasmCode* code = WasmCompilationUnit::CompileWasmFunction(
isolate, native_module, &detected, thrower, module_env, &func);
isolate, native_module, &detected, thrower, &func);
if (code == nullptr) {
TruncatedUserString<> name(wire_bytes.GetNameOrNull(&func, module));
thrower->CompileError("Compilation of #%d:%.*s failed.", i, name.length(),
@ -713,7 +702,7 @@ void ValidateSequentially(Isolate* isolate, NativeModule* native_module,
void CompileNativeModule(Isolate* isolate, ErrorThrower* thrower,
Handle<WasmModuleObject> module_object,
const WasmModule* wasm_module, ModuleEnv* env) {
const WasmModule* wasm_module) {
NativeModule* const native_module = module_object->native_module();
ModuleWireBytes wire_bytes(native_module->wire_bytes());
@ -741,7 +730,7 @@ void CompileNativeModule(Isolate* isolate, ErrorThrower* thrower,
if (compile_parallel) {
CompileInParallel(isolate, native_module, module_object, thrower);
} else {
CompileSequentially(isolate, native_module, env, thrower);
CompileSequentially(isolate, native_module, thrower);
}
if (thrower->error()) return;
}
@ -829,25 +818,27 @@ class FinishCompileTask : public CancelableTask {
// The runnable task that performs compilations in the background.
class BackgroundCompileTask : public CancelableTask {
public:
explicit BackgroundCompileTask(CompilationState* compilation_state,
explicit BackgroundCompileTask(NativeModule* native_module,
CancelableTaskManager* task_manager)
: CancelableTask(task_manager), compilation_state_(compilation_state) {}
: CancelableTask(task_manager), native_module_(native_module) {}
void RunInternal() override {
TRACE_COMPILE("(3b) Compiling...\n");
// The number of currently running background tasks is reduced in
// {OnBackgroundTaskStopped}.
while (!compilation_state_->failed()) {
if (!FetchAndExecuteCompilationUnit(compilation_state_,
ModuleEnv env = native_module_->CreateModuleEnv();
auto* compilation_state = native_module_->compilation_state();
while (!compilation_state->failed()) {
if (!FetchAndExecuteCompilationUnit(&env, compilation_state,
&detected_features_)) {
break;
}
}
compilation_state_->OnBackgroundTaskStopped(detected_features_);
compilation_state->OnBackgroundTaskStopped(detected_features_);
}
private:
CompilationState* compilation_state_;
NativeModule* const native_module_;
WasmFeatures detected_features_ = kNoWasmFeatures;
};
} // namespace
@ -893,16 +884,15 @@ MaybeHandle<WasmModuleObject> CompileToModuleObject(
// TODO(clemensh): For the same module (same bytes / same hash), we should
// only have one WasmModuleObject. Otherwise, we might only set
// breakpoints on a (potentially empty) subset of the instances.
ModuleEnv env = CreateDefaultModuleEnv(wasm_module);
// Create the compiled module object and populate with compiled functions
// and information needed at instantiation time. This object needs to be
// serializable. Instantiation may occur off a deserialized version of this
// object.
Handle<WasmModuleObject> module_object = WasmModuleObject::New(
isolate, enabled, std::move(module), env, std::move(wire_bytes_copy),
script, asm_js_offset_table);
CompileNativeModule(isolate, thrower, module_object, wasm_module, &env);
isolate, enabled, std::move(module), std::move(wire_bytes_copy), script,
asm_js_offset_table);
CompileNativeModule(isolate, thrower, module_object, wasm_module);
if (thrower->error()) return {};
// Compile JS->wasm wrappers for exported functions.
@ -1013,14 +1003,15 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
TRACE("Recompiling module without bounds checks\n");
constexpr bool allow_trap_handler = false;
ModuleEnv env = CreateDefaultModuleEnv(module_, allow_trap_handler);
// TODO(wasm): Fix this before enabling the trap handler fallback.
USE(allow_trap_handler);
// Disable trap handlers on this native module.
NativeModule* native_module = module_object_->native_module();
native_module->DisableTrapHandler();
// Recompile all functions in this native module.
ErrorThrower thrower(isolate_, "recompile");
CompileNativeModule(isolate_, &thrower, module_object_, module_, &env);
CompileNativeModule(isolate_, &thrower, module_object_, module_);
if (thrower.error()) {
return {};
}
@ -2483,7 +2474,6 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
module->source_map_url);
Handle<ByteArray> asm_js_offset_table;
ModuleEnv env = CreateDefaultModuleEnv(module);
// TODO(wasm): Improve efficiency of storing module wire bytes. Only store
// relevant sections, not function bodies
@ -2494,7 +2484,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
// breakpoints on a (potentially empty) subset of the instances.
// Create the module object.
job_->module_object_ = WasmModuleObject::New(
job_->isolate_, job_->enabled_features_, module_, env,
job_->isolate_, job_->enabled_features_, module_,
{std::move(job_->bytes_copy_), job_->wire_bytes_.length()}, script,
asm_js_offset_table);
job_->native_module_ = job_->module_object_->native_module();
@ -2850,21 +2840,18 @@ void CompilationStateDeleter::operator()(
}
std::unique_ptr<CompilationState, CompilationStateDeleter> NewCompilationState(
Isolate* isolate, const ModuleEnv& env) {
Isolate* isolate, NativeModule* native_module) {
return std::unique_ptr<CompilationState, CompilationStateDeleter>(
new CompilationState(isolate, env));
}
ModuleEnv* GetModuleEnv(CompilationState* compilation_state) {
return compilation_state->module_env();
new CompilationState(isolate, native_module));
}
CompilationState::CompilationState(internal::Isolate* isolate,
const ModuleEnv& env)
NativeModule* native_module)
: isolate_(isolate),
wasm_engine_(isolate->wasm_engine()),
module_env_(env),
compile_mode_(FLAG_wasm_tier_up && env.module->origin == kWasmOrigin
native_module_(native_module),
compile_mode_(FLAG_wasm_tier_up &&
native_module->module()->origin == kWasmOrigin
? CompileMode::kTiering
: CompileMode::kRegular),
max_background_tasks_(std::max(
@ -3042,7 +3029,7 @@ void CompilationState::RestartBackgroundTasks(size_t max) {
for (; num_restart > 0; --num_restart) {
auto task = base::make_unique<BackgroundCompileTask>(
this, &background_task_manager_);
native_module_, &background_task_manager_);
// If --wasm-num-compilation-tasks=0 is passed, do only spawn foreground
// tasks. This is used to make timing deterministic.

View File

@ -150,9 +150,8 @@ void WasmCode::LogCode(Isolate* isolate) const {
ModuleWireBytes wire_bytes(native_module()->wire_bytes());
// TODO(herhut): Allow to log code without on-heap round-trip of the name.
ModuleEnv* module_env = GetModuleEnv(native_module()->compilation_state());
WireBytesRef name_ref =
module_env->module->LookupFunctionName(wire_bytes, index());
native_module()->module()->LookupFunctionName(wire_bytes, index());
WasmName name_vec = wire_bytes.GetNameOrNull(name_ref);
if (!name_vec.is_empty()) {
MaybeHandle<String> maybe_name = isolate->factory()->NewStringFromUtf8(
@ -339,18 +338,17 @@ WasmCode::~WasmCode() {
NativeModule::NativeModule(Isolate* isolate, const WasmFeatures& enabled,
bool can_request_more, VirtualMemory code_space,
WasmCodeManager* code_manager,
std::shared_ptr<const WasmModule> module,
const ModuleEnv& env)
std::shared_ptr<const WasmModule> module)
: enabled_features_(enabled),
module_(std::move(module)),
compilation_state_(NewCompilationState(isolate, env)),
compilation_state_(NewCompilationState(isolate, this)),
import_wrapper_cache_(std::unique_ptr<WasmImportWrapperCache>(
new WasmImportWrapperCache(this))),
free_code_space_(code_space.region()),
wasm_code_manager_(code_manager),
can_request_more_memory_(can_request_more),
use_trap_handler_(env.use_trap_handler) {
DCHECK_EQ(module_.get(), env.module);
use_trap_handler_(trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler
: kNoTrapHandler) {
DCHECK_NOT_NULL(module_);
owned_code_space_.emplace_back(std::move(code_space));
owned_code_.reserve(num_functions());
@ -386,6 +384,10 @@ void NativeModule::LogWasmCodes(Isolate* isolate) {
}
}
ModuleEnv NativeModule::CreateModuleEnv() const {
return {module(), use_trap_handler_, kRuntimeExceptionSupport};
}
WasmCode* NativeModule::AddOwnedCode(
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
size_t safepoint_table_offset, size_t handler_table_offset,
@ -932,8 +934,7 @@ bool WasmCodeManager::ShouldForceCriticalMemoryPressureNotification() {
std::unique_ptr<NativeModule> WasmCodeManager::NewNativeModule(
Isolate* isolate, const WasmFeatures& enabled, size_t memory_estimate,
bool can_request_more, std::shared_ptr<const WasmModule> module,
const ModuleEnv& env) {
bool can_request_more, std::shared_ptr<const WasmModule> module) {
if (ShouldForceCriticalMemoryPressureNotification()) {
(reinterpret_cast<v8::Isolate*>(isolate))
->MemoryPressureNotification(MemoryPressureLevel::kCritical);
@ -963,7 +964,7 @@ std::unique_ptr<NativeModule> WasmCodeManager::NewNativeModule(
Address end = mem.end();
std::unique_ptr<NativeModule> ret(
new NativeModule(isolate, enabled, can_request_more, std::move(mem), this,
std::move(module), env));
std::move(module)));
TRACE_HEAP("New NativeModule %p: Mem: %" PRIuPTR ",+%zu\n", this, start,
size);
AssignRangesAndAddModule(start, end, ret.get());

View File

@ -314,6 +314,10 @@ class V8_EXPORT_PRIVATE NativeModule final {
CompilationState* compilation_state() { return compilation_state_.get(); }
// Create a {ModuleEnv} object for compilation. Only valid as long as this
// {NativeModule} is alive.
ModuleEnv CreateModuleEnv() const;
uint32_t num_functions() const {
return module_->num_declared_functions + module_->num_imported_functions;
}
@ -349,7 +353,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
NativeModule(Isolate* isolate, const WasmFeatures& enabled_features,
bool can_request_more, VirtualMemory code_space,
WasmCodeManager* code_manager,
std::shared_ptr<const WasmModule> module, const ModuleEnv& env);
std::shared_ptr<const WasmModule> module);
WasmCode* AddAnonymousCode(Handle<Code>, WasmCode::Kind kind,
const char* name = nullptr);
@ -473,7 +477,7 @@ class V8_EXPORT_PRIVATE WasmCodeManager final {
std::unique_ptr<NativeModule> NewNativeModule(
Isolate* isolate, const WasmFeatures& enabled_features,
size_t memory_estimate, bool can_request_more,
std::shared_ptr<const WasmModule> module, const ModuleEnv& env);
std::shared_ptr<const WasmModule> module);
NativeModule* LookupNativeModule(Address pc) const;
WasmCode* LookupCode(Address pc) const;

View File

@ -178,7 +178,6 @@ bool WasmEngine::CompileFunction(Isolate* isolate, NativeModule* native_module,
WasmFeatures detected = kNoWasmFeatures;
WasmCode* ret = WasmCompilationUnit::CompileWasmFunction(
isolate, native_module, &detected, &thrower,
GetModuleEnv(native_module->compilation_state()),
&native_module->module()->functions[function_index], tier);
return ret != nullptr;
}

View File

@ -175,19 +175,16 @@ enum DispatchTableElements : int {
// static
Handle<WasmModuleObject> WasmModuleObject::New(
Isolate* isolate, const wasm::WasmFeatures& enabled,
std::shared_ptr<const wasm::WasmModule> shared_module, wasm::ModuleEnv& env,
std::shared_ptr<const wasm::WasmModule> shared_module,
OwnedVector<const uint8_t> wire_bytes, Handle<Script> script,
Handle<ByteArray> asm_js_offset_table) {
DCHECK_EQ(shared_module.get(), env.module);
// Create a new {NativeModule} first.
size_t native_memory_estimate =
isolate->wasm_engine()->code_manager()->EstimateNativeModuleSize(
env.module);
shared_module.get());
auto native_module = isolate->wasm_engine()->code_manager()->NewNativeModule(
isolate, enabled, native_memory_estimate,
wasm::NativeModule::kCanAllocateMoreMemory, std::move(shared_module),
env);
wasm::NativeModule::kCanAllocateMoreMemory, std::move(shared_module));
native_module->set_wire_bytes(std::move(wire_bytes));
native_module->SetRuntimeStubs(isolate);

View File

@ -137,7 +137,7 @@ class WasmModuleObject : public JSObject {
// Creates a new {WasmModuleObject} with a new {NativeModule} underneath.
static Handle<WasmModuleObject> New(
Isolate* isolate, const wasm::WasmFeatures& enabled,
std::shared_ptr<const wasm::WasmModule> module, wasm::ModuleEnv& env,
std::shared_ptr<const wasm::WasmModule> module,
OwnedVector<const uint8_t> wire_bytes, Handle<Script> script,
Handle<ByteArray> asm_js_offset_table);

View File

@ -268,6 +268,9 @@ size_t NativeModuleSerializer::Measure() const {
}
void NativeModuleSerializer::WriteHeader(Writer* writer) {
// TODO(eholk): We need to properly preserve the flag whether the trap
// handler was used or not when serializing.
writer->Write(native_module_->num_functions());
writer->Write(native_module_->num_imported_functions());
}
@ -555,17 +558,10 @@ MaybeHandle<WasmModuleObject> DeserializeNativeModule(
Handle<Script> script =
CreateWasmScript(isolate, wire_bytes, module->source_map_url);
// TODO(eholk): We need to properly preserve the flag whether the trap
// handler was used or not when serializing.
UseTrapHandler use_trap_handler =
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler : kNoTrapHandler;
ModuleEnv env(module, use_trap_handler,
RuntimeExceptionSupport::kRuntimeExceptionSupport);
OwnedVector<uint8_t> wire_bytes_copy = OwnedVector<uint8_t>::Of(wire_bytes);
Handle<WasmModuleObject> module_object = WasmModuleObject::New(
isolate, enabled_features, std::move(decode_result).value(), env,
isolate, enabled_features, std::move(decode_result).value(),
std::move(wire_bytes_copy), script, Handle<ByteArray>::null());
NativeModule* native_module = module_object->native_module();

View File

@ -123,15 +123,11 @@ std::unique_ptr<wasm::NativeModule> AllocateNativeModule(Isolate* isolate,
size_t code_size) {
std::shared_ptr<wasm::WasmModule> module(new wasm::WasmModule());
module->num_declared_functions = 1;
wasm::ModuleEnv env(
module.get(), wasm::UseTrapHandler::kNoTrapHandler,
wasm::RuntimeExceptionSupport::kNoRuntimeExceptionSupport);
// We have to add the code object to a NativeModule, because the
// WasmCallDescriptor assumes that code is on the native heap and not
// within a code object.
return isolate->wasm_engine()->code_manager()->NewNativeModule(
isolate, wasm::kAllWasmFeatures, code_size, false, std::move(module),
env);
isolate, wasm::kAllWasmFeatures, code_size, false, std::move(module));
}
void TestReturnMultipleValues(MachineType type) {

View File

@ -22,11 +22,8 @@ std::unique_ptr<NativeModule> NewModule(Isolate* isolate) {
std::shared_ptr<WasmModule> module(new WasmModule);
bool can_request_more = false;
size_t size = 100;
ModuleEnv env(module.get(), UseTrapHandler::kNoTrapHandler,
RuntimeExceptionSupport::kNoRuntimeExceptionSupport);
auto native_module =
manager->NewNativeModule(isolate, kAllWasmFeatures, size,
can_request_more, std::move(module), env);
auto native_module = manager->NewNativeModule(
isolate, kAllWasmFeatures, size, can_request_more, std::move(module));
native_module->SetRuntimeStubs(isolate);
return native_module;
}

View File

@ -354,7 +354,6 @@ TEST(SharedEngineRunThreadedTierUp) {
WasmFeatures detected = kNoWasmFeatures;
WasmCompilationUnit::CompileWasmFunction(
isolate.isolate(), module.get(), &detected, &thrower,
GetModuleEnv(module->compilation_state()),
&module->module()->functions[0], ExecutionTier::kOptimized);
CHECK_EQ(23, isolate.Run(instance));
});

View File

@ -209,9 +209,8 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
Handle<Script> script =
isolate_->factory()->NewScript(isolate_->factory()->empty_string());
script->set_type(Script::TYPE_WASM);
ModuleEnv env = CreateModuleEnv();
Handle<WasmModuleObject> module_object =
WasmModuleObject::New(isolate_, enabled_features_, test_module_, env, {},
WasmModuleObject::New(isolate_, enabled_features_, test_module_, {},
script, Handle<ByteArray>::null());
// This method is called when we initialize TestEnvironment. We don't
// have a memory yet, so we won't create it here. We'll update the
@ -411,7 +410,7 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
->native_module()
->wire_bytes();
ModuleEnv module_env = builder_->CreateModuleEnv();
ModuleEnv env = builder_->CreateModuleEnv();
ScopedVector<uint8_t> func_wire_bytes(function_->code.length());
memcpy(func_wire_bytes.start(), wire_bytes.start() + function_->code.offset(),
func_wire_bytes.length());
@ -420,11 +419,10 @@ void WasmFunctionCompiler::Build(const byte* start, const byte* end) {
func_wire_bytes.start(), func_wire_bytes.end()};
NativeModule* native_module =
builder_->instance_object()->module_object()->native_module();
WasmCompilationUnit unit(isolate()->wasm_engine(), &module_env, native_module,
func_body, function_->func_index,
isolate()->counters(), tier);
WasmCompilationUnit unit(isolate()->wasm_engine(), native_module, func_body,
function_->func_index, isolate()->counters(), tier);
WasmFeatures unused_detected_features;
unit.ExecuteCompilation(&unused_detected_features);
unit.ExecuteCompilation(&env, &unused_detected_features);
CHECK(!unit.failed());
if (WasmCode::ShouldBeLogged(isolate())) unit.result()->LogCode(isolate());
}

View File

@ -138,16 +138,12 @@ std::unique_ptr<wasm::NativeModule> AllocateNativeModule(i::Isolate* isolate,
size_t code_size) {
std::shared_ptr<wasm::WasmModule> module(new wasm::WasmModule);
module->num_declared_functions = 1;
wasm::ModuleEnv env(
module.get(), wasm::UseTrapHandler::kNoTrapHandler,
wasm::RuntimeExceptionSupport::kNoRuntimeExceptionSupport);
// We have to add the code object to a NativeModule, because the
// WasmCallDescriptor assumes that code is on the native heap and not
// within a code object.
return isolate->wasm_engine()->code_manager()->NewNativeModule(
isolate, i::wasm::kAllWasmFeatures, code_size, false, std::move(module),
env);
isolate, i::wasm::kAllWasmFeatures, code_size, false, std::move(module));
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {

View File

@ -165,10 +165,8 @@ class WasmCodeManagerTest : public TestWithContext,
std::shared_ptr<WasmModule> module(new WasmModule);
module->num_declared_functions = kNumFunctions;
bool can_request_more = style == Growable;
ModuleEnv env(module.get(), UseTrapHandler::kNoTrapHandler,
RuntimeExceptionSupport::kNoRuntimeExceptionSupport);
return manager->NewNativeModule(i_isolate(), kAllWasmFeatures, size,
can_request_more, std::move(module), env);
can_request_more, std::move(module));
}
WasmCode* AddCode(NativeModule* native_module, uint32_t index, size_t size) {