| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | /* Simple non-optimizing compiler.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is one of the two compilers implementing Factor; the second one is written | 
					
						
							|  |  |  | in Factor and performs advanced optimizations. See core/compiler/compiler.factor. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The non-optimizing compiler compiles a quotation at a time by concatenating | 
					
						
							|  |  |  | machine code chunks; prolog, epilog, call word, jump to word, etc. These machine | 
					
						
							|  |  |  | code chunks are generated from Factor code in core/cpu/.../bootstrap.factor. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Calls to words and constant quotations (referenced by conditionals and dips) | 
					
						
							|  |  |  | are direct jumps to machine code blocks. Literals are also referenced directly | 
					
						
							|  |  |  | without going through the literal table. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It actually does do a little bit of very simple optimization: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1) Tail call optimization. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 2) If a quotation is determined to not call any other words (except for a few | 
					
						
							|  |  |  | special words which are open-coded, see below), then no prolog/epilog is | 
					
						
							|  |  |  | generated. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3) When in tail position and immediately preceded by literal arguments, the | 
					
						
							|  |  |  | 'if' is generated inline, instead of as a call to the 'if' word. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 4) When preceded by a quotation, calls to 'dip', '2dip' and '3dip' are | 
					
						
							|  |  |  | open-coded as retain stack manipulation surrounding a subroutine call. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 5) Sub-primitives are primitive words which are implemented in assembly and not | 
					
						
							|  |  |  | in the VM. They are open-coded and no subroutine call is generated. This | 
					
						
							|  |  |  | includes stack shufflers, some fixnum arithmetic words, and words such as tag, | 
					
						
							|  |  |  | slot and eq?. A primitive call is relatively expensive (two subroutine calls) | 
					
						
							|  |  |  | so this results in a big speedup for relatively little effort. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | bool quotation_jit::primitive_call_p(cell i) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	return (i + 2) == array_capacity(elements.untagged()) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i)).type_p(FIXNUM_TYPE) | 
					
						
							|  |  |  | 		&& array_nth(elements.untagged(),i + 1) == userenv[JIT_PRIMITIVE_WORD]; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | bool quotation_jit::fast_if_p(cell i) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	return (i + 3) == array_capacity(elements.untagged()) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(QUOTATION_TYPE) | 
					
						
							|  |  |  | 		&& array_nth(elements.untagged(),i + 2) == userenv[JIT_IF_WORD]; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | bool quotation_jit::fast_dip_p(cell i) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	return (i + 2) <= array_capacity(elements.untagged()) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE) | 
					
						
							|  |  |  | 		&& array_nth(elements.untagged(),i + 1) == userenv[JIT_DIP_WORD]; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | bool quotation_jit::fast_2dip_p(cell i) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	return (i + 2) <= array_capacity(elements.untagged()) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE) | 
					
						
							|  |  |  | 		&& array_nth(elements.untagged(),i + 1) == userenv[JIT_2DIP_WORD]; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | bool quotation_jit::fast_3dip_p(cell i) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	return (i + 2) <= array_capacity(elements.untagged()) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i)).type_p(QUOTATION_TYPE) | 
					
						
							|  |  |  | 		&& array_nth(elements.untagged(),i + 1) == userenv[JIT_3DIP_WORD]; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | bool quotation_jit::mega_lookup_p(cell i) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	return (i + 3) < array_capacity(elements.untagged()) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i)).type_p(ARRAY_TYPE) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i + 1)).type_p(FIXNUM_TYPE) | 
					
						
							|  |  |  | 		&& tagged<object>(array_nth(elements.untagged(),i + 2)).type_p(ARRAY_TYPE) | 
					
						
							|  |  |  | 		&& array_nth(elements.untagged(),i + 3) == userenv[MEGA_LOOKUP_WORD]; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | bool quotation_jit::stack_frame_p() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	fixnum length = array_capacity(elements.untagged()); | 
					
						
							|  |  |  | 	fixnum i; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for(i = 0; i < length - 1; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		cell obj = array_nth(elements.untagged(),i); | 
					
						
							|  |  |  | 		switch(tagged<object>(obj).type()) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 		case WORD_TYPE: | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			if(untag<word>(obj)->subprimitive == F) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case QUOTATION_TYPE: | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			if(fast_dip_p(i) || fast_2dip_p(i) || fast_3dip_p(i)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				return true; | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | void quotation_jit::iterate_quotation() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	bool stack_frame = stack_frame_p(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	set_position(0); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if(stack_frame) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		emit(userenv[JIT_PROLOG]); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	cell i; | 
					
						
							|  |  |  | 	cell length = array_capacity(elements.untagged()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	bool tail_call = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for(i = 0; i < length; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		set_position(i); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		gc_root<object> obj(array_nth(elements.untagged(),i)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		switch(obj.type()) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 		case WORD_TYPE: | 
					
						
							|  |  |  | 			/* Intrinsics */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			if(obj.as<word>()->subprimitive != F) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 				emit_subprimitive(obj.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			/* The (execute) primitive is special-cased */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			else if(obj.value() == userenv[JIT_EXECUTE_WORD]) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				if(i == length - 1) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 					if(stack_frame) emit(userenv[JIT_EPILOG]); | 
					
						
							|  |  |  | 					tail_call = true; | 
					
						
							|  |  |  | 					emit(userenv[JIT_EXECUTE_JUMP]); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 					emit(userenv[JIT_EXECUTE_CALL]); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			/* Everything else */ | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if(i == length - 1) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 					if(stack_frame) emit(userenv[JIT_EPILOG]); | 
					
						
							|  |  |  | 					tail_call = true; | 
					
						
							| 
									
										
										
										
											2009-05-06 23:44:30 -04:00
										 |  |  | 					/* Inline cache misses are special-cased.
 | 
					
						
							|  |  |  | 					   The calling convention for tail | 
					
						
							|  |  |  | 					   calls stores the address of the next | 
					
						
							|  |  |  | 					   instruction in a register. However, | 
					
						
							|  |  |  | 					   PIC miss stubs themselves tail-call | 
					
						
							|  |  |  | 					   the inline cache miss primitive, and | 
					
						
							|  |  |  | 					   we don't want to clobber the saved | 
					
						
							|  |  |  | 					   address. */ | 
					
						
							| 
									
										
										
										
											2009-05-06 23:04:01 -04:00
										 |  |  | 					if(obj.value() == userenv[PIC_MISS_WORD] | 
					
						
							|  |  |  | 					   || obj.value() == userenv[PIC_MISS_TAIL_WORD]) | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						word_special(obj.value()); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 					{ | 
					
						
							|  |  |  | 						word_jump(obj.value()); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 					word_call(obj.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case WRAPPER_TYPE: | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 			push(obj.as<wrapper>()->object); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case FIXNUM_TYPE: | 
					
						
							|  |  |  | 			/* Primitive calls */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			if(primitive_call_p(i)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 				emit_with(userenv[JIT_PRIMITIVE],obj.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				i++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				tail_call = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case QUOTATION_TYPE: | 
					
						
							|  |  |  | 			/* 'if' preceeded by two literal quotations (this is why if and ? are
 | 
					
						
							|  |  |  | 			   mutually recursive in the library, but both still work) */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			if(fast_if_p(i)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 				if(stack_frame) emit(userenv[JIT_EPILOG]); | 
					
						
							|  |  |  | 				tail_call = true; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if(compiling) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 					jit_compile(array_nth(elements.untagged(),i),relocate); | 
					
						
							|  |  |  | 					jit_compile(array_nth(elements.untagged(),i + 1),relocate); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-06 21:04:49 -04:00
										 |  |  | 				literal(array_nth(elements.untagged(),i)); | 
					
						
							|  |  |  | 				literal(array_nth(elements.untagged(),i + 1)); | 
					
						
							|  |  |  | 				emit(userenv[JIT_IF]); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				i += 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			/* dip */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			else if(fast_dip_p(i)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				if(compiling) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 					jit_compile(obj.value(),relocate); | 
					
						
							|  |  |  | 				emit_with(userenv[JIT_DIP],obj.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				i++; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			/* 2dip */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			else if(fast_2dip_p(i)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				if(compiling) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 					jit_compile(obj.value(),relocate); | 
					
						
							|  |  |  | 				emit_with(userenv[JIT_2DIP],obj.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				i++; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			/* 3dip */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			else if(fast_3dip_p(i)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				if(compiling) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 					jit_compile(obj.value(),relocate); | 
					
						
							|  |  |  | 				emit_with(userenv[JIT_3DIP],obj.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				i++; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		case ARRAY_TYPE: | 
					
						
							|  |  |  | 			/* Method dispatch */ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			if(mega_lookup_p(i)) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 				emit_mega_cache_lookup( | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 					array_nth(elements.untagged(),i), | 
					
						
							|  |  |  | 					untag_fixnum(array_nth(elements.untagged(),i + 1)), | 
					
						
							|  |  |  | 					array_nth(elements.untagged(),i + 2)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 				i += 3; | 
					
						
							|  |  |  | 				tail_call = true; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			push(obj.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(!tail_call) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		set_position(length); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if(stack_frame) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			emit(userenv[JIT_EPILOG]); | 
					
						
							|  |  |  | 		emit(userenv[JIT_RETURN]); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void set_quot_xt(quotation *quot, code_block *code) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-05 12:07:20 -04:00
										 |  |  | 	if(code->type != QUOTATION_TYPE) | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		critical_error("Bad param to set_quot_xt",(cell)code); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	quot->code = code; | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	quot->xt = code->xt(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void jit_compile(cell quot_, bool relocating) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<quotation> quot(quot_); | 
					
						
							| 
									
										
										
										
											2009-05-12 04:09:15 -04:00
										 |  |  | 	if(quot->code) return; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	quotation_jit compiler(quot.value(),true,relocating); | 
					
						
							|  |  |  | 	compiler.iterate_quotation(); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	code_block *compiled = compiler.to_code_block(); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	set_quot_xt(quot.untagged(),compiled); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	if(relocating) relocate_code_block(compiled); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | PRIMITIVE(jit_compile) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	jit_compile(dpop(),true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* push a new quotation on the stack */ | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | PRIMITIVE(array_to_quotation) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	quotation *quot = allot<quotation>(sizeof(quotation)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	quot->array = dpeek(); | 
					
						
							|  |  |  | 	quot->cached_effect = F; | 
					
						
							|  |  |  | 	quot->cache_counter = F; | 
					
						
							| 
									
										
										
										
											2009-05-12 04:09:15 -04:00
										 |  |  | 	quot->xt = (void *)lazy_jit_compile; | 
					
						
							|  |  |  | 	quot->code = NULL; | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	drepl(tag<quotation>(quot)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | PRIMITIVE(quotation_xt) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	quotation *quot = untag_check<quotation>(dpeek()); | 
					
						
							|  |  |  | 	drepl(allot_cell((cell)quot->xt)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-05 12:33:35 -04:00
										 |  |  | void compile_all_words() | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<array> words(find_all_words()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	cell i; | 
					
						
							|  |  |  | 	cell length = array_capacity(words.untagged()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	for(i = 0; i < length; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		gc_root<word> word(array_nth(words.untagged(),i)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		if(!word->code || !word_optimized_p(word.untagged())) | 
					
						
							|  |  |  | 			jit_compile_word(word.value(),word->def,false); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		update_word_xt(word.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	iterate_code_heap(relocate_code_block); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | fixnum quot_code_offset_to_scan(cell quot_, cell offset) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<quotation> quot(quot_); | 
					
						
							|  |  |  | 	gc_root<array> array(quot->array); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 06:07:14 -04:00
										 |  |  | 	quotation_jit compiler(quot.value(),false,false); | 
					
						
							|  |  |  | 	compiler.compute_position(offset); | 
					
						
							|  |  |  | 	compiler.iterate_quotation(); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 06:07:14 -04:00
										 |  |  | 	return compiler.get_position(); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | VM_ASM_API cell lazy_jit_compile_impl(cell quot_, stack_frame *stack) | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<quotation> quot(quot_); | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 	stack_chain->callstack_top = stack; | 
					
						
							|  |  |  | 	jit_compile(quot.value(),true); | 
					
						
							|  |  |  | 	return quot.value(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-12 04:09:15 -04:00
										 |  |  | PRIMITIVE(quot_compiled_p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	tagged<quotation> quot(dpop()); | 
					
						
							|  |  |  | 	quot.untag_check(); | 
					
						
							|  |  |  | 	dpush(tag_boolean(quot->code != NULL)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |