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