[wasm][fuzzer] Refactor second instantiation
The fuzzer instantiates the module twice: Once for reference interpretation / execution, and once for the actual execution of Liftoff/TurboFan code. For some reason, the two code paths for interpretation and Liftoff reference execution used different patterns: Interpretation was using the first instance, and then creating a second instance for actual execution, whereas the Liftoff path used a second instance for the reference execution and used the first one for the actual execution. This CL refactors this to always create a "reference instance" first, use that for either the interpreter or Liftoff, and then create a second instance for the actual execution. R=thibaudm@chromium.org Bug: v8:12425 Change-Id: I19754264240d8570f00161abb7aecba1cc2b2ae0 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3683323 Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Thibaud Michaud <thibaudm@chromium.org> Cr-Commit-Position: refs/heads/main@{#80900}
This commit is contained in:
parent
4b1b7e29ba
commit
85cf4be909
@ -97,15 +97,19 @@ void InterpretAndExecuteModule(i::Isolate* isolate,
|
||||
if (module_object->module()->start_function_index >= 0) return;
|
||||
|
||||
HandleScope handle_scope(isolate); // Avoid leaking handles.
|
||||
Handle<WasmInstanceObject> instance;
|
||||
Handle<WasmInstanceObject> instance_ref;
|
||||
|
||||
// Try to instantiate, return if it fails.
|
||||
// Try to instantiate the reference instance, return if it fails. Use
|
||||
// {module_ref} if provided (for "Liftoff as reference"), {module_object}
|
||||
// otherwise (for "interpreter as reference").
|
||||
{
|
||||
ErrorThrower thrower(isolate, "WebAssembly Instantiation");
|
||||
ErrorThrower thrower(isolate, "InterpretAndExecuteModule");
|
||||
if (!GetWasmEngine()
|
||||
->SyncInstantiate(isolate, &thrower, module_object, {},
|
||||
{}) // no imports & memory
|
||||
.ToHandle(&instance)) {
|
||||
->SyncInstantiate(
|
||||
isolate, &thrower,
|
||||
module_ref.is_null() ? module_object : module_ref, {},
|
||||
{}) // no imports & memory
|
||||
.ToHandle(&instance_ref)) {
|
||||
isolate->clear_pending_exception();
|
||||
thrower.Reset(); // Ignore errors.
|
||||
return;
|
||||
@ -114,7 +118,7 @@ void InterpretAndExecuteModule(i::Isolate* isolate,
|
||||
|
||||
// Get the "main" exported function. Do nothing if it does not exist.
|
||||
Handle<WasmExportedFunction> main_function;
|
||||
if (!testing::GetExportedFunction(isolate, instance, "main")
|
||||
if (!testing::GetExportedFunction(isolate, instance_ref, "main")
|
||||
.ToHandle(&main_function)) {
|
||||
return;
|
||||
}
|
||||
@ -122,17 +126,15 @@ void InterpretAndExecuteModule(i::Isolate* isolate,
|
||||
base::OwnedVector<Handle<Object>> compiled_args =
|
||||
testing::MakeDefaultArguments(isolate, main_function->sig());
|
||||
bool exception_ref = false;
|
||||
bool exception = false;
|
||||
int32_t result_ref = 0;
|
||||
int32_t result = 0;
|
||||
|
||||
if (module_ref.is_null()) {
|
||||
// Use the interpreter as reference.
|
||||
base::OwnedVector<WasmValue> arguments =
|
||||
testing::MakeDefaultInterpreterArguments(isolate, main_function->sig());
|
||||
|
||||
// Now interpret.
|
||||
testing::WasmInterpretationResult interpreter_result =
|
||||
testing::InterpretWasmModule(isolate, instance,
|
||||
testing::InterpretWasmModule(isolate, instance_ref,
|
||||
main_function->function_index(),
|
||||
arguments.begin());
|
||||
if (interpreter_result.failed()) return;
|
||||
@ -150,35 +152,8 @@ void InterpretAndExecuteModule(i::Isolate* isolate,
|
||||
DCHECK(interpreter_result.trapped());
|
||||
exception_ref = true;
|
||||
}
|
||||
// Reset the instance before the test run.
|
||||
{
|
||||
ErrorThrower thrower(isolate, "Second Instantiation");
|
||||
// We instantiated before, so the second instantiation must also succeed.
|
||||
if (!GetWasmEngine()
|
||||
->SyncInstantiate(isolate, &thrower, module_object, {},
|
||||
{}) // no imports & memory
|
||||
.ToHandle(&instance)) {
|
||||
DCHECK(thrower.error());
|
||||
FATAL("Second instantiation failed unexpectedly: %s",
|
||||
thrower.error_msg());
|
||||
}
|
||||
DCHECK(!thrower.error());
|
||||
}
|
||||
} else {
|
||||
Handle<WasmInstanceObject> instance_ref;
|
||||
{
|
||||
ErrorThrower thrower(isolate, "WebAssembly Instantiation");
|
||||
// We instantiated before, so the second instantiation must also succeed.
|
||||
if (!GetWasmEngine()
|
||||
->SyncInstantiate(isolate, &thrower, module_ref, {},
|
||||
{}) // no imports & memory
|
||||
.ToHandle(&instance_ref)) {
|
||||
DCHECK(thrower.error());
|
||||
FATAL("Second instantiation failed unexpectedly: %s",
|
||||
thrower.error_msg());
|
||||
}
|
||||
DCHECK(!thrower.error());
|
||||
}
|
||||
// Use Liftoff code as reference.
|
||||
result_ref = testing::CallWasmFunctionForTesting(
|
||||
isolate, instance_ref, "main", static_cast<int>(compiled_args.size()),
|
||||
compiled_args.begin(), &exception_ref);
|
||||
@ -190,7 +165,24 @@ void InterpretAndExecuteModule(i::Isolate* isolate,
|
||||
if (*nondeterminism != 0) return;
|
||||
}
|
||||
|
||||
result = testing::CallWasmFunctionForTesting(
|
||||
// Instantiate a fresh instance for the actual (non-ref) execution.
|
||||
Handle<WasmInstanceObject> instance;
|
||||
{
|
||||
ErrorThrower thrower(isolate, "InterpretAndExecuteModule (second)");
|
||||
// We instantiated before, so the second instantiation must also succeed.
|
||||
if (!GetWasmEngine()
|
||||
->SyncInstantiate(isolate, &thrower, module_object, {},
|
||||
{}) // no imports & memory
|
||||
.ToHandle(&instance)) {
|
||||
DCHECK(thrower.error());
|
||||
FATAL("Second instantiation failed unexpectedly: %s",
|
||||
thrower.error_msg());
|
||||
}
|
||||
DCHECK(!thrower.error());
|
||||
}
|
||||
|
||||
bool exception = false;
|
||||
int32_t result = testing::CallWasmFunctionForTesting(
|
||||
isolate, instance, "main", static_cast<int>(compiled_args.size()),
|
||||
compiled_args.begin(), &exception);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user