Coverage Report

Created: 2018-07-03 15:31

/home/travis/build/MoarVM/MoarVM/src/6model/reprs/MVMCompUnit.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
#include "platform/mmap.h"
3
4
/* This representation's function pointer table. */
5
static const MVMREPROps MVMCompUnit_this_repr;
6
7
/* Creates a new type object of this representation, and associates it with
8
 * the given HOW. Also sets the invocation protocol handler in the STable. */
9
144
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
10
144
    MVMSTable *st = MVM_gc_allocate_stable(tc, &MVMCompUnit_this_repr, HOW);
11
144
12
144
    MVMROOT(tc, st, {
13
144
        MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
14
144
        MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
15
144
        st->size = sizeof(MVMCompUnit);
16
144
    });
17
144
18
144
    return st->WHAT;
19
144
}
20
21
/* Initializes a new instance. */
22
2.80k
static void initialize(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data) {
23
2.80k
    MVMCompUnit *cu = (MVMCompUnit *)root;
24
2.80k
    MVMROOT(tc, cu, {
25
2.80k
        MVMObject *rm = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTReentrantMutex);
26
2.80k
        MVM_ASSIGN_REF(tc, &(root->header), cu->body.deserialize_frame_mutex, rm);
27
2.80k
        cu->body.inline_tweak_mutex = MVM_malloc(sizeof(uv_mutex_t));
28
2.80k
        uv_mutex_init(cu->body.inline_tweak_mutex);
29
2.80k
    });
30
2.80k
}
31
32
/* Copies the body of one object to another. */
33
0
static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest) {
34
0
    MVM_exception_throw_adhoc(tc, "this representation (CompUnit) cannot be cloned");
35
0
}
36
37
/* Adds held objects to the GC worklist. */
38
3.54k
static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorklist *worklist) {
39
3.54k
    MVMCompUnitBody *body = (MVMCompUnitBody *)data;
40
3.54k
    MVMuint32 i;
41
3.54k
42
3.54k
    /* Add code refs to the worklists. */
43
191k
    for (i = 0; i < body->num_frames; i++)
44
188k
        MVM_gc_worklist_add(tc, worklist, &body->coderefs[i]);
45
3.54k
46
3.54k
    /* Add extop names to the worklist. */
47
3.54k
    for (i = 0; i < body->num_extops; i++)
48
0
        MVM_gc_worklist_add(tc, worklist, &body->extops[i].name);
49
3.54k
50
3.54k
    /* Add strings to the worklists. */
51
918k
    for (i = 0; i < body->num_strings; i++)
52
914k
        MVM_gc_worklist_add(tc, worklist, &body->strings[i]);
53
3.54k
54
3.54k
    /* Add serialization contexts to the worklist. */
55
11.9k
    for (i = 0; i < body->num_scs; i++) {
56
8.35k
        if (body->scs[i]) {
57
7.89k
            MVM_gc_worklist_add(tc, worklist, &body->scs[i]);
58
7.89k
        }
59
8.35k
        /* Unresolved sc bodies' handles are marked by the GC instance root marking. */
60
8.35k
    }
61
3.54k
62
3.54k
    MVM_gc_worklist_add(tc, worklist, &body->deserialize_frame_mutex);
63
3.54k
64
3.54k
    /* Add various other referenced strings, etc. */
65
3.54k
    MVM_gc_worklist_add(tc, worklist, &body->hll_name);
66
3.54k
    MVM_gc_worklist_add(tc, worklist, &body->filename);
67
3.54k
}
68
69
/* Called by the VM in order to free memory associated with this object. */
70
0
static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
71
0
    MVMCompUnitBody *body = &((MVMCompUnit *)obj)->body;
72
0
73
0
    int i;
74
0
    for (i = 0; i < body->num_callsites; i++) {
75
0
        MVMCallsite *cs = body->callsites[i];
76
0
        if (!cs->is_interned)
77
0
            MVM_callsite_destroy(cs);
78
0
    }
79
0
80
0
    uv_mutex_destroy(body->inline_tweak_mutex);
81
0
    MVM_free(body->inline_tweak_mutex);
82
0
    MVM_free(body->coderefs);
83
0
    if (body->callsites)
84
0
        MVM_fixed_size_free(tc, tc->instance->fsa,
85
0
            body->num_callsites * sizeof(MVMCallsite *),
86
0
            body->callsites);
87
0
    if (body->extops)
88
0
        MVM_fixed_size_free(tc, tc->instance->fsa,
89
0
            body->num_extops * sizeof(MVMExtOpRecord),
90
0
            body->extops);
91
0
    if (body->strings)
92
0
        MVM_fixed_size_free(tc, tc->instance->fsa,
93
0
            body->num_strings * sizeof(MVMString *),
94
0
            body->strings);
95
0
    MVM_free(body->scs);
96
0
    MVM_free(body->scs_to_resolve);
97
0
    MVM_free(body->sc_handle_idxs);
98
0
    MVM_free(body->string_heap_fast_table);
99
0
    switch (body->deallocate) {
100
0
    case MVM_DEALLOCATE_NOOP:
101
0
        break;
102
0
    case MVM_DEALLOCATE_FREE:
103
0
        MVM_free(body->data_start);
104
0
        break;
105
0
    case MVM_DEALLOCATE_UNMAP:
106
0
        MVM_platform_unmap_file(body->data_start, body->handle, body->data_size);
107
0
        break;
108
0
    default:
109
0
        MVM_panic(MVM_exitcode_NYI, "Invalid deallocate of %u during MVMCompUnit gc_free", body->deallocate);
110
0
    }
111
0
}
112
113
static const MVMStorageSpec storage_spec = {
114
    MVM_STORAGE_SPEC_REFERENCE, /* inlineable */
115
    0,                          /* bits */
116
    0,                          /* align */
117
    MVM_STORAGE_SPEC_BP_NONE,   /* boxed_primitive */
118
    0,                          /* can_box */
119
    0,                          /* is_unsigned */
120
};
121
122
123
/* Gets the storage specification for this representation. */
124
0
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
125
0
    /* XXX in the end we'll support inlining of this... */
126
0
    return &storage_spec;
127
0
}
128
129
/* Compose the representation. */
130
0
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info) {
131
0
    /* Nothing to do for this REPR. */
132
0
}
133
134
/* Calculates the non-GC-managed memory we hold on to. */
135
0
static MVMuint64 unmanaged_size(MVMThreadContext *tc, MVMSTable *st, void *data) {
136
0
    MVMCompUnitBody *body = (MVMCompUnitBody *)data;
137
0
    MVMuint64 size = 0;
138
0
    MVMuint32 index;
139
0
140
0
    size += sizeof(MVMCallsite *) * body->num_callsites;
141
0
    for (index = 0; index < body->num_callsites; index++) {
142
0
        MVMCallsite *cs = body->callsites[index];
143
0
        if (cs && !cs->is_interned) {
144
0
            size += sizeof(MVMCallsite);
145
0
146
0
            size += sizeof(MVMCallsiteEntry) * cs->flag_count;
147
0
148
0
            size += sizeof(MVMString *) * MVM_callsite_num_nameds(tc, cs);
149
0
        }
150
0
    }
151
0
152
0
    if (body->deallocate == MVM_DEALLOCATE_FREE) {
153
0
        /* XXX do we want to count mmapped data for the bytecode segment, too? */
154
0
        size += body->data_size;
155
0
    }
156
0
157
0
    size += sizeof(MVMObject *) * body->num_frames;
158
0
159
0
    size += sizeof(MVMExtOpRecord *) * body->num_extops;
160
0
161
0
    size += sizeof(MVMString *) * body->num_strings;
162
0
163
0
    size += body->serialized_size;
164
0
165
0
    /* since SCs are GC-managed themselves, only the array containing them
166
0
     * is added to the unmanaged size here. */
167
0
    size += body->num_scs * (
168
0
            sizeof(MVMSerializationContext *) +     /* scs */
169
0
            sizeof(MVMSerializationContextBody *) + /* scs_to_resolve */
170
0
            sizeof(MVMint32)                        /* sc_handle_idxs */
171
0
            );
172
0
173
0
    return size;
174
0
}
175
176
0
static void describe_refs(MVMThreadContext *tc, MVMHeapSnapshotState *ss, MVMSTable *st, void *data) {
177
0
    MVMCompUnitBody     *body      = (MVMCompUnitBody *)data;
178
0
    MVMuint32 i;
179
0
180
0
    /* Add code refs to the worklists. */
181
0
    for (i = 0; i < body->num_frames; i++)
182
0
        MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
183
0
            (MVMCollectable *)body->coderefs[i], "Code refs array entry");
184
0
185
0
    /* Add extop names to the worklist. */
186
0
    for (i = 0; i < body->num_extops; i++)
187
0
        MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
188
0
            (MVMCollectable *)body->extops[i].name, "Ext-op names list entry");
189
0
190
0
    /* Add strings to the worklists. */
191
0
    for (i = 0; i < body->num_strings; i++)
192
0
        MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
193
0
            (MVMCollectable *)body->strings[i], "Strings heap entry");
194
0
195
0
    /* Add serialization contexts to the worklist. */
196
0
    for (i = 0; i < body->num_scs; i++)
197
0
        MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
198
0
            (MVMCollectable *)body->scs[i], "Serialization context dependency");
199
0
200
0
    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
201
0
        (MVMCollectable *)body->deserialize_frame_mutex, "Update_mutex");
202
0
203
0
    /* Add various other referenced strings, etc. */
204
0
    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
205
0
        (MVMCollectable *)body->hll_name, "HLL name");
206
0
    MVM_profile_heap_add_collectable_rel_const_cstr(tc, ss,
207
0
        (MVMCollectable *)body->filename, "Filename");
208
0
}
209
210
/* Initializes the representation. */
211
144
const MVMREPROps * MVMCompUnit_initialize(MVMThreadContext *tc) {
212
144
    return &MVMCompUnit_this_repr;
213
144
}
214
215
static const MVMREPROps MVMCompUnit_this_repr = {
216
    type_object_for,
217
    MVM_gc_allocate_object,
218
    initialize,
219
    copy_to,
220
    MVM_REPR_DEFAULT_ATTR_FUNCS,
221
    MVM_REPR_DEFAULT_BOX_FUNCS,
222
    MVM_REPR_DEFAULT_POS_FUNCS,
223
    MVM_REPR_DEFAULT_ASS_FUNCS,
224
    MVM_REPR_DEFAULT_ELEMS,
225
    get_storage_spec,
226
    NULL, /* change_type */
227
    NULL, /* serialize */
228
    NULL, /* deserialize */
229
    NULL, /* serialize_repr_data */
230
    NULL, /* deserialize_repr_data */
231
    NULL, /* deserialize_stable_size */
232
    gc_mark,
233
    gc_free,
234
    NULL, /* gc_cleanup */
235
    NULL, /* gc_mark_repr_data */
236
    NULL, /* gc_free_repr_data */
237
    compose,
238
    NULL, /* spesh */
239
    "MVMCompUnit", /* name */
240
    MVM_REPR_ID_MVMCompUnit,
241
    unmanaged_size,
242
    describe_refs,
243
};