]> gitweb.factorcode.org Git - factor.git/blob - vm/data_heap_checker.cpp
Fix conflict
[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                         printf("card not marked\n");
46                         printf("source generation: %d\n",gen);
47                         printf("target generation: %d\n",target);
48                         printf("object: 0x%lx\n",(cell)obj);
49                         printf("object type: %ld\n",obj->type());
50                         printf("slot pointer: 0x%lx\n",(cell)slot_ptr);
51                         printf("slot value: 0x%lx\n",*slot_ptr);
52                         printf("card of object: 0x%lx\n",object_card_pointer);
53                         printf("card of slot: 0x%lx\n",slot_card_pointer);
54                         printf("\n");
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 }