diff --git a/js/src/jit/LoongArchMinimalJit.cpp b/js/src/jit/LoongArchMinimalJit.cpp index 75ea23b914..9b5ca7ea09 100644 --- a/js/src/jit/LoongArchMinimalJit.cpp +++ b/js/src/jit/LoongArchMinimalJit.cpp @@ -16,6 +16,7 @@ #include "jsopcode.h" #include "jsscript.h" #include "vm/Interpreter.h" +#include "vm/Stack.h" using namespace js; @@ -563,6 +564,34 @@ CanUseMinimalJit(JSScript* script, const CallArgs& args) return true; } +static bool +CanDirectCallMinimalJit(JSContext* cx, HandleFunction fun, JSScript* script, const CallArgs& args) +{ + if (!fun || !fun->isInterpreted() || !script) + return false; + + if (!CanUseMinimalJit(script, args)) + return false; + + if (fun->isSelfHostedBuiltin() || fun->isArrow() || fun->needsSomeEnvironmentObject()) + return false; + + if (script->selfHosted() || script->strict() || script->treatAsRunOnce()) + return false; + + if (cx->compartment()->isDebuggee() || cx->runtime()->profilingScripts || + cx->runtime()->spsProfiler.enabled()) + { + return false; + } + + Activation* activation = cx->runtime()->activation(); + if (!activation || !activation->isInterpreter()) + return false; + + return true; +} + static bool CanUseMinimalJit(RunState& state, InvokeState& invoke) { @@ -612,6 +641,30 @@ LookupOrCompileMinimalJit(JSContext* cx, JSScript* script, TinyLoongArchJitCode* } // namespace +bool +TryCallLoongArchMinimalJit(JSContext* cx, HandleFunction fun, const CallArgs& args, bool* handled) +{ + *handled = false; + + JSScript* script = fun ? fun->nonLazyScript() : nullptr; + if (!CanDirectCallMinimalJit(cx, fun, script, args)) + return true; + + TinyLoongArchJitCode fn; + if (!LookupOrCompileMinimalJit(cx, script, &fn)) + return true; + + int32_t result = 0; + int32_t arg0 = script->numArgs() >= 1 ? args[0].toInt32() : 0; + int32_t arg1 = script->numArgs() >= 2 ? args[1].toInt32() : 0; + if (!fn(arg0, arg1, &result)) + return true; + + args.rval().setInt32(result); + *handled = true; + return true; +} + bool TryEnterLoongArchMinimalJit(JSContext* cx, RunState& state) { diff --git a/js/src/jit/LoongArchMinimalJit.h b/js/src/jit/LoongArchMinimalJit.h index 81e5084559..f814075d97 100644 --- a/js/src/jit/LoongArchMinimalJit.h +++ b/js/src/jit/LoongArchMinimalJit.h @@ -7,6 +7,7 @@ #define jit_LoongArchMinimalJit_h #include "jspubtd.h" +#include "js/CallArgs.h" namespace js { @@ -15,6 +16,7 @@ class RunState; namespace jit { [[nodiscard]] bool TryEnterLoongArchMinimalJit(JSContext* cx, RunState& state); +[[nodiscard]] bool TryCallLoongArchMinimalJit(JSContext* cx, HandleFunction fun, const CallArgs& args, bool* handled); } // namespace jit } // namespace js diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 77bc861ee8..fef8f61f29 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -503,6 +503,14 @@ js::InternalCallOrConstruct(JSContext* cx, const CallArgs& args, MaybeConstruct if (!JSFunction::getOrCreateScript(cx, fun)) return false; + if (construct != CONSTRUCT) { + bool handled; + if (!jit::TryCallLoongArchMinimalJit(cx, fun, args, &handled)) + return false; + if (handled) + return true; + } + /* Run function until JSOP_RETRVAL, JSOP_RETURN or error. */ InvokeState state(cx, args, construct);