]> gitweb.factorcode.org Git - factor.git/blob - vm/data_heap_checker.cpp
VM: Remove unnecessary _ suffix in constructors
[factor.git] / vm / data_heap_checker.cpp
1 #include "master.hpp"
2
3 /* A tool to debug write barriers. Call check_data_heap() to ensure that all
4 cards that should be marked are actually marked. */
5
6 namespace factor {
7
8 enum generation {
9   nursery_generation,
10   aging_generation,
11   tenured_generation
12 };
13
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;
21   else {
22     critical_error("Bad object", (cell) obj);
23     return (generation) - 1;
24   }
25 }
26
27 struct slot_checker {
28   factor_vm* parent;
29   object* obj;
30   generation gen;
31
32   slot_checker(factor_vm* parent, object* obj, generation gen)
33       : parent(parent), obj(obj), gen(gen) {}
34
35   void check_write_barrier(cell* slot_ptr, generation target, char 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
50                 << std::endl;
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;
56       parent->factorbug();
57     }
58   }
59
60   void operator()(cell* slot_ptr) {
61     if (!immediate_p(*slot_ptr)) {
62       generation target = generation_of(parent, untag<object>(*slot_ptr));
63       switch (gen) {
64         case nursery_generation:
65           break;
66         case aging_generation:
67           if (target == nursery_generation)
68             check_write_barrier(slot_ptr, target, card_points_to_nursery);
69           break;
70         case tenured_generation:
71           if (target == nursery_generation)
72             check_write_barrier(slot_ptr, target, card_points_to_nursery);
73           else if (target == aging_generation)
74             check_write_barrier(slot_ptr, target, card_points_to_aging);
75           break;
76       }
77     }
78   }
79 };
80
81 struct object_checker {
82   factor_vm* parent;
83
84   explicit object_checker(factor_vm* parent) : parent(parent) {}
85
86   void operator()(object* obj) {
87     slot_checker checker(parent, obj, generation_of(parent, obj));
88     obj->each_slot(checker);
89   }
90 };
91
92 void factor_vm::check_data_heap() {
93   object_checker checker(this);
94   each_object(checker);
95 }
96
97 }