Issue #3049 - Cache minimal JIT code on JSScript

This commit is contained in:
Basilisk-Dev 2026-04-16 00:01:33 -04:00 committed by wuggy
commit a48c1edbde
3 changed files with 23 additions and 46 deletions

View file

@ -10,7 +10,6 @@
#include "mozilla/ArrayUtils.h"
#include "jit/ProcessExecutableMemory.h"
#include "js/HashTable.h"
#include "js/Vector.h"
#include "js/Value.h"
#include "jsopcode.h"
@ -150,34 +149,6 @@ struct BranchPatch
LoongArchReg reg;
};
struct CachedJitCode
{
TinyLoongArchJitCode fn;
uint8_t* code;
};
using MinimalJitCache = HashMap<JSScript*, CachedJitCode, DefaultHasher<JSScript*>, SystemAllocPolicy>;
static MinimalJitCache*
GetMinimalJitCache()
{
static MinimalJitCache* cache;
if (cache)
return cache;
cache = js_new<MinimalJitCache>();
if (!cache)
return nullptr;
if (!cache->init()) {
js_delete(cache);
cache = nullptr;
return nullptr;
}
return cache;
}
class MinimalLoongArchCompiler
{
JSScript* script_;
@ -604,12 +575,8 @@ CanUseMinimalJit(RunState& state, InvokeState& invoke)
static bool
LookupOrCompileMinimalJit(JSContext* cx, JSScript* script, TinyLoongArchJitCode* fnOut)
{
MinimalJitCache* cache = GetMinimalJitCache();
if (!cache)
return false;
if (MinimalJitCache::Ptr entry = cache->lookup(script)) {
*fnOut = entry->value().fn;
if (uint8_t* code = script->loongArchMinimalJitCodeRaw()) {
*fnOut = JS_DATA_TO_FUNC_PTR(TinyLoongArchJitCode, code);
return true;
}
@ -625,17 +592,9 @@ LookupOrCompileMinimalJit(JSContext* cx, JSScript* script, TinyLoongArchJitCode*
if (!code.makeExecutable())
return false;
CachedJitCode compiled = {
JS_DATA_TO_FUNC_PTR(TinyLoongArchJitCode, code.bytes()),
code.release()
};
if (!cache->put(script, compiled)) {
DeallocateExecutableMemory(compiled.code, compiler.codeSize());
return false;
}
*fnOut = compiled.fn;
uint8_t* raw = code.release();
script->setLoongArchMinimalJitCode(raw, uint32_t(compiler.codeSize()));
*fnOut = JS_DATA_TO_FUNC_PTR(TinyLoongArchJitCode, raw);
return true;
}

View file

@ -38,6 +38,7 @@
#include "frontend/SharedContext.h"
#include "gc/Marking.h"
#include "jit/BaselineJIT.h"
#include "jit/ProcessExecutableMemory.h"
#include "jit/Ion.h"
#include "jit/IonCode.h"
#include "js/MemoryMetrics.h"
@ -3105,6 +3106,9 @@ JSScript::finalize(FreeOp* fop)
jit::DestroyJitScripts(fop, this);
if (loongArchMinimalJitCode_)
jit::DeallocateExecutableMemory(loongArchMinimalJitCode_, loongArchMinimalJitCodeSize_);
destroyScriptCounts(fop);
destroyDebugScript(fop);

View file

@ -921,9 +921,13 @@ class JSScript : public js::gc::TenuredCell
*/
uint8_t* baselineOrIonRaw;
uint8_t* baselineOrIonSkipArgCheck;
uint8_t* loongArchMinimalJitCode_;
// 32-bit fields.
uint32_t loongArchMinimalJitCodeSize_;
uint32_t dataSize_; /* size of the used part of the data array */
uint32_t lineno_; /* base line number of script */
@ -1591,6 +1595,16 @@ class JSScript : public js::gc::TenuredCell
static size_t offsetOfBaselineOrIonSkipArgCheck() {
return offsetof(JSScript, baselineOrIonSkipArgCheck);
}
uint8_t* loongArchMinimalJitCodeRaw() const {
return loongArchMinimalJitCode_;
}
uint32_t loongArchMinimalJitCodeSize() const {
return loongArchMinimalJitCodeSize_;
}
void setLoongArchMinimalJitCode(uint8_t* code, uint32_t size) {
loongArchMinimalJitCode_ = code;
loongArchMinimalJitCodeSize_ = size;
}
bool isRelazifiable() const {
return (selfHosted() || lazyScript) && !hasInnerFunctions_ && !types_ &&