[wasm] Disable trap handlers within the same NativeModule
The current implementation allocates a new {NativeModule} if trap handlers are disabled. Afterwards, all export wrappers need to be patched to call to the code objects in this new native module (this patching is done in {CodeSpecialization}). With the jump table, we want to get rid of this patching, hence we need to reuse the same jump table, hence we cannot allocate a new {NativeModule}. Instead, we should update the existing one with the new code. R=mstarzinger@chromium.org CC=eholk@chromium.org Bug: v8:7143, v8:7758 Change-Id: If2f395d462752b9084ed1e5f0a81f71d400ccfca Reviewed-on: https://chromium-review.googlesource.com/1095262 Reviewed-by: Eric Holk <eholk@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Cr-Commit-Position: refs/heads/master@{#53645}
This commit is contained in:
parent
481cabfe31
commit
d50075453a
@ -1635,29 +1635,18 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
|
|||||||
TRACE("Recompiling module without bounds checks\n");
|
TRACE("Recompiling module without bounds checks\n");
|
||||||
constexpr bool allow_trap_handler = false;
|
constexpr bool allow_trap_handler = false;
|
||||||
ModuleEnv env = CreateDefaultModuleEnv(module_, allow_trap_handler);
|
ModuleEnv env = CreateDefaultModuleEnv(module_, allow_trap_handler);
|
||||||
Handle<WasmCompiledModule> compiled_module(
|
// Disable trap handlers on this native module.
|
||||||
module_object_->compiled_module(), isolate_);
|
NativeModule* native_module =
|
||||||
// Create a new native module...
|
module_object_->compiled_module()->GetNativeModule();
|
||||||
auto native_module =
|
native_module->DisableTrapHandler();
|
||||||
isolate_->wasm_engine()->code_manager()->NewNativeModule(*module_,
|
|
||||||
env);
|
|
||||||
Handle<Foreign> native_module_wrapper =
|
|
||||||
Managed<wasm::NativeModule>::FromUniquePtr(
|
|
||||||
isolate_,
|
|
||||||
0, // TODO(eholk): estimate size
|
|
||||||
std::move(native_module));
|
|
||||||
compiled_module->set_native_module(*native_module_wrapper);
|
|
||||||
compiled_module->GetNativeModule()->SetRuntimeStubs(isolate_);
|
|
||||||
|
|
||||||
// ...and then compile it.
|
// Recompile all functions in this native module.
|
||||||
ErrorThrower thrower(isolate_, "recompile");
|
ErrorThrower thrower(isolate_, "recompile");
|
||||||
CompileNativeModule(isolate_, &thrower, module_object_, module_, &env);
|
CompileNativeModule(isolate_, &thrower, module_object_, module_, &env);
|
||||||
if (thrower.error()) {
|
if (thrower.error()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
DCHECK(!module_object_->compiled_module()
|
DCHECK(!native_module->use_trap_handler());
|
||||||
->GetNativeModule()
|
|
||||||
->use_trap_handler());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,6 +801,20 @@ void NativeModule::ReleaseProtectedInstructions() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeModule::DisableTrapHandler() {
|
||||||
|
// Switch {use_trap_handler_} from true to false.
|
||||||
|
DCHECK(use_trap_handler_);
|
||||||
|
use_trap_handler_ = false;
|
||||||
|
|
||||||
|
// Clear the code table (just to increase the chances to hit an error if we
|
||||||
|
// forget to re-add all code).
|
||||||
|
uint32_t num_wasm_functions = num_functions_ - num_imported_functions_;
|
||||||
|
memset(code_table_.get(), 0, num_wasm_functions * sizeof(WasmCode*));
|
||||||
|
|
||||||
|
// TODO(clemensh): Actually free the owned code, such that the memory can be
|
||||||
|
// recycled.
|
||||||
|
}
|
||||||
|
|
||||||
NativeModule::~NativeModule() {
|
NativeModule::~NativeModule() {
|
||||||
TRACE_HEAP("Deleting native module: %p\n", reinterpret_cast<void*>(this));
|
TRACE_HEAP("Deleting native module: %p\n", reinterpret_cast<void*>(this));
|
||||||
// Clear the handle at the beginning of destructor to make it robust against
|
// Clear the handle at the beginning of destructor to make it robust against
|
||||||
|
@ -291,6 +291,14 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
|||||||
void UnpackAndRegisterProtectedInstructions();
|
void UnpackAndRegisterProtectedInstructions();
|
||||||
void ReleaseProtectedInstructions();
|
void ReleaseProtectedInstructions();
|
||||||
|
|
||||||
|
// Transition this module from code relying on trap handlers (i.e. without
|
||||||
|
// explicit memory bounds checks) to code that does not require trap handlers
|
||||||
|
// (i.e. code with explicit bounds checks).
|
||||||
|
// This method must only be called if {use_trap_handler()} is true (it will be
|
||||||
|
// false afterwards). All code in this {NativeModule} needs to be re-added
|
||||||
|
// after calling this method.
|
||||||
|
void DisableTrapHandler();
|
||||||
|
|
||||||
// Returns the instruction start of code suitable for indirect or import calls
|
// Returns the instruction start of code suitable for indirect or import calls
|
||||||
// for the given function index. If the code at the given index is the lazy
|
// for the given function index. If the code at the given index is the lazy
|
||||||
// compile stub, it will clone a non-anonymous lazy compile stub for the
|
// compile stub, it will clone a non-anonymous lazy compile stub for the
|
||||||
@ -395,7 +403,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
|||||||
size_t committed_code_space_ = 0;
|
size_t committed_code_space_ = 0;
|
||||||
int modification_scope_depth_ = 0;
|
int modification_scope_depth_ = 0;
|
||||||
bool can_request_more_memory_;
|
bool can_request_more_memory_;
|
||||||
bool use_trap_handler_;
|
bool use_trap_handler_ = false;
|
||||||
bool is_executable_ = false;
|
bool is_executable_ = false;
|
||||||
bool lazy_compile_frozen_ = false;
|
bool lazy_compile_frozen_ = false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user