| 
									
										
										
										
											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-10-20 10:37:24 -04:00
										 |  |  | jit::jit(code_block_type type_, cell owner_, factor_vm *vm) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	: type(type_), | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:09 -04:00
										 |  |  | 	  owner(owner_,vm), | 
					
						
							|  |  |  | 	  code(vm), | 
					
						
							|  |  |  | 	  relocation(vm), | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | 	  parameters(vm), | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:09 -04:00
										 |  |  | 	  literals(vm), | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	  computing_offset_p(false), | 
					
						
							|  |  |  | 	  position(0), | 
					
						
							| 
									
										
										
										
											2009-08-17 16:37:09 -04:00
										 |  |  | 	  offset(0), | 
					
						
							| 
									
										
										
										
											2009-10-18 21:31:59 -04:00
										 |  |  | 	  parent(vm) | 
					
						
							| 
									
										
										
										
											2009-10-06 07:25:07 -04:00
										 |  |  | {} | 
					
						
							| 
									
										
										
										
											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-11-02 19:10:34 -05:00
										 |  |  | 	data_root<array> code_template(code_template_,parent); | 
					
						
							| 
									
										
										
										
											2009-05-06 21:04:49 -04:00
										 |  |  | 	cell capacity = array_capacity(code_template.untagged()); | 
					
						
							|  |  |  | 	for(cell i = 1; i < capacity; i += 3) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-12-02 01:48:41 -05:00
										 |  |  | 		relocation_class rel_class = (relocation_class)untag_fixnum(array_nth(code_template.untagged(),i)); | 
					
						
							|  |  |  | 		relocation_type rel_type = (relocation_type)untag_fixnum(array_nth(code_template.untagged(),i + 1)); | 
					
						
							| 
									
										
										
										
											2009-05-06 21:04:49 -04:00
										 |  |  | 		cell offset = array_nth(code_template.untagged(),i + 2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 01:48:41 -05:00
										 |  |  | 		relocation_entry new_entry(rel_type,rel_class,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-11-02 19:10:34 -05:00
										 |  |  | 	data_root<array> code_template(code_template_,parent); | 
					
						
							| 
									
										
										
										
											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-11-02 19:10:34 -05:00
										 |  |  | 	data_root<byte_array> insns(array_nth(code_template.untagged(),0),parent); | 
					
						
							| 
									
										
										
										
											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-12-02 05:28:15 -05:00
										 |  |  | void jit::emit_with_literal(cell code_template_, cell argument_) { | 
					
						
							| 
									
										
										
										
											2009-11-02 19:10:34 -05:00
										 |  |  | 	data_root<array> code_template(code_template_,parent); | 
					
						
							|  |  |  | 	data_root<object> argument(argument_,parent); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	literal(argument.value()); | 
					
						
							|  |  |  | 	emit(code_template.value()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | void jit::emit_with_parameter(cell code_template_, cell argument_) { | 
					
						
							|  |  |  | 	data_root<array> code_template(code_template_,parent); | 
					
						
							|  |  |  | 	data_root<object> argument(argument_,parent); | 
					
						
							|  |  |  | 	parameter(argument.value()); | 
					
						
							|  |  |  | 	emit(code_template.value()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 07:20:09 -05:00
										 |  |  | bool jit::emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	data_root<word> word(word_,parent); | 
					
						
							|  |  |  | 	data_root<array> code_template(word->subprimitive,parent); | 
					
						
							|  |  |  | 	parameters.append(untag<array>(array_nth(code_template.untagged(),0))); | 
					
						
							|  |  |  | 	literals.append(untag<array>(array_nth(code_template.untagged(),1))); | 
					
						
							|  |  |  | 	emit(array_nth(code_template.untagged(),2)); | 
					
						
							|  |  |  | 	if(array_capacity(code_template.untagged()) == 5) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(tail_call_p) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if(stack_frame_p) emit(parent->special_objects[JIT_EPILOG]); | 
					
						
							|  |  |  | 			emit(array_nth(code_template.untagged(),4)); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			emit(array_nth(code_template.untagged(),3)); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											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-12-02 05:28:15 -05:00
										 |  |  | 	emit_with_literal(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell))); | 
					
						
							| 
									
										
										
										
											2009-10-23 01:33:53 -04:00
										 |  |  | 	emit(parent->special_objects[type]); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* 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(); | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | 	parameters.trim(); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	literals.trim(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-18 21:31:59 -04:00
										 |  |  | 	return parent->add_code_block( | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 		type, | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		code.elements.value(), | 
					
						
							| 
									
										
										
										
											2009-10-18 21:26:21 -04:00
										 |  |  | 		false_object, /* no labels */ | 
					
						
							| 
									
										
										
										
											2009-10-06 07:25:07 -04:00
										 |  |  | 		owner.value(), | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		relocation.elements.value(), | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | 		parameters.elements.value(), | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		literals.elements.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |