]> gitweb.factorcode.org Git - factor.git/blob - vm/jit.cpp
Fix conflict
[factor.git] / vm / jit.cpp
1 #include "master.hpp"
2
3 namespace factor
4 {
5
6 /* Simple code generator used by:
7 - profiler (profiler.cpp),
8 - quotation compiler (quotations.cpp),
9 - megamorphic caches (dispatch.cpp),
10 - polymorphic inline caches (inline_cache.cpp) */
11
12 /* Allocates memory */
13 jit::jit(code_block_type type_, cell owner_, factor_vm *vm)
14         : type(type_),
15           owner(owner_,vm),
16           code(vm),
17           relocation(vm),
18           literals(vm),
19           computing_offset_p(false),
20           position(0),
21           offset(0),
22           parent(vm)
23 {}
24
25 void jit::emit_relocation(cell code_template_)
26 {
27         data_root<array> code_template(code_template_,parent);
28         cell capacity = array_capacity(code_template.untagged());
29         for(cell i = 1; i < capacity; i += 3)
30         {
31                 cell rel_class = array_nth(code_template.untagged(),i);
32                 cell rel_type = array_nth(code_template.untagged(),i + 1);
33                 cell offset = array_nth(code_template.untagged(),i + 2);
34
35                 relocation_entry new_entry(
36                         (relocation_type)untag_fixnum(rel_type),
37                         (relocation_class)untag_fixnum(rel_class),
38                         code.count + untag_fixnum(offset));
39                 relocation.append_bytes(&new_entry,sizeof(relocation_entry));
40         }
41 }
42
43 /* Allocates memory */
44 void jit::emit(cell code_template_)
45 {
46         data_root<array> code_template(code_template_,parent);
47
48         emit_relocation(code_template.value());
49
50         data_root<byte_array> insns(array_nth(code_template.untagged(),0),parent);
51
52         if(computing_offset_p)
53         {
54                 cell size = array_capacity(insns.untagged());
55
56                 if(offset == 0)
57                 {
58                         position--;
59                         computing_offset_p = false;
60                 }
61                 else if(offset < size)
62                 {
63                         position++;
64                         computing_offset_p = false;
65                 }
66                 else
67                         offset -= size;
68         }
69
70         code.append_byte_array(insns.value());
71 }
72
73 void jit::emit_with(cell code_template_, cell argument_) {
74         data_root<array> code_template(code_template_,parent);
75         data_root<object> argument(argument_,parent);
76         literal(argument.value());
77         emit(code_template.value());
78 }
79
80 void jit::emit_class_lookup(fixnum index, cell type)
81 {
82         emit_with(parent->special_objects[PIC_LOAD],tag_fixnum(-index * sizeof(cell)));
83         emit(parent->special_objects[type]);
84 }
85
86 /* Facility to convert compiled code offsets to quotation offsets.
87 Call jit_compute_offset() with the compiled code offset, then emit
88 code, and at the end jit->position is the quotation position. */
89 void jit::compute_position(cell offset_)
90 {
91         computing_offset_p = true;
92         position = 0;
93         offset = offset_;
94 }
95
96 /* Allocates memory */
97 code_block *jit::to_code_block()
98 {
99         code.trim();
100         relocation.trim();
101         literals.trim();
102
103         return parent->add_code_block(
104                 type,
105                 code.elements.value(),
106                 false_object, /* no labels */
107                 owner.value(),
108                 relocation.elements.value(),
109                 literals.elements.value());
110 }
111
112 }