Commit dbe3362d authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Factor out {GetWasmFunctionInfo} function

There are several places where we extract function information
(instance and function index) from the deoptimization data. Add a
central method to do this.

Drive-by: Move {AttachWasmFunctionInfo} from wasm-compiler.h to
wasm-objects.h.

R=titzer@chromium.org

Change-Id: I768d2c9aa8049f75a6be02242b1fe524ff42e3e4
Reviewed-on: https://chromium-review.googlesource.com/793046Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49682}
parent 2cbfa244
......@@ -4320,31 +4320,6 @@ void ValidateImportWrapperReferencesImmovables(Handle<Code> wrapper) {
} // namespace
void AttachWasmFunctionInfo(Isolate* isolate, Handle<Code> code,
MaybeHandle<WeakCell> weak_instance,
int func_index) {
DCHECK(weak_instance.is_null() ||
weak_instance.ToHandleChecked()->value()->IsWasmInstanceObject());
Handle<FixedArray> deopt_data = isolate->factory()->NewFixedArray(2, TENURED);
if (!weak_instance.is_null()) {
// TODO(wasm): Introduce constants for the indexes in wasm deopt data.
deopt_data->set(0, *weak_instance.ToHandleChecked());
}
deopt_data->set(1, Smi::FromInt(func_index));
code->set_deoptimization_data(*deopt_data);
}
void AttachWasmFunctionInfo(Isolate* isolate, Handle<Code> code,
MaybeHandle<WasmInstanceObject> instance,
int func_index) {
MaybeHandle<WeakCell> weak_instance;
if (!instance.is_null()) {
weak_instance = isolate->factory()->NewWeakCell(instance.ToHandleChecked());
}
AttachWasmFunctionInfo(isolate, code, weak_instance, func_index);
}
Handle<Code> CompileWasmToJSWrapper(
Isolate* isolate, Handle<JSReceiver> target, wasm::FunctionSig* sig,
uint32_t index, wasm::ModuleOrigin origin,
......
......@@ -183,21 +183,6 @@ Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index,
wasm::FunctionSig* sig,
Handle<WasmInstanceObject> instance);
// Attach function information in the form of deoptimization data to the given
// code object. This information will be used for generating stack traces,
// calling imported functions in the interpreter, knowing which function to
// compile in a lazy compile stub, and more. The deopt data will be a newly
// allocated FixedArray of length 2, where the first element is a WeakCell
// containing the WasmInstanceObject, and the second element is the function
// index.
// If calling this method repeatedly for the same instance, pass a WeakCell
// directly in order to avoid creating many cells pointing to the same instance.
void AttachWasmFunctionInfo(Isolate*, Handle<Code>,
MaybeHandle<WeakCell> weak_instance,
int func_index);
void AttachWasmFunctionInfo(Isolate*, Handle<Code>,
MaybeHandle<WasmInstanceObject>, int func_index);
enum CWasmEntryParameters {
kCodeObject,
kArgumentsBuffer,
......
......@@ -632,11 +632,10 @@ Handle<Code> CompileLazy(Isolate* isolate) {
// instance and function index. Otherwise this must be a wasm->wasm call
// within one instance, so extract the information from the caller.
if (lazy_compile_code->deoptimization_data()->length() > 0) {
DCHECK_LE(2, lazy_compile_code->deoptimization_data()->length());
exp_deopt_data = handle(lazy_compile_code->deoptimization_data(), isolate);
auto* weak_cell = WeakCell::cast(exp_deopt_data->get(0));
instance = handle(WasmInstanceObject::cast(weak_cell->value()), isolate);
func_index = Smi::ToInt(exp_deopt_data->get(1));
auto func_info = GetWasmFunctionInfo(isolate, lazy_compile_code);
instance = func_info.instance.ToHandleChecked();
func_index = func_info.func_index;
}
it.Advance();
// Third frame: The calling wasm code or js-to-wasm wrapper.
......@@ -766,7 +765,7 @@ void LazyCompilationOrchestrator::CompileFunction(
CHECK(!thrower.error());
Handle<Code> code = maybe_code.ToHandleChecked();
compiler::AttachWasmFunctionInfo(isolate, code, instance, func_index);
AttachWasmFunctionInfo(isolate, code, instance, func_index);
DCHECK_EQ(Builtins::kWasmCompileLazy,
Code::cast(compiled_module->code_table()->get(func_index))
......@@ -828,18 +827,15 @@ Handle<Code> LazyCompilationOrchestrator::CompileLazy(
DisallowHeapAllocation no_gc;
SourcePositionTableIterator source_pos_iterator(
caller->SourcePositionTable());
DCHECK_EQ(2, caller->deoptimization_data()->length());
Handle<WeakCell> weak_caller_instance(
WeakCell::cast(caller->deoptimization_data()->get(0)), isolate);
Handle<WasmInstanceObject> caller_instance(
WasmInstanceObject::cast(weak_caller_instance->value()), isolate);
Handle<WasmCompiledModule> caller_module(caller_instance->compiled_module(),
isolate);
auto caller_func_info = GetWasmFunctionInfo(isolate, caller);
Handle<WasmCompiledModule> caller_module(
caller_func_info.instance.ToHandleChecked()->compiled_module(),
isolate);
SeqOneByteString* module_bytes = caller_module->module_bytes();
int caller_func_index = Smi::ToInt(caller->deoptimization_data()->get(1));
const byte* func_bytes =
module_bytes->GetChars() +
caller_module->module()->functions[caller_func_index].code.offset();
module_bytes->GetChars() + caller_module->module()
->functions[caller_func_info.func_index]
.code.offset();
for (RelocIterator it(*caller, RelocInfo::kCodeTargetMask); !it.done();
it.next()) {
Code* callee =
......@@ -1290,12 +1286,14 @@ Handle<Code> EnsureExportedLazyDeoptData(Isolate* isolate,
if (code->deoptimization_data()->length() == 0) {
code = isolate->factory()->CopyCode(code);
code_table->set(func_index, *code);
compiler::AttachWasmFunctionInfo(isolate, code, instance, func_index);
AttachWasmFunctionInfo(isolate, code, instance, func_index);
}
#ifdef DEBUG
auto func_info = GetWasmFunctionInfo(isolate, code);
DCHECK_IMPLIES(!instance.is_null(),
WeakCell::cast(code->deoptimization_data()->get(0))->value() ==
*instance);
DCHECK_EQ(func_index, Smi::ToInt(code->deoptimization_data()->get(1)));
*func_info.instance.ToHandleChecked() == *instance);
DCHECK_EQ(func_index, func_info.func_index);
#endif
return code;
}
......@@ -1377,8 +1375,8 @@ Handle<Code> MakeWasmToWasmWrapper(
// Set the deoptimization data for the WasmToWasm wrapper. This is
// needed by the interpreter to find the imported instance for
// a cross-instance call.
compiler::AttachWasmFunctionInfo(isolate, wrapper_code, imported_instance,
imported_function->function_index());
AttachWasmFunctionInfo(isolate, wrapper_code, imported_instance,
imported_function->function_index());
return wrapper_code;
}
......@@ -1707,8 +1705,8 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
// unique copy to attach updated deoptimization data.
if (orig_code->deoptimization_data()->length() > 0) {
Handle<Code> code = factory->CopyCode(orig_code);
compiler::AttachWasmFunctionInfo(isolate_, code,
Handle<WasmInstanceObject>(), i);
AttachWasmFunctionInfo(isolate_, code,
Handle<WasmInstanceObject>(), i);
code_table->set(i, *code);
}
break;
......@@ -1886,7 +1884,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
i < num_functions; ++i) {
Handle<Code> code = handle(Code::cast(code_table->get(i)), isolate_);
if (code->kind() == Code::WASM_FUNCTION) {
compiler::AttachWasmFunctionInfo(isolate_, code, weak_link, i);
AttachWasmFunctionInfo(isolate_, code, weak_link, i);
continue;
}
DCHECK_EQ(Builtins::kWasmCompileLazy, code->builtin_index());
......
......@@ -2406,17 +2406,13 @@ class ThreadImpl {
if (code->kind() == Code::WASM_FUNCTION ||
code->kind() == Code::WASM_TO_WASM_FUNCTION) {
FixedArray* deopt_data = code->deoptimization_data();
DCHECK_EQ(2, deopt_data->length());
WasmInstanceObject* target_instance =
WasmInstanceObject::cast(WeakCell::cast(deopt_data->get(0))->value());
if (target_instance != codemap()->instance()) {
auto func_info = GetWasmFunctionInfo(isolate, code);
if (*func_info.instance.ToHandleChecked() != codemap()->instance()) {
return CallExternalWasmFunction(isolate, code, signature);
}
int target_func_idx = Smi::ToInt(deopt_data->get(1));
DCHECK_LE(0, target_func_idx);
DCHECK_LE(0, func_info.func_index);
return {ExternalCallResult::INTERNAL,
codemap()->GetCode(target_func_idx)};
codemap()->GetCode(func_info.func_index)};
}
return CallExternalJSFunction(isolate, code, signature);
......
......@@ -310,7 +310,7 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table,
func_index, new_context_address);
// TODO(6792): No longer needed once WebAssembly code is off heap.
CodeSpaceMemoryModificationScope modification_scope(isolate->heap());
compiler::AttachWasmFunctionInfo(isolate, code, instance, func_index);
AttachWasmFunctionInfo(isolate, code, instance, func_index);
}
UpdateDispatchTables(isolate, dispatch_tables, index, wasm_function, code);
......@@ -1608,6 +1608,46 @@ Handle<Code> WasmCompiledModule::CompileLazy(
patch_caller);
}
void AttachWasmFunctionInfo(Isolate* isolate, Handle<Code> code,
MaybeHandle<WeakCell> weak_instance,
int func_index) {
DCHECK(weak_instance.is_null() ||
weak_instance.ToHandleChecked()->value()->IsWasmInstanceObject());
Handle<FixedArray> deopt_data = isolate->factory()->NewFixedArray(2, TENURED);
if (!weak_instance.is_null()) {
// TODO(wasm): Introduce constants for the indexes in wasm deopt data.
deopt_data->set(0, *weak_instance.ToHandleChecked());
}
deopt_data->set(1, Smi::FromInt(func_index));
code->set_deoptimization_data(*deopt_data);
}
void AttachWasmFunctionInfo(Isolate* isolate, Handle<Code> code,
MaybeHandle<WasmInstanceObject> instance,
int func_index) {
MaybeHandle<WeakCell> weak_instance;
if (!instance.is_null()) {
weak_instance = isolate->factory()->NewWeakCell(instance.ToHandleChecked());
}
AttachWasmFunctionInfo(isolate, code, weak_instance, func_index);
}
WasmFunctionInfo GetWasmFunctionInfo(Isolate* isolate, Handle<Code> code) {
FixedArray* deopt_data = code->deoptimization_data();
DCHECK_LE(2, deopt_data->length());
MaybeHandle<WasmInstanceObject> instance;
Object* maybe_weak_instance = deopt_data->get(0);
if (maybe_weak_instance->IsWeakCell()) {
Object* maybe_instance = WeakCell::cast(maybe_weak_instance)->value();
if (maybe_instance) {
instance = handle(WasmInstanceObject::cast(maybe_instance), isolate);
}
}
int func_index = Smi::ToInt(deopt_data->get(1));
return {instance, func_index};
}
#undef TRACE
} // namespace internal
......
......@@ -657,6 +657,27 @@ class WasmDebugInfo : public FixedArray {
wasm::FunctionSig*);
};
// Attach function information in the form of deoptimization data to the given
// code object. This information will be used for generating stack traces,
// calling imported functions in the interpreter, knowing which function to
// compile in a lazy compile stub, and more. The deopt data will be a newly
// allocated FixedArray of length 2, where the first element is a WeakCell
// containing the WasmInstanceObject, and the second element is the function
// index.
// If calling this method repeatedly for the same instance, pass a WeakCell
// directly in order to avoid creating many cells pointing to the same instance.
void AttachWasmFunctionInfo(Isolate*, Handle<Code>,
MaybeHandle<WeakCell> weak_instance,
int func_index);
void AttachWasmFunctionInfo(Isolate*, Handle<Code>,
MaybeHandle<WasmInstanceObject>, int func_index);
struct WasmFunctionInfo {
MaybeHandle<WasmInstanceObject> instance;
int func_index;
};
WasmFunctionInfo GetWasmFunctionInfo(Isolate*, Handle<Code>);
#undef DECL_OOL_QUERY
#undef DECL_OOL_CAST
#undef DECL_GETTER
......
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