Bug 1390274 - only parse URIs in the predictor when absolutely necessary. r=valentin

This moves URI creation from ParseMetaDataEntry into SetupPrediction
because ParseMetaDataEntry is called in way more circumstances than we
actually need the URI from. Even in those cases where we might use the
URI (but it's not guaranteed), we end up using the URI less often than
we create one. In case it wasn't clear, SetupPrediction is the only
thing called post-ParseMetaDataEntry that would require a parsed URI in
the first place.

SetupPrediction has the duplicated NS_NewURI calls to avoid creating
URIs for those calls to SetupPrediction that are no-ops.

MozReview-Commit-ID: HlhVj7p2uuk

--HG--
extra : rebase_source : 0349dc52225b6e93150947ea978f2ba7afa3e2f5
This commit is contained in:
Nicholas Hurley 2017-08-22 07:43:41 -07:00
Родитель 88bdb191e3
Коммит 4eb476eee2
2 изменённых файлов: 54 добавлений и 32 удалений

Просмотреть файл

@ -1311,9 +1311,9 @@ Predictor::CalculatePredictions(nsICacheEntry *entry, nsIURI *referrer,
const char *key = keysToOperateOn[i].BeginReading();
const char *value = valuesToOperateOn[i].BeginReading();
nsCOMPtr<nsIURI> uri;
nsCString uri;
uint32_t hitCount, lastHit, flags;
if (!ParseMetaDataEntry(key, value, getter_AddRefs(uri), hitCount, lastHit, flags)) {
if (!ParseMetaDataEntry(key, value, uri, hitCount, lastHit, flags)) {
// This failed, get rid of it so we don't waste space
entry->SetMetaDataElement(key, nullptr);
continue;
@ -1351,24 +1351,42 @@ Predictor::CalculatePredictions(nsICacheEntry *entry, nsIURI *referrer,
// (Maybe) adds a predictive action to the prediction runner, based on our
// calculated confidence for the subresource in question.
void
Predictor::SetupPrediction(int32_t confidence, uint32_t flags, nsIURI *uri)
Predictor::SetupPrediction(int32_t confidence, uint32_t flags, const nsCString &uri)
{
MOZ_ASSERT(NS_IsMainThread());
nsAutoCString uriStr;
uri->GetAsciiSpec(uriStr);
nsresult rv = NS_OK;
PREDICTOR_LOG(("SetupPrediction mEnablePrefetch=%d mPrefetchMinConfidence=%d "
"mPreconnectMinConfidence=%d mPreresolveMinConfidence=%d "
"flags=%d confidence=%d uri=%s", mEnablePrefetch,
mPrefetchMinConfidence, mPreconnectMinConfidence,
mPreresolveMinConfidence, flags, confidence, uriStr.get()));
mPreresolveMinConfidence, flags, confidence, uri.get()));
if (mEnablePrefetch && (flags & FLAG_PREFETCHABLE) &&
(mPrefetchRollingLoadCount || (confidence >= mPrefetchMinConfidence))) {
mPrefetches.AppendElement(uri);
nsCOMPtr<nsIURI> prefetchURI;
rv = NS_NewURI(getter_AddRefs(prefetchURI), uri, nullptr, nullptr,
mIOService);
if (NS_SUCCEEDED(rv)) {
mPrefetches.AppendElement(prefetchURI);
}
} else if (confidence >= mPreconnectMinConfidence) {
mPreconnects.AppendElement(uri);
nsCOMPtr<nsIURI> preconnectURI;
rv = NS_NewURI(getter_AddRefs(preconnectURI), uri, nullptr, nullptr,
mIOService);
if (NS_SUCCEEDED(rv)) {
mPreconnects.AppendElement(preconnectURI);
}
} else if (confidence >= mPreresolveMinConfidence) {
mPreresolves.AppendElement(uri);
nsCOMPtr<nsIURI> preresolveURI;
rv = NS_NewURI(getter_AddRefs(preresolveURI), uri, nullptr, nullptr,
mIOService);
if (NS_SUCCEEDED(rv)) {
mPreresolves.AppendElement(preresolveURI);
}
}
if (NS_FAILED(rv)) {
PREDICTOR_LOG((" NS_NewURI returned 0x%" PRIx32, static_cast<uint32_t>(rv)));
}
}
@ -1754,9 +1772,9 @@ Predictor::LearnInternal(PredictorLearnReason reason, nsICacheEntry *entry,
const char *key = keysToOperateOn[i].BeginReading();
const char *value = valuesToOperateOn[i].BeginReading();
nsCOMPtr<nsIURI> uri;
nsCString uri;
uint32_t hitCount, lastHit, flags;
if (!ParseMetaDataEntry(nullptr, value, nullptr, hitCount, lastHit, flags)) {
if (!ParseMetaDataEntry(key, value, uri, hitCount, lastHit, flags)) {
// This failed, get rid of it so we don't waste space
entry->SetMetaDataElement(key, nullptr);
continue;
@ -1796,9 +1814,9 @@ Predictor::SpaceCleaner::OnMetaDataElement(const char *key, const char *value)
return NS_OK;
}
nsCString uri;
uint32_t hitCount, lastHit, flags;
bool ok = mPredictor->ParseMetaDataEntry(nullptr, value, nullptr,
hitCount, lastHit, flags);
bool ok = mPredictor->ParseMetaDataEntry(key, value, uri, hitCount, lastHit, flags);
if (!ok) {
// Couldn't parse this one, just get rid of it
@ -1808,7 +1826,6 @@ Predictor::SpaceCleaner::OnMetaDataElement(const char *key, const char *value)
return NS_OK;
}
nsCString uri(key + (sizeof(META_DATA_PREFIX) - 1));
uint32_t uriLength = uri.Length();
if (uriLength > mPredictor->mMaxURILength) {
// Default to getting rid of URIs that are too long and were put in before
@ -1875,8 +1892,9 @@ Predictor::LearnForSubresource(nsICacheEntry *entry, nsIURI *targetURI)
uint32_t hitCount, lastHit, flags;
bool isNewResource = (NS_FAILED(rv) ||
!ParseMetaDataEntry(nullptr, value.BeginReading(),
nullptr, hitCount, lastHit, flags));
!ParseMetaDataEntry(key.BeginReading(),
value.BeginReading(), uri,
hitCount, lastHit, flags));
int32_t resourceCount = 0;
if (isNewResource) {
@ -1968,7 +1986,7 @@ Predictor::LearnForStartup(nsICacheEntry *entry, nsIURI *targetURI)
}
bool
Predictor::ParseMetaDataEntry(const char *key, const char *value, nsIURI **uri,
Predictor::ParseMetaDataEntry(const char *key, const char *value, nsCString &uri,
uint32_t &hitCount, uint32_t &lastHit,
uint32_t &flags)
{
@ -2018,12 +2036,10 @@ Predictor::ParseMetaDataEntry(const char *key, const char *value, nsIURI **uri,
if (key) {
const char *uriStart = key + (sizeof(META_DATA_PREFIX) - 1);
nsresult rv = NS_NewURI(uri, uriStart, nullptr, mIOService);
if (NS_FAILED(rv)) {
PREDICTOR_LOG((" NS_NewURI returned 0x%" PRIX32, static_cast<uint32_t>(rv)));
return false;
}
uri.AssignASCII(uriStart);
PREDICTOR_LOG((" uri -> %s", uriStart));
} else {
uri.Truncate();
}
return true;
@ -2677,7 +2693,14 @@ Predictor::CacheabilityAction::OnCacheEntryAvailable(nsICacheEntry *entry,
return NS_OK;
}
nsresult rv = entry->VisitMetaData(this);
nsCString strTargetURI;
nsresult rv = mTargetURI->GetAsciiSpec(strTargetURI);
if (NS_FAILED(rv)) {
PREDICTOR_LOG((" GetAsciiSpec returned %" PRIx32, static_cast<uint32_t>(rv)));
return NS_OK;
}
rv = entry->VisitMetaData(this);
if (NS_FAILED(rv)) {
PREDICTOR_LOG((" VisitMetaData returned %" PRIx32, static_cast<uint32_t>(rv)));
return NS_OK;
@ -2697,17 +2720,16 @@ Predictor::CacheabilityAction::OnCacheEntryAvailable(nsICacheEntry *entry,
for (size_t i = 0; i < keysToCheck.Length(); ++i) {
const char *key = keysToCheck[i].BeginReading();
const char *value = valuesToCheck[i].BeginReading();
nsCOMPtr<nsIURI> uri;
nsCString uri;
uint32_t hitCount, lastHit, flags;
if (!mPredictor->ParseMetaDataEntry(key, value, getter_AddRefs(uri),
hitCount, lastHit, flags)) {
if (!mPredictor->ParseMetaDataEntry(key, value, uri, hitCount, lastHit,
flags)) {
PREDICTOR_LOG((" failed to parse key=%s value=%s", key, value));
continue;
}
bool eq = false;
if (NS_SUCCEEDED(uri->Equals(mTargetURI, &eq)) && eq) {
if (strTargetURI.Equals(uri)) {
if (mHttpStatus == 200 && mMethod.EqualsLiteral("GET") && !hasQueryString) {
PREDICTOR_LOG((" marking %s cacheable", key));
flags |= FLAG_PREFETCHABLE;

Просмотреть файл

@ -330,8 +330,8 @@ private:
// Used to prepare any necessary prediction for a resource on a page
// * confidence - value calculated by CalculateConfidence for this resource
// * flags - the flags taken from the resource
// * uri - the URI of the resource
void SetupPrediction(int32_t confidence, uint32_t flags, nsIURI *uri);
// * uri - the ascii spec of the URI of the resource
void SetupPrediction(int32_t confidence, uint32_t flags, const nsCString &uri);
// Used to kick off a prefetch from RunPredictions if necessary
// * uri - the URI to prefetch
@ -409,11 +409,11 @@ private:
// Used to parse the data we store in cache metadata
// * key - the cache metadata key
// * value - the cache metadata value
// * uri - (out) the URI this metadata entry was about
// * uri - (out) the ascii spec of the URI this metadata entry was about
// * hitCount - (out) the number of times this URI has been seen
// * lastHit - (out) timestamp of the last time this URI was seen
// * flags - (out) flags for this metadata entry
bool ParseMetaDataEntry(const char *key, const char *value, nsIURI **uri,
bool ParseMetaDataEntry(const char *key, const char *value, nsCString &uri,
uint32_t &hitCount, uint32_t &lastHit,
uint32_t &flags);