--- a/netwerk/base/Predictor.cpp
+++ b/netwerk/base/Predictor.cpp
@@ -1306,19 +1306,19 @@ Predictor::CalculatePredictions(nsICache
keysToOperateOn.SwapElements(mKeysToOperateOn);
valuesToOperateOn.SwapElements(mValuesToOperateOn);
MOZ_ASSERT(keysToOperateOn.Length() == valuesToOperateOn.Length());
for (size_t i = 0; i < keysToOperateOn.Length(); ++i) {
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;
}
int32_t confidence = CalculateConfidence(hitCount, loadCount, lastHit,
lastLoad, globalDegradation);
if (fullUri) {
@@ -1346,34 +1346,52 @@ Predictor::CalculatePredictions(nsICache
PREDICTOR_LOG((" setting up prediction"));
SetupPrediction(confidence, flags, uri);
}
}
// (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)));
}
}
nsresult
Predictor::Prefetch(nsIURI *uri, nsIURI *referrer,
const OriginAttributes& originAttributes,
nsINetworkPredictorVerifier *verifier)
{
@@ -1749,19 +1767,19 @@ Predictor::LearnInternal(PredictorLearnR
keysToOperateOn.SwapElements(mKeysToOperateOn);
valuesToOperateOn.SwapElements(mValuesToOperateOn);
MOZ_ASSERT(keysToOperateOn.Length() == valuesToOperateOn.Length());
for (size_t i = 0; i < keysToOperateOn.Length(); ++i) {
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;
}
UpdateRollingLoadCount(entry, flags, key, hitCount, lastHit);
}
} else {
PREDICTOR_LOG((" nothing to do for toplevel"));
@@ -1791,29 +1809,28 @@ Predictor::SpaceCleaner::OnMetaDataEleme
{
MOZ_ASSERT(NS_IsMainThread());
if (!IsURIMetadataElement(key)) {
// This isn't a bit of metadata we care about
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
nsCString nsKey;
nsKey.AssignASCII(key);
mLongKeysToDelete.AppendElement(nsKey);
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
// we had our limit on URI length, in order to free up some space.
nsCString nsKey;
nsKey.AssignASCII(key);
mLongKeysToDelete.AppendElement(nsKey);
return NS_OK;
@@ -1870,18 +1887,19 @@ Predictor::LearnForSubresource(nsICacheE
return;
}
nsCString value;
rv = entry->GetMetaDataElement(key.BeginReading(), getter_Copies(value));
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) {
// This is a new addition
PREDICTOR_LOG((" new resource"));
nsCString s;
rv = entry->GetMetaDataElement(RESOURCE_META_DATA, getter_Copies(s));
if (NS_SUCCEEDED(rv)) {
@@ -1963,17 +1981,17 @@ Predictor::LearnForStartup(nsICacheEntry
// These actually do the same set of work, just on different entries, so we
// can pass through to get the real work done here
PREDICTOR_LOG(("Predictor::LearnForStartup"));
LearnForSubresource(entry, 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)
{
MOZ_ASSERT(NS_IsMainThread());
PREDICTOR_LOG(("Predictor::ParseMetaDataEntry key=%s value=%s",
key ? key : "", value));
@@ -2013,22 +2031,20 @@ Predictor::ParseMetaDataEntry(const char
PREDICTOR_LOG((" lastHit -> %u", lastHit));
value = comma + 1;
flags = static_cast<uint32_t>(atoi(value));
PREDICTOR_LOG((" flags -> %u", flags));
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;
}
NS_IMETHODIMP
Predictor::Reset()
{
@@ -2672,17 +2688,24 @@ Predictor::CacheabilityAction::OnCacheEn
PREDICTOR_LOG(("CacheabilityAction::OnCacheEntryAvailable this=%p", this));
if (NS_FAILED(result)) {
// Nothing to do
PREDICTOR_LOG((" nothing to do result=%" PRIX32 " isNew=%d",
static_cast<uint32_t>(result), isNew));
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;
}
nsTArray<nsCString> keysToCheck, valuesToCheck;
keysToCheck.SwapElements(mKeysToCheck);
valuesToCheck.SwapElements(mValuesToCheck);
@@ -2692,27 +2715,26 @@ Predictor::CacheabilityAction::OnCacheEn
if (NS_SUCCEEDED(mTargetURI->GetQuery(query)) && !query.IsEmpty()) {
hasQueryString = true;
}
MOZ_ASSERT(keysToCheck.Length() == valuesToCheck.Length());
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;
} else {
PREDICTOR_LOG((" marking %s uncacheable", key));
flags &= ~FLAG_PREFETCHABLE;
}
nsCString newValue;
--- a/netwerk/base/Predictor.h
+++ b/netwerk/base/Predictor.h
@@ -325,18 +325,18 @@ private:
// * fullUri - whether we're predicting for a full URI or origin-only
void CalculatePredictions(nsICacheEntry *entry, nsIURI *referrer,
uint32_t lastLoad, uint32_t loadCount,
int32_t globalDegradation, bool fullUri);
// 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
// * referrer - the URI of the referring page
// * originAttributes - the originAttributes of this prefetch
// * verifier - used for testing to ensure the expected prefetch happens
nsresult Prefetch(nsIURI *uri, nsIURI *referrer,
const OriginAttributes& originAttributes,
@@ -404,21 +404,21 @@ private:
// close to browser startup
// * entry - the cache entry that stores the startup page list
// * targetURI - the URI of a page that was loaded near browser startup
void LearnForStartup(nsICacheEntry *entry, nsIURI *targetURI);
// 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);
// Used to update whether a particular URI was cacheable or not.
// sourceURI and targetURI are the same as the arguments to Learn
// and httpStatus is the status code we got while loading targetURI.
void UpdateCacheabilityInternal(nsIURI *sourceURI, nsIURI *targetURI,
uint32_t httpStatus, const nsCString &method,