]> gitweb.factorcode.org Git - factor.git/blob - vm/object_start_map.cpp
vm: Tweak Factor VM to compile with Microsoft Visual Studio on Windows, in addition...
[factor.git] / vm / object_start_map.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 object_start_map::object_start_map(cell size_, cell start_) :
7         size(size_), start(start_)
8 {
9         object_start_offsets = new card[addr_to_card(size_)];
10         object_start_offsets_end = object_start_offsets + addr_to_card(size_);
11         clear_object_start_offsets();
12 }
13
14 object_start_map::~object_start_map()
15 {
16         delete[] object_start_offsets;
17 }
18
19 cell object_start_map::first_object_in_card(cell card_index)
20 {
21         return object_start_offsets[card_index];
22 }
23
24 cell object_start_map::find_object_containing_card(cell card_index)
25 {
26         if(card_index == 0)
27                 return start;
28         else
29         {
30                 card_index--;
31
32                 while(first_object_in_card(card_index) == card_starts_inside_object)
33                 {
34 #ifdef FACTOR_DEBUG
35                         /* First card should start with an object */
36                         assert(card_index > 0);
37 #endif
38                         card_index--;
39                 }
40
41                 return start + (card_index << card_bits) + first_object_in_card(card_index);
42         }
43 }
44
45 /* we need to remember the first object allocated in the card */
46 void object_start_map::record_object_start_offset(object *obj)
47 {
48         cell idx = addr_to_card((cell)obj - start);
49         card obj_start = ((cell)obj & addr_card_mask);
50         object_start_offsets[idx] = std::min(object_start_offsets[idx],obj_start);
51 }
52
53 void object_start_map::clear_object_start_offsets()
54 {
55         memset(object_start_offsets,card_starts_inside_object,addr_to_card(size));
56 }
57
58 void object_start_map::update_card_for_sweep(cell index, u16 mask)
59 {
60         cell offset = object_start_offsets[index];
61         if(offset != card_starts_inside_object)
62         {
63                 mask >>= (offset / data_alignment);
64
65                 if(mask == 0)
66                 {
67                         /* The rest of the block after the old object start is free */
68                         object_start_offsets[index] = card_starts_inside_object;
69                 }
70                 else
71                 {
72                         /* Move the object start forward if necessary */
73                         object_start_offsets[index] = (card)(offset + (rightmost_set_bit(mask) * data_alignment));
74                 }
75         }
76 }
77
78 void object_start_map::update_for_sweep(mark_bits<object> *state)
79 {
80         for(cell index = 0; index < state->bits_size; index++)
81         {
82                 cell mask = state->marked[index];
83 #ifdef FACTOR_64
84                 update_card_for_sweep(index * 4,      mask        & 0xffff);
85                 update_card_for_sweep(index * 4 + 1, (mask >> 16) & 0xffff);
86                 update_card_for_sweep(index * 4 + 2, (mask >> 32) & 0xffff);
87                 update_card_for_sweep(index * 4 + 3, (mask >> 48) & 0xffff);
88 #else
89                 update_card_for_sweep(index * 2,      mask        & 0xffff);
90                 update_card_for_sweep(index * 2 + 1, (mask >> 16) & 0xffff);
91 #endif
92         }
93 }
94
95 }