Skip to content

Instantly share code, notes, and snippets.

@MasterDuke17
Last active September 29, 2017 22:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MasterDuke17/f29bc6caa2aae6417e0eda676e545a81 to your computer and use it in GitHub Desktop.
Save MasterDuke17/f29bc6caa2aae6417e0eda676e545a81 to your computer and use it in GitHub Desktop.
diff --git a/src/6model/6model.h b/src/6model/6model.h
index abec05c0a..8aff11fb3 100644
--- a/src/6model/6model.h
+++ b/src/6model/6model.h
@@ -134,7 +134,10 @@ typedef enum {
/* Note: if you're hunting for a flag, some day in the future when we
* have used them all, this one is easy enough to eliminate by having the
* tiny number of objects marked this way in a remembered set. */
- MVM_CF_NEVER_REPOSSESS = 2048
+ MVM_CF_NEVER_REPOSSESS = 2048,
+
+ /* Does this use the FSA? */
+ MVM_CF_USES_FSA = 4096
} MVMCollectableFlags;
#ifdef MVM_USE_OVERFLOW_SERIALIZATION_INDEX
diff --git a/src/6model/reprs/MVMString.c b/src/6model/reprs/MVMString.c
index aa5d51a6a..b1dbcfc00 100644
--- a/src/6model/reprs/MVMString.c
+++ b/src/6model/reprs/MVMString.c
@@ -28,7 +28,8 @@ static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *d
switch (dest_body->storage_type) {
case MVM_STRING_GRAPHEME_32:
if (dest_body->num_graphs) {
- dest_body->storage.blob_32 = MVM_malloc(dest_body->num_graphs * sizeof(MVMGrapheme32));
+ dest_body->storage.blob_32 = MVM_fixed_size_alloc(tc, tc->instance->fsa, dest_body->num_graphs * sizeof(MVMGrapheme32));
+ dest_root->header.flags |= MVM_CF_USES_FSA;
memcpy(dest_body->storage.blob_32, src_body->storage.blob_32,
dest_body->num_graphs * sizeof(MVMGrapheme32));
}
@@ -36,13 +37,15 @@ static void copy_to(MVMThreadContext *tc, MVMSTable *st, void *src, MVMObject *d
case MVM_STRING_GRAPHEME_ASCII:
case MVM_STRING_GRAPHEME_8:
if (dest_body->num_graphs) {
- dest_body->storage.blob_8 = MVM_malloc(dest_body->num_graphs);
+ dest_body->storage.blob_8 = MVM_fixed_size_alloc(tc, tc->instance->fsa, dest_body->num_graphs);
+ dest_root->header.flags |= MVM_CF_USES_FSA;
memcpy(dest_body->storage.blob_8, src_body->storage.blob_8,
dest_body->num_graphs);
}
break;
case MVM_STRING_STRAND:
- dest_body->storage.strands = MVM_malloc(dest_body->num_strands * sizeof(MVMStringStrand));
+ dest_body->storage.strands = MVM_fixed_size_alloc(tc, tc->instance->fsa, dest_body->num_strands * sizeof(MVMStringStrand));
+ dest_root->header.flags |= MVM_CF_USES_FSA;
memcpy(dest_body->storage.strands, src_body->storage.strands,
dest_body->num_strands * sizeof(MVMStringStrand));
break;
@@ -65,7 +68,27 @@ static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorkli
/* Called by the VM in order to free memory associated with this object. */
static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
MVMString *str = (MVMString *)obj;
- MVM_free(str->body.storage.any);
+ if (obj->header.flags & MVM_CF_USES_FSA) {
+ size_t type;
+ switch (str->body.storage_type) {
+ case MVM_STRING_GRAPHEME_8:
+ type = sizeof(MVMGrapheme8);
+ break;
+ case MVM_STRING_GRAPHEME_32:
+ type = sizeof(MVMGrapheme32);
+ break;
+ case MVM_STRING_GRAPHEME_ASCII:
+ type = sizeof(MVMGraphemeASCII);
+ break;
+ case MVM_STRING_STRAND:
+ type = sizeof(MVMStringStrand);
+ break;
+ }
+ MVM_fixed_size_free(tc, tc->instance->fsa, (str->body.storage_type == MVM_STRING_STRAND ? str->body.num_strands : str->body.num_graphs) * type , str->body.storage.any);
+ }
+ else {
+ MVM_free(str->body.storage.any);
+ }
str->body.num_graphs = str->body.num_strands = 0;
}
diff --git a/src/strings/ops.c b/src/strings/ops.c
index 52360fb6c..01754c1b9 100644
--- a/src/strings/ops.c
+++ b/src/strings/ops.c
@@ -149,7 +149,7 @@ static MVMint64 knuth_morris_pratt_string_index (MVMThreadContext *tc, MVMString
/* Allocates strand storage. */
static MVMStringStrand * allocate_strands(MVMThreadContext *tc, MVMuint16 num_strands) {
- return MVM_malloc(num_strands * sizeof(MVMStringStrand));
+ return MVM_fixed_size_alloc(tc, tc->instance->fsa, num_strands * sizeof(MVMStringStrand));
}
/* Copies strands from one strand string to another. */
@@ -185,13 +185,21 @@ static void turn_32bit_into_8bit_unchecked(MVMThreadContext *tc, MVMString *str)
MVMGrapheme32 *old_buf = str->body.storage.blob_32;
MVMStringIndex i;
str->body.storage_type = MVM_STRING_GRAPHEME_8;
- str->body.storage.blob_8 = MVM_malloc(str->body.num_graphs * sizeof(MVMGrapheme8));
+ str->body.storage.blob_8 = MVM_fixed_size_alloc(tc, tc->instance->fsa,
+ str->body.num_graphs * sizeof(MVMGrapheme8));
for (i = 0; i < str->body.num_graphs; i++) {
str->body.storage.blob_8[i] = old_buf[i];
}
- MVM_free(old_buf);
+ if (str->common.header.flags & MVM_CF_USES_FSA) {
+ MVM_fixed_size_free(tc, tc->instance->fsa,
+ str->body.num_graphs * sizeof(MVMGrapheme32), old_buf);
+ }
+ else {
+ MVM_free(old_buf);
+ str->common.header.flags |= MVM_CF_USES_FSA;
+ }
}
/* Accepts an allocated string that should have body.num_graphs set but the blob
@@ -200,7 +208,8 @@ static void turn_32bit_into_8bit_unchecked(MVMThreadContext *tc, MVMString *str)
static void iterate_gi_into_string(MVMThreadContext *tc, MVMGraphemeIter *gi, MVMString *result) {
MVMuint64 i;
result->body.storage_type = MVM_STRING_GRAPHEME_8;
- result->body.storage.blob_8 = MVM_malloc(result->body.num_graphs * sizeof(MVMGrapheme8));
+ result->body.storage.blob_8 = MVM_fixed_size_alloc(tc, tc->instance->fsa,
+ result->body.num_graphs * sizeof(MVMGrapheme8));
for (i = 0; i < result->body.num_graphs; i++) {
MVMGrapheme32 g = MVM_string_gi_get_grapheme(tc, gi);
result->body.storage.blob_8[i] = g;
@@ -212,13 +221,20 @@ static void iterate_gi_into_string(MVMThreadContext *tc, MVMGraphemeIter *gi, MV
MVMuint64 prev_i = i;
/* Set up the string as 32bit now and allocate space for it */
result->body.storage_type = MVM_STRING_GRAPHEME_32;
- result->body.storage.blob_32 = MVM_malloc(result->body.num_graphs * sizeof(MVMGrapheme32));
+ result->body.storage.blob_32 = MVM_fixed_size_alloc(tc, tc->instance->fsa,
+ result->body.num_graphs * sizeof(MVMGrapheme32));
/* Copy the data so far copied from the 8bit blob since it's faster than
* setting up the grapheme iterator again */
for (i = 0; i < prev_i; i++) {
result->body.storage.blob_32[i] = old_ref[i];
}
- MVM_free(old_ref);
+ if (result->common.header.flags & MVM_CF_USES_FSA) {
+ MVM_fixed_size_free(tc, tc->instance->fsa,
+ result->body.num_graphs * sizeof(MVMGrapheme8), old_ref);
+ }
+ else {
+ MVM_free(old_ref);
+ }
/* Store the grapheme which interupted the sequence. After that we can
* continue from where we left off using the grapheme iterator */
result->body.storage.blob_32[prev_i] = g;
@@ -227,6 +243,7 @@ static void iterate_gi_into_string(MVMThreadContext *tc, MVMGraphemeIter *gi, MV
}
}
}
+ result->common.header.flags |= MVM_CF_USES_FSA;
}
/* Collapses a bunch of strands into a single blob string. */
@@ -252,10 +269,11 @@ static MVMString * re_nfg(MVMThreadContext *tc, MVMString *in) {
MVMint32 ready;
MVMString *out = NULL;
MVMuint32 bufsize = in->body.num_graphs;
+ MVMuint32 old_bufsize = bufsize;
/* Create the output buffer. We used to believe it can't ever be bigger
* than the initial estimate, but utf8-c8 showed us otherwise. */
- MVMGrapheme32 *out_buffer = MVM_malloc(bufsize * sizeof(MVMGrapheme32));
+ MVMGrapheme32 *out_buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, bufsize * sizeof(MVMGrapheme32));
MVMint64 out_pos = 0;
/* Iterate codepoints and normalizer. */
MVM_unicode_normalizer_init(tc, &norm, MVM_NORMALIZE_NFG);
@@ -269,7 +287,8 @@ static MVMString * re_nfg(MVMThreadContext *tc, MVMString *in) {
/* Doubling up the buffer size seems excessive, so just
* add a generous amount of storage */
bufsize += ready + 32;
- out_buffer = MVM_realloc(out_buffer, bufsize * sizeof(MVMGrapheme32));
+ out_buffer = MVM_fixed_size_realloc(tc, tc->instance->fsa, out_buffer, old_bufsize, bufsize * sizeof(MVMGrapheme32));
+ old_bufsize = bufsize * sizeof(MVMGrapheme32);
}
out_buffer[out_pos++] = g;
while (--ready > 0) {
@@ -281,7 +300,7 @@ static MVMString * re_nfg(MVMThreadContext *tc, MVMString *in) {
ready = MVM_unicode_normalizer_available(tc, &norm);
if (out_pos + ready > bufsize) {
bufsize += ready + 1;
- out_buffer = MVM_realloc(out_buffer, bufsize * sizeof(MVMGrapheme32));
+ out_buffer = MVM_fixed_size_realloc(tc, tc->instance->fsa, out_buffer, old_bufsize, bufsize * sizeof(MVMGrapheme32));
}
while (ready--) {
out_buffer[out_pos++] = MVM_unicode_normalizer_get_grapheme(tc, &norm);
@@ -293,6 +312,7 @@ static MVMString * re_nfg(MVMThreadContext *tc, MVMString *in) {
out->body.storage.blob_32 = out_buffer;
out->body.storage_type = MVM_STRING_GRAPHEME_32;
out->body.num_graphs = out_pos;
+ out->common.header.flags |= MVM_CF_USES_FSA;
return out;
}
@@ -556,6 +576,7 @@ MVMString * MVM_string_substring(MVMThreadContext *tc, MVMString *a, MVMint64 of
/* It's some kind of buffer. Construct a strand view into it. */
result->body.storage_type = MVM_STRING_STRAND;
result->body.storage.strands = allocate_strands(tc, 1);
+ result->common.header.flags |= MVM_CF_USES_FSA;
result->body.num_strands = 1;
result->body.storage.strands[0].blob_string = a;
result->body.storage.strands[0].start = start_pos;
@@ -568,6 +589,7 @@ MVMString * MVM_string_substring(MVMThreadContext *tc, MVMString *a, MVMint64 of
MVMStringStrand *orig_strand = &(a->body.storage.strands[0]);
result->body.storage_type = MVM_STRING_STRAND;
result->body.storage.strands = allocate_strands(tc, 1);
+ result->common.header.flags |= MVM_CF_USES_FSA;
result->body.num_strands = 1;
result->body.storage.strands[0].blob_string = orig_strand->blob_string;
result->body.storage.strands[0].start = orig_strand->start + start_pos;
@@ -710,6 +732,7 @@ MVMString * MVM_string_concatenate(MVMThreadContext *tc, MVMString *a, MVMString
/* We have it; just copy the strands to a new string and bump the
* repetitions count of the last one. */
result->body.storage.strands = allocate_strands(tc, a->body.num_strands);
+ result->common.header.flags |= MVM_CF_USES_FSA;
copy_strands(tc, a, 0, result, 0, a->body.num_strands);
result->body.storage.strands[a->body.num_strands - 1].repetitions++;
result->body.num_strands = a->body.num_strands;
@@ -742,6 +765,7 @@ MVMString * MVM_string_concatenate(MVMThreadContext *tc, MVMString *a, MVMString
/* Assemble the result. */
result->body.num_strands = strands_a + strands_b + (renormalized_section_graphs ? 1 : 0);
result->body.storage.strands = allocate_strands(tc, result->body.num_strands);
+ result->common.header.flags |= MVM_CF_USES_FSA;
/* START 1 */
if (effective_a->body.storage_type == MVM_STRING_STRAND) {
copy_strands(tc, effective_a, 0, result, 0, strands_a);
@@ -858,6 +882,7 @@ MVMString * MVM_string_repeat(MVMThreadContext *tc, MVMString *a, MVMint64 count
result->body.num_graphs = agraphs * count;
result->body.storage_type = MVM_STRING_STRAND;
result->body.storage.strands = allocate_strands(tc, 1);
+ result->common.header.flags |= MVM_CF_USES_FSA;
if (a->body.storage_type == MVM_STRING_STRAND) {
if (a->body.num_strands == 1 && a->body.storage.strands[0].repetitions == 0) {
copy_strands(tc, a, 0, result, 0, 1);
@@ -1296,7 +1321,9 @@ static MVMString * do_case_change(MVMThreadContext *tc, MVMString *s, MVMint32 t
MVMString *result;
MVMGraphemeIter gi;
MVMint64 result_graphs = sgraphs;
- MVMGrapheme32 *result_buf = MVM_malloc(result_graphs * sizeof(MVMGrapheme32));
+ MVMGrapheme32 *result_buf = MVM_fixed_size_alloc(tc, tc->instance->fsa,
+ result_graphs * sizeof(MVMGrapheme32));
+ size_t old_bytes = result_graphs * sizeof(MVMGrapheme32);
MVMint32 changed = 0;
MVMint64 i = 0;
MVM_string_gi_init(tc, &gi, s);
@@ -1369,8 +1396,9 @@ static MVMString * do_case_change(MVMThreadContext *tc, MVMString *s, MVMint32 t
/* Make space for any extra graphemes. */
if (1 < num_result_graphs) {
result_graphs += num_result_graphs - 1;
- result_buf = MVM_realloc(result_buf,
- result_graphs * sizeof(MVMGrapheme32));
+ result_buf = MVM_fixed_size_realloc(tc, tc->instance->fsa, result_buf,
+ old_bytes, result_graphs * sizeof(MVMGrapheme32));
+ old_bytes = result_graphs * sizeof(MVMGrapheme32);
}
/* Copy resulting graphemes. */
@@ -1399,8 +1427,9 @@ static MVMString * do_case_change(MVMThreadContext *tc, MVMString *s, MVMint32 t
else {
MVMuint32 j;
result_graphs += num_transformed - 1;
- result_buf = MVM_realloc(result_buf,
- result_graphs * sizeof(MVMGrapheme32));
+ result_buf = MVM_fixed_size_realloc(tc, tc->instance->fsa, result_buf,
+ old_bytes, result_graphs * sizeof(MVMGrapheme32));
+ old_bytes = result_graphs * sizeof(MVMGrapheme32);
for (j = 0; j < num_transformed; j++)
result_buf[i++] = transformed[j];
changed = 1;
@@ -1412,10 +1441,11 @@ static MVMString * do_case_change(MVMThreadContext *tc, MVMString *s, MVMint32 t
result->body.num_graphs = result_graphs;
result->body.storage_type = MVM_STRING_GRAPHEME_32;
result->body.storage.blob_32 = result_buf;
+ result->common.header.flags |= MVM_CF_USES_FSA;
return result;
}
else {
- MVM_free(result_buf);
+ MVM_fixed_size_free(tc, tc->instance->fsa, result_graphs * sizeof(MVMGrapheme32), result_buf);
}
}
STRAND_CHECK(tc, s);
@@ -1762,7 +1792,9 @@ MVMString * MVM_string_join(MVMThreadContext *tc, MVMString *separator, MVMObjec
MVMint64 position = 0;
MVMGraphemeIter gi;
result->body.storage_type = MVM_STRING_GRAPHEME_32;
- result->body.storage.blob_32 = MVM_malloc(total_graphs * sizeof(MVMGrapheme32));
+ result->body.storage.blob_32 = MVM_fixed_size_alloc(tc, tc->instance->fsa,
+ total_graphs * sizeof(MVMGrapheme32));
+ result->common.header.flags |= MVM_CF_USES_FSA;
for (i = 0; i < num_pieces; i++) {
/* Get piece. */
MVMString *piece = pieces[i];
@@ -1931,12 +1963,14 @@ MVMString * MVM_string_escape(MVMThreadContext *tc, MVMString *s) {
MVMGrapheme32 *buffer = NULL;
MVMGrapheme32 crlf;
MVMint8 string_can_fit_into_8bit = 1;
+ size_t old_bytes;
MVM_string_check_arg(tc, s, "escape");
sgraphs = MVM_string_graphs_nocheck(tc, s);
balloc = sgraphs;
- buffer = MVM_malloc(sizeof(MVMGrapheme32) * balloc);
+ buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme32) * balloc);
+ old_bytes = sizeof(MVMGrapheme32) * balloc;
crlf = MVM_nfg_crlf_grapheme(tc);
@@ -1957,7 +1991,9 @@ MVMString * MVM_string_escape(MVMThreadContext *tc, MVMString *s) {
if (esc) {
if (bpos + 2 > balloc) {
balloc += 32;
- buffer = MVM_realloc(buffer, sizeof(MVMGrapheme32) * balloc);
+ buffer = MVM_fixed_size_realloc(tc, tc->instance->fsa, buffer,
+ old_bytes, sizeof(MVMGrapheme32) * balloc);
+ old_bytes = sizeof(MVMGrapheme32) * balloc;
}
buffer[bpos++] = '\\';
buffer[bpos++] = esc;
@@ -1965,7 +2001,9 @@ MVMString * MVM_string_escape(MVMThreadContext *tc, MVMString *s) {
else if (graph == crlf) {
if (bpos + 4 > balloc) {
balloc += 32;
- buffer = MVM_realloc(buffer, sizeof(MVMGrapheme32) * balloc);
+ buffer = MVM_fixed_size_realloc(tc, tc->instance->fsa, buffer,
+ old_bytes, sizeof(MVMGrapheme32) * balloc);
+ old_bytes = sizeof(MVMGrapheme32) * balloc;
}
buffer[bpos++] = '\\';
buffer[bpos++] = 'r';
@@ -1975,7 +2013,9 @@ MVMString * MVM_string_escape(MVMThreadContext *tc, MVMString *s) {
else {
if (bpos + 1 > balloc) {
balloc += 32;
- buffer = MVM_realloc(buffer, sizeof(MVMGrapheme32) * balloc);
+ buffer = MVM_fixed_size_realloc(tc, tc->instance->fsa, buffer,
+ old_bytes, sizeof(MVMGrapheme32) * balloc);
+ old_bytes = sizeof(MVMGrapheme32) * balloc;
}
if (!can_fit_into_8bit(graph))
string_can_fit_into_8bit = 0;
@@ -1986,6 +2026,7 @@ MVMString * MVM_string_escape(MVMThreadContext *tc, MVMString *s) {
res = (MVMString *)MVM_repr_alloc_init(tc, tc->instance->VMString);
res->body.storage_type = MVM_STRING_GRAPHEME_32;
res->body.storage.blob_32 = buffer;
+ res->common.header.flags |= MVM_CF_USES_FSA;
res->body.num_graphs = bpos;
if (string_can_fit_into_8bit)
@@ -2008,7 +2049,7 @@ MVMString * MVM_string_flip(MVMThreadContext *tc, MVMString *s) {
if (s->body.storage_type == MVM_STRING_GRAPHEME_8) {
MVMGrapheme8 *rbuffer;
- rbuffer = MVM_malloc(sizeof(MVMGrapheme8) * sgraphs);
+ rbuffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme8) * sgraphs);
for (; spos < sgraphs; spos++)
rbuffer[--rpos] = s->body.storage.blob_8[spos];
@@ -2016,9 +2057,10 @@ MVMString * MVM_string_flip(MVMThreadContext *tc, MVMString *s) {
res = (MVMString *)MVM_repr_alloc_init(tc, tc->instance->VMString);
res->body.storage_type = MVM_STRING_GRAPHEME_8;
res->body.storage.blob_8 = rbuffer;
+ res->common.header.flags |= MVM_CF_USES_FSA;
} else {
MVMGrapheme32 *rbuffer;
- rbuffer = MVM_malloc(sizeof(MVMGrapheme32) * sgraphs);
+ rbuffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme32) * sgraphs);
if (s->body.storage_type == MVM_STRING_GRAPHEME_32)
for (; spos < sgraphs; spos++)
@@ -2030,6 +2072,7 @@ MVMString * MVM_string_flip(MVMThreadContext *tc, MVMString *s) {
res = (MVMString *)MVM_repr_alloc_init(tc, tc->instance->VMString);
res->body.storage_type = MVM_STRING_GRAPHEME_32;
res->body.storage.blob_32 = rbuffer;
+ res->common.header.flags |= MVM_CF_USES_FSA;
}
res->body.num_graphs = sgraphs;
@@ -2112,7 +2155,7 @@ MVMString * MVM_string_bitand(MVMThreadContext *tc, MVMString *a, MVMString *b)
alen = MVM_string_graphs_nocheck(tc, a);
blen = MVM_string_graphs_nocheck(tc, b);
sgraphs = alen < blen ? alen : blen;
- buffer = MVM_malloc(sizeof(MVMGrapheme32) * sgraphs);
+ buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme32) * sgraphs);
/* Binary-and up to the length of the shortest string. */
for (i = 0; i < sgraphs; i++)
@@ -2122,6 +2165,7 @@ MVMString * MVM_string_bitand(MVMThreadContext *tc, MVMString *a, MVMString *b)
res = (MVMString *)MVM_repr_alloc_init(tc, tc->instance->VMString);
res->body.storage_type = MVM_STRING_GRAPHEME_32;
res->body.storage.blob_32 = buffer;
+ res->common.header.flags |= MVM_CF_USES_FSA;
res->body.num_graphs = sgraphs;
STRAND_CHECK(tc, res);
@@ -2140,7 +2184,7 @@ MVMString * MVM_string_bitor(MVMThreadContext *tc, MVMString *a, MVMString *b) {
alen = MVM_string_graphs_nocheck(tc, a);
blen = MVM_string_graphs_nocheck(tc, b);
sgraphs = (alen > blen ? alen : blen);
- buffer = MVM_malloc(sizeof(MVMGrapheme32) * sgraphs);
+ buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme32) * sgraphs);
/* First, binary-or up to the length of the shortest string. */
scanlen = alen > blen ? blen : alen;
@@ -2159,6 +2203,7 @@ MVMString * MVM_string_bitor(MVMThreadContext *tc, MVMString *a, MVMString *b) {
res = (MVMString *)MVM_repr_alloc_init(tc, tc->instance->VMString);
res->body.storage_type = MVM_STRING_GRAPHEME_32;
res->body.storage.blob_32 = buffer;
+ res->common.header.flags |= MVM_CF_USES_FSA;
res->body.num_graphs = sgraphs;
STRAND_CHECK(tc, res);
@@ -2177,7 +2222,7 @@ MVMString * MVM_string_bitxor(MVMThreadContext *tc, MVMString *a, MVMString *b)
alen = MVM_string_graphs_nocheck(tc, a);
blen = MVM_string_graphs_nocheck(tc, b);
sgraphs = (alen > blen ? alen : blen);
- buffer = MVM_malloc(sizeof(MVMGrapheme32) * sgraphs);
+ buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme32) * sgraphs);
/* First, binary-xor up to the length of the shorter string. */
scanlen = alen > blen ? blen : alen;
@@ -2196,6 +2241,7 @@ MVMString * MVM_string_bitxor(MVMThreadContext *tc, MVMString *a, MVMString *b)
res = (MVMString *)MVM_repr_alloc_init(tc, tc->instance->VMString);
res->body.storage_type = MVM_STRING_GRAPHEME_32;
res->body.storage.blob_32 = buffer;
+ res->common.header.flags |= MVM_CF_USES_FSA;
res->body.num_graphs = sgraphs;
STRAND_CHECK(tc, res);
@@ -2522,13 +2568,14 @@ MVMString * MVM_string_chr(MVMThreadContext *tc, MVMint64 cp) {
s = (MVMString *)REPR(tc->instance->VMString)->allocate(tc, STABLE(tc->instance->VMString));
if (can_fit_into_8bit(g)) {
s->body.storage_type = MVM_STRING_GRAPHEME_8;
- s->body.storage.blob_8 = MVM_malloc(sizeof(MVMGrapheme8));
+ s->body.storage.blob_8 = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme8));
s->body.storage.blob_8[0] = g;
} else {
s->body.storage_type = MVM_STRING_GRAPHEME_32;
- s->body.storage.blob_32 = MVM_malloc(sizeof(MVMGrapheme32));
+ s->body.storage.blob_32 = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme32));
s->body.storage.blob_32[0] = g;
}
+ s->common.header.flags |= MVM_CF_USES_FSA;
s->body.num_graphs = 1;
return s;
}
diff --git a/src/strings/utf8.c b/src/strings/utf8.c
index 2440076ce..c79ac0825 100644
--- a/src/strings/utf8.c
+++ b/src/strings/utf8.c
@@ -177,9 +177,10 @@ MVMString * MVM_string_utf8_decode(MVMThreadContext *tc, const MVMObject *result
MVMint32 line_ending = 0;
MVMint32 state = 0;
MVMint32 bufsize = bytes;
+ MVMint32 old_bufsize = bufsize;
MVMGrapheme32 lowest_graph = 0x7fffffff;
MVMGrapheme32 highest_graph = -0x7fffffff;
- MVMGrapheme32 *buffer = MVM_malloc(sizeof(MVMGrapheme32) * bufsize);
+ MVMGrapheme32 *buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme32) * bufsize);
size_t orig_bytes;
const char *orig_utf8;
MVMint32 line;
@@ -200,9 +201,10 @@ MVMString * MVM_string_utf8_decode(MVMThreadContext *tc, const MVMObject *result
ready = MVM_unicode_normalizer_process_codepoint_to_grapheme(tc, &norm, codepoint, &g);
if (ready) {
while (count + ready >= bufsize) { /* if the buffer's full make a bigger one */
- buffer = MVM_realloc(buffer, sizeof(MVMGrapheme32) * (
+ buffer = MVM_fixed_size_realloc(tc, tc->instance->fsa, buffer, old_bufsize, sizeof(MVMGrapheme32) * (
bufsize >= UTF8_MAXINC ? (bufsize += UTF8_MAXINC) : (bufsize *= 2)
));
+ old_bufsize = bufsize;
}
buffer[count++] = g;
lowest_graph = g < lowest_graph ? g : lowest_graph;
@@ -243,18 +245,18 @@ MVMString * MVM_string_utf8_decode(MVMThreadContext *tc, const MVMObject *result
col++;
break;
case UTF8_REJECT:
- MVM_free(buffer);
+ MVM_fixed_size_free(tc, tc->instance->fsa, bufsize, buffer);
MVM_exception_throw_adhoc(tc, "Malformed UTF-8 at line %u col %u", line, col);
}
}
- MVM_free(buffer);
+ MVM_fixed_size_free(tc, tc->instance->fsa, bufsize, buffer);
MVM_exception_throw_adhoc(tc, "Concurrent modification of UTF-8 input buffer!");
break;
}
}
if (state != UTF8_ACCEPT) {
MVM_unicode_normalizer_cleanup(tc, &norm);
- MVM_free(buffer);
+ MVM_fixed_size_free(tc, tc->instance->fsa, bufsize, buffer);
MVM_exception_throw_adhoc(tc, "Malformed termination of UTF-8 string");
}
@@ -263,7 +265,8 @@ MVMString * MVM_string_utf8_decode(MVMThreadContext *tc, const MVMObject *result
ready = MVM_unicode_normalizer_available(tc, &norm);
if (ready) {
if (count + ready >= bufsize) {
- buffer = MVM_realloc(buffer, sizeof(MVMGrapheme32) * (count + ready));
+ buffer = MVM_fixed_size_realloc(tc, tc->instance->fsa, buffer, old_bufsize, sizeof(MVMGrapheme32) * (count + ready));
+ old_bufsize = sizeof(MVMGrapheme32) * (count + ready);
}
while (ready--) {
MVMGrapheme32 g;
@@ -279,21 +282,24 @@ MVMString * MVM_string_utf8_decode(MVMThreadContext *tc, const MVMObject *result
* That happens when our lowest value is bigger than -129 and our
* highest value is lower than 128. */
if (lowest_graph >= -128 && highest_graph < 128) {
- MVMGrapheme8 *new_buffer = MVM_malloc(sizeof(MVMGrapheme8) * count);
+ MVMGrapheme8 *new_buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, sizeof(MVMGrapheme8) * count);
for (ready = 0; ready < count; ready++) {
new_buffer[ready] = buffer[ready];
}
- MVM_free(buffer);
+ MVM_fixed_size_free(tc, tc->instance->fsa, old_bufsize, buffer);
result->body.storage.blob_8 = new_buffer;
+ result->common.header.flags |= MVM_CF_USES_FSA;
result->body.storage_type = MVM_STRING_GRAPHEME_8;
} else {
/* just keep the same buffer as the MVMString's buffer. Later
* we can add heuristics to resize it if we have enough free
* memory */
if (bufsize - count > 4) {
- buffer = MVM_realloc(buffer, count * sizeof(MVMGrapheme32));
+ buffer = MVM_fixed_size_realloc(tc, tc->instance->fsa, buffer, old_bufsize, count * sizeof(MVMGrapheme32));
+ old_bufsize = count * sizeof(MVMGrapheme32);
}
result->body.storage.blob_32 = buffer;
+ result->common.header.flags |= MVM_CF_USES_FSA;
result->body.storage_type = MVM_STRING_GRAPHEME_32;
}
result->body.num_graphs = count;
@@ -324,7 +330,7 @@ MVMuint32 MVM_string_utf8_decodestream(MVMThreadContext *tc, MVMDecodeStream *ds
MVMint32 state = 0;
MVMCodepoint codepoint = 0;
MVMCodepoint lag_codepoint = -1;
- MVMint32 bufsize;
+ MVMint32 bufsize, old_bufsize;
MVMGrapheme32 *buffer = NULL;
MVMDecodeStreamBytes *cur_bytes = NULL;
MVMDecodeStreamBytes *last_accept_bytes = ds->bytes_head;
@@ -346,8 +352,8 @@ MVMuint32 MVM_string_utf8_decodestream(MVMThreadContext *tc, MVMDecodeStream *ds
* use the fast path. */
can_fast_path = MVM_unicode_normalizer_empty(tc, &(ds->norm));
- bufsize = ds->result_size_guess;
- buffer = MVM_malloc(bufsize * sizeof(MVMGrapheme32));
+ old_bufsize = bufsize = ds->result_size_guess;
+ buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, bufsize * sizeof(MVMGrapheme32));
/* Decode each of the buffers. */
cur_bytes = ds->bytes_head;
@@ -396,7 +402,7 @@ MVMuint32 MVM_string_utf8_decodestream(MVMThreadContext *tc, MVMDecodeStream *ds
break;
}
case UTF8_REJECT:
- MVM_free(buffer);
+ MVM_fixed_size_free(tc, tc->instance->fsa, bufsize, buffer);
MVM_exception_throw_adhoc(tc, "Malformed UTF-8");
break;
}
@@ -425,7 +431,7 @@ MVMuint32 MVM_string_utf8_decodestream(MVMThreadContext *tc, MVMDecodeStream *ds
* one to the buffers linked list, and continue with a new
* one. */
MVM_string_decodestream_add_chars(tc, ds, buffer, bufsize);
- buffer = MVM_malloc(bufsize * sizeof(MVMGrapheme32));
+ buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, bufsize * sizeof(MVMGrapheme32));
count = 0;
}
buffer[count++] = lag_codepoint;
@@ -445,7 +451,7 @@ MVMuint32 MVM_string_utf8_decodestream(MVMThreadContext *tc, MVMDecodeStream *ds
break;
}
case UTF8_REJECT:
- MVM_free(buffer);
+ MVM_fixed_size_free(tc, tc->instance->fsa, bufsize * sizeof(MVMGrapheme32), buffer);
MVM_exception_throw_adhoc(tc, "Malformed UTF-8");
break;
}
@@ -485,7 +491,7 @@ MVMuint32 MVM_string_utf8_decodestream(MVMThreadContext *tc, MVMDecodeStream *ds
* one to the buffers linked list, and continue with a new
* one. */
MVM_string_decodestream_add_chars(tc, ds, buffer, bufsize);
- buffer = MVM_malloc(bufsize * sizeof(MVMGrapheme32));
+ buffer = MVM_fixed_size_alloc(tc, tc->instance->fsa, bufsize * sizeof(MVMGrapheme32));
count = 0;
}
buffer[count++] = g;
@@ -499,7 +505,7 @@ MVMuint32 MVM_string_utf8_decodestream(MVMThreadContext *tc, MVMDecodeStream *ds
break;
}
case UTF8_REJECT:
- MVM_free(buffer);
+ MVM_fixed_size_free(tc, tc->instance->fsa, bufsize * sizeof(MVMGrapheme32), buffer);
MVM_exception_throw_adhoc(tc, "Malformed UTF-8");
break;
}
@@ -515,7 +521,7 @@ MVMuint32 MVM_string_utf8_decodestream(MVMThreadContext *tc, MVMDecodeStream *ds
MVM_string_decodestream_add_chars(tc, ds, buffer, count);
}
else {
- MVM_free(buffer);
+ MVM_fixed_size_free(tc, tc->instance->fsa, bufsize * sizeof(MVMGrapheme32), buffer);
}
MVM_string_decodestream_discard_to(tc, ds, last_accept_bytes, last_accept_pos);
(gdb) break MVM_exception_throw_adhoc_free
Breakpoint 1 at 0x7ffff768667e: file src/core/exceptions.c, line 739.
(gdb) r
Starting program: /home/dan/Source/perl6/install/bin/moar --execname=/home/dan/Source/perl6/install/bin/perl6-gdb-m --libpath=/home/dan/Source/perl6/install/share/nqp/lib --libpath=/home/dan/Source/perl6/install/share/perl6/lib --libpath=/home/dan/Source/perl6/install/share/perl6/runtime /home/dan/Source/perl6/install/share/perl6/runtime/perl6.moarvm -e say\ \"hi\"
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff5fcf700 (LWP 1850)]
Thread 1 "moar" hit Breakpoint 1, MVM_exception_throw_adhoc_free (tc=0x5555557589a0, waste=0x7fffffffc4a0, messageFormat=0x7ffff77f66a0 "Cannot find method '%s': no method cache and no .^find_method") at src/core/exceptions.c:739
739 void MVM_exception_throw_adhoc_free(MVMThreadContext *tc, char **waste, const char *messageFormat, ...) {
(gdb) p waste[0]
$1 = 0x5555560387e0 "push"
(gdb) bt
#0 MVM_exception_throw_adhoc_free (tc=0x5555557589a0, waste=0x7fffffffc4a0, messageFormat=0x7ffff77f66a0 "Cannot find method '%s': no method cache and no .^find_method") at src/core/exceptions.c:739
#1 0x00007ffff7738b78 in MVM_6model_find_method (tc=0x5555557589a0, obj=0x7ffff6511198, name=0x555556026fb0, res=0x55555602ced8) at src/6model/6model.c:127
#2 0x00007ffff7694a17 in MVM_interp_run (tc=0x5555557589a0, initial_invoke=0x7ffff77ab6bc <toplevel_initial_invoke>, invoke_data=0x5555557d3b30) at src/core/interp.c:1818
#3 0x00007ffff77ab821 in MVM_vm_run_file (instance=0x555555758010, filename=0x7fffffffe1a9 "/home/dan/Source/perl6/install/share/perl6/runtime/perl6.moarvm") at src/moar.c:387
#4 0x000055555555541f in main (argc=8, argv=0x7fffffffdcf8) at src/main.c:255
(gdb) call MVM_dump_backtrace(tc)
at gen/moar/main.nqp:23 (/home/dan/Source/perl6/install/share/perl6/runtime/perl6.moarvm:<mainline>)
from <unknown>:1 (/home/dan/Source/perl6/install/share/perl6/runtime/perl6.moarvm:<main>)
from <unknown>:1 (/home/dan/Source/perl6/install/share/perl6/runtime/perl6.moarvm:<entry>)
(gdb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment