Coverage Report

Created: 2018-07-03 15:31

/home/travis/build/MoarVM/MoarVM/src/jit/log.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
3
/* inline this? maybe */
4
3.21M
void MVM_jit_log(MVMThreadContext *tc, const char * fmt, ...) {
5
3.21M
    va_list args;
6
3.21M
    va_start(args, fmt);
7
3.21M
    if (tc->instance->jit_log_fh) {
8
0
        vfprintf(tc->instance->jit_log_fh, fmt, args);
9
0
    }
10
3.21M
    va_end(args);
11
3.21M
}
12
13
0
void MVM_jit_log_bytecode(MVMThreadContext *tc, MVMJitCode *code) {
14
0
    /* Filename format: moar-jit-%d.bin. number can consume at most 10
15
0
     * bytes, moar-jit-.bin is 13 bytes, one byte for the zero at the
16
0
     * end, one byte for the directory separator is 25 bytes, plus the
17
0
     * length of the bytecode directory itself */
18
0
    size_t filename_size = strlen(tc->instance->jit_bytecode_dir) + 25;
19
0
    char * filename = MVM_malloc(filename_size);
20
0
    FILE * out;
21
0
    snprintf(filename, filename_size, "%s/moar-jit-%04d.bin", tc->instance->jit_bytecode_dir, code->seq_nr);
22
0
    out = fopen(filename, "w");
23
0
    if (out) {
24
0
        fwrite(code->func_ptr, sizeof(char), code->size, out);
25
0
        fclose(out);
26
0
        if (tc->instance->jit_bytecode_map) {
27
0
            char *frame_name   = code->sf
28
0
                ? MVM_string_utf8_encode_C_string(tc, code->sf->body.name)
29
0
                : NULL;
30
0
            char *frame_cuuid  = code->sf
31
0
                ? MVM_string_utf8_encode_C_string(tc, code->sf->body.cuuid)
32
0
                : NULL;
33
0
            /* I'd like to add linenumber and filename information, but it's really a lot of work at this point */
34
0
            fprintf(
35
0
                tc->instance->jit_bytecode_map,
36
0
                "%s\t%s\t%s\n",
37
0
                filename,
38
0
                frame_name ? frame_name : "(unknown)",
39
0
                frame_cuuid ? frame_cuuid : "(unknown)"
40
0
            );
41
0
            fflush(tc->instance->jit_bytecode_map);
42
0
            MVM_free(frame_name);
43
0
            MVM_free(frame_cuuid);
44
0
        }
45
0
    } else {
46
0
        MVM_jit_log(tc, "ERROR: could dump bytecode in %s\n", filename);
47
0
    }
48
0
    MVM_free(filename);
49
0
}
50
51
52
static void dump_tree(MVMThreadContext *tc, MVMJitTreeTraverser *traverser,
53
0
                      MVMJitExprTree *tree, MVMint32 node) {
54
0
    MVMJitExprNodeInfo *info   = &tree->info[node];
55
0
    const MVMJitExprOpInfo *op = info->op_info;
56
0
    MVMint32 *depth            = traverser->data;
57
0
    MVMint32 i, j;
58
0
    char indent[64];
59
0
    char nargs[80];
60
0
61
0
    (*depth)++;
62
0
#define MIN(a,b) ((a) < (b) ? (a) : (b))
63
0
    i = MIN(*depth*2, sizeof(indent)-1);
64
0
    memset(indent, ' ', i);
65
0
    indent[i] = 0;
66
0
    j = 0;
67
0
    for (i = 0; i < op->nargs; i++) {
68
0
        MVMint64 arg = tree->nodes[node+op->nchild+i+1];
69
0
        j += snprintf(nargs + j, sizeof(nargs)-j-3, "%"PRId64, arg);
70
0
        if (i+1 < op->nargs && j < sizeof(nargs)-3) {
71
0
            j += sprintf(nargs + j, ", ");
72
0
        }
73
0
    }
74
0
    nargs[j] = 0;
75
0
    MVM_jit_log(tc, "%04d%s%s (%s; sz=%d)\n", node, indent, op->name,
76
0
                nargs, info->size);
77
0
}
78
79
static void ascend_tree(MVMThreadContext *tc, MVMJitTreeTraverser *traverser,
80
0
                        MVMJitExprTree *tree, MVMint32 node) {
81
0
    MVMint32 *depth = traverser->data;
82
0
    (*depth)--;
83
0
}
84
85
86
static void write_graphviz_node(MVMThreadContext *tc, MVMJitTreeTraverser *traverser,
87
0
                                MVMJitExprTree *tree, MVMint32 node) {
88
0
    FILE *graph_file            = traverser->data;
89
0
    const MVMJitExprOpInfo *op_info = tree->info[node].op_info;
90
0
    MVMint32 first_child        = node + 1;
91
0
    MVMint32 nchild             = op_info->nchild < 0 ? tree->nodes[first_child++] : op_info->nchild;
92
0
    MVMint32 first_arg          = first_child + nchild;
93
0
    MVMint32 i;
94
0
    /* maximum length of op name is 'invokish' at 8 characters, let's allocate
95
0
     * 16; maximum number of parameters is 4, and 64 bits; printing them in
96
0
     * hexadecimal would require at most 8 characters, plus 4 for the '0x' and
97
0
     * the ', '; minus 2 for the last one, plus 2 for the ampersands, plus 0 for
98
0
     * the terminus, gives us 16 + 4*12 + 3 = 67; 80 should be plenty */
99
0
    char node_label[80];
100
0
    char *ptr = node_label + sprintf(node_label, "%s%s", op_info->name,
101
0
                                     op_info->nargs ? "(" : "");
102
0
    for (i = 0; i < op_info->nargs; i++) {
103
0
        ptr += sprintf(ptr, "%#" PRIx64 "%s", tree->nodes[first_arg+i],
104
0
                       (i + 1 < op_info->nargs) ? ", "  : ")");
105
0
    }
106
0
107
0
    fprintf(graph_file, "  n_%04d [label=\"%s\"];\n", node, node_label);
108
0
    for (i = 0; i < nchild; i++) {
109
0
        fprintf(graph_file, "    n_%04d -> n_%04d;\n", node, (MVMint32)tree->nodes[first_child+i]);
110
0
    }
111
0
}
112
113
114
262k
void MVM_jit_log_expr_tree(MVMThreadContext *tc, MVMJitExprTree *tree) {
115
262k
    MVMJitTreeTraverser traverser;
116
262k
    if (!tc->instance->jit_log_fh)
117
262k
        return;
118
0
    traverser.policy    = MVM_JIT_TRAVERSER_ONCE;
119
0
    traverser.preorder  = NULL;
120
0
    traverser.inorder   = NULL;
121
0
    traverser.postorder = &write_graphviz_node;
122
0
    traverser.data      = tc->instance->jit_log_fh;
123
0
124
0
    MVM_jit_log(tc, "Starting dump of JIT expression tree\n"
125
0
                    "====================================\n");
126
0
    MVM_jit_log(tc, "digraph {\n");
127
0
    MVM_jit_expr_tree_traverse(tc, tree, &traverser);
128
0
    MVM_jit_log(tc, "}\n");
129
0
    MVM_jit_log(tc, "End dump of JIT expression tree\n"
130
0
                    "====================================\n");
131
0
}
132
133
253k
void MVM_jit_log_tile_list(MVMThreadContext *tc, MVMJitTileList *list) {
134
253k
    MVMint32 i, j;
135
253k
    FILE *f = tc->instance->jit_log_fh;
136
253k
    if (!f)
137
253k
        return;
138
0
    fprintf(f, "Starting tile list log\n"
139
0
              "======================\n");
140
0
    for (i = 0; i < list->blocks_num; i++) {
141
0
        MVMint32 start = list->blocks[i].start, end = list->blocks[i].end;
142
0
        fprintf(f, "Block{%d} [%d-%d)\n", i, start, end);
143
0
        for (j = start; j < end; j++) {
144
0
            MVMJitTile *tile = list->items[j];
145
0
            fprintf(f, "    %d: %s\n", j, tile->debug_name ? tile->debug_name : "");
146
0
        }
147
0
        if (list->blocks[i].num_succ == 2) {
148
0
            fprintf(f, "-> { %d, %d }\n", list->blocks[i].succ[0], list->blocks[i].succ[1]);
149
0
        } else if (list->blocks[i].num_succ == 1) {
150
0
            fprintf(f, "-> { %d }\n", list->blocks[i].succ[0]);
151
0
        } else {
152
0
            fprintf(f, "-> {}\n");
153
0
        }
154
0
155
0
    }
156
0
    fprintf(f, "End of tile list log\n"
157
0
              "======================\n");
158
0
159
0
}