diff --git a/startupcache/StartupCache.cpp b/startupcache/StartupCache.cpp index 13a6982a4078..8789f3b90a5b 100644 --- a/startupcache/StartupCache.cpp +++ b/startupcache/StartupCache.cpp @@ -122,7 +122,6 @@ StartupCache::InitSingleton() StartupCache* StartupCache::gStartupCache; bool StartupCache::gShutdownInitiated; -bool StartupCache::gIgnoreDiskCache; enum StartupCache::TelemetrifyAge StartupCache::gPostFlushAgeAction = StartupCache::IGNORE_AGE; StartupCache::StartupCache() @@ -204,12 +203,12 @@ StartupCache::Init() rv = mObserverService->AddObserver(mListener, "startupcache-invalidate", false); NS_ENSURE_SUCCESS(rv, rv); - + rv = LoadArchive(RECORD_AGE); // Sometimes we don't have a cache yet, that's ok. // If it's corrupted, just remove it and start over. - if (gIgnoreDiskCache || (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND)) { + if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND) { NS_WARNING("Failed to load startupcache file correctly, removing!"); InvalidateCache(); } @@ -228,9 +227,6 @@ StartupCache::Init() nsresult StartupCache::LoadArchive(enum TelemetrifyAge flag) { - if (gIgnoreDiskCache) - return NS_ERROR_FAILURE; - bool exists; mArchive = NULL; nsresult rv = mFile->Exists(&exists); @@ -462,9 +458,6 @@ StartupCache::WriteToDisk() mArchive = NULL; zipW->Close(); - // We succesfully wrote the archive to disk; mark the disk file as trusted - gIgnoreDiskCache = false; - // Our reader's view of the archive is outdated now, reload it. LoadArchive(gPostFlushAgeAction); @@ -477,25 +470,10 @@ StartupCache::InvalidateCache() WaitOnWriteThread(); mTable.Clear(); mArchive = NULL; - nsresult rv = mFile->Remove(false); - if (NS_FAILED(rv) && rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST && - rv != NS_ERROR_FILE_NOT_FOUND) { - gIgnoreDiskCache = true; - mozilla::Telemetry::Accumulate(Telemetry::STARTUP_CACHE_INVALID, true); - return; - } - gIgnoreDiskCache = false; + mFile->Remove(false); LoadArchive(gPostFlushAgeAction); } -void -StartupCache::IgnoreDiskCache() -{ - gIgnoreDiskCache = true; - if (gStartupCache) - gStartupCache->InvalidateCache(); -} - /* * WaitOnWriteThread() is called from a main thread to wait for the worker * thread to finish. However since the same code is used in the worker thread and @@ -735,13 +713,6 @@ StartupCacheWrapper::InvalidateCache() return NS_OK; } -nsresult -StartupCacheWrapper::IgnoreDiskCache() -{ - StartupCache::IgnoreDiskCache(); - return NS_OK; -} - nsresult StartupCacheWrapper::GetDebugObjectOutputStream(nsIObjectOutputStream* stream, nsIObjectOutputStream** outStream) diff --git a/startupcache/StartupCache.h b/startupcache/StartupCache.h index f3e111e7bf1e..7440d71b74c5 100644 --- a/startupcache/StartupCache.h +++ b/startupcache/StartupCache.h @@ -44,12 +44,6 @@ * * InvalidateCache() may be called if a client suspects data corruption * or wishes to invalidate for any other reason. This will remove all existing cache data. - * Additionally, the static method IgnoreDiskCache() can be called if it is - * believed that the on-disk cache file is itself corrupt. This call implicitly - * calls InvalidateCache (if the singleton has been initialized) to ensure any - * data already read from disk is discarded. The cache will not load data from - * the disk file until a successful write occurs. - * * Finally, getDebugObjectOutputStream() allows debug code to wrap an objectstream * with a debug objectstream, to check for multiply-referenced objects. These will * generally fail to deserialize correctly, unless they are stateless singletons or the @@ -120,9 +114,6 @@ public: // Removes the cache file. void InvalidateCache(); - // Signal that data should not be loaded from the cache file - static void IgnoreDiskCache(); - // In DEBUG builds, returns a stream that will attempt to check for // and disallow multiple writes of the same object. nsresult GetDebugObjectOutputStream(nsIObjectOutputStream* aStream, @@ -176,7 +167,6 @@ private: static StartupCache *gStartupCache; static bool gShutdownInitiated; - static bool gIgnoreDiskCache; PRThread *mWriteThread; #ifdef DEBUG nsTHashtable mWriteObjectMap; diff --git a/startupcache/nsIStartupCache.idl b/startupcache/nsIStartupCache.idl index ece38b4edb65..ca989340fe8b 100644 --- a/startupcache/nsIStartupCache.idl +++ b/startupcache/nsIStartupCache.idl @@ -9,7 +9,7 @@ #include "nsIObserver.idl" #include "nsIObjectOutputStream.idl" -[uuid(25957820-90a1-428c-8739-b0845d3cc534)] +[uuid(c1b3796b-33af-4ff0-b83d-8eb0ca2c080f)] interface nsIStartupCache : nsISupports { @@ -24,8 +24,6 @@ interface nsIStartupCache : nsISupports void invalidateCache(); - void ignoreDiskCache(); - /** In debug builds, wraps this object output stream with a stream that will * detect and prevent the write of a multiply-referenced non-singleton object * during serialization. In non-debug, returns an add-ref'd pointer to diff --git a/startupcache/test/TestStartupCache.cpp b/startupcache/test/TestStartupCache.cpp index 4cbf30044b66..a5e389fc302f 100644 --- a/startupcache/test/TestStartupCache.cpp +++ b/startupcache/test/TestStartupCache.cpp @@ -22,7 +22,6 @@ #include "nsIPrefService.h" #include "nsITelemetry.h" #include "jsapi.h" -#include "prio.h" namespace mozilla { namespace scache { @@ -57,7 +56,7 @@ PR_END_MACRO nsresult WaitForStartupTimer() { nsresult rv; - nsCOMPtr sc + nsCOMPtr sc = do_GetService("@mozilla.org/startupcache/cache;1"); PR_Sleep(10 * PR_TicksPerSecond()); @@ -76,7 +75,7 @@ WaitForStartupTimer() { nsresult TestStartupWriteRead() { nsresult rv; - nsCOMPtr sc + nsCOMPtr sc = do_GetService("@mozilla.org/startupcache/cache;1", &rv); if (!sc) { fail("didn't get a pointer..."); @@ -119,7 +118,7 @@ TestWriteInvalidateRead() { const char* id = "id"; char* outbuf = NULL; uint32_t len; - nsCOMPtr sc + nsCOMPtr sc = do_GetService("@mozilla.org/startupcache/cache;1", &rv); sc->InvalidateCache(); @@ -248,110 +247,10 @@ TestWriteObject() { return NS_OK; } -nsresult -LockCacheFile(bool protect, nsIFile* profileDir) { - NS_ENSURE_ARG(profileDir); - - nsCOMPtr startupCache; - profileDir->Clone(getter_AddRefs(startupCache)); - NS_ENSURE_STATE(startupCache); - startupCache->AppendNative(NS_LITERAL_CSTRING("startupCache")); - - nsresult rv; -#ifndef XP_WIN - static uint32_t oldPermissions; -#else - static PRFileDesc* fd = nullptr; -#endif - - // To prevent deletion of the startupcache file, we change the containing - // directory's permissions on Linux/Mac, and hold the file open on Windows - if (protect) { -#ifndef XP_WIN - rv = startupCache->GetPermissions(&oldPermissions); - NS_ENSURE_SUCCESS(rv, rv); - rv = startupCache->SetPermissions(0555); - NS_ENSURE_SUCCESS(rv, rv); -#else - // Filename logic from StartupCache.cpp - #ifdef IS_BIG_ENDIAN - #define SC_ENDIAN "big" - #else - #define SC_ENDIAN "little" - #endif - - #if PR_BYTES_PER_WORD == 4 - #define SC_WORDSIZE "4" - #else - #define SC_WORDSIZE "8" - #endif - char sStartupCacheName[] = "startupCache." SC_WORDSIZE "." SC_ENDIAN; - startupCache->AppendNative(NS_LITERAL_CSTRING(sStartupCacheName)); - - rv = startupCache->OpenNSPRFileDesc(PR_RDONLY, 0, &fd); - NS_ENSURE_SUCCESS(rv, rv); -#endif - } else { -#ifndef XP_WIN - rv = startupCache->SetPermissions(oldPermissions); - NS_ENSURE_SUCCESS(rv, rv); -#else - PR_Close(fd); -#endif - } - - return NS_OK; -} - -nsresult -TestIgnoreDiskCache(nsIFile* profileDir) { - nsresult rv; - nsCOMPtr sc - = do_GetService("@mozilla.org/startupcache/cache;1", &rv); - sc->InvalidateCache(); - - const char* buf = "Get a Beardbook app for your smartphone"; - const char* id = "id"; - char* outbuf = NULL; - PRUint32 len; - - rv = sc->PutBuffer(id, buf, strlen(buf) + 1); - NS_ENSURE_SUCCESS(rv, rv); - rv = sc->ResetStartupWriteTimer(); - rv = WaitForStartupTimer(); - NS_ENSURE_SUCCESS(rv, rv); - - // Prevent StartupCache::InvalidateCache from deleting the disk file - rv = LockCacheFile(true, profileDir); - NS_ENSURE_SUCCESS(rv, rv); - - sc->IgnoreDiskCache(); - - rv = sc->GetBuffer(id, &outbuf, &len); - - nsresult r = LockCacheFile(false, profileDir); - NS_ENSURE_SUCCESS(r, r); - - delete[] outbuf; - - if (rv == NS_ERROR_NOT_AVAILABLE) { - passed("buffer not available after ignoring disk cache"); - } else if (NS_SUCCEEDED(rv)) { - fail("GetBuffer succeeded unexpectedly after ignoring disk cache"); - return NS_ERROR_UNEXPECTED; - } else { - fail("GetBuffer gave an unexpected failure, expected NOT_AVAILABLE"); - return rv; - } - - sc->InvalidateCache(); - return NS_OK; -} - nsresult TestEarlyShutdown() { nsresult rv; - nsCOMPtr sc + nsCOMPtr sc = do_GetService("@mozilla.org/startupcache/cache;1", &rv); sc->InvalidateCache(); @@ -400,14 +299,14 @@ SetupJS(JSContext **cxp) } bool -GetHistogramCounts(const char *testmsg, const nsACString &histogram_id, - JSContext *cx, jsval *counts) +GetHistogramCounts(const char *testmsg, JSContext *cx, jsval *counts) { nsCOMPtr telemetry = do_GetService("@mozilla.org/base/telemetry;1"); + NS_NAMED_LITERAL_CSTRING(histogram_id, "STARTUP_CACHE_AGE_HOURS"); JS::AutoValueRooter h(cx); nsresult trv = telemetry->GetHistogramById(histogram_id, cx, h.addr()); if (NS_FAILED(trv)) { - fail("%s: couldn't get histogram %s", testmsg, ToNewCString(histogram_id)); + fail("%s: couldn't get histogram", testmsg); return false; } passed(testmsg); @@ -459,32 +358,11 @@ CompareCountArrays(JSContext *cx, JSObject *before, JSObject *after) } } - // None of the elements of the histograms's count arrays differed. + // All of the elements of the histograms's count arrays differed. // Not good, we should have recorded something. return NS_ERROR_FAILURE; } -nsresult -TestHistogramValues(const char* type, bool use_js, JSContext *cx, - JSObject *before, JSObject *after) -{ - if (!use_js) { - fail("couldn't check histogram recording"); - return NS_ERROR_FAILURE; - } - nsresult compare = CompareCountArrays(cx, before, after); - if (compare == NS_ERROR_UNEXPECTED) { - fail("count comparison error"); - return compare; - } - if (compare == NS_ERROR_FAILURE) { - fail("histogram didn't record %s", type); - return compare; - } - passed("histogram records %s", type); - return NS_OK; -} - int main(int argc, char** argv) { ScopedXPCOM xpcom("Startup Cache"); @@ -520,17 +398,9 @@ int main(int argc, char** argv) if (use_js && !JS_InitStandardClasses(cx, glob)) use_js = false; - NS_NAMED_LITERAL_CSTRING(age_histogram_id, "STARTUP_CACHE_AGE_HOURS"); - NS_NAMED_LITERAL_CSTRING(invalid_histogram_id, "STARTUP_CACHE_INVALID"); - - JS::AutoValueRooter age_before_counts(cx); + JS::AutoValueRooter before_counts(cx); if (use_js && !GetHistogramCounts("STARTUP_CACHE_AGE_HOURS histogram before test", - age_histogram_id, cx, age_before_counts.addr())) - use_js = false; - - JS::AutoValueRooter invalid_before_counts(cx); - if (use_js && !GetHistogramCounts("STARTUP_CACHE_INVALID histogram before test", - invalid_histogram_id, cx, invalid_before_counts.addr())) + cx, before_counts.addr())) use_js = false; nsresult scrv; @@ -546,32 +416,31 @@ int main(int argc, char** argv) rv = 1; if (NS_FAILED(TestWriteObject())) rv = 1; - nsCOMPtr profileDir = xpcom.GetProfileDirectory(); - if (NS_FAILED(TestIgnoreDiskCache(profileDir))) - rv = 1; if (NS_FAILED(TestEarlyShutdown())) rv = 1; - JS::AutoValueRooter age_after_counts(cx); + JS::AutoValueRooter after_counts(cx); if (use_js && !GetHistogramCounts("STARTUP_CACHE_AGE_HOURS histogram after test", - age_histogram_id, cx, age_after_counts.addr())) + cx, after_counts.addr())) use_js = false; - if (NS_FAILED(TestHistogramValues("age samples", use_js, cx, - JSVAL_TO_OBJECT(age_before_counts.value()), - JSVAL_TO_OBJECT(age_after_counts.value())))) - rv = 1; - - JS::AutoValueRooter invalid_after_counts(cx); - if (use_js && !GetHistogramCounts("STARTUP_CACHE_INVALID histogram after test", - invalid_histogram_id, cx, invalid_after_counts.addr())) - use_js = false; - - // STARTUP_CACHE_INVALID should have been triggered by TestIgnoreDiskCache() - if (NS_FAILED(TestHistogramValues("invalid disk cache", use_js, cx, - JSVAL_TO_OBJECT(invalid_before_counts.value()), - JSVAL_TO_OBJECT(invalid_after_counts.value())))) + if (!use_js) { + fail("couldn't check histogram recording"); rv = 1; + } else { + nsresult compare = CompareCountArrays(cx, + JSVAL_TO_OBJECT(before_counts.value()), + JSVAL_TO_OBJECT(after_counts.value())); + if (compare == NS_ERROR_UNEXPECTED) { + fail("count comparison error"); + rv = 1; + } else if (compare == NS_ERROR_FAILURE) { + fail("histogram didn't record samples"); + rv = 1; + } else { + passed("histogram records samples"); + } + } return rv; } diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 11fe8e38c8a2..23d955519aae 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -429,10 +429,6 @@ "n_buckets": 20, "description": "Startup cache age (hours)" }, - "STARTUP_CACHE_INVALID": { - "kind": "flag", - "description": "Was the disk startup cache file detected as invalid" - }, "WORD_CACHE_HITS": { "kind": "exponential", "high": "256", diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index fbf1f924915d..7a9cc3811ccf 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -91,13 +91,11 @@ #include "nsIWidget.h" #include "nsIDocShell.h" #include "nsAppShellCID.h" -#include "mozilla/scache/StartupCache.h" #include "mozilla/unused.h" using namespace mozilla; using mozilla::unused; -using mozilla::scache::StartupCache; #ifdef XP_WIN #include "nsIWinAppHelper.h" @@ -2407,7 +2405,7 @@ static void BuildVersion(nsCString &aBuf) static void WriteVersion(nsIFile* aProfileDir, const nsCString& aVersion, const nsCString& aOSABI, nsIFile* aXULRunnerDir, - nsIFile* aAppDir, bool invalidateCache) + nsIFile* aAppDir) { nsCOMPtr file; aProfileDir->Clone(getter_AddRefs(file)); @@ -2450,30 +2448,19 @@ WriteVersion(nsIFile* aProfileDir, const nsCString& aVersion, PR_Write(fd, appDir.get(), appDir.Length()); } - static const char kInvalidationHeader[] = "InvalidateCaches=1" NS_LINEBREAK; - if (invalidateCache) - PR_Write(fd, kInvalidationHeader, sizeof(kInvalidationHeader) - 1); - static const char kNL[] = NS_LINEBREAK; PR_Write(fd, kNL, sizeof(kNL) - 1); PR_Close(fd); } -/** - * Returns true if the startup cache file was successfully removed. - * Returns false if file->Clone fails at any point (OOM) or if unable - * to remove the startup cache file. Note in particular the return value - * is unaffected by a failure to remove extensions.ini - */ -static bool -RemoveComponentRegistries(nsIFile* aProfileDir, nsIFile* aLocalProfileDir, +static void RemoveComponentRegistries(nsIFile* aProfileDir, nsIFile* aLocalProfileDir, bool aRemoveEMFiles) { nsCOMPtr file; aProfileDir->Clone(getter_AddRefs(file)); if (!file) - return false; + return; if (aRemoveEMFiles) { file->SetNativeLeafName(NS_LITERAL_CSTRING("extensions.ini")); @@ -2482,7 +2469,7 @@ RemoveComponentRegistries(nsIFile* aProfileDir, nsIFile* aLocalProfileDir, aLocalProfileDir->Clone(getter_AddRefs(file)); if (!file) - return false; + return; #if defined(XP_UNIX) || defined(XP_BEOS) #define PLATFORM_FASL_SUFFIX ".mfasl" @@ -2497,8 +2484,7 @@ RemoveComponentRegistries(nsIFile* aProfileDir, nsIFile* aLocalProfileDir, file->Remove(false); file->SetNativeLeafName(NS_LITERAL_CSTRING("startupCache")); - nsresult rv = file->Remove(true); - return NS_SUCCEEDED(rv) || rv == NS_ERROR_FILE_TARGET_DOES_NOT_EXIST; + file->Remove(true); } // To support application initiated restart via nsIAppStartup.quit, we @@ -3546,22 +3532,21 @@ XREMain::XRE_mainStartup(bool* aExitFlag) // profile in different builds the component registry must be // re-generated to prevent mysterious component loading failures. // - bool invalidateStartupCache = false; if (gSafeMode) { - invalidateStartupCache = RemoveComponentRegistries(mProfD, mProfLD, false); + RemoveComponentRegistries(mProfD, mProfLD, false); WriteVersion(mProfD, NS_LITERAL_CSTRING("Safe Mode"), osABI, - mDirProvider.GetGREDir(), mAppData->directory, invalidateStartupCache); + mDirProvider.GetGREDir(), mAppData->directory); } else if (versionOK) { if (!cachesOK) { // Remove caches, forcing component re-registration. // The new list of additional components directories is derived from // information in "extensions.ini". - invalidateStartupCache = RemoveComponentRegistries(mProfD, mProfLD, false); + RemoveComponentRegistries(mProfD, mProfLD, false); // Rewrite compatibility.ini to remove the flag WriteVersion(mProfD, version, osABI, - mDirProvider.GetGREDir(), mAppData->directory, invalidateStartupCache); + mDirProvider.GetGREDir(), mAppData->directory); } // Nothing need be done for the normal startup case. } @@ -3569,16 +3554,13 @@ XREMain::XRE_mainStartup(bool* aExitFlag) // Remove caches, forcing component re-registration // with the default set of components (this disables any potentially // troublesome incompatible XPCOM components). - invalidateStartupCache = RemoveComponentRegistries(mProfD, mProfLD, true); + RemoveComponentRegistries(mProfD, mProfLD, true); // Write out version WriteVersion(mProfD, version, osABI, - mDirProvider.GetGREDir(), mAppData->directory, invalidateStartupCache); + mDirProvider.GetGREDir(), mAppData->directory); } - if (invalidateStartupCache) - StartupCache::IgnoreDiskCache(); - if (flagFile) { flagFile->Remove(true); }