Coverage Report

Created: 2018-07-03 15:31

/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
}