Branch data Line data Source code
1 : : // This file is a part of Julia. License is MIT: https://julialang.org/license
2 : :
3 : : /*
4 : : encoding IR to/from compact representation
5 : : */
6 : : #include <stdlib.h>
7 : : #include <string.h>
8 : :
9 : : #include "julia.h"
10 : : #include "julia_internal.h"
11 : : #include "serialize.h"
12 : :
13 : : #ifndef _OS_WINDOWS_
14 : : #include <dlfcn.h>
15 : : #endif
16 : :
17 : : #include "valgrind.h"
18 : : #include "julia_assert.h"
19 : :
20 : : #ifdef __cplusplus
21 : : extern "C" {
22 : : #endif
23 : :
24 : : typedef struct {
25 : : ios_t *s;
26 : : // method we're compressing for
27 : : jl_method_t *method;
28 : : jl_ptls_t ptls;
29 : : uint8_t relocatability;
30 : : } jl_ircode_state;
31 : :
32 : : // --- encoding ---
33 : :
34 : : #define jl_encode_value(s, v) jl_encode_value_((s), (jl_value_t*)(v), 0)
35 : :
36 : 128259000 : static void tagged_root(rle_reference *rr, jl_ircode_state *s, int i)
37 : : {
38 [ + + ]: 128259000 : if (!get_root_reference(rr, s->method, i))
39 : 83689400 : s->relocatability = 0;
40 : 128259000 : }
41 : :
42 : 128259000 : static void literal_val_id(rle_reference *rr, jl_ircode_state *s, jl_value_t *v) JL_GC_DISABLED
43 : : {
44 : 128259000 : jl_array_t *rs = s->method->roots;
45 : 128259000 : int i, l = jl_array_len(rs);
46 [ + + + + ]: 128259000 : if (jl_is_symbol(v) || jl_is_concrete_type(v)) {
47 [ + + ]:13651400000 : for (i = 0; i < l; i++) {
48 [ + + ]:13649400000 : if (jl_array_ptr_ref(rs, i) == v)
49 : 92114500 : return tagged_root(rr, s, i);
50 : : }
51 : : }
52 : : else {
53 [ + + ]: 4948340000 : for (i = 0; i < l; i++) {
54 [ + + ]: 4946720000 : if (jl_egal(jl_array_ptr_ref(rs, i), v))
55 : 32530200 : return tagged_root(rr, s, i);
56 : : }
57 : : }
58 : 3613930 : jl_add_method_root(s->method, jl_precompile_toplevel_module, v);
59 : 3613930 : return tagged_root(rr, s, jl_array_len(rs) - 1);
60 : : }
61 : :
62 : 412829000 : static void jl_encode_int32(jl_ircode_state *s, int32_t x)
63 : : {
64 [ + + + + ]: 412829000 : if (x >= INT16_MIN && x <= INT16_MAX) {
65 : 412826000 : write_uint8(s->s, TAG_SHORT_INT32);
66 : 412826000 : write_uint16(s->s, (uint16_t)x);
67 : : }
68 : : else {
69 : 2990 : write_uint8(s->s, TAG_INT32);
70 : 2990 : write_int32(s->s, x);
71 : : }
72 : 412829000 : }
73 : :
74 : 2013620000 : static void jl_encode_value_(jl_ircode_state *s, jl_value_t *v, int as_literal) JL_GC_DISABLED
75 : : {
76 : : size_t i;
77 : : rle_reference rr;
78 : :
79 [ + + ]: 2013620000 : if (v == NULL) {
80 : 2265880 : write_uint8(s->s, TAG_NULL);
81 : 177466000 : return;
82 : : }
83 : :
84 : 2011350000 : void *tag = jl_lookup_ser_tag(v);
85 [ + + ]: 2011350000 : if (tag != HT_NOTFOUND) {
86 : 604413000 : uint8_t t8 = (intptr_t)tag;
87 [ + + ]: 604413000 : if (t8 <= LAST_TAG)
88 : 27579200 : write_uint8(s->s, 0);
89 : 604413000 : write_uint8(s->s, t8);
90 : : }
91 [ + + + + ]: 1406940000 : else if (jl_is_symbol(v) && (tag = jl_lookup_common_symbol(v)) != HT_NOTFOUND) {
92 : 76289200 : write_uint8(s->s, TAG_COMMONSYM);
93 : 76289200 : write_uint8(s->s, (uint8_t)(size_t)tag);
94 : : }
95 [ + + ]: 1330650000 : else if (v == (jl_value_t*)jl_core_module) {
96 : 15522600 : write_uint8(s->s, TAG_CORE);
97 : : }
98 [ + + ]: 1315130000 : else if (v == (jl_value_t*)jl_base_module) {
99 : 223740000 : write_uint8(s->s, TAG_BASE);
100 : : }
101 [ + + - + ]: 1091390000 : else if (jl_typeis(v, jl_string_type) && jl_string_len(v) == 0) {
102 : 0 : jl_encode_value(s, jl_an_empty_string);
103 : : }
104 [ + + ]: 1091390000 : else if (v == (jl_value_t*)s->method->module) {
105 : 17373500 : write_uint8(s->s, TAG_NEARBYMODULE);
106 : : }
107 [ + + + + ]: 1074010000 : else if (jl_is_datatype(v) && ((jl_datatype_t*)v)->name == jl_array_typename &&
108 [ + + + + ]: 6320120 : jl_is_long(jl_tparam1(v)) && jl_unbox_long(jl_tparam1(v)) == 1 &&
109 [ + + ]: 4165660 : !((jl_datatype_t*)v)->hasfreetypevars) {
110 : 4163420 : write_uint8(s->s, TAG_VECTORTY);
111 : 4163420 : jl_encode_value(s, jl_tparam0(v));
112 : : }
113 [ + + + + ]: 1069850000 : else if (jl_is_datatype(v) && ((jl_datatype_t*)v)->name == jl_pointer_typename &&
114 [ + + ]: 1513410 : !((jl_datatype_t*)v)->hasfreetypevars) {
115 : 1511930 : write_uint8(s->s, TAG_PTRTY);
116 : 1511930 : jl_encode_value(s, jl_tparam0(v));
117 : : }
118 [ + + ]: 1068340000 : else if (jl_is_svec(v)) {
119 : 1292960 : size_t l = jl_svec_len(v);
120 [ + - ]: 1292960 : if (l <= 255) {
121 : 1292960 : write_uint8(s->s, TAG_SVEC);
122 : 1292960 : write_uint8(s->s, (uint8_t)l);
123 : : }
124 : : else {
125 : 0 : write_uint8(s->s, TAG_LONG_SVEC);
126 : 0 : write_int32(s->s, l);
127 : : }
128 [ + + ]: 3391940 : for (i = 0; i < l; i++) {
129 : 2098990 : jl_encode_value(s, jl_svecref(v, i));
130 : : }
131 : : }
132 [ + + ]: 1067050000 : else if (jl_is_globalref(v)) {
133 [ + + ]: 60762300 : if (jl_globalref_mod(v) == s->method->module) {
134 : 18005500 : write_uint8(s->s, TAG_NEARBYGLOBAL);
135 : 18005500 : jl_encode_value(s, jl_globalref_name(v));
136 : : }
137 : : else {
138 : 42756800 : write_uint8(s->s, TAG_GLOBALREF);
139 : 42756800 : jl_encode_value(s, jl_globalref_mod(v));
140 : 42756800 : jl_encode_value(s, jl_globalref_name(v));
141 : : }
142 : : }
143 [ + + + + : 1006280000 : else if (jl_is_ssavalue(v) && ((jl_ssavalue_t*)v)->id < 256 && ((jl_ssavalue_t*)v)->id >= 0) {
+ - ]
144 : 69278200 : write_uint8(s->s, TAG_SSAVALUE);
145 : 69278200 : write_uint8(s->s, ((jl_ssavalue_t*)v)->id);
146 : : }
147 [ + + + - : 937006000 : else if (jl_is_ssavalue(v) && ((jl_ssavalue_t*)v)->id <= UINT16_MAX && ((jl_ssavalue_t*)v)->id >= 0) {
+ - ]
148 : 29465900 : write_uint8(s->s, TAG_LONG_SSAVALUE);
149 : 29465900 : write_uint16(s->s, ((jl_ssavalue_t*)v)->id);
150 : : }
151 [ + + + - : 907540000 : else if (jl_typeis(v, jl_slotnumber_type) && jl_slot_number(v) <= UINT16_MAX && jl_slot_number(v) >= 0) {
+ - ]
152 : 479576 : write_uint8(s->s, TAG_SLOTNUMBER);
153 : 479576 : write_uint16(s->s, jl_slot_number(v));
154 : : }
155 [ + + ]: 907060000 : else if (jl_is_expr(v)) {
156 : 62386300 : jl_expr_t *e = (jl_expr_t*)v;
157 : 62386300 : size_t l = jl_array_len(e->args);
158 [ + + ]: 62386300 : if (e->head == jl_call_sym) {
159 [ + + ]: 54109500 : if (l == 2) {
160 : 5132790 : write_uint8(s->s, TAG_CALL1);
161 : 5132790 : jl_encode_value(s, jl_exprarg(e, 0));
162 : 5132790 : jl_encode_value(s, jl_exprarg(e, 1));
163 : 5132790 : return;
164 : : }
165 [ + + ]: 48976700 : else if (l == 3) {
166 : 41808500 : write_uint8(s->s, TAG_CALL2);
167 : 41808500 : jl_encode_value(s, jl_exprarg(e, 0));
168 : 41808500 : jl_encode_value(s, jl_exprarg(e, 1));
169 : 41808500 : jl_encode_value(s, jl_exprarg(e, 2));
170 : 41808500 : return;
171 : : }
172 : : }
173 [ + + ]: 15445000 : if (l <= 255) {
174 : 15445000 : write_uint8(s->s, TAG_EXPR);
175 : 15445000 : write_uint8(s->s, (uint8_t)l);
176 : : }
177 : : else {
178 : 2 : write_uint8(s->s, TAG_LONG_EXPR);
179 : 2 : write_int32(s->s, l);
180 : : }
181 : 15445000 : jl_encode_value(s, e->head);
182 [ + + ]: 80097400 : for (i = 0; i < l; i++) {
183 : 64652400 : jl_encode_value(s, jl_exprarg(e, i));
184 : : }
185 : : }
186 [ + + ]: 844674000 : else if (jl_is_phinode(v)) {
187 : 10177800 : jl_array_t *edges = (jl_array_t*)jl_fieldref_noalloc(v, 0);
188 : 10177800 : jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(v, 1);
189 : 10177800 : size_t l = jl_array_len(edges);
190 [ + - + - ]: 10177800 : if (l <= 255 && jl_array_len(values) == l) {
191 : 10177800 : write_uint8(s->s, TAG_PHINODE);
192 : 10177800 : write_uint8(s->s, (uint8_t)l);
193 : : }
194 : : else {
195 : 0 : write_uint8(s->s, TAG_LONG_PHINODE);
196 : 0 : write_int32(s->s, l);
197 : 0 : write_int32(s->s, jl_array_len(values));
198 : : }
199 [ + + ]: 28184000 : for (i = 0; i < l; i++) {
200 : 18006200 : int32_t e = ((int32_t*)jl_array_data(edges))[i];
201 [ + + ]: 18006200 : if (e <= 20)
202 : 1551720 : jl_encode_value(s, jl_box_int32(e));
203 : : else
204 : 16454500 : jl_encode_int32(s, e);
205 : : }
206 : 10177800 : l = jl_array_len(values);
207 [ + + ]: 28184000 : for (i = 0; i < l; i++) {
208 : 18006200 : jl_encode_value(s, jl_array_ptr_ref(values, i));
209 : : }
210 : : }
211 [ + + ]: 834496000 : else if (jl_is_phicnode(v)) {
212 : 163146 : jl_array_t *values = (jl_array_t*)jl_fieldref_noalloc(v, 0);
213 : 163146 : size_t l = jl_array_len(values);
214 [ + - ]: 163146 : if (l <= 255) {
215 : 163146 : write_uint8(s->s, TAG_PHICNODE);
216 : 163146 : write_uint8(s->s, (uint8_t)l);
217 : : }
218 : : else {
219 : 0 : write_uint8(s->s, TAG_LONG_PHICNODE);
220 : 0 : write_int32(s->s, l);
221 : : }
222 [ + + ]: 358142 : for (i = 0; i < l; i++) {
223 : 194996 : jl_encode_value(s, jl_array_ptr_ref(values, i));
224 : : }
225 : : }
226 [ + + ]: 834333000 : else if (jl_is_gotonode(v)) {
227 : 17033400 : write_uint8(s->s, TAG_GOTONODE);
228 : 17033400 : jl_encode_value(s, jl_get_nth_field(v, 0));
229 : : }
230 [ + + ]: 817300000 : else if (jl_is_gotoifnot(v)) {
231 : 10548500 : write_uint8(s->s, TAG_GOTOIFNOT);
232 : 10548500 : jl_encode_value(s, jl_get_nth_field(v, 0));
233 : 10548500 : jl_encode_value(s, jl_get_nth_field(v, 1));
234 : : }
235 [ + + ]: 806751000 : else if (jl_is_argument(v)) {
236 : 10913700 : write_uint8(s->s, TAG_ARGUMENT);
237 : 10913700 : jl_encode_value(s, jl_get_nth_field(v, 0));
238 : : }
239 [ + + ]: 795837000 : else if (jl_is_returnnode(v)) {
240 : 4737550 : write_uint8(s->s, TAG_RETURNNODE);
241 : 4737550 : jl_encode_value(s, jl_get_nth_field(v, 0));
242 : : }
243 [ + + ]: 791100000 : else if (jl_typeis(v, jl_int64_type)) {
244 : 28608600 : void *data = jl_data_ptr(v);
245 [ + + + + ]: 28608600 : if (*(int64_t*)data >= INT16_MIN && *(int64_t*)data <= INT16_MAX) {
246 : 28548300 : write_uint8(s->s, TAG_SHORTER_INT64);
247 : 28548300 : write_uint16(s->s, (uint16_t)*(int64_t*)data);
248 : : }
249 [ + + + + ]: 60300 : else if (*(int64_t*)data >= S32_MIN && *(int64_t*)data <= S32_MAX) {
250 : 12112 : write_uint8(s->s, TAG_SHORT_INT64);
251 : 12112 : write_int32(s->s, (int32_t)*(int64_t*)data);
252 : : }
253 : : else {
254 : 48188 : write_uint8(s->s, TAG_INT64);
255 : 48188 : write_int64(s->s, *(int64_t*)data);
256 : : }
257 : : }
258 [ + + ]: 762491000 : else if (jl_typeis(v, jl_int32_type)) {
259 : 396374000 : jl_encode_int32(s, *(int32_t*)jl_data_ptr(v));
260 : : }
261 [ + + ]: 366117000 : else if (jl_typeis(v, jl_uint8_type)) {
262 : 749569 : write_uint8(s->s, TAG_UINT8);
263 : 749569 : write_int8(s->s, *(int8_t*)jl_data_ptr(v));
264 : : }
265 [ + + ]: 365367000 : else if (jl_typeis(v, jl_lineinfonode_type)) {
266 : 225930000 : write_uint8(s->s, TAG_LINEINFO);
267 [ + + ]: 1355580000 : for (i = 0; i < jl_datatype_nfields(jl_lineinfonode_type); i++)
268 : 1129650000 : jl_encode_value(s, jl_get_nth_field(v, i));
269 : : }
270 [ + + ]: 139438000 : else if (((jl_datatype_t*)jl_typeof(v))->instance == v) {
271 : 805393 : write_uint8(s->s, TAG_SINGLETON);
272 : 805393 : jl_encode_value(s, jl_typeof(v));
273 : : }
274 [ + + + + ]: 138632000 : else if (as_literal && jl_typeis(v, jl_string_type)) {
275 : 2979 : write_uint8(s->s, TAG_STRING);
276 : 2979 : write_int32(s->s, jl_string_len(v));
277 : 2979 : ios_write(s->s, jl_string_data(v), jl_string_len(v));
278 : : }
279 [ + + + - ]: 147381000 : else if (as_literal && jl_is_array(v)) {
280 : 8751260 : jl_array_t *ar = (jl_array_t*)v;
281 : 8751260 : jl_value_t *et = jl_tparam0(jl_typeof(ar));
282 : 8751260 : int isunion = jl_is_uniontype(et);
283 [ + - + - ]: 8751260 : if (ar->flags.ndims == 1 && ar->elsize <= 0x1f) {
284 : 8751260 : write_uint8(s->s, TAG_ARRAY1D);
285 : 8751260 : write_uint8(s->s, (ar->flags.ptrarray << 7) | (ar->flags.hasptr << 6) | (isunion << 5) | (ar->elsize & 0x1f));
286 : : }
287 : : else {
288 : 0 : write_uint8(s->s, TAG_ARRAY);
289 : 0 : write_uint16(s->s, ar->flags.ndims);
290 : 0 : write_uint16(s->s, (ar->flags.ptrarray << 15) | (ar->flags.hasptr << 14) | (isunion << 13) | (ar->elsize & 0x1fff));
291 : : }
292 [ + + ]: 17502500 : for (i = 0; i < ar->flags.ndims; i++)
293 : 8751260 : jl_encode_value(s, jl_box_long(jl_array_dim(ar,i)));
294 : 8751260 : jl_encode_value(s, jl_typeof(ar));
295 : 8751260 : size_t l = jl_array_len(ar);
296 [ + + ]: 8751260 : if (ar->flags.ptrarray) {
297 [ + + ]: 454030000 : for (i = 0; i < l; i++) {
298 : 447483000 : jl_value_t *e = jl_array_ptr_ref(v, i);
299 : 447483000 : jl_encode_value(s, e);
300 : : }
301 : : }
302 [ - + ]: 2205240 : else if (ar->flags.hasptr) {
303 : 0 : const char *data = (const char*)jl_array_data(ar);
304 : 0 : uint16_t elsz = ar->elsize;
305 : 0 : size_t j, np = ((jl_datatype_t*)et)->layout->npointers;
306 [ # # ]: 0 : for (i = 0; i < l; i++) {
307 : 0 : const char *start = data;
308 [ # # ]: 0 : for (j = 0; j < np; j++) {
309 : 0 : uint32_t ptr = jl_ptr_offset((jl_datatype_t*)et, j);
310 : 0 : const jl_value_t *const *fld = &((const jl_value_t *const *)data)[ptr];
311 [ # # ]: 0 : if ((const char*)fld != start)
312 : 0 : ios_write(s->s, start, (const char*)fld - start);
313 : : JL_GC_PROMISE_ROOTED(*fld);
314 : 0 : jl_encode_value(s, *fld);
315 : 0 : start = (const char*)&fld[1];
316 : : }
317 : 0 : data += elsz;
318 [ # # ]: 0 : if (data != start)
319 : 0 : ios_write(s->s, start, data - start);
320 : : }
321 : : }
322 : : else {
323 : 2205240 : ios_write(s->s, (char*)jl_array_data(ar), l * ar->elsize);
324 [ + - - + ]: 2205240 : if (jl_array_isbitsunion(ar))
325 : 0 : ios_write(s->s, jl_array_typetagdata(ar), l);
326 : : }
327 : : }
328 : : else {
329 [ + - + + : 129878000 : if (!as_literal && !(jl_is_uniontype(v) || jl_is_newvarnode(v) || jl_is_tuple(v) ||
+ + + + ]
330 [ + - + + : 128965000 : jl_is_linenode(v) || jl_is_upsilonnode(v) || jl_is_pinode(v) ||
+ + ]
331 [ + - + - : 128259000 : jl_is_slot(v) || jl_is_ssavalue(v))) {
+ - ]
332 : 128259000 : literal_val_id(&rr, s, v);
333 : 128259000 : int id = rr.index;
334 [ - + ]: 128259000 : assert(id >= 0);
335 [ + + ]: 128259000 : if (rr.key) {
336 : 1354300 : write_uint8(s->s, TAG_RELOC_METHODROOT);
337 : 1354300 : write_int64(s->s, rr.key);
338 : : }
339 [ + + ]: 128259000 : if (id < 256) {
340 : 112072000 : write_uint8(s->s, TAG_METHODROOT);
341 : 112072000 : write_uint8(s->s, id);
342 : : }
343 : : else {
344 [ - + ]: 16186700 : assert(id <= UINT16_MAX);
345 : 16186700 : write_uint8(s->s, TAG_LONG_METHODROOT);
346 : 16186700 : write_uint16(s->s, id);
347 : : }
348 : 128259000 : return;
349 : : }
350 : 1619500 : jl_datatype_t *t = (jl_datatype_t*)jl_typeof(v);
351 [ + - ]: 1619500 : if (t->size <= 255) {
352 : 1619500 : write_uint8(s->s, TAG_SHORT_GENERAL);
353 : 1619500 : write_uint8(s->s, t->size);
354 : : }
355 : : else {
356 : 0 : write_uint8(s->s, TAG_GENERAL);
357 : 0 : write_int32(s->s, t->size);
358 : : }
359 : 1619500 : jl_encode_value(s, t);
360 : :
361 : 1619500 : char *data = (char*)jl_data_ptr(v);
362 : 1619500 : size_t i, j, np = t->layout->npointers;
363 : 1619500 : uint32_t nf = t->layout->nfields;
364 : 1619500 : char *last = data;
365 [ + - ]: 4601740 : for (i = 0, j = 0; i < nf+1; i++) {
366 [ + + ]: 4601740 : char *ptr = data + (i < nf ? jl_field_offset(t, i) : jl_datatype_size(t));
367 [ + + ]: 4601740 : if (j < np) {
368 : 4166220 : char *prevptr = (char*)&((jl_value_t**)data)[jl_ptr_offset(t, j)];
369 [ + + ]: 5423450 : while (ptr > prevptr) {
370 : : // previous field contained pointers; write them and their interleaved data
371 [ + + ]: 2711660 : if (prevptr > last)
372 : 33 : ios_write(s->s, last, prevptr - last);
373 : 2711660 : jl_value_t *e = *(jl_value_t**)prevptr;
374 : : JL_GC_PROMISE_ROOTED(e);
375 : 2711660 : jl_encode_value(s, e);
376 : 2711660 : last = prevptr + sizeof(jl_value_t*);
377 : 2711660 : j++;
378 [ + + ]: 2711660 : if (j < np)
379 : 1257230 : prevptr = (char*)&((jl_value_t**)data)[jl_ptr_offset(t, j)];
380 : : else
381 : 1454430 : break;
382 : : }
383 : : }
384 [ + + ]: 4601740 : if (i == nf)
385 : 1619500 : break;
386 : : }
387 : 1619500 : char *ptr = data + jl_datatype_size(t);
388 [ + + ]: 1619500 : if (ptr > last)
389 : 165149 : ios_write(s->s, last, ptr - last);
390 : : }
391 : : }
392 : :
393 : 2205240 : static jl_code_info_flags_t code_info_flags(uint8_t pure, uint8_t propagate_inbounds, uint8_t inlineable, uint8_t inferred, uint8_t constprop)
394 : : {
395 : : jl_code_info_flags_t flags;
396 : 2205240 : flags.bits.pure = pure;
397 : 2205240 : flags.bits.propagate_inbounds = propagate_inbounds;
398 : 2205240 : flags.bits.inlineable = inlineable;
399 : 2205240 : flags.bits.inferred = inferred;
400 : 2205240 : flags.bits.constprop = constprop;
401 : 2205240 : return flags;
402 : : }
403 : :
404 : : // --- decoding ---
405 : :
406 : : static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED;
407 : :
408 : 1421090 : static jl_value_t *jl_decode_value_svec(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED
409 : : {
410 : : size_t i, len;
411 [ + - ]: 1421090 : if (tag == TAG_SVEC)
412 : 1421090 : len = read_uint8(s->s);
413 : : else
414 : 0 : len = read_int32(s->s);
415 : 1421090 : jl_svec_t *sv = jl_alloc_svec_uninit(len);
416 : 1421090 : jl_value_t **data = jl_svec_data(sv);
417 [ + + ]: 3721400 : for (i = 0; i < len; i++) {
418 : 2300300 : data[i] = jl_decode_value(s);
419 : : }
420 : 1421090 : return (jl_value_t*)sv;
421 : : }
422 : :
423 : 51143300 : static jl_value_t *jl_decode_value_array(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED
424 : : {
425 : : int16_t i, ndims;
426 : : int isptr, isunion, hasptr, elsize;
427 [ + - ]: 51143300 : if (tag == TAG_ARRAY1D) {
428 : 51143300 : ndims = 1;
429 : 51143300 : elsize = read_uint8(s->s);
430 : 51143300 : isptr = (elsize >> 7) & 1;
431 : 51143300 : hasptr = (elsize >> 6) & 1;
432 : 51143300 : isunion = (elsize >> 5) & 1;
433 : 51143300 : elsize = elsize & 0x1f;
434 : : }
435 : : else {
436 : 0 : ndims = read_uint16(s->s);
437 : 0 : elsize = read_uint16(s->s);
438 : 0 : isptr = (elsize >> 15) & 1;
439 : 0 : hasptr = (elsize >> 14) & 1;
440 : 0 : isunion = (elsize >> 13) & 1;
441 : 0 : elsize = elsize & 0x1fff;
442 : : }
443 : 51143300 : size_t *dims = (size_t*)alloca(ndims * sizeof(size_t));
444 [ + + ]: 102287000 : for (i = 0; i < ndims; i++) {
445 : 51143300 : dims[i] = jl_unbox_long(jl_decode_value(s));
446 : : }
447 : 51143300 : jl_array_t *a = jl_new_array_for_deserialization(
448 : : (jl_value_t*)NULL, ndims, dims, !isptr, hasptr, isunion, elsize);
449 : 51143300 : jl_value_t *aty = jl_decode_value(s);
450 : 51143300 : jl_set_typeof(a, aty);
451 [ + + ]: 51143300 : if (a->flags.ptrarray) {
452 : 36825200 : jl_value_t **data = (jl_value_t**)jl_array_data(a);
453 : 36825200 : size_t i, numel = jl_array_len(a);
454 [ + + ]: 550910000 : for (i = 0; i < numel; i++) {
455 : 514085000 : data[i] = jl_decode_value(s);
456 : : }
457 [ - + ]: 36825200 : assert(jl_astaggedvalue(a)->bits.gc == GC_CLEAN); // gc is disabled
458 : : }
459 [ - + ]: 14318000 : else if (a->flags.hasptr) {
460 : 0 : size_t i, numel = jl_array_len(a);
461 : 0 : char *data = (char*)jl_array_data(a);
462 : 0 : uint16_t elsz = a->elsize;
463 : 0 : jl_datatype_t *et = (jl_datatype_t*)jl_tparam0(jl_typeof(a));
464 : 0 : size_t j, np = et->layout->npointers;
465 [ # # ]: 0 : for (i = 0; i < numel; i++) {
466 : 0 : char *start = data;
467 [ # # ]: 0 : for (j = 0; j < np; j++) {
468 : 0 : uint32_t ptr = jl_ptr_offset(et, j);
469 : 0 : jl_value_t **fld = &((jl_value_t**)data)[ptr];
470 [ # # ]: 0 : if ((char*)fld != start)
471 : 0 : ios_readall(s->s, start, (const char*)fld - start);
472 : 0 : *fld = jl_decode_value(s);
473 : 0 : start = (char*)&fld[1];
474 : : }
475 : 0 : data += elsz;
476 [ # # ]: 0 : if (data != start)
477 : 0 : ios_readall(s->s, start, data - start);
478 : : }
479 [ # # ]: 0 : assert(jl_astaggedvalue(a)->bits.gc == GC_CLEAN); // gc is disabled
480 : : }
481 : : else {
482 [ + - - + ]: 14318000 : size_t extra = jl_array_isbitsunion(a) ? jl_array_len(a) : 0;
483 : 14318000 : size_t tot = jl_array_len(a) * a->elsize + extra;
484 : 14318000 : ios_readall(s->s, (char*)jl_array_data(a), tot);
485 : : }
486 : 51143300 : return (jl_value_t*)a;
487 : : }
488 : :
489 : 109123000 : static jl_value_t *jl_decode_value_expr(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED
490 : : {
491 : : size_t i, len;
492 : 109123000 : jl_sym_t *head = NULL;
493 [ + + ]: 109123000 : if (tag == TAG_EXPR) {
494 : 31192800 : len = read_uint8(s->s);
495 : : }
496 [ + + ]: 77930600 : else if (tag == TAG_CALL1) {
497 : 13165500 : len = 2;
498 : 13165500 : head = jl_call_sym;
499 : : }
500 [ + - ]: 64765100 : else if (tag == TAG_CALL2) {
501 : 64765100 : len = 3;
502 : 64765100 : head = jl_call_sym;
503 : : }
504 : : else {
505 : 0 : len = read_int32(s->s);
506 : : }
507 [ + + ]: 109123000 : if (head == NULL)
508 : 31192800 : head = (jl_sym_t*)jl_decode_value(s);
509 : 109123000 : jl_expr_t *e = jl_exprn(head, len);
510 : 109123000 : jl_value_t **data = (jl_value_t**)(e->args->data);
511 [ + + ]: 435297000 : for (i = 0; i < len; i++) {
512 : 326173000 : data[i] = jl_decode_value(s);
513 : : }
514 : 109123000 : return (jl_value_t*)e;
515 : : }
516 : :
517 : 6840960 : static jl_value_t *jl_decode_value_phi(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED
518 : : {
519 : : size_t i, len_e, len_v;
520 [ + - ]: 6840960 : if (tag == TAG_PHINODE) {
521 : 6840960 : len_e = len_v = read_uint8(s->s);
522 : : }
523 : : else {
524 : 0 : len_e = read_int32(s->s);
525 : 0 : len_v = read_int32(s->s);
526 : : }
527 : 6840960 : jl_array_t *e = jl_alloc_array_1d(jl_array_int32_type, len_e);
528 : 6840960 : jl_array_t *v = jl_alloc_vec_any(len_v);
529 : 6840960 : jl_value_t *phi = jl_new_struct(jl_phinode_type, e, v);
530 : 6840960 : int32_t *data_e = (int32_t*)(e->data);
531 [ + + ]: 19257100 : for (i = 0; i < len_e; i++) {
532 : 12416100 : data_e[i] = jl_unbox_int32(jl_decode_value(s));
533 : : }
534 : 6840960 : jl_value_t **data_v = (jl_value_t**)(v->data);
535 [ + + ]: 19257100 : for (i = 0; i < len_v; i++) {
536 : 12416100 : data_v[i] = jl_decode_value(s);
537 : : }
538 : 6840960 : return phi;
539 : : }
540 : :
541 : 61188 : static jl_value_t *jl_decode_value_phic(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED
542 : : {
543 : : size_t i, len;
544 [ + - ]: 61188 : if (tag == TAG_PHICNODE)
545 : 61188 : len = read_uint8(s->s);
546 : : else
547 : 0 : len = read_int32(s->s);
548 : 61188 : jl_array_t *v = jl_alloc_vec_any(len);
549 : 61188 : jl_value_t *phic = jl_new_struct(jl_phicnode_type, v);
550 : 61188 : jl_value_t **data = (jl_value_t**)(v->data);
551 [ + + ]: 135867 : for (i = 0; i < len; i++) {
552 : 74679 : data[i] = jl_decode_value(s);
553 : : }
554 : 61188 : return phic;
555 : : }
556 : :
557 : 49953800 : static jl_value_t *jl_decode_value_globalref(jl_ircode_state *s) JL_GC_DISABLED
558 : : {
559 : 49953800 : jl_value_t *mod = jl_decode_value(s);
560 : 49953800 : jl_value_t *var = jl_decode_value(s);
561 : 49953800 : return jl_module_globalref((jl_module_t*)mod, (jl_sym_t*)var);
562 : : }
563 : :
564 : 2850100 : static jl_value_t *jl_decode_value_any(jl_ircode_state *s, uint8_t tag) JL_GC_DISABLED
565 : : {
566 [ + - ]: 2850100 : int32_t sz = (tag == TAG_SHORT_GENERAL ? read_uint8(s->s) : read_int32(s->s));
567 : 2850100 : jl_value_t *v = jl_gc_alloc(s->ptls, sz, NULL);
568 : 2850100 : jl_set_typeof(v, (void*)(intptr_t)0x50);
569 : 2850100 : jl_datatype_t *dt = (jl_datatype_t*)jl_decode_value(s);
570 : 2850100 : jl_set_typeof(v, dt);
571 : 2850100 : char *data = (char*)jl_data_ptr(v);
572 : 2850100 : size_t i, np = dt->layout->npointers;
573 : 2850100 : char *start = data;
574 [ + + ]: 5013400 : for (i = 0; i < np; i++) {
575 : 2163300 : uint32_t ptr = jl_ptr_offset(dt, i);
576 : 2163300 : jl_value_t **fld = &((jl_value_t**)data)[ptr];
577 [ + + ]: 2163300 : if ((char*)fld != start)
578 : 29 : ios_readall(s->s, start, (const char*)fld - start);
579 : 2163300 : *fld = jl_decode_value(s);
580 : 2163300 : start = (char*)&fld[1];
581 : : }
582 : 2850100 : data += jl_datatype_size(dt);
583 [ + + ]: 2850100 : if (data != start)
584 : 1730780 : ios_readall(s->s, start, data - start);
585 : 2850100 : return v;
586 : : }
587 : :
588 : 2496800000 : static jl_value_t *jl_decode_value(jl_ircode_state *s) JL_GC_DISABLED
589 : : {
590 [ - + ]: 2496800000 : assert(!ios_eof(s->s));
591 : : jl_value_t *v;
592 : : size_t i, n;
593 : : uint64_t key;
594 : 2496800000 : uint8_t tag = read_uint8(s->s);
595 [ + + ]: 2496800000 : if (tag > LAST_TAG)
596 : 812695000 : return jl_deser_tag(tag);
597 [ + + + + : 1684100000 : switch (tag) {
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ ]
598 : 2108850 : case TAG_NULL: return NULL;
599 : 33937800 : case 0:
600 : 33937800 : tag = read_uint8(s->s);
601 : 33937800 : return jl_deser_tag(tag);
602 : 1725010 : case TAG_RELOC_METHODROOT:
603 : 1725010 : key = read_uint64(s->s);
604 : 1725010 : tag = read_uint8(s->s);
605 [ - + - - ]: 1725010 : assert(tag == TAG_METHODROOT || tag == TAG_LONG_METHODROOT);
606 [ + - ]: 1725010 : return lookup_root(s->method, key, tag == TAG_METHODROOT ? read_uint8(s->s) : read_uint16(s->s));
607 : 123940000 : case TAG_METHODROOT:
608 : 123940000 : return lookup_root(s->method, 0, read_uint8(s->s));
609 : 12171400 : case TAG_LONG_METHODROOT:
610 : 12171400 : return lookup_root(s->method, 0, read_uint16(s->s));
611 : 1421090 : case TAG_SVEC: JL_FALLTHROUGH; case TAG_LONG_SVEC:
612 : 1421090 : return jl_decode_value_svec(s, tag);
613 : 86026800 : case TAG_COMMONSYM:
614 : 86026800 : return jl_deser_symbol(read_uint8(s->s));
615 : 110916000 : case TAG_SSAVALUE:
616 : 110916000 : v = jl_box_ssavalue(read_uint8(s->s));
617 : 110916000 : return v;
618 : 16541400 : case TAG_LONG_SSAVALUE:
619 : 16541400 : v = jl_box_ssavalue(read_uint16(s->s));
620 : 16541400 : return v;
621 : 37953900 : case TAG_SLOTNUMBER:
622 : 37953900 : v = jl_box_slotnumber(read_uint16(s->s));
623 : 37953900 : return v;
624 : 51143300 : case TAG_ARRAY: JL_FALLTHROUGH; case TAG_ARRAY1D:
625 : 51143300 : return jl_decode_value_array(s, tag);
626 : 109123000 : case TAG_EXPR: JL_FALLTHROUGH;
627 : : case TAG_LONG_EXPR: JL_FALLTHROUGH;
628 : : case TAG_CALL1: JL_FALLTHROUGH;
629 : : case TAG_CALL2:
630 : 109123000 : return jl_decode_value_expr(s, tag);
631 : 6840960 : case TAG_PHINODE: JL_FALLTHROUGH; case TAG_LONG_PHINODE:
632 : 6840960 : return jl_decode_value_phi(s, tag);
633 : 61188 : case TAG_PHICNODE: JL_FALLTHROUGH; case TAG_LONG_PHICNODE:
634 : 61188 : return jl_decode_value_phic(s, tag);
635 : 15366500 : case TAG_GOTONODE: JL_FALLTHROUGH; case TAG_QUOTENODE:
636 [ + - ]: 15366500 : v = jl_new_struct_uninit(tag == TAG_GOTONODE ? jl_gotonode_type : jl_quotenode_type);
637 [ + - ]: 15366500 : set_nth_field(tag == TAG_GOTONODE ? jl_gotonode_type : jl_quotenode_type, v, 0, jl_decode_value(s), 0);
638 : 15366500 : return v;
639 : 12734100 : case TAG_GOTOIFNOT:
640 : 12734100 : v = jl_new_struct_uninit(jl_gotoifnot_type);
641 : 12734100 : set_nth_field(jl_gotoifnot_type, v, 0, jl_decode_value(s), 0);
642 : 12734100 : set_nth_field(jl_gotoifnot_type, v, 1, jl_decode_value(s), 0);
643 : 12734100 : return v;
644 : 23098000 : case TAG_ARGUMENT:
645 : 23098000 : v = jl_new_struct_uninit(jl_argument_type);
646 : 23098000 : set_nth_field(jl_argument_type, v, 0, jl_decode_value(s), 0);
647 : 23098000 : return v;
648 : 18299100 : case TAG_RETURNNODE:
649 : 18299100 : v = jl_new_struct_uninit(jl_returnnode_type);
650 : 18299100 : set_nth_field(jl_returnnode_type, v, 0, jl_decode_value(s), 0);
651 : 18299100 : return v;
652 : 28444000 : case TAG_SHORTER_INT64:
653 : 28444000 : v = jl_box_int64((int16_t)read_uint16(s->s));
654 : 28444000 : return v;
655 : 12564 : case TAG_SHORT_INT64:
656 : 12564 : v = jl_box_int64(read_int32(s->s));
657 : 12564 : return v;
658 : 50520 : case TAG_INT64:
659 : 50520 : v = jl_box_int64((int64_t)read_uint64(s->s));
660 : 50520 : return v;
661 : 369336000 : case TAG_SHORT_INT32:
662 : 369336000 : v = jl_box_int32((int16_t)read_uint16(s->s));
663 : 369336000 : return v;
664 : 2986 : case TAG_INT32:
665 : 2986 : v = jl_box_int32(read_int32(s->s));
666 : 2986 : return v;
667 : 809061 : case TAG_UINT8:
668 : 809061 : return jl_box_uint8(read_uint8(s->s));
669 : 52339800 : case TAG_NEARBYGLOBAL:
670 [ - + ]: 52339800 : assert(s->method != NULL);
671 : 52339800 : v = jl_decode_value(s);
672 : 52339800 : return jl_module_globalref(s->method->module, (jl_sym_t*)v);
673 : 21472300 : case TAG_NEARBYMODULE:
674 [ - + ]: 21472300 : assert(s->method != NULL);
675 : 21472300 : return (jl_value_t*)s->method->module;
676 : 49953800 : case TAG_GLOBALREF:
677 : 49953800 : return jl_decode_value_globalref(s);
678 : 625400 : case TAG_SINGLETON:
679 : 625400 : return ((jl_datatype_t*)jl_decode_value(s))->instance;
680 : 25093000 : case TAG_CORE:
681 : 25093000 : return (jl_value_t*)jl_core_module;
682 : 226409000 : case TAG_BASE:
683 : 226409000 : return (jl_value_t*)jl_base_module;
684 : 10087200 : case TAG_VECTORTY:
685 : 10087200 : v = jl_decode_value(s);
686 : 10087200 : return jl_apply_type2((jl_value_t*)jl_array_type, v, jl_box_long(1));
687 : 1567850 : case TAG_PTRTY:
688 : 1567850 : v = jl_decode_value(s);
689 : 1567850 : return jl_apply_type1((jl_value_t*)jl_pointer_type, v);
690 : 2398 : case TAG_STRING:
691 : 2398 : n = read_int32(s->s);
692 : 2398 : v = jl_alloc_string(n);
693 : 2398 : ios_readall(s->s, jl_string_data(v), n);
694 : 2398 : return v;
695 : 231634000 : case TAG_LINEINFO:
696 : 231634000 : v = jl_new_struct_uninit(jl_lineinfonode_type);
697 [ + + ]: 1389800000 : for (i = 0; i < jl_datatype_nfields(jl_lineinfonode_type); i++) {
698 : : //size_t offs = jl_field_offset(jl_lineinfonode_type, i);
699 : 1158170000 : set_nth_field(jl_lineinfonode_type, v, i, jl_decode_value(s), 0);
700 : : }
701 : 231634000 : return v;
702 : 2850100 : default:
703 [ + - - + ]: 2850100 : assert(tag == TAG_GENERAL || tag == TAG_SHORT_GENERAL);
704 : 2850100 : return jl_decode_value_any(s, tag);
705 : : }
706 : : }
707 : :
708 : : // --- entry points ---
709 : :
710 : 2205240 : JL_DLLEXPORT jl_array_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code)
711 : : {
712 : : JL_TIMING(AST_COMPRESS);
713 : 2205240 : JL_LOCK(&m->writelock); // protect the roots array (Might GC)
714 [ - + ]: 2205240 : assert(jl_is_method(m));
715 [ - + ]: 2205240 : assert(jl_is_code_info(code));
716 : : ios_t dest;
717 : 2205240 : ios_mem(&dest, 0);
718 : 2205240 : int en = jl_gc_enable(0); // Might GC
719 : : size_t i;
720 : :
721 [ + + ]: 2205240 : if (m->roots == NULL) {
722 : 169727 : m->roots = jl_alloc_vec_any(0);
723 : 169727 : jl_gc_wb(m, m->roots);
724 : : }
725 : 2205240 : jl_ircode_state s = {
726 : : &dest,
727 : : m,
728 : 2205240 : jl_current_task->ptls,
729 : : 1
730 : : };
731 : :
732 : 2205240 : jl_code_info_flags_t flags = code_info_flags(code->pure, code->propagate_inbounds, code->inlineable, code->inferred, code->constprop);
733 : 2205240 : write_uint8(s.s, flags.packed);
734 : 2205240 : write_uint8(s.s, code->purity.bits);
735 : :
736 : 2205240 : size_t nslots = jl_array_len(code->slotflags);
737 [ + - + - ]: 2205240 : assert(nslots >= m->nargs && nslots < INT32_MAX); // required by generated functions
738 : 2205240 : write_int32(s.s, nslots);
739 : 2205240 : ios_write(s.s, (char*)jl_array_data(code->slotflags), nslots);
740 : :
741 : : // N.B.: The layout of everything before this point is explicitly referenced
742 : : // by the various jl_ir_ accessors. Make sure to adjust those if you change
743 : : // the data layout.
744 : :
745 [ + + ]: 15436700 : for (i = 0; i < 6; i++) {
746 : 13231400 : int copy = 1;
747 [ + + ]: 13231400 : if (i == 1) { // skip codelocs
748 [ - + ]: 2205240 : assert(jl_field_offset(jl_code_info_type, i) == offsetof(jl_code_info_t, codelocs));
749 : 2205240 : continue;
750 : : }
751 [ + + ]: 11026200 : if (i == 4) { // don't copy contents of method_for_inference_limit_heuristics field
752 [ - + ]: 2205240 : assert(jl_field_offset(jl_code_info_type, i) == offsetof(jl_code_info_t, method_for_inference_limit_heuristics));
753 : 2205240 : copy = 0;
754 : : }
755 : 11026200 : jl_encode_value_(&s, jl_get_nth_field((jl_value_t*)code, i), copy);
756 : : }
757 : :
758 : : // For opaque closure, also save the slottypes. We technically only need the first slot type,
759 : : // but this is simpler for now. We may want to refactor where this gets stored in the future.
760 [ + + ]: 2205240 : if (m->is_for_opaque_closure)
761 : 97 : jl_encode_value_(&s, code->slottypes, 1);
762 : :
763 [ + + ]: 2205240 : if (m->generator)
764 : : // can't optimize generated functions
765 : 2979 : jl_encode_value_(&s, (jl_value_t*)jl_compress_argnames(code->slotnames), 1);
766 : : else
767 : 2202260 : jl_encode_value(&s, jl_nothing);
768 : :
769 : 2205240 : size_t nstmt = jl_array_len(code->code);
770 [ - + ]: 2205240 : assert(nstmt == jl_array_len(code->codelocs));
771 [ + + ]: 2205240 : if (jl_array_len(code->linetable) < 256) {
772 [ + + ]: 40179800 : for (i = 0; i < nstmt; i++) {
773 : 38169700 : write_uint8(s.s, ((int32_t*)jl_array_data(code->codelocs))[i]);
774 : : }
775 : : }
776 [ + - ]: 195069 : else if (jl_array_len(code->linetable) < 65536) {
777 [ + + ]: 73236100 : for (i = 0; i < nstmt; i++) {
778 : 73041100 : write_uint16(s.s, ((int32_t*)jl_array_data(code->codelocs))[i]);
779 : : }
780 : : }
781 : : else {
782 : 0 : ios_write(s.s, (char*)jl_array_data(code->codelocs), nstmt * sizeof(int32_t));
783 : : }
784 : :
785 : 2205240 : write_uint8(s.s, s.relocatability);
786 : :
787 : 2205240 : ios_flush(s.s);
788 : 2205240 : jl_array_t *v = jl_take_buffer(&dest);
789 : 2205240 : ios_close(s.s);
790 [ + + ]: 2205240 : if (jl_array_len(m->roots) == 0) {
791 : 99501 : m->roots = NULL;
792 : : }
793 : 2205240 : JL_GC_PUSH1(&v);
794 : 2205240 : jl_gc_enable(en);
795 : 2205240 : JL_UNLOCK(&m->writelock); // Might GC
796 : 2205240 : JL_GC_POP();
797 : 2205240 : return v;
798 : : }
799 : :
800 : 14581600 : JL_DLLEXPORT jl_code_info_t *jl_uncompress_ir(jl_method_t *m, jl_code_instance_t *metadata, jl_array_t *data)
801 : : {
802 [ + + ]: 14581600 : if (jl_is_code_info(data))
803 : 263566 : return (jl_code_info_t*)data;
804 : : JL_TIMING(AST_UNCOMPRESS);
805 : 14318000 : JL_LOCK(&m->writelock); // protect the roots array (Might GC)
806 [ - + ]: 14318000 : assert(jl_is_method(m));
807 [ - + ]: 14318000 : assert(jl_typeis(data, jl_array_uint8_type));
808 : : size_t i;
809 : : ios_t src;
810 : 14318000 : ios_mem(&src, 0);
811 : 14318000 : ios_setbuf(&src, (char*)data->data, jl_array_len(data), 0);
812 : 14318000 : src.size = jl_array_len(data);
813 : 14318000 : int en = jl_gc_enable(0); // Might GC
814 : 14318000 : jl_ircode_state s = {
815 : : &src,
816 : : m,
817 : 14318000 : jl_current_task->ptls,
818 : : 1
819 : : };
820 : :
821 : 14318000 : jl_code_info_t *code = jl_new_code_info_uninit();
822 : : jl_code_info_flags_t flags;
823 : 14318000 : flags.packed = read_uint8(s.s);
824 : 14318000 : code->constprop = flags.bits.constprop;
825 : 14318000 : code->inferred = flags.bits.inferred;
826 : 14318000 : code->inlineable = flags.bits.inlineable;
827 : 14318000 : code->propagate_inbounds = flags.bits.propagate_inbounds;
828 : 14318000 : code->pure = flags.bits.pure;
829 : 14318000 : code->purity.bits = read_uint8(s.s);
830 : :
831 : 14318000 : size_t nslots = read_int32(&src);
832 : 14318000 : code->slotflags = jl_alloc_array_1d(jl_array_uint8_type, nslots);
833 : 14318000 : ios_readall(s.s, (char*)jl_array_data(code->slotflags), nslots);
834 : :
835 [ + + ]: 100226000 : for (i = 0; i < 6; i++) {
836 [ + + ]: 85908300 : if (i == 1) // skip codelocs
837 : 14318000 : continue;
838 [ - + ]: 71590200 : assert(jl_field_isptr(jl_code_info_type, i));
839 : 71590200 : jl_value_t **fld = (jl_value_t**)((char*)jl_data_ptr(code) + jl_field_offset(jl_code_info_type, i));
840 : 71590200 : *fld = jl_decode_value(&s);
841 : : }
842 [ + + ]: 14318000 : if (m->is_for_opaque_closure)
843 : 76 : code->slottypes = jl_decode_value(&s);
844 : :
845 : 14318000 : jl_value_t *slotnames = jl_decode_value(&s);
846 [ + + ]: 14318000 : if (!jl_is_string(slotnames))
847 : 14315600 : slotnames = m->slot_syms;
848 : 14318000 : code->slotnames = jl_uncompress_argnames(slotnames);
849 : :
850 : 14318000 : size_t nstmt = jl_array_len(code->code);
851 : 14318000 : code->codelocs = (jl_value_t*)jl_alloc_array_1d(jl_array_int32_type, nstmt);
852 [ + + ]: 14318000 : if (jl_array_len(code->linetable) < 256) {
853 [ + + ]: 140849000 : for (i = 0; i < nstmt; i++) {
854 : 126662000 : ((int32_t*)jl_array_data(code->codelocs))[i] = read_uint8(s.s);
855 : : }
856 : : }
857 [ + - ]: 131272 : else if (jl_array_len(code->linetable) < 65536) {
858 [ + + ]: 42717100 : for (i = 0; i < nstmt; i++) {
859 : 42585800 : ((int32_t*)jl_array_data(code->codelocs))[i] = read_uint16(s.s);
860 : : }
861 : : }
862 : : else {
863 : 0 : ios_readall(s.s, (char*)jl_array_data(code->codelocs), nstmt * sizeof(int32_t));
864 : : }
865 : :
866 : 14318000 : (void) read_uint8(s.s); // relocatability
867 : :
868 [ - + ]: 14318000 : assert(ios_getc(s.s) == -1);
869 : 14318000 : ios_close(s.s);
870 : 14318000 : JL_GC_PUSH1(&code);
871 : 14318000 : jl_gc_enable(en);
872 : 14318000 : JL_UNLOCK(&m->writelock); // Might GC
873 : 14318000 : JL_GC_POP();
874 [ + + ]: 14318000 : if (metadata) {
875 : 238464 : code->min_world = metadata->min_world;
876 : 238464 : code->max_world = metadata->max_world;
877 : 238464 : code->rettype = metadata->rettype;
878 : 238464 : code->parent = metadata->def;
879 : : }
880 : 14318000 : return code;
881 : : }
882 : :
883 : 48298700 : JL_DLLEXPORT uint8_t jl_ir_flag_inferred(jl_array_t *data)
884 : : {
885 [ + + ]: 48298700 : if (jl_is_code_info(data))
886 : 5281090 : return ((jl_code_info_t*)data)->inferred;
887 [ - + ]: 43017600 : assert(jl_typeis(data, jl_array_uint8_type));
888 : : jl_code_info_flags_t flags;
889 : 43017600 : flags.packed = ((uint8_t*)data->data)[0];
890 : 43017600 : return flags.bits.inferred;
891 : : }
892 : :
893 : 20040700 : JL_DLLEXPORT uint8_t jl_ir_flag_inlineable(jl_array_t *data)
894 : : {
895 [ + + ]: 20040700 : if (jl_is_code_info(data))
896 : 5280060 : return ((jl_code_info_t*)data)->inlineable;
897 [ - + ]: 14760700 : assert(jl_typeis(data, jl_array_uint8_type));
898 : : jl_code_info_flags_t flags;
899 : 14760700 : flags.packed = ((uint8_t*)data->data)[0];
900 : 14760700 : return flags.bits.inlineable;
901 : : }
902 : :
903 : 0 : JL_DLLEXPORT uint8_t jl_ir_flag_pure(jl_array_t *data)
904 : : {
905 [ # # ]: 0 : if (jl_is_code_info(data))
906 : 0 : return ((jl_code_info_t*)data)->pure;
907 [ # # ]: 0 : assert(jl_typeis(data, jl_array_uint8_type));
908 : : jl_code_info_flags_t flags;
909 : 0 : flags.packed = ((uint8_t*)data->data)[0];
910 : 0 : return flags.bits.pure;
911 : : }
912 : :
913 : 72811 : JL_DLLEXPORT jl_value_t *jl_compress_argnames(jl_array_t *syms)
914 : : {
915 : 72811 : size_t nsyms = jl_array_len(syms);
916 : 72811 : size_t i, len = 0;
917 [ + + ]: 347116 : for (i = 0; i < nsyms; i++) {
918 : 274305 : jl_sym_t *name = (jl_sym_t*)jl_array_ptr_ref(syms, i);
919 [ - + ]: 274305 : assert(jl_is_symbol(name));
920 : 274305 : char *namestr = jl_symbol_name(name);
921 : 274305 : size_t namelen = strlen(namestr) + 1;
922 : 274305 : len += namelen;
923 : : }
924 : 72811 : jl_value_t *str = jl_alloc_string(len);
925 : 72811 : len = 0;
926 [ + + ]: 347116 : for (i = 0; i < nsyms; i++) {
927 : 274305 : jl_sym_t *name = (jl_sym_t*)jl_array_ptr_ref(syms, i);
928 [ - + ]: 274305 : assert(jl_is_symbol(name));
929 : 274305 : char *namestr = jl_symbol_name(name);
930 : 274305 : size_t namelen = strlen(namestr) + 1; // include nul-byte
931 [ - + ]: 274305 : assert(len + namelen <= jl_string_len(str));
932 : 274305 : memcpy(jl_string_data(str) + len, namestr, namelen);
933 : 274305 : len += namelen;
934 : : }
935 [ - + ]: 72811 : assert(len == jl_string_len(str));
936 : 72811 : return str;
937 : : }
938 : :
939 : 2810 : JL_DLLEXPORT ssize_t jl_ir_nslots(jl_array_t *data)
940 : : {
941 [ - + ]: 2810 : if (jl_is_code_info(data)) {
942 : 0 : jl_code_info_t *func = (jl_code_info_t*)data;
943 : 0 : return jl_array_len(func->slotnames);
944 : : }
945 : : else {
946 [ - + ]: 2810 : assert(jl_typeis(data, jl_array_uint8_type));
947 : 2810 : int nslots = jl_load_unaligned_i32((char*)data->data + 2);
948 : 2810 : return nslots;
949 : : }
950 : : }
951 : :
952 : 1414 : JL_DLLEXPORT uint8_t jl_ir_slotflag(jl_array_t *data, size_t i)
953 : : {
954 [ - + ]: 1414 : assert(i < jl_ir_nslots(data));
955 [ - + ]: 1414 : if (jl_is_code_info(data))
956 : 0 : return ((uint8_t*)((jl_code_info_t*)data)->slotflags->data)[i];
957 [ - + ]: 1414 : assert(jl_typeis(data, jl_array_uint8_type));
958 : 1414 : return ((uint8_t*)data->data)[2 + sizeof(int32_t) + i];
959 : : }
960 : :
961 : 14321400 : JL_DLLEXPORT jl_array_t *jl_uncompress_argnames(jl_value_t *syms)
962 : : {
963 [ - + ]: 14321400 : assert(jl_is_string(syms));
964 : : char *namestr;
965 : 14321400 : namestr = jl_string_data(syms);
966 : 14321400 : size_t remaining = jl_string_len(syms);
967 : 14321400 : size_t i, len = 0;
968 [ + + ]: 65217200 : while (remaining) {
969 : 50895800 : size_t namelen = strlen(namestr);
970 : 50895800 : len += 1;
971 : 50895800 : namestr += namelen + 1;
972 : 50895800 : remaining -= namelen + 1;
973 : : }
974 : 14321400 : namestr = jl_string_data(syms);
975 : 14321400 : jl_array_t *names = jl_alloc_array_1d(jl_array_symbol_type, len);
976 : 14321400 : JL_GC_PUSH1(&names);
977 [ + + ]: 65217200 : for (i = 0; i < len; i++) {
978 : 50895800 : size_t namelen = strlen(namestr);
979 : 50895800 : jl_sym_t *name = _jl_symbol(namestr, namelen);
980 : 50895800 : jl_array_ptr_set(names, i, name);
981 : 50895800 : namestr += namelen + 1;
982 : : }
983 : 14321400 : JL_GC_POP();
984 : 14321400 : return names;
985 : : }
986 : :
987 : 0 : JL_DLLEXPORT jl_value_t *jl_uncompress_argname_n(jl_value_t *syms, size_t i)
988 : : {
989 [ # # ]: 0 : assert(jl_is_string(syms));
990 : 0 : char *namestr = jl_string_data(syms);
991 : 0 : size_t remaining = jl_string_len(syms);
992 [ # # ]: 0 : while (remaining) {
993 : 0 : size_t namelen = strlen(namestr);
994 [ # # ]: 0 : if (i-- == 0) {
995 : 0 : jl_sym_t *name = _jl_symbol(namestr, namelen);
996 : 0 : return (jl_value_t*)name;
997 : : }
998 : 0 : namestr += namelen + 1;
999 : 0 : remaining -= namelen + 1;
1000 : : }
1001 : 0 : return jl_nothing;
1002 : : }
1003 : :
1004 : : #ifdef __cplusplus
1005 : : }
1006 : : #endif
|