| 
									
										
										
										
											2009-10-07 16:48:09 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:16:22 -04:00
										 |  |  | namespace factor { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 06:35:38 -04:00
										 |  |  | struct nursery_copier : no_fixup { | 
					
						
							| 
									
										
										
										
											2015-05-07 07:29:57 -04:00
										 |  |  |   bump_allocator* nursery; | 
					
						
							| 
									
										
										
										
											2016-09-22 06:35:38 -04:00
										 |  |  |   aging_space* aging; | 
					
						
							| 
									
										
										
										
											2015-05-03 21:57:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 06:35:38 -04:00
										 |  |  |   nursery_copier(bump_allocator* nursery, aging_space* aging) | 
					
						
							|  |  |  |       : nursery(nursery), aging(aging) { } | 
					
						
							| 
									
										
										
										
											2015-05-03 21:57:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 06:35:38 -04:00
										 |  |  |   object* fixup_data(object* obj) { | 
					
						
							|  |  |  |     if (!nursery->contains_p(obj)) { | 
					
						
							|  |  |  |       return obj; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-25 23:16:33 -04:00
										 |  |  |     // The while-loop is a needed micro-optimization.
 | 
					
						
							|  |  |  |     while (obj->forwarding_pointer_p()) { | 
					
						
							|  |  |  |       obj = obj->forwarding_pointer(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!nursery->contains_p(obj)) { | 
					
						
							|  |  |  |       return obj; | 
					
						
							| 
									
										
										
										
											2016-09-22 06:35:38 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-05-03 21:57:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 06:35:38 -04:00
										 |  |  |     cell size = obj->size(); | 
					
						
							|  |  |  |     object* newpointer = aging->allot(size); | 
					
						
							|  |  |  |     if (!newpointer) | 
					
						
							|  |  |  |       throw must_start_gc_again(); | 
					
						
							| 
									
										
										
										
											2015-05-03 21:57:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-22 06:35:38 -04:00
										 |  |  |     memcpy(newpointer, obj, size); | 
					
						
							|  |  |  |     obj->forward_to(newpointer); | 
					
						
							|  |  |  |     return newpointer; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-05-03 21:57:35 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:16:22 -04:00
										 |  |  | void factor_vm::collect_nursery() { | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  |   // Copy live objects from the nursery (as determined by the root set and
 | 
					
						
							|  |  |  |   // marked cards in aging and tenured) to aging space.
 | 
					
						
							| 
									
										
										
										
											2016-09-22 06:35:38 -04:00
										 |  |  |   slot_visitor<nursery_copier> | 
					
						
							|  |  |  |       visitor(this, nursery_copier(data->nursery, data->aging)); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:16:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-04 11:52:04 -04:00
										 |  |  |   cell scan = data->aging->start + data->aging->occupied_space(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   visitor.visit_all_roots(); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:16:22 -04:00
										 |  |  |   gc_event* event = current_gc->event; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (event) | 
					
						
							| 
									
										
										
										
											2016-04-24 09:21:17 -04:00
										 |  |  |     event->reset_timer(); | 
					
						
							| 
									
										
										
										
											2016-05-04 11:52:04 -04:00
										 |  |  |   visitor.visit_cards(data->tenured, card_points_to_nursery, | 
					
						
							|  |  |  |                       card_points_to_nursery); | 
					
						
							|  |  |  |   visitor.visit_cards(data->aging, card_points_to_nursery, 0xff); | 
					
						
							| 
									
										
										
										
											2016-10-19 04:31:53 -04:00
										 |  |  |   if (event) { | 
					
						
							|  |  |  |     event->ended_phase(PHASE_CARD_SCAN); | 
					
						
							|  |  |  |     event->cards_scanned += visitor.cards_scanned; | 
					
						
							|  |  |  |     event->decks_scanned += visitor.decks_scanned; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-05-11 22:16:22 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (event) | 
					
						
							| 
									
										
										
										
											2016-04-24 09:21:17 -04:00
										 |  |  |     event->reset_timer(); | 
					
						
							| 
									
										
										
										
											2016-05-04 11:52:04 -04:00
										 |  |  |   visitor.visit_code_heap_roots(&code->points_to_nursery); | 
					
						
							| 
									
										
										
										
											2016-10-19 04:31:53 -04:00
										 |  |  |   if (event) { | 
					
						
							|  |  |  |     event->ended_phase(PHASE_CODE_SCAN); | 
					
						
							|  |  |  |     event->code_blocks_scanned += code->points_to_nursery.size(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-05-11 22:16:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-04 11:52:04 -04:00
										 |  |  |   visitor.cheneys_algorithm(data->aging, scan); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:16:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-10 10:14:54 -05:00
										 |  |  |   data->reset_nursery(); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:16:22 -04:00
										 |  |  |   code->points_to_nursery.clear(); | 
					
						
							| 
									
										
										
										
											2009-10-07 16:48:09 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |