forked from jatovm/jato
-
Notifications
You must be signed in to change notification settings - Fork 2
/
compiler.c
116 lines (88 loc) · 2.09 KB
/
compiler.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
/*
* Compiles bytecode methods to machine code.
*
* Copyright (C) 2005-2007 Pekka Enberg
*
* This file is released under the GPL version 2. Please refer to the file
* LICENSE for details.
*/
#include <jit/compilation-unit.h>
#include <jit/compiler.h>
#include <jit/statement.h>
#include <jit/bc-offset-mapping.h>
#include <jit/exception.h>
#include <jit/perf-map.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static void compile_error(struct compilation_unit *cu, int err)
{
struct classblock *cb = CLASS_CB(cu->method->class);
printf("%s: Failed to compile method `%s' in class `%s', error: %i\n",
__func__, cu->method->name, cb->name, err);
}
#define SYMBOL_LEN 128
int compile(struct compilation_unit *cu)
{
char symbol[SYMBOL_LEN];
int err;
if (opt_trace_method)
trace_method(cu);
err = analyze_control_flow(cu);
if (err)
goto out;
err = convert_to_ir(cu);
if (err)
goto out;
err = sort_basic_blocks(cu);
if (err)
goto out;
if (opt_trace_cfg)
trace_cfg(cu);
if (opt_trace_tree_ir)
trace_tree_ir(cu);
err = select_instructions(cu);
if (err)
goto out;
compute_insn_positions(cu);
if (opt_trace_lir)
trace_lir(cu);
err = analyze_liveness(cu);
if (err)
goto out;
if (opt_trace_liveness)
trace_liveness(cu);
err = allocate_registers(cu);
if (err)
goto out;
if (opt_trace_regalloc)
trace_regalloc(cu);
err = insert_spill_reload_insns(cu);
if (err)
goto out;
assert(all_insn_have_bytecode_offset(cu));
err = emit_machine_code(cu);
if (err)
goto out;
if (opt_trace_machine_code)
trace_machine_code(cu);
cu->is_compiled = true;
perf_map_append(cu_symbol(cu, symbol, SYMBOL_LEN), (unsigned long) cu_native_ptr(cu), cu_native_size(cu));
out:
if (err)
compile_error(cu, err);
return err;
}
int jit_prepare_method(struct methodblock *mb)
{
mb->compilation_unit = alloc_compilation_unit(mb);
if (!mb->compilation_unit)
return -ENOMEM;
mb->trampoline = build_jit_trampoline(mb->compilation_unit);
if (!mb->trampoline) {
free_compilation_unit(mb->compilation_unit);
return -ENOMEM;
}
return 0;
}