blob: 804e97bbdb41dd548fe9e46759ff923b97d2332e [file] [log] [blame]
Ian Rogers5d76c432011-10-31 21:42:49 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3/*
4 * Maintain a card table from the the write barrier. All writes of
5 * non-NULL values to heap addresses should go through an entry in
6 * WriteBarrier, and from there to here.
7 */
8
9#ifndef DALVIK_ALLOC_CARDTABLE_H_
10#define DALVIK_ALLOC_CARDTABLE_H_
11
12#include "globals.h"
13#include "logging.h"
14#include "mem_map.h"
15#include "UniquePtr.h"
16
17namespace art {
18
19class Object;
20
21#define GC_CARD_SHIFT 7
22#define GC_CARD_SIZE (1 << GC_CARD_SHIFT)
23#define GC_CARD_CLEAN 0
24#define GC_CARD_DIRTY 0x70
25
26class CardTable {
27 public:
Ian Rogers5d76c432011-10-31 21:42:49 -070028
Ian Rogers30fab402012-01-23 15:43:46 -080029 static CardTable* Create(const byte* heap_begin, size_t heap_capacity);
Ian Rogers5d76c432011-10-31 21:42:49 -070030
Ian Rogers30fab402012-01-23 15:43:46 -080031 // Set the card associated with the given address to GC_CARD_DIRTY.
Ian Rogers5d76c432011-10-31 21:42:49 -070032 void MarkCard(const void *addr) {
33 byte* cardAddr = CardFromAddr(addr);
34 *cardAddr = GC_CARD_DIRTY;
35 }
36
Ian Rogers30fab402012-01-23 15:43:46 -080037 // Is the object on a dirty card?
Ian Rogers5d76c432011-10-31 21:42:49 -070038 bool IsDirty(const Object* obj) const {
39 return *CardFromAddr(obj) == GC_CARD_DIRTY;
40 }
41
Ian Rogers30fab402012-01-23 15:43:46 -080042 // Returns a value that when added to a heap address >> GC_CARD_SHIFT will address the appropriate
43 // card table byte. For convenience this value is cached in every Thread
44 byte* GetBiasedBegin() const {
45 return biased_begin_;
jeffhao39da0352011-11-04 14:58:55 -070046 }
47
Ian Rogers30fab402012-01-23 15:43:46 -080048 // For every dirty card between begin and end invoke the visitor with the specified argument
49 typedef void Callback(Object* obj, void* arg);
50 void Scan(byte* begin, byte* end, Callback* visitor, void* arg) const;
51
52
53 // Assertion used to check the given address is covered by the card table
54 void CheckAddrIsInCardTable(const byte* addr) const;
55
Ian Rogers5d76c432011-10-31 21:42:49 -070056 private:
57
Ian Rogers30fab402012-01-23 15:43:46 -080058 CardTable(MemMap* begin, byte* biased_begin, size_t offset) :
59 mem_map_(begin), biased_begin_(biased_begin), offset_(offset) {}
Ian Rogers5d76c432011-10-31 21:42:49 -070060
Ian Rogers30fab402012-01-23 15:43:46 -080061 // Resets all of the bytes in the card table to clean.
Ian Rogers5d76c432011-10-31 21:42:49 -070062 void ClearCardTable();
63
Ian Rogers30fab402012-01-23 15:43:46 -080064 // Returns the address of the relevant byte in the card table, given an address on the heap.
Ian Rogers5d76c432011-10-31 21:42:49 -070065 byte* CardFromAddr(const void *addr) const {
Ian Rogers30fab402012-01-23 15:43:46 -080066 byte *cardAddr = biased_begin_ + ((uintptr_t)addr >> GC_CARD_SHIFT);
67 // Sanity check the caller was asking for address covered by the card table
68 DCHECK(IsValidCard(cardAddr)) << "addr: " << addr
69 << " cardAddr: " << reinterpret_cast<void*>(cardAddr);
Ian Rogers5d76c432011-10-31 21:42:49 -070070 return cardAddr;
71 }
72
Ian Rogers30fab402012-01-23 15:43:46 -080073 // Returns the first address in the heap which maps to this card.
74 void* AddrFromCard(const byte *cardAddr) const {
75 DCHECK(IsValidCard(cardAddr));
76 uintptr_t offset = cardAddr - biased_begin_;
77 return (void *)(offset << GC_CARD_SHIFT);
78 }
Ian Rogers5d76c432011-10-31 21:42:49 -070079
Ian Rogers30fab402012-01-23 15:43:46 -080080 // Returns true iff the card table address is within the bounds of the card table.
Ian Rogers5d76c432011-10-31 21:42:49 -070081 bool IsValidCard(const byte* cardAddr) const {
Ian Rogers30fab402012-01-23 15:43:46 -080082 byte* begin = mem_map_->Begin() + offset_;
83 byte* end = mem_map_->End();
Ian Rogers5d76c432011-10-31 21:42:49 -070084 return cardAddr >= begin && cardAddr < end;
85 }
86
Ian Rogers30fab402012-01-23 15:43:46 -080087 // Verifies that all gray objects are on a dirty card.
Ian Rogers5d76c432011-10-31 21:42:49 -070088 void VerifyCardTable();
89
Ian Rogers30fab402012-01-23 15:43:46 -080090 // Mmapped pages for the card table
Ian Rogers5d76c432011-10-31 21:42:49 -070091 UniquePtr<MemMap> mem_map_;
Ian Rogers30fab402012-01-23 15:43:46 -080092 // Value used to compute card table addresses from object addresses, see GetBiasedBegin
93 byte* const biased_begin_;
94 // Card table doesn't begin at the beginning of the mem_map_, instead it is displaced by offset
95 // to allow the byte value of biased_begin_ to equal GC_CARD_DIRTY
96 const size_t offset_;
Ian Rogers5d76c432011-10-31 21:42:49 -070097};
98
99} // namespace art
100#endif // DALVIK_ALLOC_CARDTABLE_H_