1
2
3 :(scenario new_reclaim)
4 def main [
5 1:address:num <- new number:type
6 2:num <- copy 1:address:num
7 abandon 1:address:num
8 3:address:num <- new number:type
9 4:num <- copy 3:address:num
10 5:bool <- equal 2:num, 4:num
11 ]
12
13 +mem: storing 1 in location 5
14
15
16
17 :(before "End routine Fields")
18 map<int, int> free_list;
19
20 :(before "End Primitive Recipe Declarations")
21 ABANDON,
22 :(before "End Primitive Recipe Numbers")
23 put(Recipe_ordinal, "abandon", ABANDON);
24 :(before "End Primitive Recipe Checks")
25 case ABANDON: {
26 if (!inst.products.empty()) {
27 raise << maybe(get(Recipe, r).name) << "'abandon' shouldn't write to any products in '" << to_original_string(inst) << "'\n" << end();
28 break;
29 }
30 for (int i = 0; i < SIZE(inst.ingredients); ++i) {
31 if (!is_mu_address(inst.ingredients.at(i)))
32 raise << maybe(get(Recipe, r).name) << "ingredients of 'abandon' should be addresses, but ingredient " << i << " is '" << to_string(inst.ingredients.at(i)) << '\n' << end();
33 break;
34 }
35 break;
36 }
37 :(before "End Primitive Recipe Implementations")
38 case ABANDON: {
39 for (int i = 0; i < SIZE(current_instruction().ingredients); ++i) {
40 reagent ingredient = current_instruction().ingredients.at(i);
41 canonize(ingredient);
42 abandon(get_or_insert(Memory, ingredient.value), payload_size(ingredient));
43 }
44 break;
45 }
46
47 :(code)
48 void abandon(int address, int payload_size) {
49
50 for (int curr = address; curr < address+payload_size; ++curr)
51 put(Memory, curr, 0);
52
53 trace("abandon") << "saving " << address << " in free-list of size " << payload_size << end();
54 put(Memory, address, get_or_insert(Current_routine->free_list, payload_size));
55 put(Current_routine->free_list, payload_size, address);
56 }
57
58 int payload_size(reagent x) {
59 x.properties.push_back(pair<string, string_tree*>("lookup", NULL));
60 lookup_memory_core(x, false);
61 return size_of(x);
62 }
63
64 :(after "Allocate Special-cases")
65 if (get_or_insert(Current_routine->free_list, size)) {
66 trace("abandon") << "picking up space from free-list of size " << size << end();
67 int result = get_or_insert(Current_routine->free_list, size);
68 trace("mem") << "new alloc from free list: " << result << end();
69 put(Current_routine->free_list, size, get_or_insert(Memory, result));
70 put(Memory, result, 0);
71 for (int curr = result; curr < result+size; ++curr) {
72 if (get_or_insert(Memory, curr) != 0) {
73 raise << maybe(current_recipe_name()) << "memory in free list was not zeroed out: " << curr << '/' << result << "; somebody wrote to us after free!!!\n" << end();
74 break;
75 }
76 }
77 return result;
78 }
79
80 :(scenario new_differing_size_no_reclaim)
81 def main [
82 1:address:num <- new number:type
83 2:num <- copy 1:address:num
84 abandon 1:address:num
85 3:address:array:num <- new number:type, 2
86 4:num <- copy 3:address:array:num
87 5:bool <- equal 2:num, 4:num
88 ]
89
90 +mem: storing 0 in location 5
91
92 :(scenario new_reclaim_array)
93 def main [
94 1:address:array:num <- new number:type, 2
95 2:num <- copy 1:address:array:num
96 abandon 1:address:array:num
97 3:address:array:num <- new number:type, 2
98 4:num <- copy 3:address:array:num
99 5:bool <- equal 2:num, 4:num
100 ]
101
102 +mem: storing 1 in location 5