Open
Bug 1752590
Opened 3 years ago
Updated 3 years ago
Defer JS::EncodeStencil from WriteCachedStencil to cache file generation step
Categories
(Core :: JavaScript Engine, enhancement, P3)
Core
JavaScript Engine
Tracking
()
NEW
People
(Reporter: arai, Unassigned)
References
(Blocks 1 open bug)
Details
mozJSComponentLoader::ObjectForLocation
and EvalStencil
supports both ScriptPreloader
and StartupCache
as cache storage:
nsresult mozJSComponentLoader::ObjectForLocation(...) {
...
ScriptPreloader::GetSingleton().NoteStencil(nativePath, cachePath, stencil);
...
if (storeIntoStartupCache) {
...
rv = WriteCachedStencil(cache, cachePath, cx, stencil);
static bool EvalStencil(...) {
...
nsCString uriStr;
if (storeIntoPreloadCache && NS_SUCCEEDED(uri->GetSpec(uriStr))) {
ScriptPreloader::GetSingleton().NoteStencil(uriStr, cachePath, stencil);
}
if (storeIntoStartupCache) {
JSAutoRealm ar(cx, script);
WriteCachedStencil(StartupCache::GetSingleton(), cachePath, cx, stencil);
}
ScriptPreloader
performs JS::EncodeStencil
when writing cache:
void ScriptPreloader::PrepareCacheWriteInternal() {
...
for (auto& script : IterHash(mScripts, Match<ScriptStatus::Saved>())) {
...
if (!script->mSize && !script->XDREncode(jsapi.cx())) {
bool ScriptPreloader::CachedStencil::XDREncode(JSContext* cx) {
...
JS::TranscodeResult code = JS::EncodeStencil(cx, mStencil, Buffer());
But StartupCache
performs JS::EncodeStencil
immediately
nsresult WriteCachedStencil(StartupCache* cache, nsACString& uri, JSContext* cx,
JS::Stencil* stencil) {
JS::TranscodeBuffer buffer;
JS::TranscodeResult code = JS::EncodeStencil(cx, stencil, buffer);
...
nsresult rv =
cache->PutBuffer(PromiseFlatCString(uri).get(), std::move(buf), size);
Now we can hold stencil without much affecting VM/GC, the JS::EncodeStencil
can be deferred until when StartupCache
writes cache file,
so that it usually happens off-main thread, on idle time:
Result<Ok, nsresult> StartupCache::WriteToDisk() {
...
nsTArray<std::pair<const nsCString*, StartupCacheEntry*>> entries;
for (auto iter = mTable.iter(); !iter.done(); iter.next()) {
if (iter.get().value().mRequested) {
entries.AppendElement(
std::make_pair(&iter.get().key(), &iter.get().value()));
...
for (auto& e : entries) {
auto value = e.second;
value->mOffset = offset;
Span<const char> result;
MOZ_TRY_VAR(result,
ctx.BeginCompressing(writeSpan).mapErr(MapLZ4ErrorToNsresult));
MOZ_TRY(Write(fd, result.Elements(), result.Length()));
offset += result.Length();
for (size_t i = 0; i < value->mUncompressedSize; i += chunkSize) {
size_t size = std::min(chunkSize, value->mUncompressedSize - i);
char* uncompressed = value->mData.get() + i;
MOZ_TRY_VAR(result, ctx.ContinueCompressing(Span(uncompressed, size))
.mapErr(MapLZ4ErrorToNsresult));
MOZ_TRY(Write(fd, result.Elements(), result.Length()));
offset += result.Length();
}
You need to log in
before you can comment on or make changes to this bug.
Description
•