Coverage Report

Created: 2017-04-15 07:07

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