-
Notifications
You must be signed in to change notification settings - Fork 171
/
compile.c
136 lines (118 loc) · 4.89 KB
/
compile.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "moar.h"
#include "dasm_proto.h"
#include "platform/mmap.h"
#include "emit.h"
#define COPY_ARRAY(a, n, t) memcpy(MVM_malloc(n * sizeof(t)), a, n * sizeof(t))
static const MVMuint16 MAGIC_BYTECODE[] = { MVM_OP_sp_jit_enter, 0 };
MVMJitCode * MVM_jit_compile_graph(MVMThreadContext *tc, MVMJitGraph *jg) {
dasm_State *state;
char * memory;
size_t codesize;
/* Space for globals */
MVMint32 num_globals = MVM_jit_num_globals();
void ** dasm_globals = MVM_malloc(num_globals * sizeof(void*));
MVMJitNode * node = jg->first_node;
MVMJitCode * code;
MVMint32 i;
MVM_jit_log(tc, "Starting compilation\n");
/* setup dasm */
dasm_init(&state, 1);
dasm_setupglobal(&state, dasm_globals, num_globals);
dasm_setup(&state, MVM_jit_actions());
dasm_growpc(&state, jg->num_labels);
/* generate code */
MVM_jit_emit_prologue(tc, jg, &state);
while (node) {
switch(node->type) {
case MVM_JIT_NODE_LABEL:
MVM_jit_emit_label(tc, jg, &node->u.label, &state);
break;
case MVM_JIT_NODE_PRIMITIVE:
MVM_jit_emit_primitive(tc, jg, &node->u.prim, &state);
break;
case MVM_JIT_NODE_BRANCH:
MVM_jit_emit_branch(tc, jg, &node->u.branch, &state);
break;
case MVM_JIT_NODE_CALL_C:
MVM_jit_emit_call_c(tc, jg, &node->u.call, &state);
break;
case MVM_JIT_NODE_GUARD:
MVM_jit_emit_guard(tc, jg, &node->u.guard, &state);
break;
case MVM_JIT_NODE_INVOKE:
MVM_jit_emit_invoke(tc, jg, &node->u.invoke, &state);
break;
case MVM_JIT_NODE_JUMPLIST:
MVM_jit_emit_jumplist(tc, jg, &node->u.jumplist, &state);
break;
case MVM_JIT_NODE_CONTROL:
MVM_jit_emit_control(tc, jg, &node->u.control, &state);
break;
}
node = node->next;
}
MVM_jit_emit_epilogue(tc, jg, &state);
/* compile the function */
dasm_link(&state, &codesize);
memory = MVM_platform_alloc_pages(codesize, MVM_PAGE_READ|MVM_PAGE_WRITE);
dasm_encode(&state, memory);
/* set memory readable + executable */
MVM_platform_set_page_mode(memory, codesize, MVM_PAGE_READ|MVM_PAGE_EXEC);
MVM_jit_log(tc, "Bytecode size: %"MVM_PRSz"\n", codesize);
/* Create code segment */
code = MVM_malloc(sizeof(MVMJitCode));
code->func_ptr = (MVMJitFunc)memory;
code->size = codesize;
code->bytecode = (MVMuint8*)MAGIC_BYTECODE;
code->sf = jg->sg->sf;
/* Get the basic block labels */
code->num_labels = jg->num_labels;
code->labels = MVM_malloc(sizeof(void*) * code->num_labels);
for (i = 0; i < code->num_labels; i++) {
MVMint32 offset = dasm_getpclabel(&state, i);
if (offset < 0)
MVM_jit_log(tc, "Got negative offset for dynamic label %d\n", i);
code->labels[i] = memory + offset;
}
/* Copy the deopts, inlines, and handlers. Because these use the label index
* rather than the direct pointer, no fixup is necessary */
code->num_bbs = jg->num_bbs;
code->bb_labels = COPY_ARRAY(jg->bb_labels, jg->num_bbs, MVMint32);
code->num_deopts = jg->num_deopts;
code->deopts = code->num_deopts ? COPY_ARRAY(jg->deopts, jg->num_deopts, MVMJitDeopt) : NULL;
code->num_handlers = jg->num_handlers;
code->handlers = code->num_handlers ? COPY_ARRAY(jg->handlers, jg->num_handlers, MVMJitHandler) : NULL;
code->num_inlines = jg->num_inlines;
code->inlines = code->num_inlines ? COPY_ARRAY(jg->inlines, jg->num_inlines, MVMJitInline) : NULL;
/* clear up the assembler */
dasm_free(&state);
MVM_free(dasm_globals);
code->seq_nr = MVM_incr(&tc->instance->jit_seq_nr);
if (tc->instance->jit_bytecode_dir) {
MVM_jit_log_bytecode(tc, code);
}
if (tc->instance->jit_log_fh)
fflush(tc->instance->jit_log_fh);
return code;
}
void MVM_jit_destroy_code(MVMThreadContext *tc, MVMJitCode *code) {
MVM_platform_free_pages(code->func_ptr, code->size);
MVM_free(code);
}
extern int inreturn_find_count;
/* Returns 1 if we should return from the frame, the function, 0 otherwise */
MVMint32 MVM_jit_enter_code(MVMThreadContext *tc, MVMCompUnit *cu,
MVMJitCode *code) {
/* The actual JIT code returns 0 if it went through to the exit */
MVMFrame *frame = tc->cur_frame;
void *label = tc->cur_frame->jit_entry_label;
MVMint32 ctrl = code->func_ptr(tc, cu, label);
MVMint64 ofs = ((char*)frame->jit_entry_label) - ((char*)code->func_ptr);
if (ofs == 10357 && inreturn_find_count == 172) {
fprintf(stderr, "seq nr: %d ifc %d\n", code->seq_nr, inreturn_find_count);
}
if (ofs == 10357 && inreturn_find_count == 208) {
fprintf(stderr, "seq nr: %d ifc %d\n", code->seq_nr, inreturn_find_count);
}
return ctrl ? 0 : 1;
}