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