Coverage Report

Created: 2017-04-15 07:07

/home/travis/build/MoarVM/MoarVM/src/6model/reprs/MVMString.c
Line
Count
Source (jump to first uncovered line)
1
#include "moar.h"
2
3
/* This representation's function pointer table. */
4
static const MVMREPROps MVMString_this_repr;
5
6
/* Creates a new type object of this representation, and associates it with
7
 * the given HOW. */
8
130
static MVMObject * type_object_for(MVMThreadContext *tc, MVMObject *HOW) {
9
130
    MVMSTable *st = MVM_gc_allocate_stable(tc, &MVMString_this_repr, HOW);
10
130
11
130
    MVMROOT(tc, st, {
12
130
        MVMObject *obj = MVM_gc_allocate_type_object(tc, st);
13
130
        MVM_ASSIGN_REF(tc, &(st->header), st->WHAT, obj);
14
130
        st->size = sizeof(MVMString);
15
130
    });
16
130
17
130
    return st->WHAT;
18
130
}
19
20
/* Copies the body of one object to another. */
21
0
static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *dest_root, void *dest) {
22
0
    MVMStringBody *src_body     = (MVMStringBody *)src;
23
0
    MVMStringBody *dest_body    = (MVMStringBody *)dest;
24
0
    dest_body->storage_type     = src_body->storage_type;
25
0
    dest_body->num_strands      = src_body->num_strands;
26
0
    dest_body->num_graphs       = src_body->num_graphs;
27
0
    dest_body->cached_hash_code = src_body->cached_hash_code;
28
0
    switch (dest_body->storage_type) {
29
0
        case MVM_STRING_GRAPHEME_32:
30
0
            if (dest_body->num_graphs) {
31
0
                dest_body->storage.blob_32 = MVM_malloc(dest_body->num_graphs * sizeof(MVMGrapheme32));
32
0
                memcpy(dest_body->storage.blob_32, src_body->storage.blob_32,
33
0
                    dest_body->num_graphs * sizeof(MVMGrapheme32));
34
0
            }
35
0
            break;
36
0
        case MVM_STRING_GRAPHEME_ASCII:
37
0
        case MVM_STRING_GRAPHEME_8:
38
0
            if (dest_body->num_graphs) {
39
0
                dest_body->storage.blob_8 = MVM_malloc(dest_body->num_graphs);
40
0
                memcpy(dest_body->storage.blob_8, src_body->storage.blob_8,
41
0
                    dest_body->num_graphs);
42
0
            }
43
0
            break;
44
0
        case MVM_STRING_STRAND:
45
0
            dest_body->storage.strands = MVM_malloc(dest_body->num_strands * sizeof(MVMStringStrand));
46
0
            memcpy(dest_body->storage.strands, src_body->storage.strands,
47
0
                dest_body->num_strands * sizeof(MVMStringStrand));
48
0
            break;
49
0
        default:
50
0
            MVM_exception_throw_adhoc(tc, "Internal string corruption");
51
0
    }
52
0
}
53
54
/* Adds held objects to the GC worklist. */
55
129k
static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorklist *worklist) {
56
129k
    MVMStringBody *body = (MVMStringBody *)data;
57
129k
    if (body->storage_type == MVM_STRING_STRAND) {
58
91.4k
        MVMStringStrand *strands = body->storage.strands;
59
91.4k
        MVMuint16 i;
60
260k
        for (i = 0; i < body->num_strands; i++)
61
169k
            MVM_gc_worklist_add(tc, worklist, &(strands[i].blob_string));
62
91.4k
    }
63
129k
}
64
65
/* Called by the VM in order to free memory associated with this object. */
66
498k
static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
67
498k
    MVMString *str = (MVMString *)obj;
68
498k
    MVM_free(str->body.storage.any);
69
498k
    str->body.num_graphs = str->body.num_strands = 0;
70
498k
}
71
72
static const MVMStorageSpec storage_spec = {
73
    MVM_STORAGE_SPEC_REFERENCE, /* inlineable */
74
    0,                          /* bits */
75
    0,                          /* align */
76
    MVM_STORAGE_SPEC_BP_NONE,   /* boxed_primitive */
77
    0,                          /* can_box */
78
    0,                          /* is_unsigned */
79
};
80
81
/* Gets the storage specification for this representation. */
82
89
static const MVMStorageSpec * get_storage_spec(MVMThreadContext *tc, MVMSTable *st) {
83
89
    return &storage_spec;
84
89
}
85
86
/* Compose the representation. */
87
0
static void compose(MVMThreadContext *tc, MVMSTable *st, MVMObject *info) {
88
0
    /* Nothing to do for this REPR. */
89
0
}
90
91
/* Calculates the non-GC-managed memory we hold on to. */
92
50.7k
static MVMuint64 unmanaged_size(MVMThreadContext *tc, MVMSTable *st, void *data) {
93
50.7k
    MVMStringBody *body = (MVMStringBody *)data;
94
50.7k
    switch (body->storage_type) {
95
10.6k
        case MVM_STRING_GRAPHEME_32:
96
10.6k
            return sizeof(MVMGrapheme32) * body->num_graphs;
97
36.1k
        case MVM_STRING_STRAND:
98
36.1k
            return sizeof(MVMStringStrand) * body->num_strands;
99
3.97k
        default:
100
3.97k
            return body->num_graphs;
101
50.7k
    }
102
50.7k
}
103
104
/* Initializes the representation. */
105
260
const MVMREPROps * MVMString_initialize(MVMThreadContext *tc) {
106
260
    return &MVMString_this_repr;
107
260
}
108
109
static const MVMREPROps MVMString_this_repr = {
110
    type_object_for,
111
    MVM_gc_allocate_object,
112
    NULL, /* initialize */
113
    copy_to,
114
    MVM_REPR_DEFAULT_ATTR_FUNCS,
115
    MVM_REPR_DEFAULT_BOX_FUNCS,
116
    MVM_REPR_DEFAULT_POS_FUNCS,
117
    MVM_REPR_DEFAULT_ASS_FUNCS,
118
    MVM_REPR_DEFAULT_ELEMS,
119
    get_storage_spec,
120
    NULL, /* change_type */
121
    NULL, /* serialize */
122
    NULL, /* deserialize */
123
    NULL, /* serialize_repr_data */
124
    NULL, /* deserialize_repr_data */
125
    NULL, /* deserialize_stable_size */
126
    gc_mark,
127
    gc_free,
128
    NULL, /* gc_cleanup */
129
    NULL, /* gc_mark_repr_data */
130
    NULL, /* gc_free_repr_data */
131
    compose,
132
    NULL, /* spesh */
133
    "MVMString", /* name */
134
    MVM_REPR_ID_MVMString,
135
    unmanaged_size,
136
    NULL, /* describe_refs */
137
};