Coverage Report

Created: 2018-07-03 15:31

/home/travis/build/MoarVM/MoarVM/src/6model/reprs/MVMStaticFrameSpesh.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
3
/* This representation's function pointer table. */
4
static const MVMREPROps StaticFrameSpesh_this_repr;
5
6
/* Creates a new type object of this representation, and associates it with
7
 * the given HOW. */
8
144
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
9
144
    MVMSTable *st  = MVM_gc_allocate_stable(tc, &StaticFrameSpesh_this_repr, HOW);
10
144
11
144
    MVMROOT(tc, st, {
12
144
        MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
13
144
        MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
14
144
        st->size = sizeof(MVMStaticFrameSpesh);
15
144
    });
16
144
17
144
    return st->WHAT;
18
144
}
19
20
/* Copies the body of one object to another. */
21
0
static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest) {
22
0
    MVM_exception_throw_adhoc(tc, "Cannot copy object with representation StaticFrameSpesh");
23
0
}
24
25
/* Called by the VM to mark any GCable items. */
26
11.1k
static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorklist *worklist) {
27
11.1k
    MVMStaticFrameSpeshBody *body = (MVMStaticFrameSpeshBody *)data;
28
11.1k
    MVM_spesh_stats_gc_mark(tc, body->spesh_stats, worklist);
29
11.1k
    MVM_spesh_arg_guard_gc_mark(tc, body->spesh_arg_guard, worklist);
30
11.1k
    if (body->num_spesh_candidates) {
31
5.45k
        MVMint32 i, j;
32
12.7k
        for (i = 0; i < body->num_spesh_candidates; i++) {
33
100k
            for (j = 0; j < body->spesh_candidates[i]->num_spesh_slots; j++)
34
92.9k
                MVM_gc_worklist_add(tc, worklist, &body->spesh_candidates[i]->spesh_slots[j]);
35
13.2k
            for (j = 0; j < body->spesh_candidates[i]->num_inlines; j++)
36
5.94k
                MVM_gc_worklist_add(tc, worklist, &body->spesh_candidates[i]->inlines[j].sf);
37
7.26k
        }
38
5.45k
    }
39
11.1k
    MVM_spesh_plugin_state_mark(tc, body->plugin_state, worklist);
40
11.1k
}
41
42
/* Called by the VM in order to free memory associated with this object. */
43
0
static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
44
0
    MVMStaticFrameSpesh *sfs = (MVMStaticFrameSpesh *)obj;
45
0
    MVMint32 i;
46
0
    MVM_spesh_stats_destroy(tc, sfs->body.spesh_stats);
47
0
    MVM_free(sfs->body.spesh_stats);
48
0
    MVM_spesh_arg_guard_destroy(tc, sfs->body.spesh_arg_guard, 0);
49
0
    for (i = 0; i < sfs->body.num_spesh_candidates; i++)
50
0
        MVM_spesh_candidate_destroy(tc, sfs->body.spesh_candidates[i]);
51
0
    if (sfs->body.spesh_candidates)
52
0
        MVM_fixed_size_free(tc, tc->instance->fsa,
53
0
            sfs->body.num_spesh_candidates * sizeof(MVMSpeshCandidate *),
54
0
            sfs->body.spesh_candidates);
55
0
    MVM_spesh_plugin_state_free(tc, sfs->body.plugin_state);
56
0
}
57
58
static const MVMStorageSpec storage_spec = {
59
    MVM_STORAGE_SPEC_REFERENCE, /* inlineable */
60
    0,                          /* bits */
61
    0,                          /* align */
62
    MVM_STORAGE_SPEC_BP_NONE,   /* boxed_primitive */
63
    0,                          /* can_box */
64
    0,                          /* is_unsigned */
65
};
66
67
68
/* Gets the storage specification for this representation. */
69
0
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
70
0
    return &storage_spec;
71
0
}
72
73
/* Compose the representation. */
74
0
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info) {
75
0
    /* Nothing to do for this REPR. */
76
0
}
77
78
/* Set the size of the STable. */
79
0
static void deserialize_stable_size(MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader) {
80
0
    st->size = sizeof(MVMStaticFrameSpesh);
81
0
}
82
83
/* Calculates the non-GC-managed memory we hold on to. */
84
0
static MVMuint64 unmanaged_size(MVMThreadContext *tc, MVMSTable *st, void *data) {
85
0
    MVMStaticFrameSpeshBody *body = (MVMStaticFrameSpeshBody *)data;
86
0
    MVMuint64 size = 0;
87
0
    MVMuint32 spesh_idx;
88
0
    for (spesh_idx = 0; spesh_idx < body->num_spesh_candidates; spesh_idx++) {
89
0
        MVMSpeshCandidate *cand = body->spesh_candidates[spesh_idx];
90
0
91
0
        size += cand->bytecode_size;
92
0
93
0
        size += sizeof(MVMFrameHandler) * cand->num_handlers;
94
0
95
0
        size += sizeof(MVMCollectable *) * cand->num_spesh_slots;
96
0
97
0
        size += sizeof(MVMint32) * cand->num_deopts;
98
0
99
0
        size += sizeof(MVMSpeshInline) * cand->num_inlines;
100
0
101
0
        size += sizeof(MVMuint16) * (cand->num_locals + cand->num_lexicals);
102
0
103
0
        /* XXX probably don't need to measure the bytecode size here,
104
0
         * as it's probably just a pointer to the same bytecode we have in
105
0
         * the static frame anyway. */
106
0
107
0
        /* Dive into the jit code */
108
0
        if (cand->jitcode) {
109
0
            MVMJitCode *code = cand->jitcode;
110
0
111
0
            size += sizeof(MVMJitCode);
112
0
113
0
            size += sizeof(void *) * code->num_labels;
114
0
115
0
            size += sizeof(MVMJitDeopt) * code->num_deopts;
116
0
            size += sizeof(MVMJitInline) * code->num_inlines;
117
0
            size += sizeof(MVMJitHandler) * code->num_handlers;
118
0
            if (code->local_types)
119
0
                size += sizeof(MVMuint16) * code->num_locals;
120
0
        }
121
0
    }
122
0
    return size;
123
0
}
124
125
0
static void describe_refs(MVMThreadContext *tc, MVMHeapSnapshotState *ss, MVMSTable *st, void *data) {
126
0
    MVMStaticFrameSpeshBody *body = (MVMStaticFrameSpeshBody *)data;
127
0
128
0
    MVM_spesh_stats_gc_describe(tc, ss, body->spesh_stats);
129
0
    MVM_spesh_arg_guard_gc_describe(tc, ss, body->spesh_arg_guard);
130
0
131
0
    if (body->num_spesh_candidates) {
132
0
        MVMint32 i, j;
133
0
        for (i = 0; i < body->num_spesh_candidates; i++) {
134
0
            for (j = 0; j < body->spesh_candidates[i]->num_spesh_slots; j++)
135
0
                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
136
0
                    (MVMCollectable *)body->spesh_candidates[i]->spesh_slots[j],
137
0
                    "Spesh slot entry");
138
0
            for (j = 0; j < body->spesh_candidates[i]->num_inlines; j++)
139
0
                MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
140
0
                    (MVMCollectable *)body->spesh_candidates[i]->inlines[j].sf,
141
0
                    "Spesh inlined static frame");
142
0
        }
143
0
    }
144
0
}
145
146
/* Initializes the representation. */
147
144
const MVMREPROps * MVMStaticFrameSpesh_initialize(MVMThreadContext *tc) {
148
144
    return &StaticFrameSpesh_this_repr;
149
144
}
150
151
static const MVMREPROps StaticFrameSpesh_this_repr = {
152
    type_object_for,
153
    MVM_gc_allocate_object,
154
    NULL,
155
    copy_to,
156
    MVM_REPR_DEFAULT_ATTR_FUNCS,
157
    MVM_REPR_DEFAULT_BOX_FUNCS,
158
    MVM_REPR_DEFAULT_POS_FUNCS,
159
    MVM_REPR_DEFAULT_ASS_FUNCS,
160
    MVM_REPR_DEFAULT_ELEMS,
161
    get_storage_spec,
162
    NULL, /* change_type */
163
    NULL, /* serialize */
164
    NULL, /* deserialize */
165
    NULL, /* serialize_repr_data */
166
    NULL, /* deserialize_repr_data */
167
    deserialize_stable_size,
168
    gc_mark,
169
    gc_free,
170
    NULL, /* gc_cleanup */
171
    NULL, /* gc_mark_repr_data */
172
    NULL, /* gc_free_repr_data */
173
    compose,
174
    NULL, /* spesh */
175
    "MVMStaticFrameSpesh", /* name */
176
    MVM_REPR_ID_MVMStaticFrameSpesh,
177
    unmanaged_size,
178
    describe_refs
179
};