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