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