| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace factor { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-01 04:47:09 -05:00
										 |  |  | template<typename Block> struct forwarder { | 
					
						
							|  |  |  | 	mark_bits<Block> *forwarding_map; | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-01 04:47:09 -05:00
										 |  |  | 	explicit forwarder(mark_bits<Block> *forwarding_map_) : | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 		forwarding_map(forwarding_map_) {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-01 04:47:09 -05:00
										 |  |  | 	Block *operator()(Block *block) | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-11-01 04:47:09 -05:00
										 |  |  | 		return forwarding_map->forward_block(block); | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | static inline cell tuple_size_with_forwarding(mark_bits<object> *forwarding_map, object *obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* The tuple layout may or may not have been forwarded already. Tricky. */ | 
					
						
							|  |  |  | 	object *layout_obj = (object *)UNTAG(((tuple *)obj)->layout); | 
					
						
							|  |  |  | 	tuple_layout *layout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(layout_obj < obj) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* It's already been moved up; dereference through forwarding
 | 
					
						
							|  |  |  | 		map to get the size */ | 
					
						
							|  |  |  | 		layout = (tuple_layout *)forwarding_map->forward_block(layout_obj); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* It hasn't been moved up yet; dereference directly */ | 
					
						
							|  |  |  | 		layout = (tuple_layout *)layout_obj; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tuple_size(layout); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct compaction_sizer { | 
					
						
							|  |  |  | 	mark_bits<object> *forwarding_map; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	explicit compaction_sizer(mark_bits<object> *forwarding_map_) : | 
					
						
							|  |  |  | 		forwarding_map(forwarding_map_) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cell operator()(object *obj) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-27 22:31:28 -04:00
										 |  |  | 		if(!forwarding_map->marked_p(obj)) | 
					
						
							| 
									
										
										
										
											2009-11-01 04:47:09 -05:00
										 |  |  | 			return forwarding_map->unmarked_block_size(obj); | 
					
						
							| 
									
										
										
										
											2009-11-10 22:06:36 -05:00
										 |  |  | 		else if(obj->type() == TUPLE_TYPE) | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | 			return align(tuple_size_with_forwarding(forwarding_map,obj),data_alignment); | 
					
						
							| 
									
										
										
										
											2009-10-27 22:31:28 -04:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			return obj->size(); | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | struct object_compaction_updater { | 
					
						
							|  |  |  | 	factor_vm *parent; | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	mark_bits<code_block> *code_forwarding_map; | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | 	mark_bits<object> *data_forwarding_map; | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 	object_start_map *starts; | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	explicit object_compaction_updater(factor_vm *parent_, | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 		mark_bits<object> *data_forwarding_map_, | 
					
						
							|  |  |  | 		mark_bits<code_block> *code_forwarding_map_) : | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 		parent(parent_), | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 		code_forwarding_map(code_forwarding_map_), | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 		data_forwarding_map(data_forwarding_map_), | 
					
						
							|  |  |  | 		starts(&parent->data->tenured->starts) {} | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 	void operator()(object *old_address, object *new_address, cell size) | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | 		cell payload_start; | 
					
						
							| 
									
										
										
										
											2009-11-10 22:06:36 -05:00
										 |  |  | 		if(old_address->type() == TUPLE_TYPE) | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 			payload_start = tuple_size_with_forwarding(data_forwarding_map,old_address); | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 			payload_start = old_address->binary_payload_start(); | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 		memmove(new_address,old_address,size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 		slot_visitor<forwarder<object> > slot_forwarder(parent,forwarder<object>(data_forwarding_map)); | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 		slot_forwarder.visit_slots(new_address,payload_start); | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		code_block_visitor<forwarder<code_block> > code_forwarder(parent,forwarder<code_block>(code_forwarding_map)); | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 		code_forwarder.visit_object_code_block(new_address); | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 		starts->record_object_start_offset(new_address); | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | template<typename SlotForwarder> | 
					
						
							|  |  |  | struct code_block_compaction_relocation_visitor { | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 	factor_vm *parent; | 
					
						
							|  |  |  | 	code_block *old_address; | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	slot_visitor<SlotForwarder> slot_forwarder; | 
					
						
							|  |  |  | 	code_block_visitor<forwarder<code_block> > code_forwarder; | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	explicit code_block_compaction_relocation_visitor(factor_vm *parent_, | 
					
						
							|  |  |  | 		code_block *old_address_, | 
					
						
							|  |  |  | 		slot_visitor<SlotForwarder> slot_forwarder_, | 
					
						
							|  |  |  | 		code_block_visitor<forwarder<code_block> > code_forwarder_) : | 
					
						
							|  |  |  | 		parent(parent_), | 
					
						
							|  |  |  | 		old_address(old_address_), | 
					
						
							|  |  |  | 		slot_forwarder(slot_forwarder_), | 
					
						
							|  |  |  | 		code_forwarder(code_forwarder_) {} | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 01:48:41 -05:00
										 |  |  | 	void operator()(instruction_operand op) | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-01-18 02:51:27 -05:00
										 |  |  | 		cell old_offset = op.rel_offset() + (cell)old_address->entry_point(); | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 01:48:41 -05:00
										 |  |  | 		switch(op.rel_type()) | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-12-15 07:20:09 -05:00
										 |  |  | 		case RT_LITERAL: | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 			op.store_value(slot_forwarder.visit_pointer(op.load_value(old_offset))); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2010-01-18 02:51:27 -05:00
										 |  |  | 		case RT_ENTRY_POINT: | 
					
						
							|  |  |  | 		case RT_ENTRY_POINT_PIC: | 
					
						
							|  |  |  | 		case RT_ENTRY_POINT_PIC_TAIL: | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 			op.store_code_block(code_forwarder.visit_code_block(op.load_code_block(old_offset))); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case RT_HERE: | 
					
						
							| 
									
										
										
										
											2009-12-02 05:55:48 -05:00
										 |  |  | 			op.store_value(op.load_value(old_offset) - (cell)old_address + (cell)op.parent_code_block()); | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 		case RT_THIS: | 
					
						
							|  |  |  | 		case RT_CARDS_OFFSET: | 
					
						
							|  |  |  | 		case RT_DECKS_OFFSET: | 
					
						
							| 
									
										
										
										
											2009-12-02 02:09:08 -05:00
										 |  |  | 			parent->store_external_address(op); | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			op.store_value(op.load_value(old_offset)); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | template<typename SlotForwarder> | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | struct code_block_compaction_updater { | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	factor_vm *parent; | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	slot_visitor<SlotForwarder> slot_forwarder; | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 	code_block_visitor<forwarder<code_block> > code_forwarder; | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 	explicit code_block_compaction_updater(factor_vm *parent_, | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 		slot_visitor<SlotForwarder> slot_forwarder_, | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 		code_block_visitor<forwarder<code_block> > code_forwarder_) : | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 		parent(parent_), | 
					
						
							|  |  |  | 		slot_forwarder(slot_forwarder_), | 
					
						
							|  |  |  | 		code_forwarder(code_forwarder_) {} | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 	void operator()(code_block *old_address, code_block *new_address, cell size) | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 		memmove(new_address,old_address,size); | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		slot_forwarder.visit_code_block_objects(new_address); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 		code_block_compaction_relocation_visitor<SlotForwarder> visitor(parent,old_address,slot_forwarder,code_forwarder); | 
					
						
							| 
									
										
										
										
											2009-12-02 01:48:41 -05:00
										 |  |  | 		new_address->each_instruction_operand(visitor); | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-25 21:24:21 -05:00
										 |  |  | /* After a compaction, invalidate any code heap roots which are not
 | 
					
						
							|  |  |  | marked, and also slide the valid roots up so that call sites can be updated | 
					
						
							|  |  |  | correctly in case an inline cache compilation triggered compaction. */ | 
					
						
							|  |  |  | void factor_vm::update_code_roots_for_compaction() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::vector<code_root *>::const_iterator iter = code_roots.begin(); | 
					
						
							|  |  |  | 	std::vector<code_root *>::const_iterator end = code_roots.end(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mark_bits<code_block> *state = &code->allocator->state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(; iter < end; iter++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		code_root *root = *iter; | 
					
						
							| 
									
										
										
										
											2010-01-16 09:43:22 -05:00
										 |  |  | 		code_block *block = (code_block *)(root->value & (~data_alignment + 1)); | 
					
						
							| 
									
										
										
										
											2009-12-25 21:24:21 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* Offset of return address within 16-byte allocation line */ | 
					
						
							|  |  |  | 		cell offset = root->value - (cell)block; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(root->valid && state->marked_p(block)) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			block = state->forward_block(block); | 
					
						
							|  |  |  | 			root->value = (cell)block + offset; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			root->valid = false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | /* Compact data and code heaps */ | 
					
						
							| 
									
										
										
										
											2009-10-25 15:02:14 -04:00
										 |  |  | void factor_vm::collect_compact_impl(bool trace_contexts_p) | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | 	current_gc->event->started_compaction(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	tenured_space *tenured = data->tenured; | 
					
						
							|  |  |  | 	mark_bits<object> *data_forwarding_map = &tenured->state; | 
					
						
							| 
									
										
										
										
											2009-10-24 22:24:06 -04:00
										 |  |  | 	mark_bits<code_block> *code_forwarding_map = &code->allocator->state; | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Figure out where blocks are going to go */ | 
					
						
							|  |  |  | 	data_forwarding_map->compute_forwarding(); | 
					
						
							|  |  |  | 	code_forwarding_map->compute_forwarding(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-01 04:47:09 -05:00
										 |  |  | 	slot_visitor<forwarder<object> > slot_forwarder(this,forwarder<object>(data_forwarding_map)); | 
					
						
							|  |  |  | 	code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(code_forwarding_map)); | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | 	code_forwarder.visit_uninitialized_code_blocks(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-25 09:07:21 -04:00
										 |  |  | 	/* Object start offsets get recomputed by the object_compaction_updater */ | 
					
						
							|  |  |  | 	data->tenured->starts.clear_object_start_offsets(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 	/* Slide everything in tenured space up, and update data and code heap
 | 
					
						
							|  |  |  | 	pointers inside objects. */ | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	object_compaction_updater object_updater(this,data_forwarding_map,code_forwarding_map); | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | 	compaction_sizer object_sizer(data_forwarding_map); | 
					
						
							|  |  |  | 	tenured->compact(object_updater,object_sizer); | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* Slide everything in the code heap up, and update data and code heap
 | 
					
						
							|  |  |  | 	pointers inside code blocks. */ | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	code_block_compaction_updater<forwarder<object> > code_block_updater(this,slot_forwarder,code_forwarder); | 
					
						
							| 
									
										
										
										
											2009-10-25 00:51:14 -04:00
										 |  |  | 	standard_sizer<code_block> code_block_sizer; | 
					
						
							|  |  |  | 	code->allocator->compact(code_block_updater,code_block_sizer); | 
					
						
							| 
									
										
										
										
											2009-10-25 01:06:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	slot_forwarder.visit_roots(); | 
					
						
							|  |  |  | 	if(trace_contexts_p) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		slot_forwarder.visit_contexts(); | 
					
						
							|  |  |  | 		code_forwarder.visit_context_code_blocks(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 19:10:34 -05:00
										 |  |  | 	update_code_roots_for_compaction(); | 
					
						
							| 
									
										
										
										
											2009-12-02 04:31:57 -05:00
										 |  |  | 	callbacks->update(); | 
					
						
							| 
									
										
										
										
											2009-11-02 19:10:34 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-27 00:57:26 -04:00
										 |  |  | 	current_gc->event->ended_compaction(); | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | struct object_grow_heap_updater { | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 	code_block_visitor<forwarder<code_block> > code_forwarder; | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	explicit object_grow_heap_updater(code_block_visitor<forwarder<code_block> > code_forwarder_) : | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 		code_forwarder(code_forwarder_) {} | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-05 22:49:03 -05:00
										 |  |  | 	void operator()(object *obj) | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 		code_forwarder.visit_object_code_block(obj); | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | struct dummy_slot_forwarder { | 
					
						
							|  |  |  | 	object *operator()(object *obj) { return obj; } | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | /* Compact just the code heap, after growing the data heap */ | 
					
						
							| 
									
										
										
										
											2009-11-01 05:40:15 -05:00
										 |  |  | void factor_vm::collect_compact_code_impl(bool trace_contexts_p) | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* Figure out where blocks are going to go */ | 
					
						
							| 
									
										
										
										
											2009-11-01 05:40:15 -05:00
										 |  |  | 	mark_bits<code_block> *code_forwarding_map = &code->allocator->state; | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | 	code_forwarding_map->compute_forwarding(); | 
					
						
							| 
									
										
										
										
											2009-11-24 20:29:59 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	slot_visitor<dummy_slot_forwarder> slot_forwarder(this,dummy_slot_forwarder()); | 
					
						
							| 
									
										
										
										
											2009-11-01 04:47:09 -05:00
										 |  |  | 	code_block_visitor<forwarder<code_block> > code_forwarder(this,forwarder<code_block>(code_forwarding_map)); | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | 	code_forwarder.visit_uninitialized_code_blocks(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-01 05:40:15 -05:00
										 |  |  | 	if(trace_contexts_p) | 
					
						
							|  |  |  | 		code_forwarder.visit_context_code_blocks(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Update code heap references in data heap */ | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	object_grow_heap_updater updater(code_forwarder); | 
					
						
							| 
									
										
										
										
											2009-11-01 05:40:15 -05:00
										 |  |  | 	each_object(updater); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | 	/* Slide everything in the code heap up, and update code heap
 | 
					
						
							|  |  |  | 	pointers inside code blocks. */ | 
					
						
							| 
									
										
										
										
											2009-11-28 20:48:26 -05:00
										 |  |  | 	code_block_compaction_updater<dummy_slot_forwarder> code_block_updater(this,slot_forwarder,code_forwarder); | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | 	standard_sizer<code_block> code_block_sizer; | 
					
						
							|  |  |  | 	code->allocator->compact(code_block_updater,code_block_sizer); | 
					
						
							| 
									
										
										
										
											2009-11-02 19:10:34 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	update_code_roots_for_compaction(); | 
					
						
							| 
									
										
										
										
											2009-12-02 04:31:57 -05:00
										 |  |  | 	callbacks->update(); | 
					
						
							| 
									
										
										
										
											2009-10-31 22:06:34 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 01:48:41 -05:00
										 |  |  | void factor_vm::collect_compact(bool trace_contexts_p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	collect_mark_impl(trace_contexts_p); | 
					
						
							|  |  |  | 	collect_compact_impl(trace_contexts_p); | 
					
						
							|  |  |  | 	code->flush_icache(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void factor_vm::collect_growing_heap(cell requested_bytes, bool trace_contexts_p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Grow the data heap and copy all live objects to the new heap. */ | 
					
						
							|  |  |  | 	data_heap *old = data; | 
					
						
							|  |  |  | 	set_data_heap(data->grow(requested_bytes)); | 
					
						
							|  |  |  | 	collect_mark_impl(trace_contexts_p); | 
					
						
							|  |  |  | 	collect_compact_code_impl(trace_contexts_p); | 
					
						
							|  |  |  | 	code->flush_icache(); | 
					
						
							|  |  |  | 	delete old; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 05:18:33 -04:00
										 |  |  | } |