source: tests/collections/string-gc.cfa@ 2137eb7

Last change on this file since 2137eb7 was 7b0e8b7, checked in by Michael Brooks <mlbrooks@…>, 4 years ago

String heap growth implemented

  • Property mode set to 100644
File size: 4.2 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
122void fillNoCompact() {
123 // show that allocating in a heap filled with mostly live strings (no collectable garbage) causes heap growth
124
125 sout | "======================== fillNoCompact";
126
127 size_t lastTimeBytesAvail = bytesRemaining();
128 assert( lastTimeBytesAvail >= 200 ); // starting this test with nontrivial room
129
130 // mostly fill the pad
131 string_res a = "aaa"; // will have to be moved
132 string_res z = "zzz";
133 for (i; 5) {
134 while ( bytesRemaining() > 10 ) {
135 z += ".";
136 }
137 sout | "about to expand, a = " | a;
138 while ( bytesRemaining() <= 10 ) {
139 z += ".";
140 }
141 sout | "expanded, a = " | a;
142
143 // each growth gives more usable space than the last
144 assert( bytesRemaining() > lastTimeBytesAvail );
145 lastTimeBytesAvail = bytesRemaining();
146 }
147}
148
149int main() {
150 basicFillCompact();
151 fillCompact_withSharedEdits();
152 fillNoCompact();
153}
Note: See TracBrowser for help on using the repository browser.