[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:
Clemens Hammacher 2018-06-11 17:16:26 +02:00 committed by Commit Bot
parent 481cabfe31
commit d50075453a
3 changed files with 29 additions and 18 deletions

View File

@ -1635,29 +1635,18 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
TRACE("Recompiling module without bounds checks\n");
constexpr bool allow_trap_handler = false;
ModuleEnv env = CreateDefaultModuleEnv(module_, allow_trap_handler);
Handle<WasmCompiledModule> compiled_module(
module_object_->compiled_module(), isolate_);
// Create a new native module...
auto native_module =
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_);
// Disable trap handlers on this native module.
NativeModule* native_module =
module_object_->compiled_module()->GetNativeModule();
native_module->DisableTrapHandler();
// ...and then compile it.
// Recompile all functions in this native module.
ErrorThrower thrower(isolate_, "recompile");
CompileNativeModule(isolate_, &thrower, module_object_, module_, &env);
if (thrower.error()) {
return {};
}
DCHECK(!module_object_->compiled_module()
->GetNativeModule()
->use_trap_handler());
DCHECK(!native_module->use_trap_handler());
}
}

View File

@ -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() {
TRACE_HEAP("Deleting native module: %p\n", reinterpret_cast<void*>(this));
// Clear the handle at the beginning of destructor to make it robust against

View File

@ -291,6 +291,14 @@ class V8_EXPORT_PRIVATE NativeModule final {
void UnpackAndRegisterProtectedInstructions();
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
// 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
@ -395,7 +403,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
size_t committed_code_space_ = 0;
int modification_scope_depth_ = 0;
bool can_request_more_memory_;
bool use_trap_handler_;
bool use_trap_handler_ = false;
bool is_executable_ = false;
bool lazy_compile_frozen_ = false;