Backed out changeset dc1a00f252c8 (bug 1662676) for cpp failures in CacheIndexRecordWrapper. CLOSED TREE

This commit is contained in:
Dorel Luca 2021-05-17 18:13:14 +03:00
Родитель 12a25a8cd0
Коммит 241907c8fc
6 изменённых файлов: 207 добавлений и 173 удалений

Просмотреть файл

@ -41,16 +41,14 @@ namespace {
class FrecencyComparator {
public:
bool Equals(const RefPtr<CacheIndexRecordWrapper>& a,
const RefPtr<CacheIndexRecordWrapper>& b) const {
bool Equals(CacheIndexRecord* a, CacheIndexRecord* b) const {
if (!a || !b) {
return false;
}
return a->Get()->mFrecency == b->Get()->mFrecency;
return a->mFrecency == b->mFrecency;
}
bool LessThan(const RefPtr<CacheIndexRecordWrapper>& a,
const RefPtr<CacheIndexRecordWrapper>& b) const {
bool LessThan(CacheIndexRecord* a, CacheIndexRecord* b) const {
// Removed (=null) entries must be at the end of the array.
if (!a) {
return false;
@ -60,19 +58,39 @@ class FrecencyComparator {
}
// Place entries with frecency 0 at the end of the non-removed entries.
if (a->Get()->mFrecency == 0) {
if (a->mFrecency == 0) {
return false;
}
if (b->Get()->mFrecency == 0) {
if (b->mFrecency == 0) {
return true;
}
return a->Get()->mFrecency < b->Get()->mFrecency;
return a->mFrecency < b->mFrecency;
}
};
} // namespace
CacheIndexRecord::~CacheIndexRecord() {
if (!StaticPrefs::network_cache_frecency_array_check_enabled()) {
return;
}
if (!(mFlags & CacheIndexEntry::kDirtyMask) &&
((mFlags & CacheIndexEntry::kFileSizeMask) == 0)) {
return;
}
RefPtr<CacheIndex> index = CacheIndex::gInstance;
if (index) {
CacheIndex::sLock.AssertCurrentThreadOwns();
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
bool found = index->mFrecencyArray.RecordExisted(this);
MOZ_DIAGNOSTIC_ASSERT(!found);
#endif
}
}
/**
* This helper class is responsible for keeping CacheIndex::mIndexStats and
* CacheIndex::mFrecencyArray up to date.
@ -91,8 +109,18 @@ class CacheIndexEntryAutoManage {
const CacheIndexEntry* entry = FindEntry();
mIndex->mIndexStats.BeforeChange(entry);
if (entry && entry->IsInitialized() && !entry->IsRemoved()) {
mOldRecord = entry->mRec;
mOldFrecency = entry->mRec->Get()->mFrecency;
mOldRecord = entry->mRec.get();
mOldFrecency = entry->mRec->mFrecency;
} else {
if (entry) {
// If we are here, it means mOldRecord is null. We'd like to check this
// entry's record is not in the frecency array, since we remove the
// record from the frecency array only when mOldRecord is not null.
if (mIndex->mFrecencyArray.RecordExisted(entry->mRec.get())) {
MOZ_DIAGNOSTIC_ASSERT(false);
mIndex->mFrecencyArray.RemoveRecord(entry->mRec.get());
}
}
}
}
@ -106,28 +134,29 @@ class CacheIndexEntryAutoManage {
}
if (entry && !mOldRecord) {
mIndex->mFrecencyArray.AppendRecord(entry->mRec);
mIndex->AddRecordToIterators(entry->mRec);
mIndex->mFrecencyArray.AppendRecord(entry->mRec.get());
mIndex->AddRecordToIterators(entry->mRec.get());
} else if (!entry && mOldRecord) {
mIndex->mFrecencyArray.RemoveRecord(mOldRecord);
mIndex->RemoveRecordFromIterators(mOldRecord);
} else if (entry && mOldRecord) {
if (entry->mRec != mOldRecord) {
auto rec = entry->mRec.get();
if (rec != mOldRecord) {
// record has a different address, we have to replace it
mIndex->ReplaceRecordInIterators(mOldRecord, entry->mRec);
mIndex->ReplaceRecordInIterators(mOldRecord, rec);
if (entry->mRec->Get()->mFrecency == mOldFrecency) {
if (entry->mRec->mFrecency == mOldFrecency) {
// If frecency hasn't changed simply replace the pointer
mIndex->mFrecencyArray.ReplaceRecord(mOldRecord, entry->mRec);
mIndex->mFrecencyArray.ReplaceRecord(mOldRecord, rec);
} else {
// Remove old pointer and insert the new one at the end of the array
mIndex->mFrecencyArray.RemoveRecord(mOldRecord);
mIndex->mFrecencyArray.AppendRecord(entry->mRec);
mIndex->mFrecencyArray.AppendRecord(rec);
}
} else if (entry->mRec->Get()->mFrecency != mOldFrecency) {
} else if (entry->mRec->mFrecency != mOldFrecency) {
// Move the element at the end of the array
mIndex->mFrecencyArray.RemoveRecord(entry->mRec);
mIndex->mFrecencyArray.AppendRecord(entry->mRec);
mIndex->mFrecencyArray.RemoveRecord(rec);
mIndex->mFrecencyArray.AppendRecord(rec);
}
} else {
// both entries were removed or not initialized, do nothing
@ -169,7 +198,7 @@ class CacheIndexEntryAutoManage {
const SHA1Sum::Hash* mHash;
RefPtr<CacheIndex> mIndex;
RefPtr<CacheIndexRecordWrapper> mOldRecord;
CacheIndexRecord* mOldRecord;
uint32_t mOldFrecency;
bool mDoNotSearchInIndex;
bool mDoNotSearchInUpdates;
@ -845,6 +874,7 @@ nsresult CacheIndex::RemoveEntry(const SHA1Sum::Hash* aHash) {
return NS_ERROR_NOT_AVAILABLE;
}
CacheIndexRecord* removedRecord = nullptr;
{
CacheIndexEntryAutoManage entryMng(aHash, index);
@ -875,6 +905,7 @@ nsresult CacheIndex::RemoveEntry(const SHA1Sum::Hash* aHash) {
} else {
if (entry) {
if (!entry->IsDirty() && entry->IsFileEmpty()) {
removedRecord = entry->mRec.get();
index->mIndex.RemoveEntry(entry);
entry = nullptr;
} else {
@ -916,6 +947,13 @@ nsresult CacheIndex::RemoveEntry(const SHA1Sum::Hash* aHash) {
updated->MarkFresh();
}
}
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
if (removedRecord) {
MOZ_DIAGNOSTIC_ASSERT(!index->mFrecencyArray.RecordExisted(removedRecord));
}
#else
Unused << removedRecord;
#endif
index->StartUpdatingIndexIfNeeded();
index->WriteIndexToDiskIfNeeded();
@ -1278,7 +1316,7 @@ nsresult CacheIndex::GetEntryForEviction(bool aIgnoreEmptyEntries,
index->mFrecencyArray.SortIfNeeded();
for (auto iter = index->mFrecencyArray.Iter(); !iter.Done(); iter.Next()) {
CacheIndexRecord* rec = iter.Get()->Get();
CacheIndexRecord* rec = iter.Get();
memcpy(&hash, rec->mHash, sizeof(SHA1Sum::Hash));
@ -1395,11 +1433,11 @@ nsresult CacheIndex::GetCacheStats(nsILoadContextInfo* aInfo, uint32_t* aSize,
*aCount = 0;
for (auto iter = index->mFrecencyArray.Iter(); !iter.Done(); iter.Next()) {
if (aInfo &&
!CacheIndexEntry::RecordMatchesLoadContextInfo(iter.Get(), aInfo))
CacheIndexRecord* record = iter.Get();
if (aInfo && !CacheIndexEntry::RecordMatchesLoadContextInfo(record, aInfo))
continue;
*aSize += CacheIndexEntry::GetFileSize(*(iter.Get()->Get()));
*aSize += CacheIndexEntry::GetFileSize(*record);
++*aCount;
}
@ -1608,6 +1646,7 @@ void CacheIndex::ProcessPendingOperations() {
MOZ_ASSERT(update->IsFresh());
CacheIndexEntry* entry = mIndex.GetEntry(*update->Hash());
CacheIndexRecord* removedRecord = nullptr;
{
CacheIndexEntryAutoManage emng(update->Hash(), this);
emng.DoNotSearchInUpdates();
@ -1621,6 +1660,7 @@ void CacheIndex::ProcessPendingOperations() {
// Entries with empty file are not stored in index on disk. Just
// remove the entry, but only in case the entry is not dirty, i.e.
// the entry file was empty when we wrote the index.
removedRecord = entry->mRec.get();
mIndex.RemoveEntry(entry);
entry = nullptr;
} else {
@ -1641,6 +1681,13 @@ void CacheIndex::ProcessPendingOperations() {
*entry = *update;
}
}
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
if (removedRecord) {
MOZ_DIAGNOSTIC_ASSERT(!mFrecencyArray.RecordExisted(removedRecord));
}
#else
Unused << removedRecord;
#endif
iter.Remove();
}
@ -3338,23 +3385,23 @@ void CacheIndex::ReleaseBuffer() {
mRWBufPos = 0;
}
void CacheIndex::FrecencyArray::AppendRecord(CacheIndexRecordWrapper* aRecord) {
void CacheIndex::FrecencyArray::AppendRecord(CacheIndexRecord* aRecord) {
LOG(
("CacheIndex::FrecencyArray::AppendRecord() [record=%p, hash=%08x%08x%08x"
"%08x%08x]",
aRecord, LOGSHA1(aRecord->Get()->mHash)));
aRecord, LOGSHA1(aRecord->mHash)));
MOZ_ASSERT(!mRecs.Contains(aRecord));
mRecs.AppendElement(aRecord);
// If the new frecency is 0, the element should be at the end of the array,
// i.e. this change doesn't affect order of the array
if (aRecord->Get()->mFrecency != 0) {
if (aRecord->mFrecency != 0) {
++mUnsortedElements;
}
}
void CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecordWrapper* aRecord) {
void CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecord* aRecord) {
LOG(("CacheIndex::FrecencyArray::RemoveRecord() [record=%p]", aRecord));
decltype(mRecs)::index_type idx;
@ -3368,8 +3415,8 @@ void CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecordWrapper* aRecord) {
SortIfNeeded();
}
void CacheIndex::FrecencyArray::ReplaceRecord(
CacheIndexRecordWrapper* aOldRecord, CacheIndexRecordWrapper* aNewRecord) {
void CacheIndex::FrecencyArray::ReplaceRecord(CacheIndexRecord* aOldRecord,
CacheIndexRecord* aNewRecord) {
LOG(
("CacheIndex::FrecencyArray::ReplaceRecord() [oldRecord=%p, "
"newRecord=%p]",
@ -3381,6 +3428,10 @@ void CacheIndex::FrecencyArray::ReplaceRecord(
mRecs[idx] = aNewRecord;
}
bool CacheIndex::FrecencyArray::RecordExisted(CacheIndexRecord* aRecord) {
return mRecs.Contains(aRecord);
}
void CacheIndex::FrecencyArray::SortIfNeeded() {
const uint32_t kMaxUnsortedCount = 512;
const uint32_t kMaxUnsortedPercent = 10;
@ -3412,7 +3463,7 @@ void CacheIndex::FrecencyArray::SortIfNeeded() {
}
}
void CacheIndex::AddRecordToIterators(CacheIndexRecordWrapper* aRecord) {
void CacheIndex::AddRecordToIterators(CacheIndexRecord* aRecord) {
sLock.AssertCurrentThreadOwns();
for (uint32_t i = 0; i < mIterators.Length(); ++i) {
@ -3423,7 +3474,7 @@ void CacheIndex::AddRecordToIterators(CacheIndexRecordWrapper* aRecord) {
}
}
void CacheIndex::RemoveRecordFromIterators(CacheIndexRecordWrapper* aRecord) {
void CacheIndex::RemoveRecordFromIterators(CacheIndexRecord* aRecord) {
sLock.AssertCurrentThreadOwns();
for (uint32_t i = 0; i < mIterators.Length(); ++i) {
@ -3434,8 +3485,8 @@ void CacheIndex::RemoveRecordFromIterators(CacheIndexRecordWrapper* aRecord) {
}
}
void CacheIndex::ReplaceRecordInIterators(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecordWrapper* aNewRecord) {
void CacheIndex::ReplaceRecordInIterators(CacheIndexRecord* aOldRecord,
CacheIndexRecord* aNewRecord) {
sLock.AssertCurrentThreadOwns();
for (uint32_t i = 0; i < mIterators.Length(); ++i) {

Просмотреть файл

@ -101,6 +101,8 @@ struct CacheIndexRecord {
mOnStopTime(kIndexTimeNotAvailable),
mContentType(nsICacheEntry::CONTENT_TYPE_UNKNOWN),
mFlags(0) {}
~CacheIndexRecord();
};
#pragma pack(pop)
@ -114,18 +116,6 @@ static_assert(sizeof(CacheIndexRecord::mHash) +
sizeof(CacheIndexRecord),
"Unexpected sizeof(CacheIndexRecord)!");
class CacheIndexRecordWrapper final {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheIndexRecordWrapper)
CacheIndexRecordWrapper() : mRec(MakeUnique<CacheIndexRecord>()) {}
CacheIndexRecord* Get() { return mRec.get(); }
private:
~CacheIndexRecordWrapper() = default;
UniquePtr<CacheIndexRecord> mRec;
};
class CacheIndexEntry : public PLDHashEntryHdr {
public:
typedef const SHA1Sum::Hash& KeyType;
@ -133,10 +123,10 @@ class CacheIndexEntry : public PLDHashEntryHdr {
explicit CacheIndexEntry(KeyTypePointer aKey) {
MOZ_COUNT_CTOR(CacheIndexEntry);
mRec = new CacheIndexRecordWrapper();
mRec = MakeUnique<CacheIndexRecord>();
LOG(("CacheIndexEntry::CacheIndexEntry() - Created record [rec=%p]",
mRec->Get()));
memcpy(&mRec->Get()->mHash, aKey, sizeof(SHA1Sum::Hash));
mRec.get()));
memcpy(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash));
}
CacheIndexEntry(const CacheIndexEntry& aOther) {
MOZ_ASSERT_UNREACHABLE("CacheIndexEntry copy constructor is forbidden!");
@ -144,12 +134,12 @@ class CacheIndexEntry : public PLDHashEntryHdr {
~CacheIndexEntry() {
MOZ_COUNT_DTOR(CacheIndexEntry);
LOG(("CacheIndexEntry::~CacheIndexEntry() - Deleting record [rec=%p]",
mRec->Get()));
mRec.get()));
}
// KeyEquals(): does this entry match this key?
bool KeyEquals(KeyTypePointer aKey) const {
return memcmp(&mRec->Get()->mHash, aKey, sizeof(SHA1Sum::Hash)) == 0;
return memcmp(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash)) == 0;
}
// KeyToPointer(): Convert KeyType to KeyTypePointer
@ -165,93 +155,88 @@ class CacheIndexEntry : public PLDHashEntryHdr {
enum { ALLOW_MEMMOVE = true };
bool operator==(const CacheIndexEntry& aOther) const {
return KeyEquals(&aOther.mRec->Get()->mHash);
return KeyEquals(&aOther.mRec->mHash);
}
CacheIndexEntry& operator=(const CacheIndexEntry& aOther) {
MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aOther.mRec->Get()->mHash,
sizeof(SHA1Sum::Hash)) == 0);
mRec->Get()->mFrecency = aOther.mRec->Get()->mFrecency;
mRec->Get()->mOriginAttrsHash = aOther.mRec->Get()->mOriginAttrsHash;
mRec->Get()->mOnStartTime = aOther.mRec->Get()->mOnStartTime;
mRec->Get()->mOnStopTime = aOther.mRec->Get()->mOnStopTime;
mRec->Get()->mContentType = aOther.mRec->Get()->mContentType;
mRec->Get()->mFlags = aOther.mRec->Get()->mFlags;
MOZ_ASSERT(
memcmp(&mRec->mHash, &aOther.mRec->mHash, sizeof(SHA1Sum::Hash)) == 0);
mRec->mFrecency = aOther.mRec->mFrecency;
mRec->mOriginAttrsHash = aOther.mRec->mOriginAttrsHash;
mRec->mOnStartTime = aOther.mRec->mOnStartTime;
mRec->mOnStopTime = aOther.mRec->mOnStopTime;
mRec->mContentType = aOther.mRec->mContentType;
mRec->mFlags = aOther.mRec->mFlags;
return *this;
}
void InitNew() {
mRec->Get()->mFrecency = 0;
mRec->Get()->mOriginAttrsHash = 0;
mRec->Get()->mOnStartTime = kIndexTimeNotAvailable;
mRec->Get()->mOnStopTime = kIndexTimeNotAvailable;
mRec->Get()->mContentType = nsICacheEntry::CONTENT_TYPE_UNKNOWN;
mRec->Get()->mFlags = 0;
mRec->mFrecency = 0;
mRec->mOriginAttrsHash = 0;
mRec->mOnStartTime = kIndexTimeNotAvailable;
mRec->mOnStopTime = kIndexTimeNotAvailable;
mRec->mContentType = nsICacheEntry::CONTENT_TYPE_UNKNOWN;
mRec->mFlags = 0;
}
void Init(OriginAttrsHash aOriginAttrsHash, bool aAnonymous, bool aPinned) {
MOZ_ASSERT(mRec->Get()->mFrecency == 0);
MOZ_ASSERT(mRec->Get()->mOriginAttrsHash == 0);
MOZ_ASSERT(mRec->Get()->mOnStartTime == kIndexTimeNotAvailable);
MOZ_ASSERT(mRec->Get()->mOnStopTime == kIndexTimeNotAvailable);
MOZ_ASSERT(mRec->Get()->mContentType ==
nsICacheEntry::CONTENT_TYPE_UNKNOWN);
MOZ_ASSERT(mRec->mFrecency == 0);
MOZ_ASSERT(mRec->mOriginAttrsHash == 0);
MOZ_ASSERT(mRec->mOnStartTime == kIndexTimeNotAvailable);
MOZ_ASSERT(mRec->mOnStopTime == kIndexTimeNotAvailable);
MOZ_ASSERT(mRec->mContentType == nsICacheEntry::CONTENT_TYPE_UNKNOWN);
// When we init the entry it must be fresh and may be dirty
MOZ_ASSERT((mRec->Get()->mFlags & ~kDirtyMask) == kFreshMask);
MOZ_ASSERT((mRec->mFlags & ~kDirtyMask) == kFreshMask);
mRec->Get()->mOriginAttrsHash = aOriginAttrsHash;
mRec->Get()->mFlags |= kInitializedMask;
mRec->mOriginAttrsHash = aOriginAttrsHash;
mRec->mFlags |= kInitializedMask;
if (aAnonymous) {
mRec->Get()->mFlags |= kAnonymousMask;
mRec->mFlags |= kAnonymousMask;
}
if (aPinned) {
mRec->Get()->mFlags |= kPinnedMask;
mRec->mFlags |= kPinnedMask;
}
}
const SHA1Sum::Hash* Hash() const { return &mRec->Get()->mHash; }
const SHA1Sum::Hash* Hash() const { return &mRec->mHash; }
bool IsInitialized() const {
return !!(mRec->Get()->mFlags & kInitializedMask);
}
bool IsInitialized() const { return !!(mRec->mFlags & kInitializedMask); }
mozilla::net::OriginAttrsHash OriginAttrsHash() const {
return mRec->Get()->mOriginAttrsHash;
return mRec->mOriginAttrsHash;
}
bool Anonymous() const { return !!(mRec->Get()->mFlags & kAnonymousMask); }
bool Anonymous() const { return !!(mRec->mFlags & kAnonymousMask); }
bool IsRemoved() const { return !!(mRec->Get()->mFlags & kRemovedMask); }
void MarkRemoved() { mRec->Get()->mFlags |= kRemovedMask; }
bool IsRemoved() const { return !!(mRec->mFlags & kRemovedMask); }
void MarkRemoved() { mRec->mFlags |= kRemovedMask; }
bool IsDirty() const { return !!(mRec->Get()->mFlags & kDirtyMask); }
void MarkDirty() { mRec->Get()->mFlags |= kDirtyMask; }
void ClearDirty() { mRec->Get()->mFlags &= ~kDirtyMask; }
bool IsDirty() const { return !!(mRec->mFlags & kDirtyMask); }
void MarkDirty() { mRec->mFlags |= kDirtyMask; }
void ClearDirty() { mRec->mFlags &= ~kDirtyMask; }
bool IsFresh() const { return !!(mRec->Get()->mFlags & kFreshMask); }
void MarkFresh() { mRec->Get()->mFlags |= kFreshMask; }
bool IsFresh() const { return !!(mRec->mFlags & kFreshMask); }
void MarkFresh() { mRec->mFlags |= kFreshMask; }
bool IsPinned() const { return !!(mRec->Get()->mFlags & kPinnedMask); }
bool IsPinned() const { return !!(mRec->mFlags & kPinnedMask); }
void SetFrecency(uint32_t aFrecency) { mRec->Get()->mFrecency = aFrecency; }
uint32_t GetFrecency() const { return mRec->Get()->mFrecency; }
void SetFrecency(uint32_t aFrecency) { mRec->mFrecency = aFrecency; }
uint32_t GetFrecency() const { return mRec->mFrecency; }
void SetHasAltData(bool aHasAltData) {
aHasAltData ? mRec->Get()->mFlags |= kHasAltDataMask
: mRec->Get()->mFlags &= ~kHasAltDataMask;
}
bool GetHasAltData() const {
return !!(mRec->Get()->mFlags & kHasAltDataMask);
aHasAltData ? mRec->mFlags |= kHasAltDataMask
: mRec->mFlags &= ~kHasAltDataMask;
}
bool GetHasAltData() const { return !!(mRec->mFlags & kHasAltDataMask); }
void SetOnStartTime(uint16_t aTime) { mRec->Get()->mOnStartTime = aTime; }
uint16_t GetOnStartTime() const { return mRec->Get()->mOnStartTime; }
void SetOnStartTime(uint16_t aTime) { mRec->mOnStartTime = aTime; }
uint16_t GetOnStartTime() const { return mRec->mOnStartTime; }
void SetOnStopTime(uint16_t aTime) { mRec->Get()->mOnStopTime = aTime; }
uint16_t GetOnStopTime() const { return mRec->Get()->mOnStopTime; }
void SetOnStopTime(uint16_t aTime) { mRec->mOnStopTime = aTime; }
uint16_t GetOnStopTime() const { return mRec->mOnStopTime; }
void SetContentType(uint8_t aType) { mRec->Get()->mContentType = aType; }
uint8_t GetContentType() const { return GetContentType(mRec->Get()); }
void SetContentType(uint8_t aType) { mRec->mContentType = aType; }
uint8_t GetContentType() const { return GetContentType(mRec.get()); }
static uint8_t GetContentType(CacheIndexRecord* aRec) {
if (aRec->mContentType >= nsICacheEntry::CONTENT_TYPE_LAST) {
LOG(
@ -272,11 +257,11 @@ class CacheIndexEntry : public PLDHashEntryHdr {
kFileSizeMask));
aFileSize = kFileSizeMask;
}
mRec->Get()->mFlags &= ~kFileSizeMask;
mRec->Get()->mFlags |= aFileSize;
mRec->mFlags &= ~kFileSizeMask;
mRec->mFlags |= aFileSize;
}
// Returns filesize in kilobytes.
uint32_t GetFileSize() const { return GetFileSize(*(mRec->Get())); }
uint32_t GetFileSize() const { return GetFileSize(*mRec); }
static uint32_t GetFileSize(const CacheIndexRecord& aRec) {
return aRec.mFlags & kFileSizeMask;
}
@ -287,39 +272,38 @@ class CacheIndexEntry : public PLDHashEntryHdr {
void WriteToBuf(void* aBuf) {
uint8_t* ptr = static_cast<uint8_t*>(aBuf);
memcpy(ptr, mRec->Get()->mHash, sizeof(SHA1Sum::Hash));
memcpy(ptr, mRec->mHash, sizeof(SHA1Sum::Hash));
ptr += sizeof(SHA1Sum::Hash);
NetworkEndian::writeUint32(ptr, mRec->Get()->mFrecency);
NetworkEndian::writeUint32(ptr, mRec->mFrecency);
ptr += sizeof(uint32_t);
NetworkEndian::writeUint64(ptr, mRec->Get()->mOriginAttrsHash);
NetworkEndian::writeUint64(ptr, mRec->mOriginAttrsHash);
ptr += sizeof(uint64_t);
NetworkEndian::writeUint16(ptr, mRec->Get()->mOnStartTime);
NetworkEndian::writeUint16(ptr, mRec->mOnStartTime);
ptr += sizeof(uint16_t);
NetworkEndian::writeUint16(ptr, mRec->Get()->mOnStopTime);
NetworkEndian::writeUint16(ptr, mRec->mOnStopTime);
ptr += sizeof(uint16_t);
*ptr = mRec->Get()->mContentType;
*ptr = mRec->mContentType;
ptr += sizeof(uint8_t);
// Dirty and fresh flags should never go to disk, since they make sense only
// during current session.
NetworkEndian::writeUint32(
ptr, mRec->Get()->mFlags & ~(kDirtyMask | kFreshMask));
NetworkEndian::writeUint32(ptr, mRec->mFlags & ~(kDirtyMask | kFreshMask));
}
void ReadFromBuf(void* aBuf) {
const uint8_t* ptr = static_cast<const uint8_t*>(aBuf);
MOZ_ASSERT(memcmp(&mRec->Get()->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0);
MOZ_ASSERT(memcmp(&mRec->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0);
ptr += sizeof(SHA1Sum::Hash);
mRec->Get()->mFrecency = NetworkEndian::readUint32(ptr);
mRec->mFrecency = NetworkEndian::readUint32(ptr);
ptr += sizeof(uint32_t);
mRec->Get()->mOriginAttrsHash = NetworkEndian::readUint64(ptr);
mRec->mOriginAttrsHash = NetworkEndian::readUint64(ptr);
ptr += sizeof(uint64_t);
mRec->Get()->mOnStartTime = NetworkEndian::readUint16(ptr);
mRec->mOnStartTime = NetworkEndian::readUint16(ptr);
ptr += sizeof(uint16_t);
mRec->Get()->mOnStopTime = NetworkEndian::readUint16(ptr);
mRec->mOnStopTime = NetworkEndian::readUint16(ptr);
ptr += sizeof(uint16_t);
mRec->Get()->mContentType = *ptr;
mRec->mContentType = *ptr;
ptr += sizeof(uint8_t);
mRec->Get()->mFlags = NetworkEndian::readUint32(ptr);
mRec->mFlags = NetworkEndian::readUint32(ptr);
}
void Log() const {
@ -328,20 +312,20 @@ class CacheIndexEntry : public PLDHashEntryHdr {
" initialized=%u, removed=%u, dirty=%u, anonymous=%u, "
"originAttrsHash=%" PRIx64 ", frecency=%u, hasAltData=%u, "
"onStartTime=%u, onStopTime=%u, contentType=%u, size=%u]",
this, LOGSHA1(mRec->Get()->mHash), IsFresh(), IsInitialized(),
IsRemoved(), IsDirty(), Anonymous(), OriginAttrsHash(), GetFrecency(),
this, LOGSHA1(mRec->mHash), IsFresh(), IsInitialized(), IsRemoved(),
IsDirty(), Anonymous(), OriginAttrsHash(), GetFrecency(),
GetHasAltData(), GetOnStartTime(), GetOnStopTime(), GetContentType(),
GetFileSize()));
}
static bool RecordMatchesLoadContextInfo(CacheIndexRecordWrapper* aRec,
static bool RecordMatchesLoadContextInfo(CacheIndexRecord* aRec,
nsILoadContextInfo* aInfo) {
MOZ_ASSERT(aInfo);
if (!aInfo->IsPrivate() &&
GetOriginAttrsHash(*aInfo->OriginAttributesPtr()) ==
aRec->Get()->mOriginAttrsHash &&
aInfo->IsAnonymous() == !!(aRec->Get()->mFlags & kAnonymousMask)) {
aRec->mOriginAttrsHash &&
aInfo->IsAnonymous() == !!(aRec->mFlags & kAnonymousMask)) {
return true;
}
@ -350,7 +334,7 @@ class CacheIndexEntry : public PLDHashEntryHdr {
// Memory reporting
size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
return mallocSizeOf(mRec->Get());
return mallocSizeOf(mRec.get());
}
size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
@ -389,7 +373,7 @@ class CacheIndexEntry : public PLDHashEntryHdr {
// FileSize in kilobytes
static const uint32_t kFileSizeMask = 0x00FFFFFF;
RefPtr<CacheIndexRecordWrapper> mRec;
UniquePtr<CacheIndexRecord> mRec;
};
class CacheIndexEntryUpdate : public CacheIndexEntry {
@ -405,8 +389,8 @@ class CacheIndexEntryUpdate : public CacheIndexEntry {
}
CacheIndexEntryUpdate& operator=(const CacheIndexEntry& aOther) {
MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aOther.mRec->Get()->mHash,
sizeof(SHA1Sum::Hash)) == 0);
MOZ_ASSERT(
memcmp(&mRec->mHash, &aOther.mRec->mHash, sizeof(SHA1Sum::Hash)) == 0);
mUpdateFlags = 0;
*(static_cast<CacheIndexEntry*>(this)) = aOther;
return *this;
@ -450,35 +434,34 @@ class CacheIndexEntryUpdate : public CacheIndexEntry {
}
void ApplyUpdate(CacheIndexEntry* aDst) {
MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aDst->mRec->Get()->mHash,
sizeof(SHA1Sum::Hash)) == 0);
MOZ_ASSERT(
memcmp(&mRec->mHash, &aDst->mRec->mHash, sizeof(SHA1Sum::Hash)) == 0);
if (mUpdateFlags & kFrecencyUpdatedMask) {
aDst->mRec->Get()->mFrecency = mRec->Get()->mFrecency;
aDst->mRec->mFrecency = mRec->mFrecency;
}
aDst->mRec->Get()->mOriginAttrsHash = mRec->Get()->mOriginAttrsHash;
aDst->mRec->mOriginAttrsHash = mRec->mOriginAttrsHash;
if (mUpdateFlags & kOnStartTimeUpdatedMask) {
aDst->mRec->Get()->mOnStartTime = mRec->Get()->mOnStartTime;
aDst->mRec->mOnStartTime = mRec->mOnStartTime;
}
if (mUpdateFlags & kOnStopTimeUpdatedMask) {
aDst->mRec->Get()->mOnStopTime = mRec->Get()->mOnStopTime;
aDst->mRec->mOnStopTime = mRec->mOnStopTime;
}
if (mUpdateFlags & kContentTypeUpdatedMask) {
aDst->mRec->Get()->mContentType = mRec->Get()->mContentType;
aDst->mRec->mContentType = mRec->mContentType;
}
if (mUpdateFlags & kHasAltDataUpdatedMask &&
((aDst->mRec->Get()->mFlags ^ mRec->Get()->mFlags) & kHasAltDataMask)) {
((aDst->mRec->mFlags ^ mRec->mFlags) & kHasAltDataMask)) {
// Toggle the bit if we need to.
aDst->mRec->Get()->mFlags ^= kHasAltDataMask;
aDst->mRec->mFlags ^= kHasAltDataMask;
}
if (mUpdateFlags & kFileSizeUpdatedMask) {
// Copy all flags except |HasAltData|.
aDst->mRec->Get()->mFlags |= (mRec->Get()->mFlags & ~kHasAltDataMask);
aDst->mRec->mFlags |= (mRec->mFlags & ~kHasAltDataMask);
} else {
// Copy all flags except |HasAltData| and file size.
aDst->mRec->Get()->mFlags &= kFileSizeMask;
aDst->mRec->Get()->mFlags |=
(mRec->Get()->mFlags & ~kHasAltDataMask & ~kFileSizeMask);
aDst->mRec->mFlags &= kFileSizeMask;
aDst->mRec->mFlags |= (mRec->mFlags & ~kHasAltDataMask & ~kFileSizeMask);
}
}
@ -1053,10 +1036,10 @@ class CacheIndex final : public CacheFileIOListener, public nsIRunnable {
void ReleaseBuffer();
// Methods used by CacheIndexEntryAutoManage to keep the iterators up to date.
void AddRecordToIterators(CacheIndexRecordWrapper* aRecord);
void RemoveRecordFromIterators(CacheIndexRecordWrapper* aRecord);
void ReplaceRecordInIterators(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecordWrapper* aNewRecord);
void AddRecordToIterators(CacheIndexRecord* aRecord);
void RemoveRecordFromIterators(CacheIndexRecord* aRecord);
void ReplaceRecordInIterators(CacheIndexRecord* aOldRecord,
CacheIndexRecord* aNewRecord);
// Memory reporting (private part)
size_t SizeOfExcludingThisInternal(mozilla::MallocSizeOf mallocSizeOf) const;
@ -1171,7 +1154,7 @@ class CacheIndex final : public CacheFileIOListener, public nsIRunnable {
class FrecencyArray {
class Iterator {
public:
explicit Iterator(nsTArray<RefPtr<CacheIndexRecordWrapper>>* aRecs)
explicit Iterator(nsTArray<CacheIndexRecord*>* aRecs)
: mRecs(aRecs), mIdx(0) {
while (!Done() && !(*mRecs)[mIdx]) {
mIdx++;
@ -1180,7 +1163,7 @@ class CacheIndex final : public CacheFileIOListener, public nsIRunnable {
bool Done() const { return mIdx == mRecs->Length(); }
CacheIndexRecordWrapper* Get() const {
CacheIndexRecord* Get() const {
MOZ_ASSERT(!Done());
return (*mRecs)[mIdx];
}
@ -1194,7 +1177,7 @@ class CacheIndex final : public CacheFileIOListener, public nsIRunnable {
}
private:
nsTArray<RefPtr<CacheIndexRecordWrapper>>* mRecs;
nsTArray<CacheIndexRecord*>* mRecs;
uint32_t mIdx;
};
@ -1204,10 +1187,11 @@ class CacheIndex final : public CacheFileIOListener, public nsIRunnable {
FrecencyArray() : mUnsortedElements(0), mRemovedElements(0) {}
// Methods used by CacheIndexEntryAutoManage to keep the array up to date.
void AppendRecord(CacheIndexRecordWrapper* aRecord);
void RemoveRecord(CacheIndexRecordWrapper* aRecord);
void ReplaceRecord(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecordWrapper* aNewRecord);
void AppendRecord(CacheIndexRecord* aRecord);
void RemoveRecord(CacheIndexRecord* aRecord);
void ReplaceRecord(CacheIndexRecord* aOldRecord,
CacheIndexRecord* aNewRecord);
bool RecordExisted(CacheIndexRecord* aRecord);
void SortIfNeeded();
size_t Length() const { return mRecs.Length() - mRemovedElements; }
@ -1216,7 +1200,7 @@ class CacheIndex final : public CacheFileIOListener, public nsIRunnable {
private:
friend class CacheIndex;
nsTArray<RefPtr<CacheIndexRecordWrapper>> mRecs;
nsTArray<CacheIndexRecord*> mRecs;
uint32_t mUnsortedElements;
// Instead of removing elements from the array immediately, we null them out
// and the iterator skips them when accessing the array. The null pointers
@ -1281,7 +1265,7 @@ class CacheIndex final : public CacheFileIOListener, public nsIRunnable {
};
// List of async observers that want to get disk consumption information
nsTArray<RefPtr<DiskConsumptionObserver>> mDiskConsumptionObservers;
nsTArray<RefPtr<DiskConsumptionObserver> > mDiskConsumptionObservers;
// Number of bytes written to the cache since the last telemetry report
uint64_t mTotalBytesWritten;

Просмотреть файл

@ -15,14 +15,14 @@ CacheIndexContextIterator::CacheIndexContextIterator(CacheIndex* aIndex,
nsILoadContextInfo* aInfo)
: CacheIndexIterator(aIndex, aAddNew), mInfo(aInfo) {}
void CacheIndexContextIterator::AddRecord(CacheIndexRecordWrapper* aRecord) {
void CacheIndexContextIterator::AddRecord(CacheIndexRecord* aRecord) {
if (CacheIndexEntry::RecordMatchesLoadContextInfo(aRecord, mInfo)) {
CacheIndexIterator::AddRecord(aRecord);
}
}
void CacheIndexContextIterator::AddRecords(
const nsTArray<RefPtr<CacheIndexRecordWrapper>>& aRecords) {
const nsTArray<CacheIndexRecord*>& aRecords) {
// We need to add one by one so that those with wrong context are ignored.
for (uint32_t i = 0; i < aRecords.Length(); ++i) {
AddRecord(aRecords[i]);

Просмотреть файл

@ -19,9 +19,8 @@ class CacheIndexContextIterator : public CacheIndexIterator {
virtual ~CacheIndexContextIterator() = default;
private:
virtual void AddRecord(CacheIndexRecordWrapper* aRecord) override;
virtual void AddRecords(
const nsTArray<RefPtr<CacheIndexRecordWrapper>>& aRecords);
virtual void AddRecord(CacheIndexRecord* aRecord) override;
virtual void AddRecords(const nsTArray<CacheIndexRecord*>& aRecords);
nsCOMPtr<nsILoadContextInfo> mInfo;
};

Просмотреть файл

@ -36,7 +36,7 @@ nsresult CacheIndexIterator::GetNextHash(SHA1Sum::Hash* aHash) {
return mStatus;
}
memcpy(aHash, mRecords.PopLastElement()->Get()->mHash, sizeof(SHA1Sum::Hash));
memcpy(aHash, mRecords.PopLastElement()->mHash, sizeof(SHA1Sum::Hash));
return NS_OK;
}
@ -70,21 +70,21 @@ nsresult CacheIndexIterator::CloseInternal(nsresult aStatus) {
return NS_OK;
}
void CacheIndexIterator::AddRecord(CacheIndexRecordWrapper* aRecord) {
void CacheIndexIterator::AddRecord(CacheIndexRecord* aRecord) {
LOG(("CacheIndexIterator::AddRecord() [this=%p, record=%p]", this, aRecord));
mRecords.AppendElement(aRecord);
}
bool CacheIndexIterator::RemoveRecord(CacheIndexRecordWrapper* aRecord) {
bool CacheIndexIterator::RemoveRecord(CacheIndexRecord* aRecord) {
LOG(("CacheIndexIterator::RemoveRecord() [this=%p, record=%p]", this,
aRecord));
return mRecords.RemoveElement(aRecord);
}
bool CacheIndexIterator::ReplaceRecord(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecordWrapper* aNewRecord) {
bool CacheIndexIterator::ReplaceRecord(CacheIndexRecord* aOldRecord,
CacheIndexRecord* aNewRecord) {
LOG(
("CacheIndexIterator::ReplaceRecord() [this=%p, oldRecord=%p, "
"newRecord=%p]",

Просмотреть файл

@ -40,14 +40,14 @@ class CacheIndexIterator {
nsresult CloseInternal(nsresult aStatus);
bool ShouldBeNewAdded() { return mAddNew; }
virtual void AddRecord(CacheIndexRecordWrapper* aRecord);
bool RemoveRecord(CacheIndexRecordWrapper* aRecord);
bool ReplaceRecord(CacheIndexRecordWrapper* aOldRecord,
CacheIndexRecordWrapper* aNewRecord);
virtual void AddRecord(CacheIndexRecord* aRecord);
bool RemoveRecord(CacheIndexRecord* aRecord);
bool ReplaceRecord(CacheIndexRecord* aOldRecord,
CacheIndexRecord* aNewRecord);
nsresult mStatus;
RefPtr<CacheIndex> mIndex;
nsTArray<RefPtr<CacheIndexRecordWrapper>> mRecords;
nsTArray<CacheIndexRecord*> mRecords;
bool mAddNew;
};