namespace mirror { class Object;
} // namespace mirror
namespace gc {
namespace space { class ContinuousSpace;
} // namespace space
class Heap;
namespace accounting {
template<size_t kAlignment> class SpaceBitmap;
// Maintain a card table from the the write barrier. All writes of // non-null values to heap addresses should go through an entry in // WriteBarrier, and from there to here. class CardTable { public: static constexpr size_t kCardShift = 10; static constexpr size_t kCardSize = 1 << kCardShift; static constexpr uint8_t kCardClean = 0x0; // Value written into the card by the write-barrier to indicate that // reference(s) to some object starting in this card has been modified. static constexpr uint8_t kCardDirty = 0x70; // Value to indicate that a dirty card is 'aged' now in the sense that it has // been noticed by the GC and will be visited. static constexpr uint8_t kCardAged = kCardDirty - 1; // Further ageing an aged card usually means clearing the card as we have // already visited it when ageing it the first time. This value is used to // avoid re-visiting (in the second pass of CMC marking phase) cards which // contain old-to-young references and have not been dirtied since the first // pass of marking. We can't simply clean these cards as they are needed later // in compaction phase to update the old-to-young references. static constexpr uint8_t kCardAged2 = kCardAged - 1;
// Set the card associated with the given address to `kCardDirty`.
ALWAYS_INLINE void MarkCard(constvoid *addr) {
*CardFromAddr(addr) = kCardDirty;
}
// Is the object on a dirty card? bool IsDirty(const mirror::Object* obj) const { return GetCard(obj) == kCardDirty;
}
// Is the object on a clean card? bool IsClean(const mirror::Object* obj) const { return GetCard(obj) == kCardClean;
}
// Return the state of the card at an address.
uint8_t GetCard(const mirror::Object* obj) const { return *CardFromAddr(obj);
}
// Visit and clear cards within memory range, only visits dirty cards. template <typename Visitor> void VisitClear(constvoid* start, constvoid* end, const Visitor& visitor) {
uint8_t* card_start = CardFromAddr(start);
uint8_t* card_end = CardFromAddr(end); for (uint8_t* it = card_start; it != card_end; ++it) { if (*it == kCardDirty) {
*it = kCardClean;
visitor(it);
}
}
}
// Returns a value that when added to a heap address >> `kCardShift` will address the appropriate // card table byte. For convenience this value is cached in every Thread.
uint8_t* GetBiasedBegin() const { return biased_begin_;
}
// For every dirty (at least minimum age) card between begin and end invoke // bitmap's VisitMarkedRange() to invoke 'visitor' on every object in the // card. Calls 'mod_visitor' for each such card in case the caller wants to // modify the value. Returns how many cards the visitor was run on. // NOTE: 'visitor' is called on one whole card at a time. Therefore, // 'scan_begin' and 'scan_end' are aligned to card-size before visitor is // called. Therefore visitor may get called on objects before 'scan_begin' // and/or after 'scan_end'. Visitor shall detect that and act appropriately. template <bool kClearCard, typename Visitor, typename ModifyVisitor>
size_t Scan(SpaceBitmap<kObjectAlignment>* bitmap,
uint8_t* scan_begin,
uint8_t* scan_end, const Visitor& visitor, const ModifyVisitor& mod_visitor, const uint8_t minimum_age)
REQUIRES_SHARED(Locks::mutator_lock_, Locks::heap_bitmap_lock_);
// Assertion used to check the given address is covered by the card table void CheckAddrIsInCardTable(const uint8_t* addr) const;
// Resets all of the bytes in the card table to clean. void ClearCardTable();
// Clear a range of cards that covers start to end, start and end must be aligned to kCardSize. void ClearCardRange(uint8_t* start, uint8_t* end);
// Returns the first address in the heap which maps to this card. void* AddrFromCard(const uint8_t *card_addr) const ALWAYS_INLINE;
// Returns the address of the relevant byte in the card table, given an address on the heap.
uint8_t* CardFromAddr(constvoid *addr) const ALWAYS_INLINE;
// Verifies that all gray objects are on a dirty card. void VerifyCardTable();
// Mmapped pages for the card table
MemMap mem_map_; // Value used to compute card table addresses from object addresses, see GetBiasedBegin
uint8_t* const biased_begin_; // Card table doesn't begin at the beginning of the mem_map_, instead it is displaced by offset // to allow the byte value of `biased_begin_` to equal `kCardDirty`. const size_t offset_;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.