diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh index bcd5c4b1b5..2d866a8cc8 100644 --- a/src/mem/cache/cache_blk.hh +++ b/src/mem/cache/cache_blk.hh @@ -155,6 +155,39 @@ class CacheBlk : public TaggedEntry CacheBlk(const CacheBlk&) = delete; CacheBlk& operator=(const CacheBlk&) = delete; + CacheBlk(const CacheBlk&&) = delete; + /** + * Move assignment operator. + * This should only be used to move an existing valid entry into an + * invalid one, not to create a new entry. In the end the valid entry + * will become invalid, and the invalid, valid. All location related + * variables will remain the same, that is, an entry cannot move its + * data, just its metadata contents. + */ + virtual CacheBlk& + operator=(CacheBlk&& other) + { + // Copying an entry into a valid one would imply in skipping all + // replacement steps, so it cannot be allowed + assert(!isValid()); + assert(other.isValid()); + + insert(other.getTag(), other.isSecure()); + + if (other.wasPrefetched()) { + setPrefetched(); + } + setCoherenceBits(other.coherence); + setTaskId(other.getTaskId()); + setWhenReady(curTick()); + setRefCount(other.getRefCount()); + setSrcRequestorId(other.getSrcRequestorId()); + std::swap(lockList, other.lockList); + + other.invalidate(); + + return *this; + } virtual ~CacheBlk() {}; /** @@ -168,7 +201,7 @@ class CacheBlk : public TaggedEntry clearCoherenceBits(AllBits); setTaskId(ContextSwitchTaskId::Unknown); - whenReady = MaxTick; + setWhenReady(MaxTick); setRefCount(0); setSrcRequestorId(Request::invldRequestorId); lockList.clear(); diff --git a/src/mem/cache/tags/sector_blk.hh b/src/mem/cache/tags/sector_blk.hh index ea3c79aa9a..2d649cd427 100644 --- a/src/mem/cache/tags/sector_blk.hh +++ b/src/mem/cache/tags/sector_blk.hh @@ -62,7 +62,17 @@ class SectorSubBlk : public CacheBlk SectorSubBlk() : CacheBlk(), _sectorBlk(nullptr), _sectorOffset(0) {} SectorSubBlk(const SectorSubBlk&) = delete; SectorSubBlk& operator=(const SectorSubBlk&) = delete; - ~SectorSubBlk() {}; + SectorSubBlk(SectorSubBlk&&) = delete; + /** + * Move assignment operator. + * This should only be used to move an existing valid entry into an + * invalid one, not to create a new entry. In the end the valid entry + * will become invalid, and the invalid, valid. All location related + * variables will remain the same, that is, an entry cannot change + * its sector block nor its offset. + */ + SectorSubBlk& operator=(SectorSubBlk&& other) = default; + ~SectorSubBlk() = default; /** * Set sector block associated to this block. diff --git a/src/mem/cache/tags/super_blk.cc b/src/mem/cache/tags/super_blk.cc index 0f570f9479..a6d8afb816 100644 --- a/src/mem/cache/tags/super_blk.cc +++ b/src/mem/cache/tags/super_blk.cc @@ -41,6 +41,30 @@ CompressionBlk::CompressionBlk() { } +CacheBlk& +CompressionBlk::operator=(CacheBlk&& other) +{ + operator=(std::move(static_cast(other))); + return *this; +} + +CompressionBlk& +CompressionBlk::operator=(CompressionBlk&& other) +{ + // Copy internal variables; if moving, that means we had an expansion or + // contraction, and therefore the size is no longer valid, so it is not + // moved + setDecompressionLatency(other.getDecompressionLatency()); + if (other.isCompressed()) { + setCompressed(); + } else { + setUncompressed(); + } + + CacheBlk::operator=(std::move(other)); + return *this; +} + bool CompressionBlk::isCompressed() const { diff --git a/src/mem/cache/tags/super_blk.hh b/src/mem/cache/tags/super_blk.hh index bca32662fc..d7abe18723 100644 --- a/src/mem/cache/tags/super_blk.hh +++ b/src/mem/cache/tags/super_blk.hh @@ -66,7 +66,17 @@ class CompressionBlk : public SectorSubBlk CompressionBlk(); CompressionBlk(const CompressionBlk&) = delete; CompressionBlk& operator=(const CompressionBlk&) = delete; - ~CompressionBlk() {}; + CompressionBlk(CompressionBlk&&) = delete; + /** + * Move assignment operator. + * This should only be used to move an existing valid entry into an + * invalid one, not to create a new entry. In the end the valid entry + * will become invalid, and the invalid, valid. All location related + * variables will remain the same. + */ + CompressionBlk& operator=(CompressionBlk&& other); + CacheBlk& operator=(CacheBlk&& other); + ~CompressionBlk() = default; /** * Check if this block holds compressed data.