forked from mirrors/gecko-dev
Bug 1898677 - Cache the result of bytecode encoding condition. r=nbp
Differential Revision: https://phabricator.services.mozilla.com/D211517
This commit is contained in:
parent
ad246a46f8
commit
071e366ef9
6 changed files with 73 additions and 41 deletions
|
|
@ -193,6 +193,10 @@ void ModuleLoader::OnModuleLoadComplete(ModuleLoadRequest* aRequest) {
|
|||
nsresult ModuleLoader::CompileFetchedModule(
|
||||
JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::CompileOptions& aOptions,
|
||||
ModuleLoadRequest* aRequest, JS::MutableHandle<JSObject*> aModuleOut) {
|
||||
if (aRequest->IsTextSource()) {
|
||||
ScriptLoader::CalculateBytecodeCacheFlag(aRequest);
|
||||
}
|
||||
|
||||
if (aRequest->GetScriptLoadContext()->mWasCompiledOMT) {
|
||||
JS::InstantiationStorage storage;
|
||||
RefPtr<JS::Stencil> stencil =
|
||||
|
|
@ -209,7 +213,7 @@ nsresult ModuleLoader::CompileFetchedModule(
|
|||
}
|
||||
|
||||
if (aRequest->IsTextSource() &&
|
||||
ScriptLoader::ShouldCacheBytecode(aRequest)) {
|
||||
aRequest->PassedConditionForBytecodeEncoding()) {
|
||||
if (!JS::StartIncrementalEncoding(aCx, std::move(stencil))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
@ -257,7 +261,8 @@ nsresult ModuleLoader::CompileFetchedModule(
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (aRequest->IsTextSource() && ScriptLoader::ShouldCacheBytecode(aRequest)) {
|
||||
if (aRequest->IsTextSource() &&
|
||||
aRequest->PassedConditionForBytecodeEncoding()) {
|
||||
if (!JS::StartIncrementalEncoding(aCx, std::move(stencil))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2368,7 +2368,7 @@ nsresult ScriptLoader::FillCompileOptionsForRequest(
|
|||
}
|
||||
|
||||
/* static */
|
||||
bool ScriptLoader::ShouldCacheBytecode(ScriptLoadRequest* aRequest) {
|
||||
void ScriptLoader::CalculateBytecodeCacheFlag(ScriptLoadRequest* aRequest) {
|
||||
using mozilla::TimeDuration;
|
||||
using mozilla::TimeStamp;
|
||||
|
||||
|
|
@ -2378,7 +2378,8 @@ bool ScriptLoader::ShouldCacheBytecode(ScriptLoadRequest* aRequest) {
|
|||
if (!aRequest->mCacheInfo) {
|
||||
LOG(("ScriptLoadRequest (%p): Cannot cache anything (cacheInfo = %p)",
|
||||
aRequest, aRequest->mCacheInfo.get()));
|
||||
return false;
|
||||
aRequest->MarkSkippedBytecodeEncoding();
|
||||
return;
|
||||
}
|
||||
|
||||
// Look at the preference to know which strategy (parameters) should be used
|
||||
|
|
@ -2398,7 +2399,8 @@ bool ScriptLoader::ShouldCacheBytecode(ScriptLoadRequest* aRequest) {
|
|||
// Reader mode, keep requesting alternate data but no longer save it.
|
||||
LOG(("ScriptLoadRequest (%p): Bytecode-cache: Encoding disabled.",
|
||||
aRequest));
|
||||
return false;
|
||||
aRequest->MarkSkippedBytecodeEncoding();
|
||||
return;
|
||||
}
|
||||
case -1: {
|
||||
// Eager mode, skip heuristics!
|
||||
|
|
@ -2430,7 +2432,8 @@ bool ScriptLoader::ShouldCacheBytecode(ScriptLoadRequest* aRequest) {
|
|||
if (sourceLength < minLength) {
|
||||
LOG(("ScriptLoadRequest (%p): Bytecode-cache: Script is too small.",
|
||||
aRequest));
|
||||
return false;
|
||||
aRequest->MarkSkippedBytecodeEncoding();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2442,17 +2445,19 @@ bool ScriptLoader::ShouldCacheBytecode(ScriptLoadRequest* aRequest) {
|
|||
if (NS_FAILED(aRequest->mCacheInfo->GetCacheTokenFetchCount(&fetchCount))) {
|
||||
LOG(("ScriptLoadRequest (%p): Bytecode-cache: Cannot get fetchCount.",
|
||||
aRequest));
|
||||
return false;
|
||||
aRequest->MarkSkippedBytecodeEncoding();
|
||||
return;
|
||||
}
|
||||
LOG(("ScriptLoadRequest (%p): Bytecode-cache: fetchCount = %d.", aRequest,
|
||||
fetchCount));
|
||||
if (fetchCount < fetchCountMin) {
|
||||
return false;
|
||||
aRequest->MarkSkippedBytecodeEncoding();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(("ScriptLoadRequest (%p): Bytecode-cache: Trigger encoding.", aRequest));
|
||||
return true;
|
||||
aRequest->MarkPassedConditionForBytecodeEncoding();
|
||||
}
|
||||
|
||||
class MOZ_RAII AutoSetProcessingScriptTag {
|
||||
|
|
@ -2580,8 +2585,8 @@ nsresult ScriptLoader::CompileOrDecodeClassicScript(
|
|||
}
|
||||
|
||||
MOZ_ASSERT(aRequest->IsSource());
|
||||
bool encodeBytecode = ShouldCacheBytecode(aRequest);
|
||||
aExec.SetEncodeBytecode(encodeBytecode);
|
||||
CalculateBytecodeCacheFlag(aRequest);
|
||||
aExec.SetEncodeBytecode(aRequest->PassedConditionForBytecodeEncoding());
|
||||
|
||||
if (aRequest->GetScriptLoadContext()->mCompileOrDecodeTask) {
|
||||
// Off-main-thread parsing.
|
||||
|
|
@ -2624,11 +2629,11 @@ nsCString& ScriptLoader::BytecodeMimeTypeFor(ScriptLoadRequest* aRequest) {
|
|||
|
||||
void ScriptLoader::MaybePrepareForBytecodeEncodingBeforeExecute(
|
||||
ScriptLoadRequest* aRequest, JS::Handle<JSScript*> aScript) {
|
||||
if (!ShouldCacheBytecode(aRequest)) {
|
||||
if (!aRequest->PassedConditionForBytecodeEncoding()) {
|
||||
return;
|
||||
}
|
||||
|
||||
aRequest->MarkForBytecodeEncoding(aScript);
|
||||
aRequest->MarkScriptForBytecodeEncoding(aScript);
|
||||
}
|
||||
|
||||
nsresult ScriptLoader::MaybePrepareForBytecodeEncodingAfterExecute(
|
||||
|
|
@ -2674,7 +2679,7 @@ void ScriptLoader::MaybePrepareModuleForBytecodeEncodingBeforeExecute(
|
|||
return;
|
||||
}
|
||||
|
||||
if (ShouldCacheBytecode(aRequest)) {
|
||||
if (aRequest->PassedConditionForBytecodeEncoding()) {
|
||||
aRequest->MarkModuleForBytecodeEncoding();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -686,7 +686,7 @@ class ScriptLoader final : public JS::loader::ScriptLoaderInterface {
|
|||
|
||||
// Returns wether we should save the bytecode of this script after the
|
||||
// execution of the script.
|
||||
static bool ShouldCacheBytecode(ScriptLoadRequest* aRequest);
|
||||
static void CalculateBytecodeCacheFlag(ScriptLoadRequest* aRequest);
|
||||
|
||||
void RunScriptWhenSafe(ScriptLoadRequest* aRequest);
|
||||
|
||||
|
|
|
|||
|
|
@ -87,13 +87,7 @@ class ModuleLoadRequest final : public ScriptLoadRequest {
|
|||
return mRootModule;
|
||||
}
|
||||
|
||||
bool IsModuleMarkedForBytecodeEncoding() const {
|
||||
return mIsMarkedForBytecodeEncoding;
|
||||
}
|
||||
void MarkModuleForBytecodeEncoding() {
|
||||
MOZ_ASSERT(!IsModuleMarkedForBytecodeEncoding());
|
||||
mIsMarkedForBytecodeEncoding = true;
|
||||
}
|
||||
void MarkModuleForBytecodeEncoding() { MarkForBytecodeEncoding(); }
|
||||
|
||||
// Convenience methods to call into the module loader for this request.
|
||||
|
||||
|
|
@ -137,11 +131,6 @@ class ModuleLoadRequest final : public ScriptLoadRequest {
|
|||
// Is this the top level request for a dynamic module import?
|
||||
const bool mIsDynamicImport;
|
||||
|
||||
// True if this module is planned to be saved in the bytecode cache.
|
||||
// ModuleLoadRequest doesn't use ScriptLoadRequest::mScriptForBytecodeEncoding
|
||||
// field because the JSScript reference isn't always avaialble for module.
|
||||
bool mIsMarkedForBytecodeEncoding = false;
|
||||
|
||||
// Pointer to the script loader, used to trigger actions when the module load
|
||||
// finishes.
|
||||
RefPtr<ModuleLoaderBase> mLoader;
|
||||
|
|
|
|||
|
|
@ -181,21 +181,14 @@ void ScriptLoadRequest::SetPendingFetchingError() {
|
|||
mState = State::PendingFetchingError;
|
||||
}
|
||||
|
||||
void ScriptLoadRequest::MarkForBytecodeEncoding(JSScript* aScript) {
|
||||
void ScriptLoadRequest::MarkScriptForBytecodeEncoding(JSScript* aScript) {
|
||||
MOZ_ASSERT(!IsModuleRequest());
|
||||
MOZ_ASSERT(!IsMarkedForBytecodeEncoding());
|
||||
MOZ_ASSERT(!mScriptForBytecodeEncoding);
|
||||
MarkForBytecodeEncoding();
|
||||
mScriptForBytecodeEncoding = aScript;
|
||||
HoldJSObjects(this);
|
||||
}
|
||||
|
||||
bool ScriptLoadRequest::IsMarkedForBytecodeEncoding() const {
|
||||
if (IsModuleRequest()) {
|
||||
return AsModuleRequest()->IsModuleMarkedForBytecodeEncoding();
|
||||
}
|
||||
|
||||
return !!mScriptForBytecodeEncoding;
|
||||
}
|
||||
|
||||
static bool IsInternalURIScheme(nsIURI* uri) {
|
||||
return uri->SchemeIs("moz-extension") || uri->SchemeIs("resource") ||
|
||||
uri->SchemeIs("chrome");
|
||||
|
|
|
|||
|
|
@ -182,9 +182,33 @@ class ScriptLoadRequest : public nsISupports,
|
|||
|
||||
void SetPendingFetchingError();
|
||||
|
||||
void MarkForBytecodeEncoding(JSScript* aScript);
|
||||
bool PassedConditionForBytecodeEncoding() const {
|
||||
return mBytecodeEncodingPlan == BytecodeEncodingPlan::PassedCondition ||
|
||||
mBytecodeEncodingPlan == BytecodeEncodingPlan::MarkedForEncode;
|
||||
}
|
||||
|
||||
bool IsMarkedForBytecodeEncoding() const;
|
||||
void MarkSkippedBytecodeEncoding() {
|
||||
MOZ_ASSERT(mBytecodeEncodingPlan == BytecodeEncodingPlan::Uninitialized);
|
||||
mBytecodeEncodingPlan = BytecodeEncodingPlan::Skipped;
|
||||
}
|
||||
|
||||
void MarkPassedConditionForBytecodeEncoding() {
|
||||
MOZ_ASSERT(mBytecodeEncodingPlan == BytecodeEncodingPlan::Uninitialized);
|
||||
mBytecodeEncodingPlan = BytecodeEncodingPlan::PassedCondition;
|
||||
}
|
||||
|
||||
bool IsMarkedForBytecodeEncoding() const {
|
||||
return mBytecodeEncodingPlan == BytecodeEncodingPlan::MarkedForEncode;
|
||||
}
|
||||
|
||||
protected:
|
||||
void MarkForBytecodeEncoding() {
|
||||
MOZ_ASSERT(mBytecodeEncodingPlan == BytecodeEncodingPlan::PassedCondition);
|
||||
mBytecodeEncodingPlan = BytecodeEncodingPlan::MarkedForEncode;
|
||||
}
|
||||
|
||||
public:
|
||||
void MarkScriptForBytecodeEncoding(JSScript* aScript);
|
||||
|
||||
mozilla::CORSMode CORSMode() const { return mFetchOptions->mCORSMode; }
|
||||
|
||||
|
|
@ -218,6 +242,23 @@ class ScriptLoadRequest : public nsISupports,
|
|||
State mState; // Are we still waiting for a load to complete?
|
||||
bool mFetchSourceOnly; // Request source, not cached bytecode.
|
||||
|
||||
enum class BytecodeEncodingPlan : uint8_t {
|
||||
// This is not yet considered for encoding.
|
||||
Uninitialized,
|
||||
|
||||
// This is marked for skipping the encoding.
|
||||
Skipped,
|
||||
|
||||
// This fits the condition for the encoding (e.g. file size, fetch count).
|
||||
PassedCondition,
|
||||
|
||||
// This is marked for encoding, with setting sufficient input,
|
||||
// e.g. mScriptForBytecodeEncoding for script.
|
||||
MarkedForEncode,
|
||||
};
|
||||
BytecodeEncodingPlan mBytecodeEncodingPlan =
|
||||
BytecodeEncodingPlan::Uninitialized;
|
||||
|
||||
// The referrer policy used for the initial fetch and for fetching any
|
||||
// imported modules
|
||||
enum mozilla::dom::ReferrerPolicy mReferrerPolicy;
|
||||
|
|
@ -247,10 +288,9 @@ class ScriptLoadRequest : public nsISupports,
|
|||
RefPtr<LoadedScript> mLoadedScript;
|
||||
|
||||
// Holds the top-level JSScript that corresponds to the current source, once
|
||||
// it is parsed, and planned to be saved in the bytecode cache.
|
||||
// it is parsed, and marked to be saved in the bytecode cache.
|
||||
//
|
||||
// NOTE: This field is not used for ModuleLoadRequest.
|
||||
// See ModuleLoadRequest::mIsMarkedForBytecodeEncoding.
|
||||
JS::Heap<JSScript*> mScriptForBytecodeEncoding;
|
||||
|
||||
// Holds the Cache information, which is used to register the bytecode
|
||||
|
|
|
|||
Loading…
Reference in a new issue