[wasm-c-api][ptr-compr] Fix call target caching

The previous pseudo-smi storage scheme for caching call target
addresses in a struct without requiring a custom visitor only
works on uncompressed 64-bit platforms. This patch fixes other
platforms (natural or compressed 32-bit) by boxing the address
in a Foreign.

Change-Id: I3c182c1d9ccae4858cac2757fc3daa40d1520998
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1771780
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63422}
This commit is contained in:
Jakob Kummerow 2019-08-28 14:03:58 +02:00 committed by Commit Bot
parent e955efd524
commit db5ebb2d8a
4 changed files with 30 additions and 10 deletions

View File

@ -986,7 +986,7 @@ extern class WasmExportedFunctionData extends Struct {
// The remaining fields are for fast calling from C++. The contract is
// that they are lazily populated, and either all will be present or none.
c_wrapper_code: Object;
wasm_call_target: Smi; // Pseudo-smi: one-bit shift on all platforms.
wasm_call_target: Smi | Foreign;
packed_args_size: Smi;
}

View File

@ -1354,6 +1354,26 @@ i::Handle<i::Object> WasmRefToV8(i::Isolate* isolate, const Ref* ref) {
return impl(ref)->v8_object();
}
i::Handle<i::Object> CallTargetForCaching(i::Isolate* isolate,
i::Address real_call_target) {
if (i::kTaggedSize == i::kInt32Size) {
return isolate->factory()->NewForeign(real_call_target);
} else {
// 64-bit uncompressed platform.
return i::handle(i::Smi((real_call_target << i::kSmiTagSize) | i::kSmiTag),
isolate);
}
}
i::Address CallTargetFromCache(i::Object cached_call_target) {
if (i::kTaggedSize == i::kInt32Size) {
return i::Foreign::cast(cached_call_target).foreign_address();
} else {
// 64-bit uncompressed platform.
return cached_call_target.ptr() >> i::kSmiTagSize;
}
}
void PrepareFunctionData(i::Isolate* isolate,
i::Handle<i::WasmExportedFunctionData> function_data,
i::wasm::FunctionSig* sig) {
@ -1366,12 +1386,12 @@ void PrepareFunctionData(i::Isolate* isolate,
// Compute packed args size.
function_data->set_packed_args_size(
i::wasm::CWasmArgumentsPacker::TotalSize(sig));
// Get call target (function table offset). This is an Address, we store
// it as a pseudo-Smi by shifting it by one bit, so the GC leaves it alone.
i::Address call_target =
function_data->instance().GetCallTarget(function_data->function_index());
i::Smi smi_target((call_target << i::kSmiTagSize) | i::kSmiTag);
function_data->set_wasm_call_target(smi_target);
// Get call target (function table offset), and wrap it as a cacheable object
// (pseudo-Smi or Foreign, depending on platform).
i::Handle<i::Object> call_target = CallTargetForCaching(
isolate,
function_data->instance().GetCallTarget(function_data->function_index()));
function_data->set_wasm_call_target(*call_target);
}
void PushArgs(i::wasm::FunctionSig* sig, const Val args[],
@ -1495,7 +1515,7 @@ auto Func::call(const Val args[], Val results[]) const -> own<Trap> {
i::Handle<i::Code> wrapper_code = i::Handle<i::Code>(
i::Code::cast(function_data->c_wrapper_code()), isolate);
i::Address call_target =
function_data->wasm_call_target().ptr() >> i::kSmiTagSize;
CallTargetFromCache(function_data->wasm_call_target());
i::wasm::CWasmArgumentsPacker packer(function_data->packed_args_size());
PushArgs(sig, args, &packer, store);

View File

@ -324,7 +324,7 @@ SMI_ACCESSORS(WasmExportedFunctionData, jump_table_offset,
kJumpTableOffsetOffset)
SMI_ACCESSORS(WasmExportedFunctionData, function_index, kFunctionIndexOffset)
ACCESSORS(WasmExportedFunctionData, c_wrapper_code, Object, kCWrapperCodeOffset)
ACCESSORS(WasmExportedFunctionData, wasm_call_target, Smi,
ACCESSORS(WasmExportedFunctionData, wasm_call_target, Object,
kWasmCallTargetOffset)
SMI_ACCESSORS(WasmExportedFunctionData, packed_args_size, kPackedArgsSizeOffset)

View File

@ -792,7 +792,7 @@ class WasmExportedFunctionData : public Struct {
DECL_INT_ACCESSORS(jump_table_offset)
DECL_INT_ACCESSORS(function_index)
DECL_ACCESSORS(c_wrapper_code, Object)
DECL_ACCESSORS(wasm_call_target, Smi)
DECL_ACCESSORS(wasm_call_target, Object)
DECL_INT_ACCESSORS(packed_args_size)
DECL_CAST(WasmExportedFunctionData)