/home/travis/build/MoarVM/MoarVM/src/jit/interface.c
Line | Count | Source |
1 | | #include "moar.h" |
2 | | #include "internal.h" |
3 | | |
4 | 35.1M | static void assert_within_region(MVMThreadContext *tc, MVMJitCode *code, void *address) { |
5 | 35.1M | #if MVM_JIT_DEBUG |
6 | | MVMint32 ofs = (char*)address - (char*)code->func_ptr; |
7 | | if ((0 <= ofs) && (ofs < code->size)) |
8 | | return; |
9 | | MVM_panic(1, "JIT: address out of range for code!\n" |
10 | | "(label %p, func_ptr %p, code size %lui, offset %li, frame_nr %i, seq nr %i)", |
11 | | address, code->func_ptr, code->size, ofs, |
12 | | tc->cur_frame->sequence_nr, code->seq_nr); |
13 | | #endif |
14 | 35.1M | } |
15 | | |
16 | | |
17 | | /* Enter the JIT code segment. The label is a continuation point where control |
18 | | * is resumed after the frame is properly setup. */ |
19 | 14.9M | void MVM_jit_code_enter(MVMThreadContext *tc, MVMJitCode *code, MVMCompUnit *cu) { |
20 | 14.9M | void *label = tc->cur_frame->jit_entry_label; |
21 | 14.9M | |
22 | 14.9M | assert_within_region(tc, code, label); |
23 | 14.9M | |
24 | 14.9M | code->func_ptr(tc, cu, label); |
25 | 14.9M | } |
26 | | |
27 | 970k | void * MVM_jit_code_get_current_position(MVMThreadContext *tc, MVMJitCode *code, MVMFrame *frame) { |
28 | 970k | if (tc->cur_frame == frame && tc->jit_return_address != NULL) { |
29 | 63.3k | /* currently on C stack */ |
30 | 63.3k | void *return_address = *tc->jit_return_address; |
31 | 63.3k | assert_within_region(tc, code, return_address); |
32 | 63.3k | return return_address; |
33 | 907k | } else { |
34 | 907k | /* trampolined-out of this frame, so jit_entry_label is correct */ |
35 | 907k | return frame->jit_entry_label; |
36 | 907k | } |
37 | 970k | } |
38 | | |
39 | 9.84M | void MVM_jit_code_set_current_position(MVMThreadContext *tc, MVMJitCode *code, MVMFrame *frame, void *position) { |
40 | 9.84M | assert_within_region(tc, code, position); |
41 | 9.84M | if (tc->cur_frame == frame && tc->jit_return_address != NULL) { |
42 | 9.84M | *tc->jit_return_address = position; |
43 | 135 | } else { |
44 | 135 | frame->jit_entry_label = position; |
45 | 135 | } |
46 | 9.84M | } |
47 | | |
48 | 17.6M | void MVM_jit_code_trampoline(MVMThreadContext *tc) { |
49 | 17.6M | if (tc->jit_return_address != NULL) { |
50 | 5.15M | MVMJitCode *code = tc->cur_frame->spesh_cand->jitcode; |
51 | 5.15M | void *reentry_label = *tc->jit_return_address; |
52 | 5.15M | assert_within_region(tc, code, reentry_label); |
53 | 5.15M | /* Store our current position */ |
54 | 5.15M | tc->cur_frame->jit_entry_label = *tc->jit_return_address; |
55 | 5.15M | /* Tell currently-active JIT code that we're leaving this frame */ |
56 | 5.15M | assert_within_region(tc, code, code->exit_label); |
57 | 5.15M | *tc->jit_return_address = code->exit_label; |
58 | 5.15M | /* And tell further frame handlers that as far as they are concerned, |
59 | 5.15M | we're not on the stack anymore */ |
60 | 5.15M | tc->jit_return_address = NULL; |
61 | 5.15M | } |
62 | 17.6M | } |
63 | | |
64 | | |
65 | 3.23k | MVMint32 MVM_jit_code_get_active_deopt_idx(MVMThreadContext *tc, MVMJitCode *code, MVMFrame *frame) { |
66 | 3.23k | MVMint32 i; |
67 | 3.23k | void *current_position = MVM_jit_code_get_current_position(tc, code, frame); |
68 | 6.36k | for (i = 0; i < code->num_deopts; i++) { |
69 | 5.29k | if (code->labels[code->deopts[i].label] == current_position) { |
70 | 2.16k | break; |
71 | 2.16k | } |
72 | 5.29k | } |
73 | 3.23k | return i; |
74 | 3.23k | } |
75 | | |
76 | 79.7k | MVMint32 MVM_jit_code_get_active_handlers(MVMThreadContext *tc, MVMJitCode *code, void *current_position, MVMint32 i) { |
77 | 292k | for (; i < code->num_handlers; i++) { |
78 | 290k | void *start_label = code->labels[code->handlers[i].start_label]; |
79 | 290k | void *end_label = code->labels[code->handlers[i].end_label]; |
80 | 290k | if (start_label <= current_position && current_position <= end_label) { |
81 | 77.7k | break; |
82 | 77.7k | } |
83 | 290k | } |
84 | 79.7k | return i; |
85 | 79.7k | } |
86 | | |
87 | 1.06M | MVMint32 MVM_jit_code_get_active_inlines(MVMThreadContext *tc, MVMJitCode *code, void *current_position, MVMint32 i) { |
88 | 5.31M | for (;i < code->num_inlines; i++) { |
89 | 4.41M | void *inline_start = code->labels[code->inlines[i].start_label]; |
90 | 4.41M | void *inline_end = code->labels[code->inlines[i].end_label]; |
91 | 4.41M | if (inline_start <= current_position && current_position <= inline_end) |
92 | 157k | break; |
93 | 4.41M | } |
94 | 1.06M | return i; |
95 | 1.06M | } |