| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | #include "master.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  | namespace factor { | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Simple code generator used by:
 | 
					
						
							|  |  |  | // - quotation compiler (quotations.cpp),
 | 
					
						
							|  |  |  | // - megamorphic caches (dispatch.cpp),
 | 
					
						
							|  |  |  | // - polymorphic inline caches (inline_cache.cpp)
 | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Allocates memory (`code` and `relocation` initializers create
 | 
					
						
							|  |  |  | // growable_byte_array)
 | 
					
						
							| 
									
										
										
										
											2016-10-19 03:28:59 -04:00
										 |  |  | jit::jit(cell owner, factor_vm* vm) | 
					
						
							|  |  |  |     : owner(owner, vm), | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  |       code(vm), | 
					
						
							|  |  |  |       relocation(vm), | 
					
						
							|  |  |  |       parameters(vm), | 
					
						
							|  |  |  |       literals(vm), | 
					
						
							|  |  |  |       computing_offset_p(false), | 
					
						
							|  |  |  |       position(0), | 
					
						
							|  |  |  |       offset(0), | 
					
						
							|  |  |  |       parent(vm) { | 
					
						
							|  |  |  |   fixnum old_count = atomic::fetch_add(&parent->current_jit_count, 1); | 
					
						
							|  |  |  |   FACTOR_ASSERT(old_count >= 0); | 
					
						
							| 
									
										
										
										
											2013-05-13 00:53:47 -04:00
										 |  |  |   (void)old_count; | 
					
						
							| 
									
										
										
										
											2011-11-02 02:40:46 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  | jit::~jit() { | 
					
						
							|  |  |  |   fixnum old_count = atomic::fetch_subtract(&parent->current_jit_count, 1); | 
					
						
							|  |  |  |   FACTOR_ASSERT(old_count >= 1); | 
					
						
							| 
									
										
										
										
											2013-05-13 00:53:47 -04:00
										 |  |  |   (void)old_count; | 
					
						
							| 
									
										
										
										
											2011-11-02 02:40:46 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Allocates memory
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  | void jit::emit_relocation(cell relocation_template_) { | 
					
						
							|  |  |  |   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++) { | 
					
						
							|  |  |  |     relocation_entry entry = relocations[i]; | 
					
						
							| 
									
										
										
										
											2015-12-11 22:02:53 -05:00
										 |  |  |     relocation_entry new_entry(entry.type(), entry.klass(), | 
					
						
							|  |  |  |                                entry.offset() + code.count); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  |     relocation.append_bytes(&new_entry, sizeof(relocation_entry)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Allocates memory
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  | void jit::emit(cell code_template_) { | 
					
						
							|  |  |  |   data_root<array> code_template(code_template_, parent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   emit_relocation(array_nth(code_template.untagged(), 0)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   data_root<byte_array> insns(array_nth(code_template.untagged(), 1), parent); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (computing_offset_p) { | 
					
						
							|  |  |  |     cell size = array_capacity(insns.untagged()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (offset == 0) { | 
					
						
							|  |  |  |       position--; | 
					
						
							|  |  |  |       computing_offset_p = false; | 
					
						
							|  |  |  |     } else if (offset < size) { | 
					
						
							|  |  |  |       position++; | 
					
						
							|  |  |  |       computing_offset_p = false; | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |       offset -= size; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   code.append_byte_array(insns.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Allocates memory
 | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | void jit::emit_with_literal(cell code_template_, cell argument_) { | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  |   data_root<array> code_template(code_template_, parent); | 
					
						
							|  |  |  |   data_root<object> argument(argument_, parent); | 
					
						
							|  |  |  |   literal(argument.value()); | 
					
						
							|  |  |  |   emit(code_template.value()); | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Allocates memory
 | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | void jit::emit_with_parameter(cell code_template_, cell argument_) { | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  |   data_root<array> code_template(code_template_, parent); | 
					
						
							|  |  |  |   data_root<object> argument(argument_, parent); | 
					
						
							|  |  |  |   parameter(argument.value()); | 
					
						
							|  |  |  |   emit(code_template.value()); | 
					
						
							| 
									
										
										
										
											2009-12-02 05:28:15 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Allocates memory
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04: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-12-15 07:20:09 -05:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -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.
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  | void jit::compute_position(cell offset_) { | 
					
						
							|  |  |  |   computing_offset_p = true; | 
					
						
							|  |  |  |   position = 0; | 
					
						
							|  |  |  |   offset = offset_; | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  | // Allocates memory (trim(), add_code_block)
 | 
					
						
							| 
									
										
										
										
											2016-10-19 03:28:59 -04:00
										 |  |  | code_block* jit::to_code_block(code_block_type type, cell frame_size) { | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  |   // Emit dummy GC info
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  |   code.grow_bytes(alignment_for(code.count + 4, data_alignment)); | 
					
						
							| 
									
										
										
										
											2013-05-13 00:28:25 -04:00
										 |  |  |   uint32_t dummy_gc_info = 0; | 
					
						
							|  |  |  |   code.append_bytes(&dummy_gc_info, sizeof(uint32_t)); | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   code.trim(); | 
					
						
							|  |  |  |   relocation.trim(); | 
					
						
							|  |  |  |   parameters.trim(); | 
					
						
							|  |  |  |   literals.trim(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return parent->add_code_block( | 
					
						
							| 
									
										
										
										
											2016-08-21 10:26:04 -04:00
										 |  |  |       type, code.elements.value(), false_object, // no labels
 | 
					
						
							| 
									
										
										
										
											2013-05-11 22:07:15 -04:00
										 |  |  |       owner.value(), relocation.elements.value(), parameters.elements.value(), | 
					
						
							|  |  |  |       literals.elements.value(), frame_size); | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | } |