Commit 4f4086dc authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[ext-code-space] Avoid Code <-> CodeT conversions in runtime, pt.4

This CL migrates the following objects' APIs to CodeT:
* WasmFunctionData,
* WasmInternalFunction.

Bug: v8:11880
Change-Id: Ib3f0eb41894cbd3c6b30430c4e5616eb45fbbaec
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3338701Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78377}
parent 00a757fa
......@@ -1535,7 +1535,7 @@ Handle<WasmInternalFunction> Factory::NewWasmInternalFunction(
result.set_foreign_address(isolate(), opt_call_target);
result.set_ref(*ref);
// Default values, will be overwritten by the caller.
result.set_code(isolate()->builtins()->code(Builtin::kAbort));
result.set_code(*BUILTIN_CODET(isolate(), Abort));
result.set_external(*undefined_value());
return handle(result, isolate());
}
......@@ -1543,7 +1543,7 @@ Handle<WasmInternalFunction> Factory::NewWasmInternalFunction(
Handle<WasmJSFunctionData> Factory::NewWasmJSFunctionData(
Address opt_call_target, Handle<JSReceiver> callable, int return_count,
int parameter_count, Handle<PodArray<wasm::ValueType>> serialized_sig,
Handle<Code> wrapper_code, Handle<Map> rtt) {
Handle<CodeT> wrapper_code, Handle<Map> rtt) {
Handle<WasmApiFunctionRef> ref = NewWasmApiFunctionRef(callable);
Handle<WasmInternalFunction> internal =
NewWasmInternalFunction(opt_call_target, ref, rtt);
......@@ -1561,7 +1561,7 @@ Handle<WasmJSFunctionData> Factory::NewWasmJSFunctionData(
}
Handle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
Handle<Code> export_wrapper, Handle<WasmInstanceObject> instance,
Handle<CodeT> export_wrapper, Handle<WasmInstanceObject> instance,
Address call_target, Handle<Object> ref, int func_index,
Address sig_address, int wrapper_budget, Handle<Map> rtt) {
Handle<Foreign> sig_foreign = NewForeign(sig_address);
......@@ -1587,7 +1587,7 @@ Handle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
Handle<WasmCapiFunctionData> Factory::NewWasmCapiFunctionData(
Address call_target, Handle<Foreign> embedder_data,
Handle<Code> wrapper_code, Handle<Map> rtt,
Handle<CodeT> wrapper_code, Handle<Map> rtt,
Handle<PodArray<wasm::ValueType>> serialized_sig) {
Handle<WasmApiFunctionRef> ref = NewWasmApiFunctionRef(Handle<JSReceiver>());
Handle<WasmInternalFunction> internal =
......
......@@ -589,10 +589,10 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<Map> rtt);
Handle<WasmCapiFunctionData> NewWasmCapiFunctionData(
Address call_target, Handle<Foreign> embedder_data,
Handle<Code> wrapper_code, Handle<Map> rtt,
Handle<CodeT> wrapper_code, Handle<Map> rtt,
Handle<PodArray<wasm::ValueType>> serialized_sig);
Handle<WasmExportedFunctionData> NewWasmExportedFunctionData(
Handle<Code> export_wrapper, Handle<WasmInstanceObject> instance,
Handle<CodeT> export_wrapper, Handle<WasmInstanceObject> instance,
Address call_target, Handle<Object> ref, int func_index,
Address sig_address, int wrapper_budget, Handle<Map> rtt);
Handle<WasmApiFunctionRef> NewWasmApiFunctionRef(Handle<JSReceiver> callable);
......@@ -601,7 +601,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<WasmJSFunctionData> NewWasmJSFunctionData(
Address opt_call_target, Handle<JSReceiver> callable, int return_count,
int parameter_count, Handle<PodArray<wasm::ValueType>> serialized_sig,
Handle<Code> wrapper_code, Handle<Map> rtt);
Handle<CodeT> wrapper_code, Handle<Map> rtt);
Handle<WasmStruct> NewWasmStruct(const wasm::StructType* type,
wasm::WasmValue* args, Handle<Map> map);
Handle<WasmArray> NewWasmArray(const wasm::ArrayType* type,
......
......@@ -996,6 +996,10 @@ Address CodeDataContainer::InstructionStart() const {
return code_entry_point();
}
Address CodeDataContainer::raw_instruction_start() {
return code_entry_point();
}
void CodeDataContainer::clear_padding() {
memset(reinterpret_cast<void*>(address() + kUnalignedSize), 0,
kSize - kUnalignedSize);
......
......@@ -102,6 +102,9 @@ class CodeDataContainer : public HeapObject {
// Alias for code_entry_point to make it API compatible with Code.
inline Address InstructionStart() const;
// Alias for code_entry_point to make it API compatible with Code.
inline Address raw_instruction_start();
#ifdef V8_EXTERNAL_CODE_SPACE
//
// A collection of getters and predicates that forward queries to associated
......
......@@ -100,13 +100,13 @@ CodeT SharedFunctionInfo::GetCode() const {
if (data.IsWasmExportedFunctionData()) {
// Having a WasmExportedFunctionData means the code is in there.
DCHECK(HasWasmExportedFunctionData());
return ToCodeT(wasm_exported_function_data().wrapper_code());
return wasm_exported_function_data().wrapper_code();
}
if (data.IsWasmJSFunctionData()) {
return ToCodeT(wasm_js_function_data().wrapper_code());
return wasm_js_function_data().wrapper_code();
}
if (data.IsWasmCapiFunctionData()) {
return ToCodeT(wasm_capi_function_data().wrapper_code());
return wasm_capi_function_data().wrapper_code();
}
#endif // V8_ENABLE_WEBASSEMBLY
if (data.IsUncompiledData()) {
......@@ -122,7 +122,7 @@ CodeT SharedFunctionInfo::GetCode() const {
if (data.IsInterpreterData()) {
CodeT code = InterpreterTrampoline();
DCHECK(code.IsCodeT());
DCHECK(FromCodeT(code).is_interpreter_trampoline_builtin());
DCHECK(code.is_interpreter_trampoline_builtin());
return code;
}
UNREACHABLE();
......
......@@ -231,7 +231,7 @@ RUNTIME_FUNCTION(Runtime_WasmCompileLazy) {
namespace {
void ReplaceWrapper(Isolate* isolate, Handle<WasmInstanceObject> instance,
int function_index, Handle<Code> wrapper_code) {
int function_index, Handle<CodeT> wrapper_code) {
Handle<WasmInternalFunction> internal =
WasmInstanceObject::GetWasmInternalFunction(isolate, instance,
function_index)
......@@ -269,9 +269,10 @@ RUNTIME_FUNCTION(Runtime_WasmCompileWrapper) {
return ReadOnlyRoots(isolate).undefined_value();
}
Handle<Code> wrapper_code =
Handle<CodeT> wrapper_code = ToCodeT(
wasm::JSToWasmWrapperCompilationUnit::CompileSpecificJSToWasmWrapper(
isolate, sig, module);
isolate, sig, module),
isolate);
// Replace the wrapper for the function that triggered the tier-up.
// This is to verify that the wrapper is replaced, even if the function
......
......@@ -1527,9 +1527,7 @@ void PrepareFunctionData(i::Isolate* isolate,
const i::wasm::FunctionSig* sig,
const i::wasm::WasmModule* module) {
// If the data is already populated, return immediately.
// TODO(v8:11880): avoid roundtrips between cdc and code.
if (function_data->c_wrapper_code() !=
ToCodeT(*BUILTIN_CODE(isolate, Illegal))) {
if (function_data->c_wrapper_code() != *BUILTIN_CODET(isolate, Illegal)) {
return;
}
// Compile wrapper code.
......@@ -1671,9 +1669,7 @@ auto Func::call(const Val args[], Val results[]) const -> own<Trap> {
const i::wasm::FunctionSig* sig =
instance->module()->functions[function_index].sig;
PrepareFunctionData(isolate, function_data, sig, instance->module());
// TODO(v8:11880): avoid roundtrips between cdc and code.
i::Handle<i::CodeT> wrapper_code = i::Handle<i::CodeT>(
i::CodeT::cast(function_data->c_wrapper_code()), isolate);
i::Handle<i::CodeT> wrapper_code(function_data->c_wrapper_code(), isolate);
i::Address call_target = function_data->internal().foreign_address();
i::wasm::CWasmArgumentsPacker packer(function_data->packed_args_size());
......
......@@ -787,9 +787,10 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
if (module_->start_function_index >= 0) {
int start_index = module_->start_function_index;
auto& function = module_->functions[start_index];
Handle<Code> wrapper_code =
JSToWasmWrapperCompilationUnit::CompileJSToWasmWrapper(
isolate_, function.sig, module_, function.imported);
Handle<CodeT> wrapper_code =
ToCodeT(JSToWasmWrapperCompilationUnit::CompileJSToWasmWrapper(
isolate_, function.sig, module_, function.imported),
isolate_);
// TODO(clemensb): Don't generate an exported function for the start
// function. Use CWasmEntry instead.
start_function_ = WasmExportedFunction::New(
......
......@@ -2571,8 +2571,8 @@ void WebAssemblySuspenderReturnPromiseOnSuspend(
int index = data.function_index();
i::Handle<i::WasmInstanceObject> instance(
i::WasmInstanceObject::cast(data.internal().ref()), i_isolate);
i::Handle<i::Code> wrapper = i_isolate->builtins()->code_handle(
i::Builtin::kWasmReturnPromiseOnSuspend);
i::Handle<i::CodeT> wrapper =
BUILTIN_CODET(i_isolate, WasmReturnPromiseOnSuspend);
i::Handle<i::JSObject> result =
i::Handle<i::WasmExternalFunction>::cast(i::WasmExportedFunction::New(
i_isolate, instance, index,
......
......@@ -287,13 +287,6 @@ CAST_ACCESSOR(WasmExportedFunction)
// WasmFunctionData
ACCESSORS(WasmFunctionData, internal, WasmInternalFunction, kInternalOffset)
DEF_GETTER(WasmFunctionData, wrapper_code, Code) {
return FromCodeT(TorqueGeneratedClass::wrapper_code(cage_base));
}
void WasmFunctionData::set_wrapper_code(Code code, WriteBarrierMode mode) {
TorqueGeneratedClass::set_wrapper_code(ToCodeT(code), mode);
}
wasm::FunctionSig* WasmExportedFunctionData::sig() const {
return reinterpret_cast<wasm::FunctionSig*>(signature().foreign_address());
}
......@@ -307,16 +300,6 @@ CAST_ACCESSOR(WasmJSFunction)
// WasmJSFunctionData
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmJSFunctionData)
// WasmInternalFunction
ACCESSORS(WasmInternalFunction, raw_code, CodeT, kCodeOffset)
DEF_GETTER(WasmInternalFunction, code, Code) {
return FromCodeT(raw_code(cage_base));
}
void WasmInternalFunction::set_code(Code code, WriteBarrierMode mode) {
set_raw_code(ToCodeT(code), mode);
}
// WasmCapiFunction
WasmCapiFunction::WasmCapiFunction(Address ptr) : JSFunction(ptr) {
SLOW_DCHECK(IsWasmCapiFunction(*this));
......
......@@ -1385,16 +1385,18 @@ WasmInstanceObject::GetOrCreateWasmInternalFunction(
Handle<Object> entry =
FixedArray::get(module_object->export_wrappers(), wrapper_index, isolate);
Handle<Code> wrapper;
if (entry->IsCode()) {
wrapper = Handle<Code>::cast(entry);
Handle<CodeT> wrapper;
if (entry->IsCodeT()) {
wrapper = Handle<CodeT>::cast(entry);
} else {
// The wrapper may not exist yet if no function in the exports section has
// this signature. We compile it and store the wrapper in the module for
// later use.
wrapper = wasm::JSToWasmWrapperCompilationUnit::CompileJSToWasmWrapper(
isolate, function.sig, instance->module(), function.imported);
module_object->export_wrappers().set(wrapper_index, ToCodeT(*wrapper));
wrapper = ToCodeT(
wasm::JSToWasmWrapperCompilationUnit::CompileJSToWasmWrapper(
isolate, function.sig, instance->module(), function.imported),
isolate);
module_object->export_wrappers().set(wrapper_index, *wrapper);
}
auto external = Handle<WasmExternalFunction>::cast(WasmExportedFunction::New(
isolate, instance, function_index,
......@@ -1882,8 +1884,7 @@ Handle<WasmCapiFunction> WasmCapiFunction::New(
Handle<Map> rtt = isolate->factory()->wasm_internal_function_map();
Handle<WasmCapiFunctionData> fun_data =
isolate->factory()->NewWasmCapiFunctionData(
call_target, embedder_data,
isolate->builtins()->code_handle(Builtin::kIllegal), rtt,
call_target, embedder_data, BUILTIN_CODET(isolate, Illegal), rtt,
serialized_signature);
Handle<SharedFunctionInfo> shared =
isolate->factory()->NewSharedFunctionInfoForWasmCapiFunction(fun_data);
......@@ -1904,7 +1905,7 @@ int WasmExportedFunction::function_index() {
Handle<WasmExportedFunction> WasmExportedFunction::New(
Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index,
int arity, Handle<Code> export_wrapper) {
int arity, Handle<CodeT> export_wrapper) {
DCHECK(
CodeKind::JS_TO_WASM_FUNCTION == export_wrapper->kind() ||
(export_wrapper->is_builtin() &&
......@@ -2042,8 +2043,9 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
}
// TODO(wasm): Think about caching and sharing the JS-to-JS wrappers per
// signature instead of compiling a new one for every instantiation.
Handle<Code> wrapper_code =
compiler::CompileJSToJSWrapper(isolate, sig, nullptr).ToHandleChecked();
Handle<CodeT> wrapper_code = ToCodeT(
compiler::CompileJSToJSWrapper(isolate, sig, nullptr).ToHandleChecked(),
isolate);
// WasmJSFunctions use on-heap Code objects as call targets, so we can't
// cache the target address, unless the WasmJSFunction wraps a
......@@ -2075,9 +2077,10 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
}
// TODO(wasm): Think about caching and sharing the wasm-to-JS wrappers per
// signature instead of compiling a new one for every instantiation.
Handle<Code> wasm_to_js_wrapper_code =
Handle<CodeT> wasm_to_js_wrapper_code = ToCodeT(
compiler::CompileWasmToJSWrapper(isolate, sig, kind, expected_arity)
.ToHandleChecked();
.ToHandleChecked(),
isolate);
function_data->internal().set_code(*wasm_to_js_wrapper_code);
}
......
......@@ -597,7 +597,7 @@ class WasmExportedFunction : public JSFunction {
V8_EXPORT_PRIVATE static Handle<WasmExportedFunction> New(
Isolate* isolate, Handle<WasmInstanceObject> instance, int func_index,
int arity, Handle<Code> export_wrapper);
int arity, Handle<CodeT> export_wrapper);
Address GetWasmCallTarget();
......@@ -693,7 +693,6 @@ class WasmFunctionData
: public TorqueGeneratedWasmFunctionData<WasmFunctionData, HeapObject> {
public:
DECL_ACCESSORS(internal, WasmInternalFunction)
DECL_ACCESSORS(wrapper_code, Code)
DECL_PRINTER(WasmFunctionData)
......@@ -736,8 +735,6 @@ class WasmInternalFunction
: public TorqueGeneratedWasmInternalFunction<WasmInternalFunction,
Foreign> {
public:
DECL_ACCESSORS(code, Code)
// Returns a handle to the corresponding WasmInternalFunction if {external} is
// a WasmExternalFunction, or an empty handle otherwise.
static MaybeHandle<WasmInternalFunction> FromExternal(Handle<Object> external,
......@@ -749,9 +746,6 @@ class WasmInternalFunction
class BodyDescriptor;
TQ_OBJECT_CONSTRUCTORS(WasmInternalFunction)
private:
DECL_ACCESSORS(raw_code, CodeT)
};
// Information for a WasmJSFunction which is referenced as the function data of
......@@ -761,7 +755,7 @@ class WasmJSFunctionData
: public TorqueGeneratedWasmJSFunctionData<WasmJSFunctionData,
WasmFunctionData> {
public:
DECL_ACCESSORS(wasm_to_js_wrapper_code, Code)
DECL_ACCESSORS(wasm_to_js_wrapper_code, CodeT)
// Dispatched behavior.
DECL_PRINTER(WasmJSFunctionData)
......
......@@ -1821,9 +1821,8 @@ WASM_COMPILED_EXEC_TEST(FunctionRefs) {
Handle<WasmInternalFunction>::cast(result_cast_reference)->external(),
tester.isolate()));
// TODO(v8:11880): avoid roundtrips between cdc and code.
CHECK_EQ(FromCodeT(cast_function->code()).raw_instruction_start(),
FromCodeT(cast_function_reference->code()).raw_instruction_start());
CHECK_EQ(cast_function->code().raw_instruction_start(),
cast_function_reference->code().raw_instruction_start());
tester.CheckResult(test, 1);
tester.CheckResult(test_fail_1, 0);
......
......@@ -32,12 +32,12 @@ Handle<WasmInstanceObject> CompileModule(Zone* zone, Isolate* isolate,
return maybe_instance.ToHandleChecked();
}
bool IsGeneric(Code wrapper) {
bool IsGeneric(CodeT wrapper) {
return wrapper.is_builtin() &&
wrapper.builtin_id() == Builtin::kGenericJSToWasmWrapper;
}
bool IsSpecific(Code wrapper) {
bool IsSpecific(CodeT wrapper) {
return wrapper.kind() == CodeKind::JS_TO_WASM_FUNCTION;
}
......@@ -153,11 +153,10 @@ TEST(WrapperReplacement) {
// Call the exported Wasm function as many times as required to almost
// exhaust the remaining budget for using the generic wrapper.
Handle<Code> wrapper_before_call;
Handle<CodeT> wrapper_before_call;
for (int i = remaining_budget; i > 0; --i) {
// Verify that the wrapper to be used is the generic one.
wrapper_before_call =
Handle<Code>(main_function_data->wrapper_code(), isolate);
wrapper_before_call = handle(main_function_data->wrapper_code(), isolate);
CHECK(IsGeneric(*wrapper_before_call));
// Call the function.
Handle<Object> params[1] = {SmiHandle(isolate, i)};
......@@ -167,7 +166,7 @@ TEST(WrapperReplacement) {
}
// Get the wrapper-code object after the wrapper replacement.
Code wrapper_after_call = main_function_data->wrapper_code();
CodeT wrapper_after_call = main_function_data->wrapper_code();
// Verify that the budget has been exhausted.
CHECK_EQ(main_function_data->wrapper_budget(), 0);
......
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