source: tests/collections/string-gc.cfa @ 4b3b352

ADTast-experimentalenumpthread-emulationqualifiedEnum
Last change on this file since 4b3b352 was 0f781fb8, checked in by Michael Brooks <mlbrooks@…>, 3 years ago

Refactoring of string internals. Existing tests pass.

Adding tracking for multiple string heaps, or "scratchpads."
Cases of allocating across different pad contexts aren't implemented yet.
Adding basic controls to manage these contexts, which lead to expected assertion failures
at unimplemented cases.

  • Property mode set to 100644
File size: 3.4 KB
Line 
1#include <string_res.hfa>
2
3size_t bytesRemaining() {
4    return DEBUG_string_bytes_avail_until_gc( DEBUG_string_heap() );
5}
6
7size_t heapOffsetStart( string_res & s ) {
8    const char * startByte = DEBUG_string_heap_start( DEBUG_string_heap() );
9    assert( s.Handle.s >= startByte );
10    return s.Handle.s - startByte;
11}
12
13void prtStrRep(const char * label, string_res & s) {
14    sout | label | "from" | heapOffsetStart(s) | "to" | (heapOffsetStart(s) + size(s));
15}
16#define PRT_STR_REP(s) prtStrRep( #s, s )
17
18void basicFillCompact() {
19    sout | "======================== basicFillCompact";
20    string_res xinit = "hello!";
21    string_res x = {xinit, COPY_VALUE};
22    string_res padder = "----|";
23    sout | x;
24    for( 3 ) {
25        x += padder;
26        sout | x;
27    }
28
29    // x and padder overlap
30    sout | "--A";
31    sout | "length of x:" | size(x);
32    PRT_STR_REP(padder);
33    PRT_STR_REP(x);
34
35    while ( bytesRemaining() + 1 > 5 ) { // until room for "q" but not another "----|" thereafter
36        x += padder;
37    }
38
39    // x and padder still overlap; now x is huge
40    sout | "--B";
41    sout | "length of x:" | size(x);
42    PRT_STR_REP(padder);
43    PRT_STR_REP(x);
44
45    assert( bytesRemaining() >= 1 );
46    x = "q";
47
48    // x and padder no longer overlap; baseline xinit
49    sout | "--C";
50    PRT_STR_REP(xinit);
51    PRT_STR_REP(padder);
52    PRT_STR_REP(x);
53
54    // want the next edit to straddle the bound
55    assert( bytesRemaining() < size(padder) );
56
57    sout | "--D";
58    sout | "before append, x = " | x;     // q
59    x += padder;                         // trigger compaction
60    sout | "after append, x = " | x;      // q----|
61
62    // x and padder moved to the start
63    sout | "--E";
64    PRT_STR_REP(xinit);
65    PRT_STR_REP(padder);
66    PRT_STR_REP(x);
67
68    // plenty of room now
69    sout | "--F";
70    sout | bytesRemaining() | "bytes available before re-fill";
71
72    // fill it again
73    string_res z = "zzz";
74    while ( bytesRemaining() > 1 ) {
75        z += ".";
76    }
77
78    sout | bytesRemaining() | "bytes available after re-fill";
79
80    // ensure not affected (shows it's not referencing an invalid location that hadn't been overwritten from the original value yet)
81    // black-box criterion that matches earlier "saw it move"
82    sout | "--G";
83    sout | "after re-fill, x = " | x;      // q----|
84
85    // leave the heap basically empty, for the next test
86    z = "";                        // turn used space into gargbage
87    string_res whatever = "asdf";  // trigger compaction
88    assert( bytesRemaining() > 100 );
89}
90
91void fillCompact_withSharedEdits() {
92    // do an assignment that causes a collection to happen, while there are edits shared (substrings)
93
94    sout | "======================== fillCompact_withSharedEdits";
95
96    // mostly fill the pad
97    string_res z = "zzz";
98    while ( bytesRemaining() > 10 ) {
99        z += ".";
100    }
101    z = "";  // leave compaction possible
102
103    // setup
104    string_res x = "hello";
105    string_res y = { x, SHARE_EDITS, 0, 5 };
106    PRT_STR_REP(x);
107    PRT_STR_REP(y);
108    sout | "-";
109
110    sout | "before reassign, x = " | x;     // hello
111    sout | "before reassign, y = " | y;     // hello
112
113    x = "0123456789"; // compact here
114
115    sout | "after reassign, x = " | x;      // 0123456789
116    sout | "after reassign, y = " | y;      // 0123456789
117
118    PRT_STR_REP(x);
119    PRT_STR_REP(y);
120}
121
122int main() {
123    basicFillCompact();
124    fillCompact_withSharedEdits();
125}
Note: See TracBrowser for help on using the repository browser.