3 // A tool to debug write barriers. Call check_data_heap() to ensure that all
4 // cards that should be marked are actually marked.
14 inline generation
generation_of(factor_vm
* parent
, object
* obj
) {
15 if (parent
->data
->nursery
->contains_p(obj
))
16 return NURSERY_GENERATION
;
17 else if (parent
->data
->aging
->contains_p(obj
))
18 return AGING_GENERATION
;
19 else if (parent
->data
->tenured
->contains_p(obj
))
20 return TENURED_GENERATION
;
22 critical_error("Bad object", (cell
)obj
);
23 return (generation
)-1;
32 slot_checker(factor_vm
* parent
, object
* obj
, generation gen
)
33 : parent(parent
), obj(obj
), gen(gen
) {}
35 void check_write_barrier(cell
* slot_ptr
, generation target
, cell mask
) {
36 cell object_card_pointer
= parent
->cards_offset
+ ((cell
)obj
>> card_bits
);
37 cell slot_card_pointer
=
38 parent
->cards_offset
+ ((cell
)slot_ptr
>> card_bits
);
39 char slot_card_value
= *(char*)slot_card_pointer
;
40 if ((slot_card_value
& mask
) != mask
) {
41 std::cout
<< "card not marked" << std::endl
;
42 std::cout
<< "source generation: " << gen
<< std::endl
;
43 std::cout
<< "target generation: " << target
<< std::endl
;
44 std::cout
<< "object: 0x" << std::hex
<< (cell
)
45 obj
<< std::dec
<< std::endl
;
46 std::cout
<< "object type: " << obj
->type() << std::endl
;
47 std::cout
<< "slot pointer: 0x" << std::hex
<< (cell
)
48 slot_ptr
<< std::dec
<< std::endl
;
49 std::cout
<< "slot value: 0x" << std::hex
<< *slot_ptr
<< std::dec
51 std::cout
<< "card of object: 0x" << std::hex
<< object_card_pointer
52 << std::dec
<< std::endl
;
53 std::cout
<< "card of slot: 0x" << std::hex
<< slot_card_pointer
54 << std::dec
<< std::endl
;
55 std::cout
<< std::endl
;
60 void operator()(cell
* slot_ptr
) {
61 if (immediate_p(*slot_ptr
))
64 generation target
= generation_of(parent
, untag
<object
>(*slot_ptr
));
65 if (gen
== AGING_GENERATION
&& target
== NURSERY_GENERATION
) {
66 check_write_barrier(slot_ptr
, target
, card_points_to_nursery
);
67 } else if (gen
== TENURED_GENERATION
) {
68 if (target
== NURSERY_GENERATION
) {
69 check_write_barrier(slot_ptr
, target
, card_points_to_nursery
);
70 } else if (target
== AGING_GENERATION
) {
71 check_write_barrier(slot_ptr
, target
, card_points_to_aging
);
77 void factor_vm::check_data_heap() {
78 auto checker
= [&](object
* obj
){
79 generation obj_gen
= generation_of(this, obj
);
80 slot_checker
s_checker(this, obj
, obj_gen
);
81 obj
->each_slot(s_checker
);