AutoWriteBarrier.h [plain text]
#pragma once
#ifndef __AUTO_WRITEBARRIER__
#define __AUTO_WRITEBARRIER__
#include "AutoConfiguration.h"
#include "AutoDefs.h"
#include "AutoRange.h"
namespace Auto {
class MemoryScanner;
class Zone;
class WriteBarrier : public Range {
private:
void *_base; usword_t _protect;
public:
enum {
card_unmarked = 0,
card_marked = 1,
card_marked_untouched = 0x3
};
WriteBarrier(void *base, void *address, const usword_t size, const usword_t protect = 0)
: Range(address, size), _base(base), _protect(protect)
{
}
static inline const usword_t bytes_needed(usword_t n) {
return partition2(n, write_barrier_quantum_log2);
}
inline const usword_t card_index(void *address) const {
uintptr_t normalized = (uintptr_t)address - (uintptr_t)_base;
usword_t i = normalized >> write_barrier_quantum_log2;
ASSERTION(_protect <= i);
ASSERTION(i < size());
return i;
}
inline void *card_address(usword_t i) const { return displace(_base, i << write_barrier_quantum_log2); }
inline bool is_card_marked(usword_t i) { return ((unsigned char *)address())[i] != card_unmarked; }
inline void mark_card(usword_t i) { ((unsigned char *)address())[i] = card_marked; }
inline void mark_card_untouched(usword_t i) { ((unsigned char *)address())[i] = card_marked_untouched; }
inline void clear_cards() { bzero(displace(address(), _protect), size() - _protect); }
void mark_cards_untouched();
void clear_untouched_cards();
inline bool is_card_marked(void *address) {
usword_t i = card_index(address);
return is_card_marked(i);
}
inline void mark_card(void *address) {
const usword_t i = card_index(address);
mark_card(i);
}
inline void mark_cards(void *address, const usword_t size) {
usword_t i = card_index(address);
const usword_t j = card_index(displace(address, size - 1));
for ( ; i <= j; i++) mark_card(i);
}
void scan_ranges(void *address, const usword_t size, MemoryScanner &scanner);
};
};
#endif // __AUTO_WRITEBARRIER__