| 
									
										
										
										
											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 code generator used by:
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | - profiler (profiler.cpp), | 
					
						
							|  |  |  | - quotation compiler (quotations.cpp), | 
					
						
							|  |  |  | - megamorphic caches (dispatch.cpp), | 
					
						
							|  |  |  | - polymorphic inline caches (inline_cache.cpp) */ | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | jit::jit(cell type_, cell owner_) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	: type(type_), | 
					
						
							|  |  |  | 	  owner(owner_), | 
					
						
							|  |  |  | 	  code(), | 
					
						
							|  |  |  | 	  relocation(), | 
					
						
							|  |  |  | 	  literals(), | 
					
						
							|  |  |  | 	  computing_offset_p(false), | 
					
						
							|  |  |  | 	  position(0), | 
					
						
							|  |  |  | 	  offset(0) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	if(stack_traces_p()) literal(owner.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-06 21:04:49 -04:00
										 |  |  | void jit::emit_relocation(cell code_template_) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-06 21:04:49 -04:00
										 |  |  | 	gc_root<array> code_template(code_template_); | 
					
						
							|  |  |  | 	cell capacity = array_capacity(code_template.untagged()); | 
					
						
							|  |  |  | 	for(cell i = 1; i < capacity; i += 3) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-06 21:04:49 -04:00
										 |  |  | 		cell rel_class = array_nth(code_template.untagged(),i); | 
					
						
							|  |  |  | 		cell rel_type = array_nth(code_template.untagged(),i + 1); | 
					
						
							|  |  |  | 		cell offset = array_nth(code_template.untagged(),i + 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		relocation_entry new_entry | 
					
						
							|  |  |  | 			= (untag_fixnum(rel_type) << 28) | 
					
						
							| 
									
										
										
										
											2009-05-02 21:47:29 -04:00
										 |  |  | 			| (untag_fixnum(rel_class) << 24) | 
					
						
							|  |  |  | 			| ((code.count + untag_fixnum(offset))); | 
					
						
							| 
									
										
										
										
											2009-05-06 21:04:49 -04:00
										 |  |  | 		relocation.append_bytes(&new_entry,sizeof(relocation_entry)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void jit::emit(cell code_template_) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<array> code_template(code_template_); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-06 21:04:49 -04:00
										 |  |  | 	emit_relocation(code_template.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_root<byte_array> insns(array_nth(code_template.untagged(),0)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	if(computing_offset_p) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		cell size = array_capacity(insns.untagged()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		if(offset == 0) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			position--; | 
					
						
							|  |  |  | 			computing_offset_p = false; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		else if(offset < size) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			position++; | 
					
						
							|  |  |  | 			computing_offset_p = false; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 			offset -= size; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	code.append_byte_array(insns.value()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void jit::emit_with(cell code_template_, cell argument_) { | 
					
						
							|  |  |  | 	gc_root<array> code_template(code_template_); | 
					
						
							|  |  |  | 	gc_root<object> argument(argument_); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	literal(argument.value()); | 
					
						
							|  |  |  | 	emit(code_template.value()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void jit::emit_class_lookup(fixnum index, cell type) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	emit_with(userenv[PIC_LOAD],tag_fixnum(-index * sizeof(cell))); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	emit(userenv[type]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Facility to convert compiled code offsets to quotation offsets.
 | 
					
						
							|  |  |  | Call jit_compute_offset() with the compiled code offset, then emit | 
					
						
							|  |  |  | code, and at the end jit->position is the quotation position. */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | void jit::compute_position(cell offset_) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	computing_offset_p = true; | 
					
						
							|  |  |  | 	position = 0; | 
					
						
							|  |  |  | 	offset = offset_; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | code_block *jit::to_code_block() | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | { | 
					
						
							|  |  |  | 	code.trim(); | 
					
						
							|  |  |  | 	relocation.trim(); | 
					
						
							|  |  |  | 	literals.trim(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return add_code_block( | 
					
						
							|  |  |  | 		type, | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		code.elements.value(), | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		F, /* no labels */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		relocation.elements.value(), | 
					
						
							|  |  |  | 		literals.elements.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |