Paste: card scanning

Author: slava
Mode: c++
Date: Wed, 14 Oct 2009 07:29:46
Plain Text |
	template<typename SourceGeneration, typename Unmarker>
	void trace_cards(SourceGeneration *gen, card mask, Unmarker unmarker)
	{
		u64 start_time = current_micros();
	
		card_deck *decks = this->data->decks;
		card_deck *cards = this->data->cards;
	
		cell gen_start_card = addr_to_card(gen->start - this->data->start);

		cell first_deck = card_deck_for_address(gen->start);
		cell last_deck = card_deck_for_address(gen->end);
	
		cell start = 0, binary_start = 0, end = 0;
	
		for(cell deck_index = first_deck; deck_index < last_deck; deck_index++)
		{
			if(decks[deck_index] & mask)
			{
				cell first_card = first_card_in_deck(deck_index);
				cell last_card = last_card_in_deck(deck_index);
	
				bool deck_dirty = false;
	
				for(cell card_index = first_card; card_index < last_card; card_index++)
				{
					if(cards[card_index] & mask)
					{
						if(end < card_start_address(card_index))
						{
							start = gen->find_object_containing_card(card_index - gen_start_card);
							binary_start = start + this->myvm->binary_payload_start((object *)start);
							end = start + this->myvm->untagged_object_size((object *)start);
						}
	
						bool card_dirty = false;
	
#ifdef FACTOR_DEBUG
						assert(addr_to_card(start - this->data->start) <= card_index);
						assert(start < card_end_address(card_index));
#endif

scan_next_object:				{
							card_dirty |= trace_partial_objects(
								start,
								binary_start,
								card_start_address(card_index),
								card_end_address(card_index));
							if(end < card_end_address(card_index))
							{
								start = gen->next_object_after(this->myvm,start);
								if(start)
								{
									binary_start = start + this->myvm->binary_payload_start((object *)start);
									end = start + this->myvm->untagged_object_size((object *)start);
									goto scan_next_object;
								}
							}
						}
	
						unmarker(card_dirty,&cards[card_index]);
						this->myvm->gc_stats.cards_scanned++;
	
						deck_dirty |= card_dirty;

						if(!start) goto end;
					}
				}
	
				unmarker(deck_dirty,&decks[deck_index]);
			}
		}

end:		this->myvm->gc_stats.card_scan_time += (current_micros() - start_time);
	}

New Annotation

Summary:
Author:
Mode:
Body: