forked from mirrors/gecko-dev
Backed out changeset f2359b80aaa2 (bug 1746447) for causing assertion failures in StartupCache. CLOSED TREE
This commit is contained in:
parent
f7c5d9e7ee
commit
7da2891038
1 changed files with 38 additions and 58 deletions
|
|
@ -65,7 +65,6 @@ MOZ_DEFINE_MALLOC_SIZE_OF(StartupCacheMallocSizeOf)
|
|||
NS_IMETHODIMP
|
||||
StartupCache::CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData, bool aAnonymize) {
|
||||
MutexAutoLock lock(mTableLock);
|
||||
MOZ_COLLECT_REPORT(
|
||||
"explicit/startup-cache/mapping", KIND_NONHEAP, UNITS_BYTES,
|
||||
mCacheData.nonHeapSizeOfExcludingThis(),
|
||||
|
|
@ -227,11 +226,8 @@ nsresult StartupCache::Init() {
|
|||
false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mTableLock);
|
||||
auto result = LoadArchive();
|
||||
rv = result.isErr() ? result.unwrapErr() : NS_OK;
|
||||
}
|
||||
|
||||
gFoundDiskCacheOnInit = rv != NS_ERROR_FILE_NOT_FOUND;
|
||||
|
||||
|
|
@ -264,8 +260,6 @@ Result<Ok, nsresult> StartupCache::LoadArchive() {
|
|||
MOZ_ASSERT(NS_IsMainThread(), "Can only load startup cache on main thread");
|
||||
if (gIgnoreDiskCache) return Err(NS_ERROR_FAILURE);
|
||||
|
||||
mTableLock.AssertCurrentThreadOwns();
|
||||
|
||||
MOZ_TRY(mCacheData.init(mFile));
|
||||
auto size = mCacheData.size();
|
||||
if (CanPrefetchMemory()) {
|
||||
|
|
@ -365,7 +359,6 @@ bool StartupCache::HasEntry(const char* id) {
|
|||
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Startup cache only available on main thread");
|
||||
|
||||
MutexAutoLock lock(mTableLock);
|
||||
return mTable.has(nsDependentCString(id));
|
||||
}
|
||||
|
||||
|
|
@ -381,7 +374,6 @@ nsresult StartupCache::GetBuffer(const char* id, const char** outbuf,
|
|||
auto telemetry =
|
||||
MakeScopeExit([&label] { Telemetry::AccumulateCategorical(label); });
|
||||
|
||||
MutexAutoLock lock(mTableLock);
|
||||
decltype(mTable)::Ptr p = mTable.lookup(nsDependentCString(id));
|
||||
if (!p) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
|
@ -426,7 +418,6 @@ nsresult StartupCache::GetBuffer(const char* id, const char** outbuf,
|
|||
uncompressed.From(totalWritten), compressed.From(totalRead));
|
||||
if (NS_WARN_IF(result.isErr())) {
|
||||
value.mData = nullptr;
|
||||
MutexAutoUnlock unlock(mTableLock);
|
||||
InvalidateCache();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
@ -466,19 +457,19 @@ nsresult StartupCache::PutBuffer(const char* id, UniquePtr<char[]>&& inbuf,
|
|||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Try to gain the table write lock. If the background task to write the
|
||||
// cache is running, this will fail.
|
||||
MutexAutoTryLock lock(mTableLock);
|
||||
if (!lock) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
mTableLock.AssertCurrentThreadOwns();
|
||||
bool exists = mTable.has(nsDependentCString(id));
|
||||
|
||||
if (exists) {
|
||||
NS_WARNING("Existing entry in StartupCache.");
|
||||
// Double-caching is undesirable but not an error.
|
||||
return NS_OK;
|
||||
}
|
||||
// Try to gain the table write lock. If the background task to write the
|
||||
// cache is running, this will fail.
|
||||
if (!mTableLock.TryLock()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
auto lockGuard = MakeScopeExit([&] { mTableLock.Unlock(); });
|
||||
|
||||
// putNew returns false on alloc failure - in the very unlikely event we hit
|
||||
// that and aren't going to crash elsewhere, there's no reason we need to
|
||||
|
|
@ -622,7 +613,7 @@ Result<Ok, nsresult> StartupCache::WriteToDisk() {
|
|||
void StartupCache::InvalidateCache(bool memoryOnly) {
|
||||
WaitOnPrefetchThread();
|
||||
// Ensure we're not writing using mTable...
|
||||
MutexAutoLock lock(mTableLock);
|
||||
MutexAutoLock unlock(mTableLock);
|
||||
|
||||
mWrittenOnce = false;
|
||||
if (memoryOnly) {
|
||||
|
|
@ -672,16 +663,16 @@ void StartupCache::MaybeInitShutdownWrite() {
|
|||
void StartupCache::EnsureShutdownWriteComplete() {
|
||||
// If we've already written or there's nothing to write,
|
||||
// we don't need to do anything. This is the common case.
|
||||
if (mWrittenOnce) {
|
||||
return;
|
||||
}
|
||||
MutexAutoLock lock(mTableLock);
|
||||
if (mCacheData.initialized() && !ShouldCompactCache()) {
|
||||
if (mWrittenOnce || (mCacheData.initialized() && !ShouldCompactCache())) {
|
||||
return;
|
||||
}
|
||||
// Otherwise, ensure the write happens. The timer should have been cancelled
|
||||
// already in MaybeInitShutdownWrite.
|
||||
|
||||
if (!mTableLock.TryLock()) {
|
||||
// Uh oh, we're writing away from the main thread. Wait to gain the lock,
|
||||
// to ensure the write completes.
|
||||
mTableLock.Lock();
|
||||
} else {
|
||||
// We got the lock. Keep the following in sync with
|
||||
// MaybeWriteOffMainThread:
|
||||
WaitOnPrefetchThread();
|
||||
|
|
@ -695,6 +686,8 @@ void StartupCache::EnsureShutdownWriteComplete() {
|
|||
// We've had the lock, and `WriteToDisk()` sets mWrittenOnce and mDirty
|
||||
// when done, and checks for them when starting, so we don't need to do
|
||||
// anything else.
|
||||
}
|
||||
mTableLock.Unlock();
|
||||
}
|
||||
|
||||
void StartupCache::IgnoreDiskCache() {
|
||||
|
|
@ -714,22 +707,14 @@ void StartupCache::ThreadedPrefetch(void* aClosure) {
|
|||
NS_SetCurrentThreadName("StartupCache");
|
||||
mozilla::IOInterposer::RegisterCurrentThread();
|
||||
StartupCache* startupCacheObj = static_cast<StartupCache*>(aClosure);
|
||||
uint8_t* buf;
|
||||
size_t size;
|
||||
{
|
||||
MutexAutoLock lock(startupCacheObj->mTableLock);
|
||||
buf = startupCacheObj->mCacheData.get<uint8_t>().get();
|
||||
size = startupCacheObj->mCacheData.size();
|
||||
}
|
||||
// PrefetchMemory does madvise/equivalent, but doesn't access the memory
|
||||
// pointed to by buf
|
||||
uint8_t* buf = startupCacheObj->mCacheData.get<uint8_t>().get();
|
||||
size_t size = startupCacheObj->mCacheData.size();
|
||||
MMAP_FAULT_HANDLER_BEGIN_BUFFER(buf, size)
|
||||
PrefetchMemory(buf, size);
|
||||
MMAP_FAULT_HANDLER_CATCH()
|
||||
mozilla::IOInterposer::UnregisterCurrentThread();
|
||||
}
|
||||
|
||||
// mTableLock must be held
|
||||
bool StartupCache::ShouldCompactCache() {
|
||||
// If we've requested less than 4/5 of the startup cache, then we should
|
||||
// probably compact it down. This can happen quite easily after the first run,
|
||||
|
|
@ -763,24 +748,19 @@ void StartupCache::MaybeWriteOffMainThread() {
|
|||
return;
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mTableLock);
|
||||
if (mCacheData.initialized() && !ShouldCompactCache()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep this code in sync with EnsureShutdownWriteComplete.
|
||||
WaitOnPrefetchThread();
|
||||
{
|
||||
MutexAutoLock lock(mTableLock);
|
||||
mDirty = true;
|
||||
mCacheData.reset();
|
||||
}
|
||||
|
||||
RefPtr<StartupCache> self = this;
|
||||
nsCOMPtr<nsIRunnable> runnable =
|
||||
NS_NewRunnableFunction("StartupCache::Write", [self]() mutable {
|
||||
MutexAutoLock lock(self->mTableLock);
|
||||
MutexAutoLock unlock(self->mTableLock);
|
||||
auto result = self->WriteToDisk();
|
||||
Unused << NS_WARN_IF(result.isErr());
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue