Commit 86acc1d0 authored by Maya Lekova's avatar Maya Lekova Committed by V8 LUCI CQ

Revert "[fastcall] Add Wasm entry for Fast API calls"

This reverts commit bd72152e.

Reason for revert: TSAN reports a data race, please see https://ci.chromium.org/ui/p/v8/builders/ci/V8%20Linux64%20TSAN%20-%20isolates/18124/overview

Original change's description:
> [fastcall] Add Wasm entry for Fast API calls
>
> Allow Wasm to generate calls directly to Fast API C functions.
> This massively reduces the overhead of these calls (~300%).
> Currently options parameter is not supported.
>
> This is a rebase of the work originally done by devsnek in:
> https://chromium-review.googlesource.com/c/v8/v8/+/2718666.
>
> Bug: chromium:1052746
> Change-Id: I1bb1de68b440044cc8a4e528adf9d8e0e6692a07
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3364356
> Reviewed-by: Clemens Backes <clemensb@chromium.org>
> Reviewed-by: Manos Koukoutos <manoskouk@chromium.org>
> Reviewed-by: Maya Lekova <mslekova@chromium.org>
> Commit-Queue: Paolo Severini <paolosev@microsoft.com>
> Cr-Commit-Position: refs/heads/main@{#78664}

Bug: chromium:1052746
Change-Id: I957708cf1cff6ee8f90678ee48428f5c12f75a53
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3398121
Auto-Submit: Maya Lekova <mslekova@chromium.org>
Owners-Override: Maya Lekova <mslekova@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#78665}
parent bd72152e
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <iosfwd> #include <iosfwd>
#include "include/v8-fast-api-calls.h"
#include "src/base/bits.h" #include "src/base/bits.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/flags/flags.h" #include "src/flags/flags.h"
...@@ -275,35 +274,6 @@ class MachineType { ...@@ -275,35 +274,6 @@ class MachineType {
} }
} }
static MachineType TypeForCType(const CTypeInfo& type) {
switch (type.GetType()) {
case CTypeInfo::Type::kVoid:
return MachineType::AnyTagged();
case CTypeInfo::Type::kBool:
return MachineType::Bool();
case CTypeInfo::Type::kInt32:
return MachineType::Int32();
case CTypeInfo::Type::kUint32:
return MachineType::Uint32();
case CTypeInfo::Type::kInt64:
return MachineType::Int64();
case CTypeInfo::Type::kAny:
static_assert(
sizeof(AnyCType) == kInt64Size,
"CTypeInfo::Type::kAny is assumed to be of size 64 bits.");
return MachineType::Int64();
case CTypeInfo::Type::kUint64:
return MachineType::Uint64();
case CTypeInfo::Type::kFloat32:
return MachineType::Float32();
case CTypeInfo::Type::kFloat64:
return MachineType::Float64();
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kApiObject:
return MachineType::AnyTagged();
}
}
constexpr bool LessThanOrEqualPointerSize() const { constexpr bool LessThanOrEqualPointerSize() const {
return ElementSizeLog2Of(this->representation()) <= kSystemPointerSizeLog2; return ElementSizeLog2Of(this->representation()) <= kSystemPointerSizeLog2;
} }
......
...@@ -4979,6 +4979,36 @@ void EffectControlLinearizer::LowerStoreMessage(Node* node) { ...@@ -4979,6 +4979,36 @@ void EffectControlLinearizer::LowerStoreMessage(Node* node) {
__ StoreField(AccessBuilder::ForExternalIntPtr(), offset, object_pattern); __ StoreField(AccessBuilder::ForExternalIntPtr(), offset, object_pattern);
} }
namespace {
MachineType MachineTypeFor(CTypeInfo::Type type) {
switch (type) {
case CTypeInfo::Type::kVoid:
return MachineType::AnyTagged();
case CTypeInfo::Type::kBool:
return MachineType::Bool();
case CTypeInfo::Type::kInt32:
return MachineType::Int32();
case CTypeInfo::Type::kUint32:
return MachineType::Uint32();
case CTypeInfo::Type::kInt64:
return MachineType::Int64();
case CTypeInfo::Type::kAny:
static_assert(sizeof(AnyCType) == 8,
"CTypeInfo::Type::kAny is assumed to be of size 64 bits.");
return MachineType::Int64();
case CTypeInfo::Type::kUint64:
return MachineType::Uint64();
case CTypeInfo::Type::kFloat32:
return MachineType::Float32();
case CTypeInfo::Type::kFloat64:
return MachineType::Float64();
case CTypeInfo::Type::kV8Value:
case CTypeInfo::Type::kApiObject:
return MachineType::AnyTagged();
}
}
} // namespace
Node* EffectControlLinearizer::AdaptFastCallTypedArrayArgument( Node* EffectControlLinearizer::AdaptFastCallTypedArrayArgument(
Node* node, ElementsKind expected_elements_kind, Node* node, ElementsKind expected_elements_kind,
GraphAssemblerLabel<0>* bailout) { GraphAssemblerLabel<0>* bailout) {
...@@ -5320,14 +5350,13 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) { ...@@ -5320,14 +5350,13 @@ Node* EffectControlLinearizer::LowerFastApiCall(Node* node) {
MachineSignature::Builder builder( MachineSignature::Builder builder(
graph()->zone(), 1, c_arg_count + (c_signature->HasOptions() ? 1 : 0)); graph()->zone(), 1, c_arg_count + (c_signature->HasOptions() ? 1 : 0));
MachineType return_type = MachineType return_type = MachineTypeFor(c_signature->ReturnInfo().GetType());
MachineType::TypeForCType(c_signature->ReturnInfo());
builder.AddReturn(return_type); builder.AddReturn(return_type);
for (int i = 0; i < c_arg_count; ++i) { for (int i = 0; i < c_arg_count; ++i) {
CTypeInfo type = c_signature->ArgumentInfo(i); CTypeInfo type = c_signature->ArgumentInfo(i);
MachineType machine_type = MachineType machine_type =
type.GetSequenceType() == CTypeInfo::SequenceType::kScalar type.GetSequenceType() == CTypeInfo::SequenceType::kScalar
? MachineType::TypeForCType(type) ? MachineTypeFor(type.GetType())
: MachineType::AnyTagged(); : MachineType::AnyTagged();
builder.AddParam(machine_type); builder.AddParam(machine_type);
} }
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#include "src/compiler/fast-api-calls.h" #include "src/compiler/fast-api-calls.h"
#include "src/compiler/globals.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
...@@ -80,44 +78,6 @@ OverloadsResolutionResult ResolveOverloads( ...@@ -80,44 +78,6 @@ OverloadsResolutionResult ResolveOverloads(
return OverloadsResolutionResult::Invalid(); return OverloadsResolutionResult::Invalid();
} }
bool CanOptimizeFastSignature(const CFunctionInfo* c_signature) {
USE(c_signature);
#ifndef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
if (c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kFloat32 ||
c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kFloat64) {
return false;
}
#endif
#ifndef V8_TARGET_ARCH_64_BIT
if (c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kInt64 ||
c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kUint64) {
return false;
}
#endif
for (unsigned int i = 0; i < c_signature->ArgumentCount(); ++i) {
USE(i);
#ifndef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
if (c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kFloat32 ||
c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kFloat64) {
return false;
}
#endif
#ifndef V8_TARGET_ARCH_64_BIT
if (c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kInt64 ||
c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kUint64) {
return false;
}
#endif
}
return true;
}
} // namespace fast_api_call } // namespace fast_api_call
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
...@@ -42,8 +42,6 @@ OverloadsResolutionResult ResolveOverloads( ...@@ -42,8 +42,6 @@ OverloadsResolutionResult ResolveOverloads(
Zone* zone, const FastApiCallFunctionVector& candidates, Zone* zone, const FastApiCallFunctionVector& candidates,
unsigned int arg_count); unsigned int arg_count);
bool CanOptimizeFastSignature(const CFunctionInfo* c_signature);
} // namespace fast_api_call } // namespace fast_api_call
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <functional> #include <functional>
#include "include/v8-fast-api-calls.h"
#include "src/api/api-inl.h" #include "src/api/api-inl.h"
#include "src/base/small-vector.h" #include "src/base/small-vector.h"
#include "src/builtins/builtins-promise.h" #include "src/builtins/builtins-promise.h"
...@@ -18,7 +19,6 @@ ...@@ -18,7 +19,6 @@
#include "src/compiler/allocation-builder.h" #include "src/compiler/allocation-builder.h"
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/compilation-dependencies.h" #include "src/compiler/compilation-dependencies.h"
#include "src/compiler/fast-api-calls.h"
#include "src/compiler/feedback-source.h" #include "src/compiler/feedback-source.h"
#include "src/compiler/graph-assembler.h" #include "src/compiler/graph-assembler.h"
#include "src/compiler/js-graph.h" #include "src/compiler/js-graph.h"
...@@ -3518,6 +3518,42 @@ Reduction JSCallReducer::ReduceCallWasmFunction( ...@@ -3518,6 +3518,42 @@ Reduction JSCallReducer::ReduceCallWasmFunction(
} }
#endif // V8_ENABLE_WEBASSEMBLY #endif // V8_ENABLE_WEBASSEMBLY
#ifndef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
namespace {
bool HasFPParamsInSignature(const CFunctionInfo* c_signature) {
if (c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kFloat32 ||
c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kFloat64) {
return true;
}
for (unsigned int i = 0; i < c_signature->ArgumentCount(); ++i) {
if (c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kFloat32 ||
c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kFloat64) {
return true;
}
}
return false;
}
} // namespace
#endif
#ifndef V8_TARGET_ARCH_64_BIT
namespace {
bool Has64BitIntegerParamsInSignature(const CFunctionInfo* c_signature) {
if (c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kInt64 ||
c_signature->ReturnInfo().GetType() == CTypeInfo::Type::kUint64) {
return true;
}
for (unsigned int i = 0; i < c_signature->ArgumentCount(); ++i) {
if (c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kInt64 ||
c_signature->ArgumentInfo(i).GetType() == CTypeInfo::Type::kUint64) {
return true;
}
}
return false;
}
} // namespace
#endif
// Given a FunctionTemplateInfo, checks whether the fast API call can be // Given a FunctionTemplateInfo, checks whether the fast API call can be
// optimized, applying the initial step of the overload resolution algorithm: // optimized, applying the initial step of the overload resolution algorithm:
// Given an overload set function_template_info.c_signatures, and a list of // Given an overload set function_template_info.c_signatures, and a list of
...@@ -3562,9 +3598,16 @@ FastApiCallFunctionVector CanOptimizeFastCall( ...@@ -3562,9 +3598,16 @@ FastApiCallFunctionVector CanOptimizeFastCall(
const size_t len = c_signature->ArgumentCount() - kReceiver; const size_t len = c_signature->ArgumentCount() - kReceiver;
bool optimize_to_fast_call = (len == arg_count); bool optimize_to_fast_call = (len == arg_count);
#ifndef V8_ENABLE_FP_PARAMS_IN_C_LINKAGE
optimize_to_fast_call = optimize_to_fast_call =
optimize_to_fast_call && optimize_to_fast_call && !HasFPParamsInSignature(c_signature);
fast_api_call::CanOptimizeFastSignature(c_signature); #else
USE(c_signature);
#endif
#ifndef V8_TARGET_ARCH_64_BIT
optimize_to_fast_call =
optimize_to_fast_call && !Has64BitIntegerParamsInSignature(c_signature);
#endif
if (optimize_to_fast_call) { if (optimize_to_fast_call) {
result.push_back({functions[i], c_signature}); result.push_back({functions[i], c_signature});
......
This diff is collapsed.
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
// Clients of this interface shouldn't depend on lots of compiler internals. // Clients of this interface shouldn't depend on lots of compiler internals.
// Do not include anything from src/compiler here! // Do not include anything from src/compiler here!
#include "src/base/small-vector.h" #include "src/base/small-vector.h"
#include "src/objects/js-function.h"
#include "src/runtime/runtime.h" #include "src/runtime/runtime.h"
#include "src/wasm/function-body-decoder.h" #include "src/wasm/function-body-decoder.h"
#include "src/wasm/function-compiler.h" #include "src/wasm/function-compiler.h"
...@@ -73,7 +72,6 @@ enum class WasmImportCallKind : uint8_t { ...@@ -73,7 +72,6 @@ enum class WasmImportCallKind : uint8_t {
kLinkError, // static Wasm->Wasm type error kLinkError, // static Wasm->Wasm type error
kRuntimeTypeError, // runtime Wasm->JS type error kRuntimeTypeError, // runtime Wasm->JS type error
kWasmToCapi, // fast Wasm->C-API call kWasmToCapi, // fast Wasm->C-API call
kWasmToJSFastApi, // fast Wasm->JS Fast API C call
kWasmToWasm, // fast Wasm->Wasm call kWasmToWasm, // fast Wasm->Wasm call
kJSFunctionArityMatch, // fast Wasm->JS call kJSFunctionArityMatch, // fast Wasm->JS call
kJSFunctionArityMismatch, // Wasm->JS, needs adapter frame kJSFunctionArityMismatch, // Wasm->JS, needs adapter frame
...@@ -133,11 +131,6 @@ V8_EXPORT_PRIVATE wasm::WasmCompilationResult CompileWasmImportCallWrapper( ...@@ -133,11 +131,6 @@ V8_EXPORT_PRIVATE wasm::WasmCompilationResult CompileWasmImportCallWrapper(
wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::NativeModule*, wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::NativeModule*,
const wasm::FunctionSig*); const wasm::FunctionSig*);
// Compiles a wrapper to call a Fast API function from Wasm.
wasm::WasmCode* CompileWasmJSFastCallWrapper(wasm::NativeModule*,
const wasm::FunctionSig*,
Handle<JSFunction> target);
// Returns an OptimizedCompilationJob object for a JS to Wasm wrapper. // Returns an OptimizedCompilationJob object for a JS to Wasm wrapper.
std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob( std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob(
Isolate* isolate, const wasm::FunctionSig* sig, Isolate* isolate, const wasm::FunctionSig* sig,
......
...@@ -39,8 +39,6 @@ namespace { ...@@ -39,8 +39,6 @@ namespace {
class FastCApiObject { class FastCApiObject {
public: public:
static FastCApiObject& instance();
#ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS #ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
static AnyCType AddAllFastCallbackPatch(AnyCType receiver, static AnyCType AddAllFastCallbackPatch(AnyCType receiver,
AnyCType should_fallback, AnyCType should_fallback,
...@@ -77,37 +75,6 @@ class FastCApiObject { ...@@ -77,37 +75,6 @@ class FastCApiObject {
static_cast<double>(arg_i64) + static_cast<double>(arg_u64) + static_cast<double>(arg_i64) + static_cast<double>(arg_u64) +
static_cast<double>(arg_f32) + arg_f64; static_cast<double>(arg_f32) + arg_f64;
} }
#ifdef V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
static AnyCType AddAllFastCallbackNoOptionsPatch(
AnyCType receiver, AnyCType should_fallback, AnyCType arg_i32,
AnyCType arg_u32, AnyCType arg_i64, AnyCType arg_u64, AnyCType arg_f32,
AnyCType arg_f64) {
AnyCType ret;
ret.double_value = AddAllFastCallbackNoOptions(
receiver.object_value, should_fallback.bool_value, arg_i32.int32_value,
arg_u32.uint32_value, arg_i64.int64_value, arg_u64.uint64_value,
arg_f32.float_value, arg_f64.double_value);
return ret;
}
#endif // V8_USE_SIMULATOR_WITH_GENERIC_C_CALLS
static double AddAllFastCallbackNoOptions(Local<Object> receiver,
bool should_fallback,
int32_t arg_i32, uint32_t arg_u32,
int64_t arg_i64, uint64_t arg_u64,
float arg_f32, double arg_f64) {
// For Wasm call, we don't pass FastCApiObject as the receiver, so we need
// to retrieve the FastCApiObject instance from a static variable.
DCHECK(Utils::OpenHandle(*receiver)->IsJSGlobalProxy() ||
Utils::OpenHandle(*receiver)->IsUndefined());
static FastCApiObject& self = FastCApiObject::instance();
self.fast_call_count_++;
return static_cast<double>(arg_i32) + static_cast<double>(arg_u32) +
static_cast<double>(arg_i64) + static_cast<double>(arg_u64) +
static_cast<double>(arg_f32) + arg_f64;
}
static void AddAllSlowCallback(const FunctionCallbackInfo<Value>& args) { static void AddAllSlowCallback(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate(); Isolate* isolate = args.GetIsolate();
...@@ -653,9 +620,6 @@ class FastCApiObject { ...@@ -653,9 +620,6 @@ class FastCApiObject {
thread_local FastCApiObject kFastCApiObject; thread_local FastCApiObject kFastCApiObject;
} // namespace } // namespace
// static
FastCApiObject& FastCApiObject::instance() { return kFastCApiObject; }
void CreateFastCAPIObject(const FunctionCallbackInfo<Value>& info) { void CreateFastCAPIObject(const FunctionCallbackInfo<Value>& info) {
if (!info.IsConstructCall()) { if (!info.IsConstructCall()) {
info.GetIsolate()->ThrowError( info.GetIsolate()->ThrowError(
...@@ -801,7 +765,6 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) { ...@@ -801,7 +765,6 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
FastCApiObject::AddAll32BitIntFastCallback_5ArgsPatch)); FastCApiObject::AddAll32BitIntFastCallback_5ArgsPatch));
const CFunction c_function_overloads[] = {add_all_32bit_int_6args_c_func, const CFunction c_function_overloads[] = {add_all_32bit_int_6args_c_func,
add_all_32bit_int_5args_c_func}; add_all_32bit_int_5args_c_func};
api_obj_ctor->PrototypeTemplate()->Set( api_obj_ctor->PrototypeTemplate()->Set(
isolate, "overloaded_add_all_32bit_int", isolate, "overloaded_add_all_32bit_int",
FunctionTemplate::NewWithCFunctionOverloads( FunctionTemplate::NewWithCFunctionOverloads(
...@@ -809,16 +772,6 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) { ...@@ -809,16 +772,6 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
signature, 1, ConstructorBehavior::kThrow, signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, {c_function_overloads, 2})); SideEffectType::kHasSideEffect, {c_function_overloads, 2}));
CFunction add_all_no_options_c_func = CFunction::Make(
FastCApiObject::AddAllFastCallbackNoOptions V8_IF_USE_SIMULATOR(
FastCApiObject::AddAllFastCallbackNoOptionsPatch));
api_obj_ctor->PrototypeTemplate()->Set(
isolate, "add_all_no_options",
FunctionTemplate::New(
isolate, FastCApiObject::AddAllSlowCallback, Local<Value>(),
Local<Signature>(), 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &add_all_no_options_c_func));
CFunction add_32bit_int_c_func = CFunction::Make( CFunction add_32bit_int_c_func = CFunction::Make(
FastCApiObject::Add32BitIntFastCallback V8_IF_USE_SIMULATOR( FastCApiObject::Add32BitIntFastCallback V8_IF_USE_SIMULATOR(
FastCApiObject::Add32BitIntFastCallbackPatch)); FastCApiObject::Add32BitIntFastCallbackPatch));
...@@ -828,7 +781,6 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) { ...@@ -828,7 +781,6 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
isolate, FastCApiObject::Add32BitIntSlowCallback, Local<Value>(), isolate, FastCApiObject::Add32BitIntSlowCallback, Local<Value>(),
signature, 1, ConstructorBehavior::kThrow, signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &add_32bit_int_c_func)); SideEffectType::kHasSideEffect, &add_32bit_int_c_func));
CFunction is_valid_api_object_c_func = CFunction is_valid_api_object_c_func =
CFunction::Make(FastCApiObject::IsFastCApiObjectFastCallback); CFunction::Make(FastCApiObject::IsFastCApiObjectFastCallback);
api_obj_ctor->PrototypeTemplate()->Set( api_obj_ctor->PrototypeTemplate()->Set(
...@@ -837,7 +789,6 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) { ...@@ -837,7 +789,6 @@ Local<FunctionTemplate> Shell::CreateTestFastCApiTemplate(Isolate* isolate) {
isolate, FastCApiObject::IsFastCApiObjectSlowCallback, isolate, FastCApiObject::IsFastCApiObjectSlowCallback,
Local<Value>(), signature, 1, ConstructorBehavior::kThrow, Local<Value>(), signature, 1, ConstructorBehavior::kThrow,
SideEffectType::kHasSideEffect, &is_valid_api_object_c_func)); SideEffectType::kHasSideEffect, &is_valid_api_object_c_func));
api_obj_ctor->PrototypeTemplate()->Set( api_obj_ctor->PrototypeTemplate()->Set(
isolate, "fast_call_count", isolate, "fast_call_count",
FunctionTemplate::New( FunctionTemplate::New(
......
...@@ -1197,19 +1197,6 @@ bool InstanceBuilder::ProcessImportedFunction( ...@@ -1197,19 +1197,6 @@ bool InstanceBuilder::ProcessImportedFunction(
isolate_->factory()->undefined_value()); isolate_->factory()->undefined_value());
break; break;
} }
case compiler::WasmImportCallKind::kWasmToJSFastApi: {
NativeModule* native_module = instance->module_object().native_module();
DCHECK(js_receiver->IsJSFunction());
Handle<JSFunction> function = Handle<JSFunction>::cast(js_receiver);
WasmCodeRefScope code_ref_scope;
WasmCode* wasm_code = compiler::CompileWasmJSFastCallWrapper(
native_module, expected_sig, function);
ImportedFunctionEntry entry(instance, func_index);
entry.SetWasmToJs(isolate_, js_receiver, wasm_code,
isolate_->factory()->undefined_value());
break;
}
default: { default: {
// The imported function is a callable. // The imported function is a callable.
...@@ -1624,8 +1611,7 @@ void InstanceBuilder::CompileImportWrappers( ...@@ -1624,8 +1611,7 @@ void InstanceBuilder::CompileImportWrappers(
compiler::WasmImportCallKind kind = resolved.kind; compiler::WasmImportCallKind kind = resolved.kind;
if (kind == compiler::WasmImportCallKind::kWasmToWasm || if (kind == compiler::WasmImportCallKind::kWasmToWasm ||
kind == compiler::WasmImportCallKind::kLinkError || kind == compiler::WasmImportCallKind::kLinkError ||
kind == compiler::WasmImportCallKind::kWasmToCapi || kind == compiler::WasmImportCallKind::kWasmToCapi) {
kind == compiler::WasmImportCallKind::kWasmToJSFastApi) {
continue; continue;
} }
......
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --turbo-fast-api-calls --expose-fast-api
load('test/mjsunit/wasm/wasm-module-builder.js');
assertThrows(() => d8.test.FastCAPI());
const fast_c_api = new d8.test.FastCAPI();
function buildWasm(name, sig, body) {
const builder = new WasmModuleBuilder();
const add_all_no_options = builder.addImport(
'fast_c_api',
'add_all_no_options',
makeSig(
[kWasmI32, kWasmI32, kWasmI32, kWasmI64, kWasmI64, kWasmF32, kWasmF64],
[kWasmF64],
),
);
const add_all_no_options_mismatch = builder.addImport(
'fast_c_api',
'add_all_no_options',
makeSig(
[kWasmI32, kWasmI32, kWasmI32, kWasmI64, kWasmF32, kWasmI64, kWasmF64],
[kWasmF64],
),
);
const add_all_nested_bound = builder.addImport(
'fast_c_api',
'add_all_nested_bound',
makeSig(
[kWasmI32, kWasmI32, kWasmI32, kWasmI64, kWasmI64, kWasmF32, kWasmF64],
[kWasmF64],
),
);
builder
.addFunction(name, sig)
.addBody(body({
add_all_no_options,
add_all_no_options_mismatch,
add_all_nested_bound,
}))
.exportFunc();
const x = {};
const module = builder.instantiate({
fast_c_api: {
add_all_no_options: fast_c_api.add_all_no_options.bind(fast_c_api),
add_all_no_options_mismatch: fast_c_api.add_all_no_options.bind(fast_c_api),
add_all_nested_bound: fast_c_api.add_all_no_options
.bind(fast_c_api)
.bind(x),
},
});
return module.exports[name];
}
// ----------- add_all -----------
// `add_all` has the following signature:
// double add_all(bool /*should_fallback*/, int32_t, uint32_t,
// int64_t, uint64_t, float, double)
const max_safe_float = 2**24 - 1;
const add_all_result = -42 + 45 + Number.MIN_SAFE_INTEGER + Number.MAX_SAFE_INTEGER +
max_safe_float * 0.5 + Math.PI;
const add_all_wasm = buildWasm(
'add_all_wasm', makeSig([], [kWasmF64]),
({ add_all_no_options }) => [
...wasmI32Const(0),
...wasmI32Const(-42),
...wasmI32Const(45),
kExprI64Const, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x70, // Number.MIN_SAFE_INTEGER
kExprI64Const, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, // Number.MAX_SAFE_INTEGER
...wasmF32Const(max_safe_float * 0.5),
...wasmF64Const(Math.PI),
kExprCallFunction, add_all_no_options,
kExprReturn,
],
);
if (fast_c_api.supports_fp_params) {
// Test wasm hits fast path.
fast_c_api.reset_counts();
assertEquals(add_all_result, add_all_wasm());
assertEquals(1, fast_c_api.fast_call_count());
assertEquals(0, fast_c_api.slow_call_count());
} else {
// Test wasm hits slow path.
fast_c_api.reset_counts();
assertEquals(add_all_result, add_all_wasm());
assertEquals(0, fast_c_api.fast_call_count());
assertEquals(1, fast_c_api.slow_call_count());
}
// ----------- Test add_all signature mismatch -----------
const add_all_mismatch_wasm = buildWasm(
'add_all_mismatch_wasm', makeSig([], [kWasmF64]),
({ add_all_no_options_mismatch }) => [
...wasmI32Const(0),
...wasmI32Const(45),
...wasmI32Const(-42),
kExprI64Const, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, // Number.MAX_SAFE_INTEGER
...wasmF32Const(max_safe_float * 0.5),
kExprI64Const, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x70, // Number.MIN_SAFE_INTEGER
...wasmF64Const(Math.PI),
kExprCallFunction, add_all_no_options_mismatch,
kExprReturn,
],
);
// Test that wasm takes slow path.
fast_c_api.reset_counts();
add_all_mismatch_wasm();
assertEquals(0, fast_c_api.fast_call_count());
assertEquals(1, fast_c_api.slow_call_count());
// ----------- Test add_all nested bound function -----------
const add_all_nested_bound_wasm = buildWasm(
'add_all_nested_bound_wasm', makeSig([], [kWasmF64]),
({ add_all_nested_bound }) => [
...wasmI32Const(0),
...wasmI32Const(-42),
...wasmI32Const(45),
kExprI64Const, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x70, // Number.MIN_SAFE_INTEGER
kExprI64Const, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, // Number.MAX_SAFE_INTEGER
...wasmF32Const(max_safe_float * 0.5),
...wasmF64Const(Math.PI),
kExprCallFunction, add_all_nested_bound,
kExprReturn,
],
);
// Test wasm hits slow path.
fast_c_api.reset_counts();
assertEquals(add_all_result, add_all_nested_bound_wasm());
assertEquals(0, fast_c_api.fast_call_count());
assertEquals(1, fast_c_api.slow_call_count());
...@@ -472,8 +472,6 @@ ...@@ -472,8 +472,6 @@
# Tests tracing when generating wasm in TurboFan. # Tests tracing when generating wasm in TurboFan.
'tools/compiler-trace-flags-wasm': [SKIP], 'tools/compiler-trace-flags-wasm': [SKIP],
'compiler/fast-api-calls-wasm': [SKIP],
}], # not has_webassembly or variant == jitless }], # not has_webassembly or variant == jitless
############################################################################## ##############################################################################
......
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