| 
									
										
										
										
											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
										 |  |  | - 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) | 
					
						
							| 
									
										
										
										
											2011-11-02 02:40:46 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-07 20:58:53 -05:00
										 |  |  | 	fixnum old_count = atomic::fetch_add(&parent->current_jit_count, 1); | 
					
						
							| 
									
										
										
										
											2011-11-17 23:42:30 -05:00
										 |  |  | 	FACTOR_ASSERT(old_count >= 0); | 
					
						
							| 
									
										
										
										
											2011-11-23 01:51:54 -05:00
										 |  |  | 	(void)old_count; | 
					
						
							| 
									
										
										
										
											2011-11-02 02:40:46 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | jit::~jit() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-07 20:58:53 -05:00
										 |  |  | 	fixnum old_count = atomic::fetch_subtract(&parent->current_jit_count, 1); | 
					
						
							| 
									
										
										
										
											2011-11-17 23:42:30 -05:00
										 |  |  | 	FACTOR_ASSERT(old_count >= 1); | 
					
						
							| 
									
										
										
										
											2011-11-23 01:51:54 -05:00
										 |  |  | 	(void)old_count; | 
					
						
							| 
									
										
										
										
											2011-11-02 02:40:46 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-14 03:44:35 -04:00
										 |  |  | void jit::emit_relocation(cell relocation_template_) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-09-14 03:44:35 -04:00
										 |  |  | 	data_root<byte_array> relocation_template(relocation_template_,parent); | 
					
						
							|  |  |  | 	cell capacity = array_capacity(relocation_template.untagged()) | 
					
						
							|  |  |  | 		/ sizeof(relocation_entry); | 
					
						
							|  |  |  | 	relocation_entry *relocations = relocation_template->data<relocation_entry>(); | 
					
						
							|  |  |  | 	for(cell i = 0; i < capacity; i++) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-09-14 03:44:35 -04:00
										 |  |  | 		relocation_entry entry = relocations[i]; | 
					
						
							|  |  |  | 		relocation_entry new_entry(entry.rel_type(), entry.rel_class(), | 
					
						
							|  |  |  | 			entry.rel_offset() + code.count); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-14 03:44:35 -04:00
										 |  |  | 	emit_relocation(array_nth(code_template.untagged(),0)); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-09-14 03:44:35 -04:00
										 |  |  | 	data_root<byte_array> insns(array_nth(code_template.untagged(),1),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()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-16 01:00:08 -04:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											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()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-16 01:00:08 -04:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											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()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-16 01:00:08 -04:00
										 |  |  | /* Allocates memory */ | 
					
						
							| 
									
										
										
										
											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)); | 
					
						
							| 
									
										
										
										
											2012-08-16 01:00:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-15 07:20:09 -05:00
										 |  |  | 	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-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 */ | 
					
						
							| 
									
										
										
										
											2011-11-30 15:39:21 -05:00
										 |  |  | code_block *jit::to_code_block(cell frame_size) | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-11 20:06:00 -04:00
										 |  |  | 	/* Emit dummy GC info */ | 
					
						
							|  |  |  | 	code.grow_bytes(alignment_for(code.count + 4,data_alignment)); | 
					
						
							|  |  |  | 	u32 dummy_gc_info = 0; | 
					
						
							|  |  |  | 	code.append_bytes(&dummy_gc_info,sizeof(u32)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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(), | 
					
						
							| 
									
										
										
										
											2011-11-25 21:58:21 -05:00
										 |  |  | 		literals.elements.value(), | 
					
						
							| 
									
										
										
										
											2011-11-30 15:39:21 -05:00
										 |  |  | 		frame_size); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |