]> gitweb.factorcode.org Git - factor.git/blob - vm/data_heap_checker.cpp
Merge branch 'master' of git://factorcode.org/git/factor
[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
9 enum generation {
10         nursery_generation,
11         aging_generation,
12         tenured_generation
13 };
14
15 inline generation generation_of(factor_vm *parent, object *obj)
16 {
17         if(parent->data->nursery->contains_p(obj))
18                 return nursery_generation;
19         else if(parent->data->aging->contains_p(obj))
20                 return aging_generation;
21         else if(parent->data->tenured->contains_p(obj))
22                 return tenured_generation;
23         else
24         {
25                 critical_error("Bad object",(cell)obj);
26                 return (generation)-1;
27         }
28 }
29
30 struct slot_checker {
31         factor_vm *parent;
32         object *obj;
33         generation gen;
34
35         explicit slot_checker(factor_vm *parent_, object *obj_, generation gen_) :
36                 parent(parent_), obj(obj_), gen(gen_) {}
37
38         void check_write_barrier(cell *slot_ptr, generation target, char mask)
39         {
40                 cell object_card_pointer = parent->cards_offset + ((cell)obj >> card_bits);
41                 cell slot_card_pointer = parent->cards_offset + ((cell)slot_ptr >> card_bits);
42                 char slot_card_value = *(char *)slot_card_pointer;
43                 if((slot_card_value & mask) != mask)
44                 {
45                         std::cout << "card not marked" << std::endl;
46                         std::cout << "source generation: " << gen << std::endl;
47                         std::cout << "target generation: " << target << std::endl;
48                         std::cout << "object: 0x" << std::hex << (cell)obj << std::dec << std::endl;
49                         std::cout << "object type: " << obj->type() << std::endl;
50                         std::cout << "slot pointer: 0x" << std::hex << (cell)slot_ptr << std::dec << std::endl;
51                         std::cout << "slot value: 0x" << std::hex << *slot_ptr << std::dec << std::endl;
52                         std::cout << "card of object: 0x" << std::hex << object_card_pointer << std::dec << std::endl;
53                         std::cout << "card of slot: 0x" << std::hex << slot_card_pointer << std::dec << std::endl;
54                         std::cout << std::endl;
55                         parent->factorbug();
56                 }
57         }
58
59         void operator()(cell *slot_ptr)
60         {
61                 if(!immediate_p(*slot_ptr))
62                 {
63                         generation target = generation_of(parent,untag<object>(*slot_ptr));
64                         switch(gen)
65                         {
66                         case nursery_generation:
67                                 break;
68                         case aging_generation:
69                                 if(target == nursery_generation)
70                                         check_write_barrier(slot_ptr,target,card_points_to_nursery);
71                                 break;
72                         case tenured_generation:
73                                 if(target == nursery_generation)
74                                         check_write_barrier(slot_ptr,target,card_points_to_nursery);
75                                 else if(target == aging_generation)
76                                         check_write_barrier(slot_ptr,target,card_points_to_aging);
77                                 break;
78                         }
79                 }
80         }
81 };
82
83 struct object_checker {
84         factor_vm *parent;
85
86         explicit object_checker(factor_vm *parent_) : parent(parent_) {}
87
88         void operator()(object *obj)
89         {
90                 slot_checker checker(parent,obj,generation_of(parent,obj));
91                 obj->each_slot(checker);
92         }
93 };
94
95 void factor_vm::check_data_heap()
96 {
97         object_checker checker(this);
98         each_object(checker);
99 }
100
101 }