complex_unmarker(card unmask_none_, card unmask_some_) :
unmask_none(unmask_none_), unmask_some(unmask_some_) {}
- void operator()(bool result, card *ptr) {
+ void operator()(bool result, card *ptr)
+ {
*ptr &= (result ? ~unmask_some : ~unmask_none);
}
};
return copied;
}
+ inline cell card_index(cell deck)
+ {
+ return deck << (deck_bits - card_bits);
+ }
+
+ inline cell card_deck_index(cell a)
+ {
+ return (a - this->data->start) >> deck_bits;
+ }
+
+ inline cell card_start_address(cell card)
+ {
+ return (card << card_bits) + this->data->start;
+ }
+
template<typename SourceGeneration, typename Unmarker>
- bool trace_card(SourceGeneration *gen, card *ptr, Unmarker unmarker)
+ bool trace_card(SourceGeneration *gen, card *cards, cell card_index, Unmarker unmarker)
{
- cell card_start = this->myvm->card_to_addr(ptr);
+ cell card_start = card_start_address(card_index);
cell card_scan = card_start + gen->first_object_in_card(card_start);
- cell card_end = this->myvm->card_to_addr(ptr + 1);
+ cell card_end = card_start_address(card_index + 1);
bool result = this->trace_objects_between(gen,card_scan,&card_end);
- unmarker(result,ptr);
+ unmarker(result,&cards[card_index]);
this->myvm->gc_stats.cards_scanned++;
}
template<typename SourceGeneration, typename Unmarker>
- bool trace_card_deck(SourceGeneration *gen, card_deck *deck, card mask, Unmarker unmarker)
+ bool trace_card_deck(SourceGeneration *gen, cell deck_index, card mask, Unmarker unmarker)
{
- card *first_card = this->myvm->deck_to_card(deck);
- card *last_card = this->myvm->deck_to_card(deck + 1);
+ cell first_card = card_index(deck_index);
+ cell last_card = card_index(deck_index + 1);
bool copied = false;
- for(card *ptr = first_card; ptr < last_card; ptr++)
- if(*ptr & mask) copied |= trace_card(gen,ptr,unmarker);
+ card *cards = this->data->cards;
+ for(cell i = first_card; i < last_card; i++)
+ {
+ if(cards[i] & mask) copied |= trace_card(gen,cards,i,unmarker);
+ }
this->myvm->gc_stats.decks_scanned++;
{
u64 start = current_micros();
- card_deck *first_deck = this->myvm->addr_to_deck(gen->start);
- card_deck *last_deck = this->myvm->addr_to_deck(gen->end);
+ cell first_deck = card_deck_index(gen->start);
+ cell last_deck = card_deck_index(gen->end);
- for(card_deck *ptr = first_deck; ptr < last_deck; ptr++)
- if(*ptr & mask) unmarker(trace_card_deck(gen,ptr,mask,unmarker),ptr);
+ card_deck *decks = this->data->decks;
+ for(cell i = first_deck; i < last_deck; i++)
+ {
+ if(decks[i] & mask)
+ unmarker(trace_card_deck(gen,i,mask,unmarker),&decks[i]);
+ }
this->myvm->gc_stats.card_scan_time += (current_micros() - start);
}
cell cards_size = total_size >> card_bits;
- cards = new char[cards_size];
+ cards = new card[cards_size];
cards_end = cards + cards_size;
cell decks_size = total_size >> deck_bits;
- decks = new char[decks_size];
+ decks = new card_deck[decks_size];
decks_end = decks + decks_size;
- cell start = align(seg->start,deck_size);
+ start = align(seg->start,deck_size);
tenured = new tenured_space(tenured_size,start);
tenured_semispace = new tenured_space(tenured_size,tenured->end);
print_string(".s .r .c -- print data, retain, call stacks\n");
print_string("e -- dump environment\n");
print_string("g -- dump generations\n");
- print_string("card <addr> -- print card containing address\n");
- print_string("addr <card> -- print address containing card\n");
print_string("data -- data heap dump\n");
print_string("words -- words dump\n");
print_string("tuples -- tuples dump\n");
}
else if(strcmp(cmd,"g") == 0)
dump_generations();
- else if(strcmp(cmd,"card") == 0)
- {
- cell addr = read_cell_hex();
- print_cell_hex((cell)addr_to_card(addr));
- nl();
- }
- else if(strcmp(cmd,"addr") == 0)
- {
- card *ptr = (card *)read_cell_hex();
- print_cell_hex(card_to_addr(ptr));
- nl();
- }
else if(strcmp(cmd,"q") == 0)
return;
else if(strcmp(cmd,"x") == 0)
old_space(cell size_, cell start_);
~old_space();
+ cell object_start_map_index(cell address)
+ {
+ return (address - start) >> card_bits;
+ }
+
+ /* Find the first object starting on or after the given address */
cell first_object_in_card(cell address)
{
- return object_start_offsets[(address - start) >> card_bits];
+ return object_start_offsets[object_start_map_index(address)];
+ }
+
+ /* Find the card which contains the header of the object which contains
+ the given address */
+ cell find_object_start_card(cell address)
+ {
+ cell i = object_start_map_index(address);
+ while(i >= 0 && object_start_offsets[i] == card_starts_inside_object) i--;
+ return i;
}
void record_object_start_offset(object *obj);