-
-
Save MasterDuke17/f29bc6caa2aae6417e0eda676e545a81 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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