]> gitweb.factorcode.org Git - factor.git/blob - vm/jit.cpp
vm: quell warnings from vars only used by asserts
[factor.git] / vm / jit.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 /* Simple code generator used by:
7 - quotation compiler (quotations.cpp),
8 - megamorphic caches (dispatch.cpp),
9 - polymorphic inline caches (inline_cache.cpp) */
10
11 /* Allocates memory */
12 jit::jit(code_block_type type_, cell owner_, factor_vm *vm)
13         : type(type_),
14           owner(owner_,vm),
15           code(vm),
16           relocation(vm),
17           parameters(vm),
18           literals(vm),
19           computing_offset_p(false),
20           position(0),
21           offset(0),
22           parent(vm)
23 {
24         fixnum old_count = atomic::fetch_add(&parent->current_jit_count, 1);
25         FACTOR_ASSERT(old_count >= 0);
26         (void)old_count;
27 }
28
29 jit::~jit()
30 {
31         fixnum old_count = atomic::fetch_subtract(&parent->current_jit_count, 1);
32         FACTOR_ASSERT(old_count >= 1);
33         (void)old_count;
34 }
35
36 void jit::emit_relocation(cell relocation_template_)
37 {
38         data_root<byte_array> relocation_template(relocation_template_,parent);
39         cell capacity = array_capacity(relocation_template.untagged())
40                 / sizeof(relocation_entry);
41         relocation_entry *relocations = relocation_template->data<relocation_entry>();
42         for(cell i = 0; i < capacity; i++)
43         {
44                 relocation_entry entry = relocations[i];
45                 relocation_entry new_entry(entry.rel_type(), entry.rel_class(),
46                         entry.rel_offset() + code.count);
47                 relocation.append_bytes(&new_entry,sizeof(relocation_entry));
48         }
49 }
50
51 /* Allocates memory */
52 void jit::emit(cell code_template_)
53 {
54         data_root<array> code_template(code_template_,parent);
55
56         emit_relocation(array_nth(code_template.untagged(),0));
57
58         data_root<byte_array> insns(array_nth(code_template.untagged(),1),parent);
59
60         if(computing_offset_p)
61         {
62                 cell size = array_capacity(insns.untagged());
63
64                 if(offset == 0)
65                 {
66                         position--;
67                         computing_offset_p = false;
68                 }
69                 else if(offset < size)
70                 {
71                         position++;
72                         computing_offset_p = false;
73                 }
74                 else
75                         offset -= size;
76         }
77
78         code.append_byte_array(insns.value());
79 }
80
81 void jit::emit_with_literal(cell code_template_, cell argument_) {
82         data_root<array> code_template(code_template_,parent);
83         data_root<object> argument(argument_,parent);
84         literal(argument.value());
85         emit(code_template.value());
86 }
87
88 void jit::emit_with_parameter(cell code_template_, cell argument_) {
89         data_root<array> code_template(code_template_,parent);
90         data_root<object> argument(argument_,parent);
91         parameter(argument.value());
92         emit(code_template.value());
93 }
94
95 bool jit::emit_subprimitive(cell word_, bool tail_call_p, bool stack_frame_p)
96 {
97         data_root<word> word(word_,parent);
98         data_root<array> code_template(word->subprimitive,parent);
99         parameters.append(untag<array>(array_nth(code_template.untagged(),0)));
100         literals.append(untag<array>(array_nth(code_template.untagged(),1)));
101         emit(array_nth(code_template.untagged(),2));
102         if(array_capacity(code_template.untagged()) == 5)
103         {
104                 if(tail_call_p)
105                 {
106                         if(stack_frame_p) emit(parent->special_objects[JIT_EPILOG]);
107                         emit(array_nth(code_template.untagged(),4));
108                         return true;
109                 }
110                 else
111                         emit(array_nth(code_template.untagged(),3));
112         }
113         return false;
114 }
115         
116 /* Facility to convert compiled code offsets to quotation offsets.
117 Call jit_compute_offset() with the compiled code offset, then emit
118 code, and at the end jit->position is the quotation position. */
119 void jit::compute_position(cell offset_)
120 {
121         computing_offset_p = true;
122         position = 0;
123         offset = offset_;
124 }
125
126 /* Allocates memory */
127 code_block *jit::to_code_block()
128 {
129         /* Emit dummy GC info */
130         code.grow_bytes(alignment_for(code.count + 4,data_alignment));
131         u32 dummy_gc_info = 0;
132         code.append_bytes(&dummy_gc_info,sizeof(u32));
133
134         code.trim();
135         relocation.trim();
136         parameters.trim();
137         literals.trim();
138
139         return parent->add_code_block(
140                 type,
141                 code.elements.value(),
142                 false_object, /* no labels */
143                 owner.value(),
144                 relocation.elements.value(),
145                 parameters.elements.value(),
146                 literals.elements.value());
147 }
148
149 }