| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | gc_event::gc_event(gc_op op_, factor_vm *parent) : | 
					
						
							|  |  |  | 	op(op_), | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | 	cards_scanned(0), | 
					
						
							|  |  |  | 	decks_scanned(0), | 
					
						
							|  |  |  | 	code_blocks_scanned(0), | 
					
						
							| 
									
										
										
										
											2009-11-18 16:58:48 -05:00
										 |  |  | 	start_time(nano_count()), | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | 	card_scan_time(0), | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | 	code_scan_time(0), | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | 	data_sweep_time(0), | 
					
						
							|  |  |  | 	code_sweep_time(0), | 
					
						
							|  |  |  | 	compaction_time(0) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-27 22:31:28 -04:00
										 |  |  | 	data_heap_before = parent->data_room(); | 
					
						
							|  |  |  | 	code_heap_before = parent->code_room(); | 
					
						
							| 
									
										
										
										
											2009-11-18 16:58:48 -05:00
										 |  |  | 	start_time = nano_count(); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::started_card_scan() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-18 16:58:48 -05:00
										 |  |  | 	temp_time = nano_count(); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::ended_card_scan(cell cards_scanned_, cell decks_scanned_) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	cards_scanned += cards_scanned_; | 
					
						
							|  |  |  | 	decks_scanned += decks_scanned_; | 
					
						
							| 
									
										
										
										
											2010-01-16 09:43:22 -05:00
										 |  |  | 	card_scan_time = (cell)(nano_count() - temp_time); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::started_code_scan() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-18 16:58:48 -05:00
										 |  |  | 	temp_time = nano_count(); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::ended_code_scan(cell code_blocks_scanned_) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	code_blocks_scanned += code_blocks_scanned_; | 
					
						
							| 
									
										
										
										
											2010-01-16 09:43:22 -05:00
										 |  |  | 	code_scan_time = (cell)(nano_count() - temp_time); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::started_data_sweep() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-18 16:58:48 -05:00
										 |  |  | 	temp_time = nano_count(); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::ended_data_sweep() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-16 09:43:22 -05:00
										 |  |  | 	data_sweep_time = (cell)(nano_count() - temp_time); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::started_code_sweep() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-18 16:58:48 -05:00
										 |  |  | 	temp_time = nano_count(); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::ended_code_sweep() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-16 09:43:22 -05:00
										 |  |  | 	code_sweep_time = (cell)(nano_count() - temp_time); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::started_compaction() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-18 16:58:48 -05:00
										 |  |  | 	temp_time = nano_count(); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::ended_compaction() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-16 09:43:22 -05:00
										 |  |  | 	compaction_time = (cell)(nano_count() - temp_time); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void gc_event::ended_gc(factor_vm *parent) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-27 22:31:28 -04:00
										 |  |  | 	data_heap_after = parent->data_room(); | 
					
						
							|  |  |  | 	code_heap_after = parent->code_room(); | 
					
						
							| 
									
										
										
										
											2010-01-16 09:43:22 -05:00
										 |  |  | 	total_time = (cell)(nano_count() - start_time); | 
					
						
							| 
									
										
										
										
											2009-10-26 23:12:44 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-04 16:21:45 -04:00
										 |  |  | gc_state::gc_state(gc_op op_, factor_vm *parent) : op(op_) | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-04 16:21:45 -04:00
										 |  |  | 	if(parent->gc_events) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		event = new gc_event(op,parent); | 
					
						
							|  |  |  | 		start_time = nano_count(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		event = NULL; | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gc_state::~gc_state() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-04 16:21:45 -04:00
										 |  |  | 	if(event) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		delete event; | 
					
						
							|  |  |  | 		event = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 04:32:28 -04:00
										 |  |  | void factor_vm::end_gc() | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-04 16:21:45 -04:00
										 |  |  | 	if(gc_events) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		current_gc->event->ended_gc(this); | 
					
						
							|  |  |  | 		gc_events->push_back(*current_gc->event); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-10-27 04:32:28 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::start_gc_again() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	end_gc(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch(current_gc->op) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	case collect_nursery_op: | 
					
						
							|  |  |  | 		current_gc->op = collect_aging_op; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case collect_aging_op: | 
					
						
							|  |  |  | 		current_gc->op = collect_to_tenured_op; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case collect_to_tenured_op: | 
					
						
							|  |  |  | 		current_gc->op = collect_full_op; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case collect_full_op: | 
					
						
							|  |  |  | 	case collect_compact_op: | 
					
						
							|  |  |  | 		current_gc->op = collect_growing_heap_op; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		critical_error("Bad GC op",current_gc->op); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-04 16:21:45 -04:00
										 |  |  | 	if(gc_events) | 
					
						
							|  |  |  | 		current_gc->event = new gc_event(current_gc->op,this); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::set_current_gc_op(gc_op op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	current_gc->op = op; | 
					
						
							|  |  |  | 	if(gc_events) current_gc->event->op = op; | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 15:02:14 -04:00
										 |  |  | void factor_vm::gc(gc_op op, cell requested_bytes, bool trace_contexts_p) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-06 05:36:34 -04:00
										 |  |  | 	assert(!gc_off); | 
					
						
							|  |  |  | 	assert(!current_gc); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | 	current_gc = new gc_state(op,this); | 
					
						
							| 
									
										
										
										
											2009-10-21 21:12:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-03 09:47:05 -04:00
										 |  |  | 	/* Keep trying to GC higher and higher generations until we don't run out
 | 
					
						
							|  |  |  | 	of space */ | 
					
						
							| 
									
										
										
										
											2010-04-02 14:10:55 -04:00
										 |  |  | 	for(;;) | 
					
						
							| 
									
										
										
										
											2009-10-09 03:57:04 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-04-02 14:10:55 -04:00
										 |  |  | 		try | 
					
						
							| 
									
										
										
										
											2009-11-03 23:25:22 -05:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2010-09-04 16:21:45 -04:00
										 |  |  | 			if(gc_events) current_gc->event->op = current_gc->op; | 
					
						
							| 
									
										
										
										
											2010-04-02 14:10:55 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			switch(current_gc->op) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 			case collect_nursery_op: | 
					
						
							|  |  |  | 				collect_nursery(); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case collect_aging_op: | 
					
						
							|  |  |  | 				collect_aging(); | 
					
						
							|  |  |  | 				if(data->high_fragmentation_p()) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2010-09-04 16:21:45 -04:00
										 |  |  | 					set_current_gc_op(collect_full_op); | 
					
						
							| 
									
										
										
										
											2010-04-02 14:10:55 -04:00
										 |  |  | 					collect_full(trace_contexts_p); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case collect_to_tenured_op: | 
					
						
							|  |  |  | 				collect_to_tenured(); | 
					
						
							|  |  |  | 				if(data->high_fragmentation_p()) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2010-09-04 16:21:45 -04:00
										 |  |  | 					set_current_gc_op(collect_full_op); | 
					
						
							| 
									
										
										
										
											2010-04-02 14:10:55 -04:00
										 |  |  | 					collect_full(trace_contexts_p); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case collect_full_op: | 
					
						
							|  |  |  | 				collect_full(trace_contexts_p); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case collect_compact_op: | 
					
						
							|  |  |  | 				collect_compact(trace_contexts_p); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			case collect_growing_heap_op: | 
					
						
							|  |  |  | 				collect_growing_heap(requested_bytes,trace_contexts_p); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				critical_error("Bad GC op",current_gc->op); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-11-03 23:25:22 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-05-06 01:32:45 -04:00
										 |  |  | 		catch(const must_start_gc_again &) | 
					
						
							| 
									
										
										
										
											2009-11-03 23:25:22 -05:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2010-04-02 14:10:55 -04:00
										 |  |  | 			/* We come back here if a generation is full */ | 
					
						
							|  |  |  | 			start_gc_again(); | 
					
						
							|  |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2009-11-03 23:25:22 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-10-14 03:06:01 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 04:32:28 -04:00
										 |  |  | 	end_gc(); | 
					
						
							| 
									
										
										
										
											2009-10-22 00:24:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-03 09:47:05 -04:00
										 |  |  | 	delete current_gc; | 
					
						
							|  |  |  | 	current_gc = NULL; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-11 20:06:00 -04:00
										 |  |  | /* primitive_minor_gc() is invoked by inline GC checks, and it needs to fill in
 | 
					
						
							|  |  |  | uninitialized stack locations before actually calling the GC. See the comment | 
					
						
							|  |  |  | in compiler.cfg.stacks.uninitialized for details. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct call_frame_scrubber { | 
					
						
							|  |  |  | 	factor_vm *parent; | 
					
						
							|  |  |  | 	context *ctx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	explicit call_frame_scrubber(factor_vm *parent_, context *ctx_) : | 
					
						
							|  |  |  | 		parent(parent_), ctx(ctx_) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void operator()(stack_frame *frame) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-06-13 17:57:16 -04:00
										 |  |  | 		cell return_address = parent->frame_offset(frame); | 
					
						
							|  |  |  | 		if(return_address == (cell)-1) | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		code_block *compiled = parent->frame_code(frame); | 
					
						
							| 
									
										
										
										
											2010-06-11 20:06:00 -04:00
										 |  |  | 		gc_info *info = compiled->block_gc_info(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-12 19:52:28 -04:00
										 |  |  | 		assert(return_address < compiled->size()); | 
					
						
							| 
									
										
										
										
											2010-10-09 17:03:46 -04:00
										 |  |  | 		cell index = info->return_address_index(return_address); | 
					
						
							|  |  |  | 		if(index != (cell)-1) | 
					
						
							| 
									
										
										
										
											2010-06-11 20:06:00 -04:00
										 |  |  | 			ctx->scrub_stacks(info,index); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::scrub_context(context *ctx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	call_frame_scrubber scrubber(this,ctx); | 
					
						
							|  |  |  | 	iterate_callstack(ctx,scrubber); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::scrub_contexts() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::set<context *>::const_iterator begin = active_contexts.begin(); | 
					
						
							|  |  |  | 	std::set<context *>::const_iterator end = active_contexts.end(); | 
					
						
							|  |  |  | 	while(begin != end) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		scrub_context(*begin); | 
					
						
							|  |  |  | 		begin++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-16 12:39:22 -04:00
										 |  |  | void factor_vm::primitive_minor_gc() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-11 20:06:00 -04:00
										 |  |  | 	scrub_contexts(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-22 00:24:35 -04:00
										 |  |  | 	gc(collect_nursery_op, | 
					
						
							| 
									
										
										
										
											2009-10-16 05:33:35 -04:00
										 |  |  | 		0, /* requested size */ | 
					
						
							| 
									
										
										
										
											2009-10-25 15:02:14 -04:00
										 |  |  | 		true /* trace contexts? */); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-16 12:39:22 -04:00
										 |  |  | void factor_vm::primitive_full_gc() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-16 12:39:22 -04:00
										 |  |  | 	gc(collect_full_op, | 
					
						
							| 
									
										
										
										
											2009-10-16 05:33:35 -04:00
										 |  |  | 		0, /* requested size */ | 
					
						
							| 
									
										
										
										
											2009-10-25 15:02:14 -04:00
										 |  |  | 		true /* trace contexts? */); | 
					
						
							| 
									
										
										
										
											2009-10-16 05:33:35 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::primitive_compact_gc() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-25 15:02:14 -04:00
										 |  |  | 	gc(collect_compact_op, | 
					
						
							| 
									
										
										
										
											2009-10-16 05:33:35 -04:00
										 |  |  | 		0, /* requested size */ | 
					
						
							| 
									
										
										
										
											2009-10-25 15:02:14 -04:00
										 |  |  | 		true /* trace contexts? */); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * It is up to the caller to fill in the object's fields in a meaningful | 
					
						
							|  |  |  |  * fashion! | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-11-10 22:06:36 -05:00
										 |  |  | object *factor_vm::allot_large_object(cell type, cell size) | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-31 04:02:19 -04:00
										 |  |  | 	/* If tenured space does not have enough room, collect and compact */ | 
					
						
							|  |  |  | 	if(!data->tenured->can_allot_p(size)) | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-31 04:02:19 -04:00
										 |  |  | 		primitive_compact_gc(); | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 04:02:19 -04:00
										 |  |  | 		/* If it still won't fit, grow the heap */ | 
					
						
							| 
									
										
										
										
											2009-10-25 14:27:40 -04:00
										 |  |  | 		if(!data->tenured->can_allot_p(size)) | 
					
						
							| 
									
										
										
										
											2009-10-16 05:33:35 -04:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-10-31 04:02:19 -04:00
										 |  |  | 			gc(collect_growing_heap_op, | 
					
						
							|  |  |  | 				size, /* requested size */ | 
					
						
							|  |  |  | 				true /* trace contexts? */); | 
					
						
							| 
									
										
										
										
											2009-10-16 05:33:35 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 	object *obj = data->tenured->allot(size); | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 03:30:48 -04:00
										 |  |  | 	/* Allows initialization code to store old->new pointers
 | 
					
						
							|  |  |  | 	without hitting the write barrier in the common case of | 
					
						
							|  |  |  | 	a nursery allocation */ | 
					
						
							| 
									
										
										
										
											2009-11-05 20:03:51 -05:00
										 |  |  | 	write_barrier(obj,size); | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 22:06:36 -05:00
										 |  |  | 	obj->initialize(type); | 
					
						
							| 
									
										
										
										
											2009-09-29 14:53:10 -04:00
										 |  |  | 	return obj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 04:32:28 -04:00
										 |  |  | void factor_vm::primitive_enable_gc_events() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	gc_events = new std::vector<gc_event>(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::primitive_disable_gc_events() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(gc_events) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-11-11 06:21:03 -05:00
										 |  |  | 		growable_array result(this); | 
					
						
							| 
									
										
										
										
											2009-10-27 04:32:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 06:21:03 -05:00
										 |  |  | 		std::vector<gc_event> *gc_events = this->gc_events; | 
					
						
							|  |  |  | 		this->gc_events = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		std::vector<gc_event>::const_iterator iter = gc_events->begin(); | 
					
						
							|  |  |  | 		std::vector<gc_event>::const_iterator end = gc_events->end(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for(; iter != end; iter++) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			gc_event event = *iter; | 
					
						
							|  |  |  | 			byte_array *obj = byte_array_from_value(&event); | 
					
						
							|  |  |  | 			result.add(tag<byte_array>(obj)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		result.trim(); | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 		ctx->push(result.elements.value()); | 
					
						
							| 
									
										
										
										
											2009-11-11 06:21:03 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		delete this->gc_events; | 
					
						
							| 
									
										
										
										
											2009-10-27 04:32:28 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							| 
									
										
										
										
											2009-12-18 16:59:56 -05:00
										 |  |  | 		ctx->push(false_object); | 
					
						
							| 
									
										
										
										
											2009-10-27 04:32:28 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |