AutoWriteBarrier.cpp [plain text]
#include "AutoConfiguration.h"
#include "AutoDefs.h"
#include "AutoRange.h"
#include "AutoMemoryScanner.h"
#include "AutoWriteBarrier.h"
#include "AutoZone.h"
namespace Auto {
void WriteBarrier::scan_marked_ranges(void *address, const usword_t size, void (^scanner) (Range&, WriteBarrier*)) {
void *end = displace(address, size);
void *last = displace(address, size - 1);
usword_t i = card_index(address);
const usword_t j = card_index(last);
Range sub_range;
while (true) {
for ( ; i <= j && !is_card_marked(i); i++) {}
if (i > j) break;
usword_t k = i;
for ( ; i <= j && is_card_marked(i); i++) {}
void *range_begin = card_address(k);
void *range_end = card_address(i);
if (range_begin < address) range_begin = address;
if (range_end > end) range_end = end;
sub_range.set_range(range_begin, range_end);
scanner(sub_range, this);
}
}
void WriteBarrier::scan_marked_ranges(void *address, const usword_t size, MemoryScanner &scanner) {
#if RADAR_6545782_FIXED
scan_marked_ranges(address, size, ^(Range &range, WriteBarrier *wb) { scanner.scan_range(range, wb); });
#else
void *end = displace(address, size);
void *last = displace(address, size - 1);
usword_t i = card_index(address);
const usword_t j = card_index(last);
Range sub_range;
while (true) {
for ( ; i <= j && !is_card_marked(i); i++) {}
if (i > j) break;
usword_t k = i;
for ( ; i <= j && is_card_marked(i); i++) {}
void *range_begin = card_address(k);
void *range_end = card_address(i);
if (range_begin < address) range_begin = address;
if (range_end > end) range_end = end;
sub_range.set_range(range_begin, range_end);
scanner.scan_range(sub_range, this);
}
#endif
}
bool WriteBarrier::range_has_marked_cards(void *address, const usword_t size) {
void *last = displace(address, size - 1);
usword_t i = card_index(address);
const usword_t j = card_index(last);
while (i <= j) if (is_card_marked(i++)) return true;
return false;
}
usword_t WriteBarrier::mark_cards_untouched() {
usword_t count = 0;
for (unsigned char *card = (unsigned char*)address() + _protect, *limit = (unsigned char *)end(); card != limit; ++card) {
if (*card != card_unmarked) {
if (__sync_bool_compare_and_swap(card, (unsigned char)card_marked, (unsigned char)card_marked_untouched))
++count;
}
}
return count;
}
usword_t WriteBarrier::clear_untouched_cards() {
usword_t count = 0;
for (unsigned char *card = (unsigned char*)address() + _protect, *limit = (unsigned char *)end(); card != limit; ++card) {
if (*card == card_marked_untouched) {
if (__sync_bool_compare_and_swap(card, (unsigned char)card_marked_untouched, (unsigned char)card_unmarked))
++count;
}
}
return count;
}
};