Skip to content
Snippets Groups Projects
Commit 7da28910 authored by smolnar's avatar smolnar
Browse files

Backed out changeset f2359b80aaa2 (bug 1746447) for causing assertion failures...

Backed out changeset f2359b80aaa2 (bug 1746447) for causing assertion failures in StartupCache. CLOSED TREE
parent f7c5d9e7
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
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,29 +663,31 @@ 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();
mDirty = true;
mCacheData.reset();
// Most of this should be redundant given MaybeWriteOffMainThread should
// have run before now.
// We got the lock. Keep the following in sync with
// MaybeWriteOffMainThread:
WaitOnPrefetchThread();
mDirty = true;
mCacheData.reset();
// Most of this should be redundant given MaybeWriteOffMainThread should
// have run before now.
auto writeResult = WriteToDisk();
Unused << NS_WARN_IF(writeResult.isErr());
// 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.
auto writeResult = WriteToDisk();
Unused << NS_WARN_IF(writeResult.isErr());
// 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;
}
if (mCacheData.initialized() && !ShouldCompactCache()) {
return;
}
// Keep this code in sync with EnsureShutdownWriteComplete.
WaitOnPrefetchThread();
{
MutexAutoLock lock(mTableLock);
mDirty = true;
mCacheData.reset();
}
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());
});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment