Coverage Report

Created: 2017-04-15 07:07

/home/travis/build/MoarVM/MoarVM/src/6model/6model.h
Line
Count
Source
1
/* Boolification mode flags. */
2
86.6k
#define MVM_BOOL_MODE_CALL_METHOD                   0
3
743k
#define MVM_BOOL_MODE_UNBOX_INT                     1
4
465
#define MVM_BOOL_MODE_UNBOX_NUM                     2
5
140k
#define MVM_BOOL_MODE_UNBOX_STR_NOT_EMPTY           3
6
3
#define MVM_BOOL_MODE_UNBOX_STR_NOT_EMPTY_OR_ZERO   4
7
1.77M
#define MVM_BOOL_MODE_NOT_TYPE_OBJECT               5
8
2
#define MVM_BOOL_MODE_BIGINT                        6
9
1.61M
#define MVM_BOOL_MODE_ITER                          7
10
1.65M
#define MVM_BOOL_MODE_HAS_ELEMS                     8
11
12
/* Controls the way that type checks are performed. By default, if there is
13
 * a type check cache we treat it as definitive. However, it's possible to
14
 * declare that in the case the type check cache has no entry we should fall
15
 * back to asking the .HOW.type_check method (set TYPE_CHECK_CACHE_THEN_METHOD).
16
 * While a normal type check asks a value if it supports another type, the
17
 * TYPE_CHECK_NEEDS_ACCEPTS flag results in a call to .accepts_type on the
18
 * HOW of the thing we're checking the value against, giving it a chance to
19
 * decide answer. These are set as the lower bits of mode_flags in MVMSTable. */
20
#define MVM_TYPE_CHECK_CACHE_DEFINITIVE    0
21
352k
#define MVM_TYPE_CHECK_CACHE_THEN_METHOD   1
22
690k
#define MVM_TYPE_CHECK_NEEDS_ACCEPTS       2
23
1.18M
#define MVM_TYPE_CHECK_CACHE_FLAG_MASK     3
24
25
/* This STable mode flag is set if we consider the method cache authoritative. */
26
225k
#define MVM_METHOD_CACHE_AUTHORITATIVE     4
27
28
/* This STable mode flag is set if the type needs finalization. */
29
6.32k
#define MVM_FINALIZE_TYPE                  8
30
31
/* This STable mode flag is set if the type is parametric (and so can be
32
 * parameterized). */
33
58.1k
#define MVM_PARAMETRIC_TYPE                 16
34
35
/* This STable mode flag is set if the type is a parameterization of some
36
 * parametric type. */
37
35.5k
#define MVM_PARAMETERIZED_TYPE              32
38
39
/* HLL type roles. */
40
48
#define MVM_HLL_ROLE_NONE                   0
41
131
#define MVM_HLL_ROLE_INT                    1
42
131
#define MVM_HLL_ROLE_NUM                    2
43
131
#define MVM_HLL_ROLE_STR                    3
44
136
#define MVM_HLL_ROLE_ARRAY                  4
45
132
#define MVM_HLL_ROLE_HASH                   5
46
133
#define MVM_HLL_ROLE_CODE                   6
47
48
/* Hint value to indicate the absence of an attribute lookup or method
49
 * dispatch hint. */
50
6.52k
#define MVM_NO_HINT -1
51
52
/* This data structure describes what storage a given representation
53
 * needs if something of that representation is to be embedded in
54
 * another place. For any representation that expects to be used
55
 * as a kind of reference type, it will just want to be a pointer.
56
 * But for other things, they would prefer to be "inlined" into
57
 * the object. */
58
struct MVMStorageSpec {
59
    /* 0 if this is to be referenced, anything else otherwise. */
60
    MVMuint16 inlineable;
61
62
    /* For things that want to be inlined, the number of bits of
63
     * storage they need and what kind of byte-boundary they want to
64
     * be aligned to. Ignored otherwise. */
65
    MVMuint16 bits;
66
    MVMuint16 align;
67
68
    /* For things that are inlined, if they are just storage of a
69
     * primitive type and can unbox, this says what primitive type
70
     * that they unbox to. */
71
    MVMuint16 boxed_primitive;
72
73
    /* The types that this one can box/unbox to. */
74
    MVMuint16 can_box;
75
76
    /* For ints, whether it's an unsigned value. */
77
    MVMuint8 is_unsigned;
78
};
79
80
/* Inlined or not. */
81
290k
#define MVM_STORAGE_SPEC_REFERENCE      0
82
15.2k
#define MVM_STORAGE_SPEC_INLINED        1
83
84
/* Possible options for boxed primitives. */
85
303k
#define MVM_STORAGE_SPEC_BP_NONE        0
86
24.8k
#define MVM_STORAGE_SPEC_BP_INT         1
87
1.23k
#define MVM_STORAGE_SPEC_BP_NUM         2
88
32.7k
#define MVM_STORAGE_SPEC_BP_STR         3
89
90
/* can_box bit field values. */
91
5.28M
#define MVM_STORAGE_SPEC_CAN_BOX_INT    1
92
1.51M
#define MVM_STORAGE_SPEC_CAN_BOX_NUM    2
93
2.16M
#define MVM_STORAGE_SPEC_CAN_BOX_STR    4
94
#define MVM_STORAGE_SPEC_CAN_BOX_MASK   7
95
96
/* Flags that may be set on any collectable. */
97
typedef enum {
98
    /* Is a type object (and thus not a concrete instance). */
99
    MVM_CF_TYPE_OBJECT = 1,
100
101
    /* Is an STable. */
102
    MVM_CF_STABLE = 2,
103
104
    /* Is a heap-promoted call frame. */
105
    MVM_CF_FRAME = 4,
106
107
    /* Has already been seen once in GC nursery. */
108
    MVM_CF_NURSERY_SEEN = 8,
109
110
    /* Has been promoted to the old generation. */
111
    MVM_CF_SECOND_GEN = 16,
112
113
    /* Is shared - that is, more than one thread knows about it. */
114
    MVM_CF_SHARED = 32,
115
116
    /* Has already been added to the gen2 aggregates pointing to nursery
117
     * objects list. */
118
    MVM_CF_IN_GEN2_ROOT_LIST = 64,
119
120
    /* A full GC run has found this object to be live. */
121
    MVM_CF_GEN2_LIVE = 128,
122
123
    /* This object in fromspace is live with a valid forwarder. */
124
    /* TODO - should be possible to use the same bit for this and GEN2_LIVE. */
125
    MVM_CF_FORWARDER_VALID = 256,
126
127
    /* Have we allocated memory to store a serialization index? */
128
    MVM_CF_SERIALZATION_INDEX_ALLOCATED = 512,
129
130
    /* Have we arranged a persistent object ID for this object? */
131
    MVM_CF_HAS_OBJECT_ID = 1024,
132
133
    /* Have we flagged this object as something we must never repossess? */
134
    /* Note: if you're hunting for a flag, some day in the future when we
135
     * have used them all, this one is easy enough to eliminate by having the
136
     * tiny number of objects marked this way in a remembered set. */
137
    MVM_CF_NEVER_REPOSSESS = 2048
138
} MVMCollectableFlags;
139
140
#ifdef MVM_USE_OVERFLOW_SERIALIZATION_INDEX
141
struct MVMSerializationIndex {
142
    MVMuint32 sc_idx;
143
    MVMuint32 idx;
144
};
145
#endif
146
147
/* Things that every GC-collectable entity has. These fall into two
148
 * categories:
149
 *   * MVMObject - objects. Almost everything is one of these.
150
 *   * MVMSTable - shared tables; one per (HOW, REPR) pairing.
151
 * Only the first can vary in size, and even then only if it's not a
152
 * type object.
153
 */
154
struct MVMCollectable {
155
    /* Put this union first, as these pointers/indexes are relatively "cold",
156
       whereas "flags" is accessed relatively frequently, as are the fields
157
       that follow in the structures into which MVMCollectable is embedded.
158
       Shrinking the size of the active part of the structure slightly
159
       increases the chance that it fits into the CPU's L1 cache, which is a
160
       "free" performance win. */
161
    union {
162
        /* Forwarding pointer, for copying/compacting GC purposes. */
163
        MVMCollectable *forwarder;
164
        /* Index of the serialization context this collectable lives in, if
165
         * any, and then location within that. */
166
#ifdef MVM_USE_OVERFLOW_SERIALIZATION_INDEX
167
        struct {
168
            MVMuint16 sc_idx;
169
            MVMuint16 idx;
170
        } sc;
171
        struct MVMSerializationIndex *sci;
172
#else
173
        struct {
174
            MVMuint32 sc_idx;
175
            MVMuint32 idx;
176
        } sc;
177
#endif
178
        /* Used to chain STables queued to be freed. */
179
        MVMSTable *st;
180
    } sc_forward_u;
181
182
    /* Identifier of the thread that currently owns the object, if any. If the
183
     * object is unshared, then this is always the creating thread. If it is
184
     * shared then it's whoever currently holds the mutex on it, or 0 if there
185
     * is no held mutex. */
186
    MVMuint32 owner;
187
188
    /* Collectable flags (see MVMCollectableFlags). */
189
    MVMuint16 flags;
190
191
    /* Object size, in bytes. */
192
    MVMuint16 size;
193
};
194
#ifdef MVM_USE_OVERFLOW_SERIALIZATION_INDEX
195
#  define MVM_DIRECT_SC_IDX_SENTINEL 0xFFFF
196
#else
197
1.17M
#  define MVM_DIRECT_SC_IDX_SENTINEL ~0
198
#endif
199
200
/* The common things every object has.
201
 *
202
 * NB - the assumption that MVMObject* can be safely cast into
203
 * MVMCollectable* is spread throughout the codebase, as well
204
 * as used directly in JIT. Thus, nothing may preceed the header!
205
 */
206
struct MVMObject {
207
    /* Commonalities that all collectable entities have. */
208
    MVMCollectable header;
209
210
    /* The s-table for the object. */
211
    MVMSTable *st;
212
};
213
214
/* An dummy object, mostly used to compute the offset of the data part of
215
 * a 6model object. */
216
struct MVMObjectStooge {
217
    MVMObject common;
218
    void *data;
219
};
220
221
/* This is used to identify an attribute for various types of cache. */
222
struct MVMAttributeIdentifier {
223
    MVMObject         *class_handle;   /* Class handle */
224
    MVMString         *attr_name;      /* Name of the attribute. */
225
    MVMint64           hint;           /* Hint for use in static/gradual typing. */
226
};
227
228
/* How do we turn something of this type into a boolean? */
229
struct MVMBoolificationSpec {
230
    MVMObject *method;
231
    MVMuint32  mode;
232
};
233
234
/* Constant for incrementing the type cache ID for new STables. This leaves
235
 * the lowest bits free for caches to attach flags (of note, the multi
236
 * dispatch cache). */
237
752k
#define MVM_TYPE_CACHE_ID_INCR 256
238
239
/* S-table, representing a meta-object/representation pairing. Note that the
240
 * items are grouped in hope that it will pack decently and do decently in
241
 * terms of cache lines. */
242
struct MVMSTable {
243
    /* Commonalities that all collectable entities have. */
244
    MVMCollectable header;
245
246
    /* The representation operation table. */
247
    const MVMREPROps *REPR;
248
249
    /* Any data specific to this type that the REPR wants to keep. */
250
    void *REPR_data;
251
252
    /* The size of an object of this type in bytes, including the
253
     * header. */
254
    MVMuint32 size;
255
256
    /* The length of the type check cache. */
257
    MVMuint16 type_check_cache_length;
258
259
    /* The type checking mode and method cache mode (see flags for this
260
     * above). */
261
    MVMuint16 mode_flags;
262
263
    /* Array of type objects. If this is set, then it is expected to contain
264
     * the type objects of all types that this type is equivalent to (e.g.
265
     * all the things it isa and all the things it does). */
266
    MVMObject **type_check_cache;
267
268
    /* By-name method dispatch cache. */
269
    MVMObject *method_cache;
270
271
    /* An ID solely for use in caches that last a VM instance. Thus it
272
     * should never, ever be serialized and you should NEVER make a
273
     * type directory based upon this ID. Otherwise you'll create memory
274
     * leaks for anonymous types, and other such screwups. */
275
    MVMuint64 type_cache_id;
276
277
    /* If this is a container, then this contains information needed in
278
     * order to fetch the value in it. If not, it'll be null, which can
279
     * be taken as a "not a container" indication. */
280
    const MVMContainerSpec *container_spec;
281
282
    /* Data that the container spec may need to function. */
283
    /* Any data specific to this type that the REPR wants to keep. */
284
    void *container_data;
285
286
    /* Information - if any - about how we can turn something of this type
287
     * into a boolean. */
288
    MVMBoolificationSpec *boolification_spec;
289
    
290
    /* The HLL that this type is owned by, if any. */
291
    MVMHLLConfig *hll_owner;
292
    
293
    /* The role that the type plays in the HLL, if any. */
294
    MVMint64 hll_role;
295
296
    /* Invocation handler. If something tries to invoke this object,
297
     * whatever hangs off this function pointer gets invoked to handle
298
     * the invocation. If it's a call into C code it may do stuff right
299
     * off the bat. However, normally it will do whatever is needed to
300
     * arrange for setting up a callframe, twiddle the interpreter's
301
     * PC as needed and return. */
302
    void (*invoke) (MVMThreadContext *tc, MVMObject *invokee,
303
        MVMCallsite *callsite, MVMRegister *args);
304
305
    /*
306
     * If this is invokable, then this contains information needed to
307
     * figure out how to invoke it. If not, it'll be null.
308
     */
309
    MVMInvocationSpec *invocation_spec;
310
311
    /* The type-object. */
312
    MVMObject *WHAT;
313
314
    /* The underlying package stash. */
315
    MVMObject *WHO;
316
317
    /* The meta-object. */
318
    MVMObject *HOW;
319
320
    /* Parametricity. Mode flags indicate what, if any, of this union is valid. */
321
    union {
322
        struct {
323
            /* The code object to use to produce a new parameterization. */
324
            MVMObject *parameterizer;
325
326
            /* Lookup table of existing parameterizations. For now, just a VM
327
             * array with alternating pairs of [arg array], object. Could in
328
             * the future we something lower level or hashy; we've yet to see
329
             * how hot-path lookups end up being in reality. */
330
            MVMObject *lookup;
331
        } ric;
332
        struct {
333
            /* The type that we are a parameterization of. */
334
            MVMObject *parametric_type;
335
336
            /* Our type parameters. */
337
            MVMObject *parameters;
338
        } erized;
339
    } paramet;
340
341
    /* We lazily deserialize HOW; this is the SC and index if needed. */
342
    MVMSerializationContext *HOW_sc;
343
    MVMuint32                HOW_idx;
344
345
    /* Also info we need to lazily deserialize the method cache. */
346
    MVMuint32                method_cache_offset;
347
    MVMSerializationContext *method_cache_sc;
348
349
    /* A string associated with this STable for debugging purposes.
350
     * Usually the name of the class this belongs to. */
351
    char *debug_name;
352
353
    /* If this STable is currently in the process of being repossessed. Used
354
     * to trigger clearup of memory pre-repossession. */
355
    MVMuint8 being_repossessed;
356
};
357
358
/* The representation operations table. Note that representations are not
359
 * classes - there's no inheritance, so there's no polymorphism. If you know
360
 * a representation statically, you can statically dereference the call to
361
 * the representation op in question. In the dynamic case, you have to go
362
 * following the pointer, however. */
363
struct MVMREPROps_Attribute {
364
    /* Gets the current value for an attribute and places it in the passed
365
     * location (specified as a register). Expects to be passed a kind flag
366
     * that matches the kind of the attribute that is being fetched. */
367
    void (*get_attribute) (MVMThreadContext *tc, MVMSTable *st,
368
        MVMObject *root, void *data, MVMObject *class_handle, MVMString *name,
369
        MVMint64 hint, MVMRegister *result, MVMuint16 kind);
370
371
    /* Binds the given object or value to the specified attribute. The
372
     * kind flag specifies the type of value being passed to be bound.*/
373
    void (*bind_attribute) (MVMThreadContext *tc, MVMSTable *st,
374
        MVMObject *root, void *data, MVMObject *class_handle, MVMString *name,
375
        MVMint64 hint, MVMRegister value, MVMuint16 kind);
376
377
    /* Gets the hint for the given attribute ID. */
378
    MVMint64 (*hint_for) (MVMThreadContext *tc, MVMSTable *st,
379
        MVMObject *class_handle, MVMString *name);
380
381
    /* Checks if an attribute has been initialized. */
382
    MVMint64 (*is_attribute_initialized) (MVMThreadContext *tc, MVMSTable *st,
383
        void *data, MVMObject *class_handle, MVMString *name,
384
        MVMint64 hint);
385
};
386
struct MVMREPROps_Boxing {
387
    /* Used with boxing. Sets an integer value, for representations that
388
     * can hold one. */
389
    void (*set_int) (MVMThreadContext *tc, MVMSTable *st,
390
        MVMObject *root, void *data, MVMint64 value);
391
392
    /* Used with boxing. Gets an integer value, for representations that
393
     * can hold one. */
394
    MVMint64 (*get_int) (MVMThreadContext *tc, MVMSTable *st,
395
        MVMObject *root, void *data);
396
397
    /* Used with boxing. Sets a floating point value, for representations that
398
     * can hold one. */
399
    void (*set_num) (MVMThreadContext *tc, MVMSTable *st,
400
        MVMObject *root, void *data, MVMnum64 value);
401
402
    /* Used with boxing. Gets a floating point value, for representations that
403
     * can hold one. */
404
    MVMnum64 (*get_num) (MVMThreadContext *tc, MVMSTable *st,
405
        MVMObject *root, void *data);
406
407
    /* Used with boxing. Sets a string value, for representations that
408
     * can hold one. */
409
    void (*set_str) (MVMThreadContext *tc, MVMSTable *st,
410
        MVMObject *root, void *data, MVMString *value);
411
412
    /* Used with boxing. Gets a string value, for representations that
413
     * can hold one. */
414
    MVMString * (*get_str) (MVMThreadContext *tc, MVMSTable *st,
415
        MVMObject *root, void *data);
416
417
    /* Used with boxing. Sets an unsinged integer value, for representations
418
     *  that can hold one. */
419
    void (*set_uint) (MVMThreadContext *tc, MVMSTable *st,
420
        MVMObject *root, void *data, MVMuint64 value);
421
422
    /* Used with boxing. Gets an unsigned integer value, for representations
423
     * that can hold one. */
424
    MVMuint64 (*get_uint) (MVMThreadContext *tc, MVMSTable *st,
425
        MVMObject *root, void *data);
426
427
    /* Some objects serve primarily as boxes of others, inlining them. This gets
428
     * gets the reference to such things, using the representation ID to distinguish
429
     * them. */
430
    void * (*get_boxed_ref) (MVMThreadContext *tc, MVMSTable *st,
431
        MVMObject *root, void *data, MVMuint32 repr_id);
432
};
433
struct MVMREPROps_Positional {
434
    /* Gets the element and the specified index and places it in the passed
435
     * location (specified as a register). Expects to be passed a kind flag
436
     * that matches the kind of the attribute that is being fetched. */
437
    void (*at_pos) (MVMThreadContext *tc, MVMSTable *st,
438
        MVMObject *root, void *data, MVMint64 index,
439
        MVMRegister *result, MVMuint16 kind);
440
441
    /* Binds the given object or value to the specified index. The
442
     * kind flag specifies the type of value being passed to be bound.*/
443
    void (*bind_pos) (MVMThreadContext *tc, MVMSTable *st,
444
        MVMObject *root, void *data, MVMint64 index,
445
        MVMRegister value, MVMuint16 kind);
446
447
    /* Sets the element count of the array, expanding or shrinking
448
     * it as needed. */
449
    void (*set_elems) (MVMThreadContext *tc, MVMSTable *st,
450
        MVMObject *root, void *data, MVMuint64 count);
451
452
    /* Pushes the specified value onto the array. */
453
    void (*push) (MVMThreadContext *tc, MVMSTable *st,
454
        MVMObject *root, void *data, MVMRegister value, MVMuint16 kind);
455
456
    /* Pops the value at the end of the array off it. */
457
    void (*pop) (MVMThreadContext *tc, MVMSTable *st,
458
        MVMObject *root, void *data, MVMRegister *value, MVMuint16 kind);
459
460
    /* Unshifts the value onto the array. */
461
    void (*unshift) (MVMThreadContext *tc, MVMSTable *st,
462
        MVMObject *root, void *data, MVMRegister value, MVMuint16 kind);
463
464
    /* Gets the value at the start of the array, and moves the starting point of
465
     * the array so that the next element is element zero. */
466
    void (*shift) (MVMThreadContext *tc, MVMSTable *st,
467
        MVMObject *root, void *data, MVMRegister *value, MVMuint16 kind);
468
469
    /* Splices the specified array into this one. Representations may optimize if
470
     * they know the type of the passed array, otherwise they should use the REPR
471
     * API. */
472
    void (*splice) (MVMThreadContext *tc, MVMSTable *st,
473
        MVMObject *root, void *data, MVMObject *target_array,
474
        MVMint64 offset, MVMuint64 elems);
475
476
    /* Multi-dimensional array read. */
477
    void (*at_pos_multidim) (MVMThreadContext *tc, MVMSTable *st,
478
        MVMObject *root, void *data, MVMint64 num_indices,
479
        MVMint64 *indices, MVMRegister *result, MVMuint16 kind);
480
481
    /* Multi-dimensional array write. */
482
    void (*bind_pos_multidim) (MVMThreadContext *tc, MVMSTable *st,
483
        MVMObject *root, void *data, MVMint64 num_indices,
484
        MVMint64 *indices, MVMRegister value, MVMuint16 kind);
485
486
    /* Gets the number of dimensions along with a C-level array of them. The
487
     * second two parameters are "out"s. The caller must not mutate dimensions,
488
     * nor persist it such that it lasts longer than the next VM safepoint. */
489
    void (*dimensions) (MVMThreadContext *tc, MVMSTable *st,
490
        MVMObject *root, void *data, MVMint64 *num_dimensions,
491
        MVMint64 **dimensions);
492
493
    /* Sets the number of dimensions. The caller is responsible for freeing
494
     * the array passed in dimensions. */
495
    void (*set_dimensions) (MVMThreadContext *tc, MVMSTable *st,
496
        MVMObject *root, void *data, MVMint64 num_dimensions,
497
        MVMint64 *dimensions);
498
499
    /* Gets the STable representing the declared element type. */
500
    MVMStorageSpec (*get_elem_storage_spec) (MVMThreadContext *tc, MVMSTable *st);
501
};
502
struct MVMREPROps_Associative {
503
    /* Gets the value at the specified key and places it in the passed
504
     * location (specified as a register). Expects to be passed a kind flag
505
     * that matches the kind of the attribute that is being fetched. */
506
    void (*at_key) (MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data,
507
        MVMObject *key, MVMRegister *result, MVMuint16 kind);
508
509
    /* Binds the object at the specified address into the hash at the specified
510
     * key. */
511
    void (*bind_key) (MVMThreadContext *tc, MVMSTable *st, MVMObject *root,
512
        void *data, MVMObject *key, MVMRegister value, MVMuint16 kind);
513
514
    /* Returns a true value of the key exists, and a false one if not. */
515
    MVMint64 (*exists_key) (MVMThreadContext *tc, MVMSTable *st,
516
        MVMObject *root, void *data, MVMObject *key);
517
518
    /* Deletes the specified key. */
519
    void (*delete_key) (MVMThreadContext *tc, MVMSTable *st,
520
        MVMObject *root, void *data, MVMObject *key);
521
522
    /* Gets the storage spec of the hash value type. */
523
    MVMStorageSpec (*get_value_storage_spec) (MVMThreadContext *tc, MVMSTable *st);
524
};
525
struct MVMREPROps {
526
    /* Creates a new type object of this representation, and
527
     * associates it with the given HOW. Also sets up a new
528
     * representation instance if needed. */
529
    MVMObject * (*type_object_for) (MVMThreadContext *tc, MVMObject *HOW);
530
531
    /* Allocates a new, but uninitialized object, based on the
532
     * specified s-table. */
533
    MVMObject * (*allocate) (MVMThreadContext *tc, MVMSTable *st);
534
535
    /* Used to initialize the body of an object representing the type
536
     * describe by the specified s-table. DATA points to the body. It
537
     * may recursively call initialize for any flattened objects. */
538
    void (*initialize) (MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data);
539
540
    /* For the given type, copies the object data from the source memory
541
     * location to the destination one. Note that it may actually be more
542
     * involved than a straightforward bit of copying; what's important is
543
     * that the representation knows about that. Note that it may have to
544
     * call copy_to recursively on representations of any flattened objects
545
     * within its body. */
546
    void (*copy_to) (MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest);
547
548
    /* Attribute access REPR function table. */
549
    MVMREPROps_Attribute attr_funcs;
550
551
    /* Boxing REPR function table. */
552
    MVMREPROps_Boxing box_funcs;
553
554
    /* Positional indexing REPR function table. */
555
    MVMREPROps_Positional pos_funcs;
556
557
    /* Associative indexing REPR function table. */
558
    MVMREPROps_Associative ass_funcs;
559
560
    /* Gets the number of elements, for any aggregate types. */
561
    MVMuint64 (*elems) (MVMThreadContext *tc, MVMSTable *st,
562
        MVMObject *root, void *data);
563
564
    /* Gets the storage specification for this representation. */
565
    const MVMStorageSpec * (*get_storage_spec) (MVMThreadContext *tc, MVMSTable *st);
566
567
    /* Handles an object changing its type. The representation is responsible
568
     * for doing any changes to the underlying data structure, and may reject
569
     * changes that it's not willing to do (for example, a representation may
570
     * choose to only handle switching to a subclass). It is also left to update
571
     * the S-Table pointer as needed; while in theory this could be factored
572
     * out, the representation probably knows more about timing issues and
573
     * thread safety requirements. */
574
    void (*change_type) (MVMThreadContext *tc, MVMObject *object, MVMObject *new_type);
575
576
    /* Object serialization. Writes the object's body out using the passed
577
     * serialization writer. */
578
    void (*serialize) (MVMThreadContext *tc, MVMSTable *st, void *data, MVMSerializationWriter *writer);
579
580
    /* Object deserialization. Reads the object's body in using the passed
581
     * serialization reader. */
582
    void (*deserialize) (MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMSerializationReader *reader);
583
584
    /* REPR data serialization. Serializes the per-type representation data that
585
     * is attached to the supplied STable. */
586
    void (*serialize_repr_data) (MVMThreadContext *tc, MVMSTable *st, MVMSerializationWriter *writer);
587
588
    /* REPR data deserialization. Deserializes the per-type representation data and
589
     * attaches it to the supplied STable. */
590
    void (*deserialize_repr_data) (MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader);
591
592
    /* Deserialization of STable size. */
593
    void (*deserialize_stable_size) (MVMThreadContext *tc, MVMSTable *st, MVMSerializationReader *reader);
594
595
    /* MoarVM-specific REPR API addition used to mark an object. This involves
596
     * adding all pointers it contains to the worklist. */
597
    void (*gc_mark) (MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorklist *worklist);
598
599
    /* MoarVM-specific REPR API addition used to free an object. */
600
    void (*gc_free) (MVMThreadContext *tc, MVMObject *object);
601
602
    /* This is called to do any cleanup of resources when an object gets
603
     * embedded inside another one. Never called on a top-level object. */
604
    void (*gc_cleanup) (MVMThreadContext *tc, MVMSTable *st, void *data);
605
606
    /* MoarVM-specific REPR API addition used to mark a REPR instance. */
607
    void (*gc_mark_repr_data) (MVMThreadContext *tc, MVMSTable *st, MVMGCWorklist *worklist);
608
609
    /* MoarVM-specific REPR API addition used to free a REPR instance. */
610
    void (*gc_free_repr_data) (MVMThreadContext *tc, MVMSTable *st);
611
612
    /* Causes the representation to be composed. Composition involves
613
     * passing the representation information that it needs in order
614
     * to compute memory layout. */
615
    void (*compose) (MVMThreadContext *tc, MVMSTable *st, MVMObject *info);
616
617
    /* Allows the REPR to produce specialized bytecode versions of various
618
     * instructions, when we know some of the types involved. */
619
    void (*spesh) (MVMThreadContext *tc, MVMSTable *st, MVMSpeshGraph *g,
620
        MVMSpeshBB *bb, MVMSpeshIns *ins);
621
622
    /* The representation's name. */
623
    const char *name;
624
625
    /* The representation's ID. */
626
    MVMuint32 ID;
627
628
    /* Optional API, for representations that allocate additonal memory and
629
     * want to report its size for debugging purposes. */
630
    MVMuint64 (*unmanaged_size) (MVMThreadContext *tc, MVMSTable *st, void *data);
631
632
    /* Optional API to describe references to other Collectables either by
633
     * index or by name, i.E. names of attributes or lexicals. */
634
    void (*describe_refs) (MVMThreadContext *tc, MVMHeapSnapshotState *ss, MVMSTable *st, void *data);
635
};
636
637
/* Various handy macros for getting at important stuff. */
638
348M
#define STABLE(o)        (((MVMObject *)(o))->st)
639
166M
#define REPR(o)          (STABLE((o))->REPR)
640
100M
#define OBJECT_BODY(o)   (&(((MVMObjectStooge *)(o))->data))
641
642
/* Macros for getting/setting type-objectness. */
643
415M
#define IS_CONCRETE(o)   (!(((MVMObject *)o)->header.flags & MVM_CF_TYPE_OBJECT))
644
645
/* Some functions related to 6model core functionality. */
646
MVM_PUBLIC MVMObject * MVM_6model_get_how(MVMThreadContext *tc, MVMSTable *st);
647
MVM_PUBLIC MVMObject * MVM_6model_get_how_obj(MVMThreadContext *tc, MVMObject *obj);
648
void MVM_6model_find_method(MVMThreadContext *tc, MVMObject *obj, MVMString *name, MVMRegister *res);
649
MVM_PUBLIC MVMObject * MVM_6model_find_method_cache_only(MVMThreadContext *tc, MVMObject *obj, MVMString *name);
650
MVMint32 MVM_6model_find_method_spesh(MVMThreadContext *tc, MVMObject *obj, MVMString *name,
651
                                      MVMint32 ss_idx, MVMRegister *res);
652
MVMint64 MVM_6model_can_method_cache_only(MVMThreadContext *tc, MVMObject *obj, MVMString *name);
653
void MVM_6model_can_method(MVMThreadContext *tc, MVMObject *obj, MVMString *name, MVMRegister *res);
654
void MVM_6model_istype(MVMThreadContext *tc, MVMObject *obj, MVMObject *type, MVMRegister *res);
655
MVM_PUBLIC MVMint64 MVM_6model_istype_cache_only(MVMThreadContext *tc, MVMObject *obj, MVMObject *type);
656
MVMint64 MVM_6model_try_cache_type_check(MVMThreadContext *tc, MVMObject *obj, MVMObject *type, MVMint32 *result);
657
void MVM_6model_invoke_default(MVMThreadContext *tc, MVMObject *invokee, MVMCallsite *callsite, MVMRegister *args);
658
void MVM_6model_stable_gc_free(MVMThreadContext *tc, MVMSTable *st);
659
MVMuint64 MVM_6model_next_type_cache_id(MVMThreadContext *tc);
660
void MVM_6model_never_repossess(MVMThreadContext *tc, MVMObject *obj);