зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1661256 part 14 - Add typed callWithABI functions calls for computed function pointer. r=jandem
Differential Revision: https://phabricator.services.mozilla.com/D91794
This commit is contained in:
Родитель
f91e2f9be9
Коммит
091ec266a9
|
@ -81,6 +81,10 @@ namespace jit {
|
|||
#define ABIFUNCTION_AND_TYPE_LIST(_) \
|
||||
_(JS::ToInt32, int32_t (*)(double))
|
||||
|
||||
// List of all ABI function signature which are using a computed function
|
||||
// pointer instead of a statically known function pointer.
|
||||
#define ABIFUNCTIONSIG_LIST(_) \
|
||||
|
||||
// GCC warns when the signature does not have matching attributes (for example
|
||||
// MOZ_MUST_USE). Squelch this warning to avoid a GCC-only footgun.
|
||||
#if MOZ_IS_GCC
|
||||
|
@ -106,6 +110,15 @@ ABIFUNCTION_LIST(DEF_TEMPLATE)
|
|||
ABIFUNCTION_AND_TYPE_LIST(DEF_TEMPLATE)
|
||||
#undef DEF_TEMPLATE
|
||||
|
||||
// Define a known list of function signatures.
|
||||
#define DEF_TEMPLATE(...) \
|
||||
template <> \
|
||||
struct ABIFunctionSignatureData<__VA_ARGS__> { \
|
||||
static constexpr bool registered = true; \
|
||||
};
|
||||
ABIFUNCTIONSIG_LIST(DEF_TEMPLATE)
|
||||
#undef DEF_TEMPLATE
|
||||
|
||||
#if MOZ_IS_GCC
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,37 @@ struct ABIFunction {
|
|||
"ABI function is not registered.");
|
||||
};
|
||||
|
||||
template <typename Sig>
|
||||
struct ABIFunctionSignatureData {
|
||||
static const bool registered = false;
|
||||
};
|
||||
|
||||
template <typename Sig>
|
||||
struct ABIFunctionSignature {
|
||||
void* address(Sig fun) const { return JS_FUNC_TO_DATA_PTR(void*, fun); }
|
||||
|
||||
// If this assertion fails, you are likely in the context of a
|
||||
// `DynamicFunction<Sig>(fn)` call. This error indicates that
|
||||
// ABIFunctionSignature has not been specialized for `Sig` by the time of this
|
||||
// call.
|
||||
//
|
||||
// This can be fixed by adding the function signature to ABIFUNCTIONSIG_LIST
|
||||
// within `ABIFunctionList-inl.h` and to add an `#include` statement of this
|
||||
// header in the file which is making the call to `DynamicFunction<Sig>(fn)`.
|
||||
static_assert(ABIFunctionSignatureData<Sig>::registered,
|
||||
"ABI function signature is not registered.");
|
||||
};
|
||||
|
||||
// This is a structure created to ensure that the dynamically computed
|
||||
// function pointer is well typed.
|
||||
//
|
||||
// It is meant to be created only through DynamicFunction function calls. In
|
||||
// extremelly rare cases, such as VMFunctions, it might be produced as a result
|
||||
// of GetVMFunctionTarget.
|
||||
struct DynFn {
|
||||
void* address;
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <utility>
|
||||
|
||||
#include "builtin/TypedObject.h"
|
||||
#include "jit/ABIFunctions.h"
|
||||
#include "jit/BaselineICList.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "jit/CompileInfo.h"
|
||||
|
@ -273,7 +274,7 @@ class JitRuntime {
|
|||
JitCode* generateDebugTrapHandler(JSContext* cx, DebugTrapHandlerKind kind);
|
||||
|
||||
bool generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
const VMFunctionData& f, DynFn nativeFun,
|
||||
uint32_t* wrapperOffset);
|
||||
|
||||
template <typename IdT>
|
||||
|
|
|
@ -38,6 +38,12 @@
|
|||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
template <typename Sig>
|
||||
DynFn DynamicFunction(Sig fun) {
|
||||
ABIFunctionSignature<Sig> sig;
|
||||
return DynFn{sig.address(fun)};
|
||||
}
|
||||
|
||||
//{{{ check_macroassembler_style
|
||||
// ===============================================================
|
||||
// Stack manipulation functions.
|
||||
|
@ -101,6 +107,12 @@ void MacroAssembler::callWithABI(void* fun, MoveOp::Type result,
|
|||
callWithABINoProfiler(fun, result, check);
|
||||
}
|
||||
|
||||
void MacroAssembler::callWithABI(DynFn fun, MoveOp::Type result,
|
||||
CheckUnsafeCallWithABI check) {
|
||||
AutoProfilerCallInstrumentation profiler(*this);
|
||||
callWithABINoProfiler(fun.address, result, check);
|
||||
}
|
||||
|
||||
template <typename Sig, Sig fun>
|
||||
void MacroAssembler::callWithABI(MoveOp::Type result,
|
||||
CheckUnsafeCallWithABI check) {
|
||||
|
|
|
@ -228,6 +228,12 @@ enum class CheckUnsafeCallWithABI {
|
|||
DontCheckOther,
|
||||
};
|
||||
|
||||
// This is a global function made to create the DynFn type in a controlled
|
||||
// environment which would check if the function signature has been registered
|
||||
// as an ABI function signature.
|
||||
template <typename Sig>
|
||||
static inline DynFn DynamicFunction(Sig fun);
|
||||
|
||||
enum class CharEncoding { Latin1, TwoByte };
|
||||
|
||||
// The public entrypoint for emitting assembly. Note that a MacroAssembler can
|
||||
|
@ -620,6 +626,9 @@ class MacroAssembler : public MacroAssemblerSpecific {
|
|||
inline void callWithABI(
|
||||
void* fun, MoveOp::Type result = MoveOp::GENERAL,
|
||||
CheckUnsafeCallWithABI check = CheckUnsafeCallWithABI::Check);
|
||||
inline void callWithABI(
|
||||
DynFn fun, MoveOp::Type result = MoveOp::GENERAL,
|
||||
CheckUnsafeCallWithABI check = CheckUnsafeCallWithABI::Check);
|
||||
template <typename Sig, Sig fun>
|
||||
inline void callWithABI(
|
||||
MoveOp::Type result = MoveOp::GENERAL,
|
||||
|
|
|
@ -131,12 +131,12 @@ const VMFunctionData& GetVMFunction(TailCallVMFunctionId id) {
|
|||
return tailCallVMFunctions[size_t(id)];
|
||||
}
|
||||
|
||||
static void* GetVMFunctionTarget(VMFunctionId id) {
|
||||
return vmFunctionTargets[size_t(id)];
|
||||
static DynFn GetVMFunctionTarget(VMFunctionId id) {
|
||||
return DynFn{vmFunctionTargets[size_t(id)]};
|
||||
}
|
||||
|
||||
static void* GetVMFunctionTarget(TailCallVMFunctionId id) {
|
||||
return tailCallVMFunctionTargets[size_t(id)];
|
||||
static DynFn GetVMFunctionTarget(TailCallVMFunctionId id) {
|
||||
return DynFn{tailCallVMFunctionTargets[size_t(id)]};
|
||||
}
|
||||
|
||||
template <typename IdT>
|
||||
|
|
|
@ -736,7 +736,7 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
}
|
||||
|
||||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
const VMFunctionData& f, DynFn nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
|
|
|
@ -563,7 +563,7 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
}
|
||||
|
||||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
const VMFunctionData& f, DynFn nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
|
|
|
@ -705,7 +705,7 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
}
|
||||
|
||||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
const VMFunctionData& f, DynFn nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
|
|
|
@ -684,7 +684,7 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
}
|
||||
|
||||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
const VMFunctionData& f, DynFn nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
|
|
|
@ -625,7 +625,7 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
}
|
||||
|
||||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
const VMFunctionData& f, DynFn nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
|
|
|
@ -641,7 +641,7 @@ void JitRuntime::generateBailoutHandler(MacroAssembler& masm,
|
|||
}
|
||||
|
||||
bool JitRuntime::generateVMWrapper(JSContext* cx, MacroAssembler& masm,
|
||||
const VMFunctionData& f, void* nativeFun,
|
||||
const VMFunctionData& f, DynFn nativeFun,
|
||||
uint32_t* wrapperOffset) {
|
||||
*wrapperOffset = startTrampolineCode(masm);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче