diff --git a/source/lib/file/vfs/file_cache.cpp b/source/lib/file/vfs/file_cache.cpp index a91ca6e917..d0f39aae3f 100644 --- a/source/lib/file/vfs/file_cache.cpp +++ b/source/lib/file/vfs/file_cache.cpp @@ -182,9 +182,11 @@ public: { shared_ptr discardedData; size_t discardedSize; bool removed = m_cache.remove_least_valuable(&discardedData, &discardedSize); - // only false if cache is empty, which can't be the case because - // allocation failed. - ENSURE(removed); + // the cache is empty, and allocation still failed. + // apparently the cache is full of data that's still + // referenced, so we can't reserve any more space. + if(!removed) + return shared_ptr(); } } } diff --git a/source/lib/file/vfs/vfs.cpp b/source/lib/file/vfs/vfs.cpp index c69cbb95da..6f0a2af8a9 100644 --- a/source/lib/file/vfs/vfs.cpp +++ b/source/lib/file/vfs/vfs.cpp @@ -158,20 +158,22 @@ public: // instead, callers should log the error, including pathname. RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); + fileContents = DummySharedPtr((u8*)0); size = file->Size(); - // safely handle zero-length files - if(!size) - fileContents = DummySharedPtr((u8*)0); - else if(size > m_cacheSize) + if(size != 0) // (the file cache can't handle zero-length allocations) { - RETURN_STATUS_IF_ERR(AllocateAligned(fileContents, size, maxSectorSize)); - RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size())); - } - else - { - fileContents = m_fileCache.Reserve(size); - RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size())); - m_fileCache.Add(pathname, fileContents, size); + if(size < m_cacheSize/2) // (avoid evicting lots of previous data) + fileContents = m_fileCache.Reserve(size); + if(fileContents) + { + RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size())); + m_fileCache.Add(pathname, fileContents, size); + } + else + { + RETURN_STATUS_IF_ERR(AllocateAligned(fileContents, size, maxSectorSize)); + RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size())); + } } }