Fix save-image-and-exit, clean up compiler a bit
							parent
							
								
									53f5994893
								
							
						
					
					
						commit
						3c5b2073ef
					
				| 
						 | 
				
			
			@ -33,7 +33,7 @@ global [ { "compiler" } add-use ] bind
 | 
			
		|||
 | 
			
		||||
    delegate
 | 
			
		||||
 | 
			
		||||
    underlying2
 | 
			
		||||
    underlying
 | 
			
		||||
 | 
			
		||||
    find-pair-next namestack*
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,6 @@ ARTICLE: "compiler-usage" "Calling the optimizing compiler"
 | 
			
		|||
"Three utility words for bulk compilation:"
 | 
			
		||||
{ $subsection compile-batch }
 | 
			
		||||
{ $subsection compile-vocabs }
 | 
			
		||||
{ $subsection compile-all }
 | 
			
		||||
"Bulk compilation saves compile warnings and errors in a global variable, instead of printing them as they arise:"
 | 
			
		||||
{ $subsection compile-errors }
 | 
			
		||||
"The warnings and errors can be viewed later:"
 | 
			
		||||
| 
						 | 
				
			
			@ -113,9 +112,6 @@ HELP: recompile
 | 
			
		|||
{ $description "Recompiles words whose compiled definitions have become out of date as a result of dependent words being redefined." } ;
 | 
			
		||||
 | 
			
		||||
HELP: compile-all
 | 
			
		||||
{ $description "Compiles all words which have not been compiled yet." } ;
 | 
			
		||||
 | 
			
		||||
HELP: recompile-all
 | 
			
		||||
{ $description "Recompiles all words." } ;
 | 
			
		||||
 | 
			
		||||
HELP: changed-words
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,14 +8,13 @@ IN: compiler
 | 
			
		|||
M: object inference-error-major? drop t ;
 | 
			
		||||
 | 
			
		||||
: compile-error ( word error -- )
 | 
			
		||||
    batch-mode get [
 | 
			
		||||
        2array compile-errors get push
 | 
			
		||||
    compile-errors get [
 | 
			
		||||
        >r 2array r> push
 | 
			
		||||
    ] [
 | 
			
		||||
        "quiet" get [ drop ] [ print-error flush ] if drop
 | 
			
		||||
    ] if ;
 | 
			
		||||
        "quiet" get [ 2drop ] [ print-error flush drop ] if
 | 
			
		||||
    ] if* ;
 | 
			
		||||
 | 
			
		||||
: begin-batch ( -- )
 | 
			
		||||
    batch-mode on
 | 
			
		||||
    V{ } clone compile-errors set-global ;
 | 
			
		||||
 | 
			
		||||
: compile-error. ( pair -- )
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +36,6 @@ M: object inference-error-major? drop t ;
 | 
			
		|||
: :warnings (:warnings) [ compile-error. ] each ;
 | 
			
		||||
 | 
			
		||||
: end-batch ( -- )
 | 
			
		||||
    batch-mode off
 | 
			
		||||
    "quiet" get [
 | 
			
		||||
        "Compile finished." print
 | 
			
		||||
        nl
 | 
			
		||||
| 
						 | 
				
			
			@ -48,6 +46,9 @@ M: object inference-error-major? drop t ;
 | 
			
		|||
        nl
 | 
			
		||||
    ] unless ;
 | 
			
		||||
 | 
			
		||||
: with-compile-errors ( quot -- )
 | 
			
		||||
    [ begin-batch call end-batch ] with-scope ; inline
 | 
			
		||||
 | 
			
		||||
: compile ( word -- )
 | 
			
		||||
    H{ } clone [
 | 
			
		||||
        compiled-xts [ (compile) ] with-variable
 | 
			
		||||
| 
						 | 
				
			
			@ -56,15 +57,10 @@ M: object inference-error-major? drop t ;
 | 
			
		|||
: compile-failed ( word error -- )
 | 
			
		||||
    dupd compile-error dup update-xt unchanged-word ;
 | 
			
		||||
 | 
			
		||||
: forget-errors ( seq -- )
 | 
			
		||||
    [ f "no-effect" set-word-prop ] each ;
 | 
			
		||||
 | 
			
		||||
: (compile-batch) ( words -- )
 | 
			
		||||
    H{ } clone [
 | 
			
		||||
        compiled-xts [
 | 
			
		||||
            [
 | 
			
		||||
                [ (compile) ] [ compile-failed ] recover
 | 
			
		||||
            ] each
 | 
			
		||||
            [ [ (compile) ] [ compile-failed ] recover ] each
 | 
			
		||||
        ] with-variable
 | 
			
		||||
    ] keep [ swap add* ] { } assoc>map modify-code-heap ;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,16 +68,11 @@ M: object inference-error-major? drop t ;
 | 
			
		|||
    dup empty? [
 | 
			
		||||
        drop
 | 
			
		||||
    ] [
 | 
			
		||||
        dup begin-batch
 | 
			
		||||
        dup forget-errors
 | 
			
		||||
        (compile-batch)
 | 
			
		||||
        end-batch
 | 
			
		||||
        [ (compile-batch) ] with-compile-errors
 | 
			
		||||
    ] if ;
 | 
			
		||||
 | 
			
		||||
: compile-vocabs ( seq -- ) [ words ] map concat compile-batch ;
 | 
			
		||||
 | 
			
		||||
: compile-all ( -- ) vocabs compile-vocabs ;
 | 
			
		||||
 | 
			
		||||
: compile-quot ( quot -- word ) define-temp dup compile ;
 | 
			
		||||
 | 
			
		||||
: compile-1 ( quot -- ) compile-quot execute ;
 | 
			
		||||
| 
						 | 
				
			
			@ -91,5 +82,8 @@ M: object inference-error-major? drop t ;
 | 
			
		|||
        dup keys compile-batch clear-assoc
 | 
			
		||||
    ] when* ;
 | 
			
		||||
 | 
			
		||||
: recompile-all ( -- )
 | 
			
		||||
    all-words [ changed-word ] each recompile ;
 | 
			
		||||
: forget-errors ( seq -- )
 | 
			
		||||
    [ f "no-effect" set-word-prop ] each ;
 | 
			
		||||
 | 
			
		||||
: compile-all ( -- )
 | 
			
		||||
    all-words dup forget-errors [ changed-word ] each recompile ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ M: x86-backend %jump-t ( label -- )
 | 
			
		|||
    ! x86, this is redundant.
 | 
			
		||||
    "scratch" operand HEX: ffffffff MOV rc-absolute-cell rel-dispatch
 | 
			
		||||
    "n" operand "n" operand "scratch" operand [+] MOV
 | 
			
		||||
    "n" operand compiled-header-size ADD ;
 | 
			
		||||
    "n" operand dup word-xt-offset [+] MOV ;
 | 
			
		||||
 | 
			
		||||
: dispatch-template ( word-table# quot -- )
 | 
			
		||||
    [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,8 @@ IN: temporary
 | 
			
		|||
 | 
			
		||||
TUPLE: testing x y z ;
 | 
			
		||||
 | 
			
		||||
[ save-image-and-exit ] unit-test-fails
 | 
			
		||||
 | 
			
		||||
[ ] [
 | 
			
		||||
    num-types get [
 | 
			
		||||
        type>class [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										68
									
								
								vm/code_gc.c
								
								
								
								
							
							
						
						
									
										68
									
								
								vm/code_gc.c
								
								
								
								
							| 
						 | 
				
			
			@ -264,18 +264,6 @@ void collect_literals(void)
 | 
			
		|||
	iterate_code_heap(collect_literals_step);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Mark all XTs referenced from a code block */
 | 
			
		||||
void mark_sweep_step(F_COMPILED *compiled, CELL code_start,
 | 
			
		||||
	CELL reloc_start, CELL literals_start, CELL words_start, CELL words_end)
 | 
			
		||||
{
 | 
			
		||||
	F_COMPILED **start = (F_COMPILED **)words_start;
 | 
			
		||||
	F_COMPILED **end = (F_COMPILED **)words_end;
 | 
			
		||||
	F_COMPILED **iter = start;
 | 
			
		||||
 | 
			
		||||
	while(iter < end)
 | 
			
		||||
		recursive_mark(compiled_to_block(*iter++));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Mark all XTs and literals referenced from a word XT */
 | 
			
		||||
void recursive_mark(F_BLOCK *block)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -391,14 +379,14 @@ void forward_object_xts(void)
 | 
			
		|||
			F_WORD *word = untag_object(obj);
 | 
			
		||||
 | 
			
		||||
			if(word->compiledp != F)
 | 
			
		||||
				set_word_xt(word,forward_xt(word->code));
 | 
			
		||||
				word->code = forward_xt(word->code);
 | 
			
		||||
		}
 | 
			
		||||
		else if(type_of(obj) == QUOTATION_TYPE)
 | 
			
		||||
		{
 | 
			
		||||
			F_QUOTATION *quot = untag_object(obj);
 | 
			
		||||
 | 
			
		||||
			if(quot->compiledp != F)
 | 
			
		||||
				set_quot_xt(quot,forward_xt(quot->code));
 | 
			
		||||
				quot->code = forward_xt(quot->code);
 | 
			
		||||
		}
 | 
			
		||||
		else if(type_of(obj) == CALLSTACK_TYPE)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -411,33 +399,33 @@ void forward_object_xts(void)
 | 
			
		|||
	gc_off = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void compaction_code_block_fixup(F_COMPILED *compiled, CELL code_start,
 | 
			
		||||
	CELL reloc_start, CELL literals_start, CELL words_start, CELL words_end)
 | 
			
		||||
/* Set the XT fields now that the heap has been compacted */
 | 
			
		||||
void fixup_object_xts(void)
 | 
			
		||||
{
 | 
			
		||||
	F_COMPILED **iter = (F_COMPILED **)words_start;
 | 
			
		||||
	F_COMPILED **end = (F_COMPILED **)words_end;
 | 
			
		||||
	begin_scan();
 | 
			
		||||
 | 
			
		||||
	while(iter < end)
 | 
			
		||||
	CELL obj;
 | 
			
		||||
 | 
			
		||||
	while((obj = next_object()) != F)
 | 
			
		||||
	{
 | 
			
		||||
		*iter = forward_xt(*iter);
 | 
			
		||||
		iter++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void forward_block_xts(void)
 | 
			
		||||
{
 | 
			
		||||
	F_BLOCK *scan = first_block(&code_heap);
 | 
			
		||||
 | 
			
		||||
	while(scan)
 | 
			
		||||
	{
 | 
			
		||||
		if(scan->status == B_ALLOCATED)
 | 
			
		||||
		if(type_of(obj) == WORD_TYPE)
 | 
			
		||||
		{
 | 
			
		||||
			iterate_code_heap_step(block_to_compiled(scan),
 | 
			
		||||
				compaction_code_block_fixup);
 | 
			
		||||
		}
 | 
			
		||||
			F_WORD *word = untag_object(obj);
 | 
			
		||||
 | 
			
		||||
		scan = next_block(&code_heap,scan);
 | 
			
		||||
			if(word->compiledp != F)
 | 
			
		||||
				set_word_xt(word,word->code);
 | 
			
		||||
		}
 | 
			
		||||
		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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void compact_heap(F_HEAP *heap)
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +438,6 @@ void compact_heap(F_HEAP *heap)
 | 
			
		|||
 | 
			
		||||
		if(scan->status == B_ALLOCATED && scan != scan->forwarding)
 | 
			
		||||
			memcpy(scan->forwarding,scan,scan->size);
 | 
			
		||||
 | 
			
		||||
		scan = next;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -465,19 +452,20 @@ void compact_code_heap(void)
 | 
			
		|||
	code_gc();
 | 
			
		||||
 | 
			
		||||
	fprintf(stderr,"*** Code heap compaction...\n");
 | 
			
		||||
	fflush(stderr);
 | 
			
		||||
 | 
			
		||||
	/* Figure out where the code heap blocks are going to end up */
 | 
			
		||||
	CELL size = compute_heap_forwarding(&code_heap);
 | 
			
		||||
 | 
			
		||||
	/* Update word and quotation XTs to point to the new locations */
 | 
			
		||||
	/* Update word and quotation code pointers */
 | 
			
		||||
	forward_object_xts();
 | 
			
		||||
 | 
			
		||||
	/* Update code block XTs to point to the new locations */
 | 
			
		||||
	forward_block_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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -317,6 +317,9 @@ F_COMPILED *add_compiled_block(
 | 
			
		|||
 | 
			
		||||
void set_word_xt(F_WORD *word, F_COMPILED *compiled)
 | 
			
		||||
{
 | 
			
		||||
	if(compiled->type != WORD_TYPE)
 | 
			
		||||
		critical_error("bad param to set_word_xt",(CELL)compiled);
 | 
			
		||||
 | 
			
		||||
	word->code = compiled;
 | 
			
		||||
	word->xt = (XT)(compiled + 1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -239,9 +239,6 @@ DEFPUSHPOP(root_,extra_roots)
 | 
			
		|||
#define REGISTER_UNTAGGED(obj) root_push(obj ? tag_object(obj) : 0)
 | 
			
		||||
#define UNREGISTER_UNTAGGED(obj) obj = untag_object(root_pop())
 | 
			
		||||
 | 
			
		||||
#define REGISTER_STRING(obj) REGISTER_UNTAGGED(obj)
 | 
			
		||||
#define UNREGISTER_STRING(obj) UNREGISTER_UNTAGGED(obj)
 | 
			
		||||
 | 
			
		||||
/* We ignore strings which point outside the data heap, but we might be given
 | 
			
		||||
a char* which points inside the data heap, in which case it is a root, for
 | 
			
		||||
example if we call unbox_char_string() the result is placed in a byte array */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,6 +150,10 @@ DEFINE_PRIMITIVE(save_image)
 | 
			
		|||
 | 
			
		||||
DEFINE_PRIMITIVE(save_image_and_exit)
 | 
			
		||||
{
 | 
			
		||||
	F_CHAR *path = unbox_native_string();
 | 
			
		||||
 | 
			
		||||
	REGISTER_C_STRING(path);
 | 
			
		||||
 | 
			
		||||
	/* strip out userenv data which is set on startup anyway */
 | 
			
		||||
	CELL i;
 | 
			
		||||
	for(i = 0; i < FIRST_SAVE_ENV; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -158,8 +162,10 @@ DEFINE_PRIMITIVE(save_image_and_exit)
 | 
			
		|||
	/* do a full GC + code heap compaction */
 | 
			
		||||
	compact_code_heap();
 | 
			
		||||
 | 
			
		||||
	UNREGISTER_C_STRING(path);
 | 
			
		||||
 | 
			
		||||
	/* Save the image */
 | 
			
		||||
	save_image(unbox_native_string());
 | 
			
		||||
	save_image(path);
 | 
			
		||||
 | 
			
		||||
	/* now exit; we cannot continue executing like this */
 | 
			
		||||
	exit(0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,9 @@ bool jit_stack_frame_p(F_ARRAY *array)
 | 
			
		|||
 | 
			
		||||
void set_quot_xt(F_QUOTATION *quot, F_COMPILED *code)
 | 
			
		||||
{
 | 
			
		||||
	if(code->type != QUOTATION_TYPE)
 | 
			
		||||
		critical_error("bad param to set_word_xt",(CELL)code);
 | 
			
		||||
 | 
			
		||||
	quot->code = code;
 | 
			
		||||
	quot->xt = (XT)(code + 1);
 | 
			
		||||
	quot->compiledp = T;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -285,9 +285,9 @@ F_STRING* reallot_string(F_STRING* string, CELL capacity, u16 fill)
 | 
			
		|||
	if(capacity < to_copy)
 | 
			
		||||
		to_copy = capacity;
 | 
			
		||||
 | 
			
		||||
	REGISTER_STRING(string);
 | 
			
		||||
	REGISTER_UNTAGGED(string);
 | 
			
		||||
	F_STRING *new_string = allot_string_internal(capacity);
 | 
			
		||||
	UNREGISTER_STRING(string);
 | 
			
		||||
	UNREGISTER_UNTAGGED(string);
 | 
			
		||||
 | 
			
		||||
	memcpy(new_string + 1,string + 1,to_copy * CHARS);
 | 
			
		||||
	fill_string(new_string,to_copy,capacity,fill);
 | 
			
		||||
| 
						 | 
				
			
			@ -381,9 +381,9 @@ F_BYTE_ARRAY *allot_c_string(CELL capacity, CELL size)
 | 
			
		|||
		F_BYTE_ARRAY *_c_str; \
 | 
			
		||||
		if(check && !check_string(s,sizeof(type))) \
 | 
			
		||||
			general_error(ERROR_C_STRING,tag_object(s),F,NULL); \
 | 
			
		||||
		REGISTER_STRING(s); \
 | 
			
		||||
		REGISTER_UNTAGGED(s); \
 | 
			
		||||
		_c_str = allot_c_string(capacity,sizeof(type)); \
 | 
			
		||||
		UNREGISTER_STRING(s); \
 | 
			
		||||
		UNREGISTER_UNTAGGED(s); \
 | 
			
		||||
		type *c_str = (type*)(_c_str + 1); \
 | 
			
		||||
		type##_string_to_memory(s,c_str); \
 | 
			
		||||
		c_str[capacity] = 0; \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue