| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | #include "master.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | /* Allocate a code heap during startup */ | 
					
						
							|  |  |  | void init_code_heap(CELL size) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	new_heap(&code_heap,size); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | bool in_code_heap_p(CELL ptr) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	return (ptr >= code_heap.segment->start | 
					
						
							|  |  |  | 		&& ptr <= code_heap.segment->end); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | void set_word_code(F_WORD *word, F_CODE_BLOCK *compiled) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-19 04:49:49 -04:00
										 |  |  | 	if(compiled->block.type != WORD_TYPE) | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 		critical_error("bad param to set_word_xt",(CELL)compiled); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	word->code = compiled; | 
					
						
							|  |  |  | 	word->optimizedp = T; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | /* Allocates memory */ | 
					
						
							|  |  |  | void default_word_code(F_WORD *word, bool relocate) | 
					
						
							| 
									
										
										
										
											2008-01-07 16:14:09 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	REGISTER_UNTAGGED(word); | 
					
						
							|  |  |  | 	jit_compile(word->def,relocate); | 
					
						
							|  |  |  | 	UNREGISTER_UNTAGGED(word); | 
					
						
							| 
									
										
										
										
											2008-01-07 16:14:09 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	word->code = untag_quotation(word->def)->code; | 
					
						
							|  |  |  | 	word->optimizedp = F; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | /* Apply a function to every code block */ | 
					
						
							|  |  |  | void iterate_code_heap(CODE_HEAP_ITERATOR iter) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	F_BLOCK *scan = first_block(&code_heap); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	while(scan) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 		if(scan->status != B_FREE) | 
					
						
							| 
									
										
										
										
											2009-03-19 04:45:37 -04:00
										 |  |  | 			iter((F_CODE_BLOCK *)scan); | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 		scan = next_block(&code_heap,scan); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | /* Copy literals referenced from all code blocks to newspace. Only for
 | 
					
						
							|  |  |  | aging and nursery collections */ | 
					
						
							|  |  |  | void copy_code_heap_roots(void) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	iterate_code_heap(copy_literal_references); | 
					
						
							| 
									
										
										
										
											2007-10-28 04:33:36 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | /* Update literals referenced from all code blocks. Only for tenured
 | 
					
						
							|  |  |  | collections, done at the end. */ | 
					
						
							|  |  |  | void update_code_heap_roots(void) | 
					
						
							| 
									
										
										
										
											2007-10-28 04:33:36 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	iterate_code_heap(update_literal_references); | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-10-28 04:33:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | /* Update pointers to words referenced from all code blocks. Only after
 | 
					
						
							|  |  |  | defining a new word. */ | 
					
						
							|  |  |  | void update_code_heap_words(void) | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	iterate_code_heap(update_word_references); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-13 04:20:34 -05:00
										 |  |  | void primitive_modify_code_heap(void) | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-12-16 15:17:28 -05:00
										 |  |  | 	F_ARRAY *alist = untag_array(dpop()); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-16 15:17:28 -05:00
										 |  |  | 	CELL count = untag_fixnum_fast(alist->capacity); | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	if(count == 0) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	CELL i; | 
					
						
							|  |  |  | 	for(i = 0; i < count; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2007-12-21 21:18:24 -05:00
										 |  |  | 		F_ARRAY *pair = untag_array(array_nth(alist,i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		F_WORD *word = untag_word(array_nth(pair,0)); | 
					
						
							| 
									
										
										
										
											2007-12-30 21:34:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-12-21 21:18:24 -05:00
										 |  |  | 		CELL data = array_nth(pair,1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if(data == F) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 			REGISTER_UNTAGGED(alist); | 
					
						
							| 
									
										
										
										
											2008-01-07 16:14:09 -05:00
										 |  |  | 			REGISTER_UNTAGGED(word); | 
					
						
							| 
									
										
										
										
											2008-01-09 01:33:40 -05:00
										 |  |  | 			default_word_code(word,false); | 
					
						
							| 
									
										
										
										
											2008-01-07 16:14:09 -05:00
										 |  |  | 			UNREGISTER_UNTAGGED(word); | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 			UNREGISTER_UNTAGGED(alist); | 
					
						
							| 
									
										
										
										
											2007-12-21 21:18:24 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			F_ARRAY *compiled_code = untag_array(data); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 			F_ARRAY *literals = untag_array(array_nth(compiled_code,0)); | 
					
						
							| 
									
										
										
										
											2008-05-30 02:31:05 -04:00
										 |  |  | 			CELL relocation = array_nth(compiled_code,1); | 
					
						
							| 
									
										
										
										
											2008-01-16 15:45:04 -05:00
										 |  |  | 			F_ARRAY *labels = untag_array(array_nth(compiled_code,2)); | 
					
						
							|  |  |  | 			F_ARRAY *code = untag_array(array_nth(compiled_code,3)); | 
					
						
							| 
									
										
										
										
											2007-12-21 21:18:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			REGISTER_UNTAGGED(alist); | 
					
						
							|  |  |  | 			REGISTER_UNTAGGED(word); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-19 04:45:37 -04:00
										 |  |  | 			F_CODE_BLOCK *compiled = add_code_block( | 
					
						
							| 
									
										
										
										
											2007-12-21 21:18:24 -05:00
										 |  |  | 				WORD_TYPE, | 
					
						
							|  |  |  | 				code, | 
					
						
							|  |  |  | 				labels, | 
					
						
							| 
									
										
										
										
											2007-12-25 23:40:36 -05:00
										 |  |  | 				relocation, | 
					
						
							| 
									
										
										
										
											2009-01-24 18:01:01 -05:00
										 |  |  | 				tag_object(literals)); | 
					
						
							| 
									
										
										
										
											2007-12-21 21:18:24 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			UNREGISTER_UNTAGGED(word); | 
					
						
							|  |  |  | 			UNREGISTER_UNTAGGED(alist); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 			set_word_code(word,compiled); | 
					
						
							| 
									
										
										
										
											2007-12-21 21:18:24 -05:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-01-02 19:36:36 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		REGISTER_UNTAGGED(alist); | 
					
						
							|  |  |  | 		update_word_xt(word); | 
					
						
							|  |  |  | 		UNREGISTER_UNTAGGED(alist); | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	update_code_heap_words(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Push the free space and total size of the code heap */ | 
					
						
							|  |  |  | void primitive_code_room(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL used, total_free, max_free; | 
					
						
							|  |  |  | 	heap_usage(&code_heap,&used,&total_free,&max_free); | 
					
						
							|  |  |  | 	dpush(tag_fixnum((code_heap.segment->size) / 1024)); | 
					
						
							|  |  |  | 	dpush(tag_fixnum(used / 1024)); | 
					
						
							|  |  |  | 	dpush(tag_fixnum(total_free / 1024)); | 
					
						
							|  |  |  | 	dpush(tag_fixnum(max_free / 1024)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | F_CODE_BLOCK *forward_xt(F_CODE_BLOCK *compiled) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-19 04:45:37 -04:00
										 |  |  | 	return (F_CODE_BLOCK *)compiled->block.forwarding; | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void forward_frame_xt(F_STACK_FRAME *frame) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	CELL offset = (CELL)FRAME_RETURN_ADDRESS(frame) - (CELL)frame_code(frame); | 
					
						
							|  |  |  | 	F_CODE_BLOCK *forwarded = forward_xt(frame_code(frame)); | 
					
						
							|  |  |  | 	frame->xt = (XT)(forwarded + 1); | 
					
						
							|  |  |  | 	FRAME_RETURN_ADDRESS(frame) = (XT)((CELL)forwarded + offset); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void forward_object_xts(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	begin_scan(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CELL obj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while((obj = next_object()) != F) | 
					
						
							| 
									
										
										
										
											2007-12-30 21:34:44 -05:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 		if(type_of(obj) == WORD_TYPE) | 
					
						
							| 
									
										
										
										
											2007-12-30 21:34:44 -05:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 			F_WORD *word = untag_object(obj); | 
					
						
							| 
									
										
										
										
											2007-12-30 21:34:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 			word->code = forward_xt(word->code); | 
					
						
							|  |  |  | 			if(word->profiling) | 
					
						
							|  |  |  | 				word->profiling = forward_xt(word->profiling); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if(type_of(obj) == QUOTATION_TYPE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			F_QUOTATION *quot = untag_object(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(quot->compiledp != F) | 
					
						
							|  |  |  | 				quot->code = forward_xt(quot->code); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if(type_of(obj) == CALLSTACK_TYPE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			F_CALLSTACK *stack = untag_object(obj); | 
					
						
							|  |  |  | 			iterate_callstack_object(stack,forward_frame_xt); | 
					
						
							| 
									
										
										
										
											2007-12-30 21:34:44 -05:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* End the heap scan */ | 
					
						
							|  |  |  | 	gc_off = false; | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-01-24 18:01:01 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | /* Set the XT fields now that the heap has been compacted */ | 
					
						
							|  |  |  | void fixup_object_xts(void) | 
					
						
							| 
									
										
										
										
											2009-01-24 18:01:01 -05:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-01-24 21:13:17 -05:00
										 |  |  | 	begin_scan(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CELL obj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while((obj = next_object()) != F) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(type_of(obj) == WORD_TYPE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			F_WORD *word = untag_object(obj); | 
					
						
							|  |  |  | 			update_word_xt(word); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if(type_of(obj) == QUOTATION_TYPE) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			F_QUOTATION *quot = untag_object(obj); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if(quot->compiledp != F) | 
					
						
							|  |  |  | 				set_quot_xt(quot,quot->code); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* End the heap scan */ | 
					
						
							|  |  |  | 	gc_off = false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Move all free space to the end of the code heap. This is not very efficient,
 | 
					
						
							|  |  |  | since it makes several passes over the code and data heaps, but we only ever | 
					
						
							|  |  |  | do this before saving a deployed image and exiting, so performaance is not | 
					
						
							|  |  |  | critical here */ | 
					
						
							|  |  |  | void compact_code_heap(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* Free all unreachable code blocks */ | 
					
						
							|  |  |  | 	gc(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Figure out where the code heap blocks are going to end up */ | 
					
						
							|  |  |  | 	CELL size = compute_heap_forwarding(&code_heap); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Update word and quotation code pointers */ | 
					
						
							|  |  |  | 	forward_object_xts(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Actually perform the compaction */ | 
					
						
							|  |  |  | 	compact_heap(&code_heap); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Update word and quotation XTs */ | 
					
						
							|  |  |  | 	fixup_object_xts(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Now update the free list; there will be a single free block at
 | 
					
						
							|  |  |  | 	the end */ | 
					
						
							|  |  |  | 	build_free_list(&code_heap,size); | 
					
						
							| 
									
										
										
										
											2009-01-24 18:01:01 -05:00
										 |  |  | } |