From 191e9bb224cad7c3ea62d986a89a9aa6301c1966 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Tue, 3 May 2016 14:39:38 -0700 Subject: 2897 --- 036abandon.cc | 143 ---------------------------------------------------------- 1 file changed, 143 deletions(-) delete mode 100644 036abandon.cc (limited to '036abandon.cc') diff --git a/036abandon.cc b/036abandon.cc deleted file mode 100644 index f454123e..00000000 --- a/036abandon.cc +++ /dev/null @@ -1,143 +0,0 @@ -//: Reclaiming memory when it's no longer used. -//: The top of layer 34 has the complete life cycle of memory. - -:(scenario new_reclaim) -def main [ - 1:address:number <- new number:type - 2:number <- copy 1:address:number # because 1 will get reset during abandon below - 1:address:number <- copy 0 # abandon - 3:address:number <- new number:type # must be same size as abandoned memory to reuse - 4:boolean <- equal 2:number, 3:address:number -] -# both allocations should have returned the same address -+mem: storing 1 in location 4 - -:(before "End Update Reference Count") -// abandon old address if necessary -// do this after all refcount updates are done, just in case old and new are identical -assert(old_address >= 0); -if (old_address == 0) return; -if (get_or_insert(Memory, old_address) < 0) { - tb_shutdown(); - DUMP(""); - cerr << "Negative refcount: " << old_address << ' ' << get_or_insert(Memory, old_address) << '\n'; - exit(0); -} -if (get_or_insert(Memory, old_address) > 0) return; -// old_address has a 0 refcount -// lookup_memory without drop_one_lookup { -trace(9999, "mem") << "automatically abandoning " << old_address << end(); -trace(9999, "mem") << "computing size to abandon at " << x.value << end(); -x.set_value(old_address+/*skip refcount*/1); -drop_from_type(x, "address"); -// } -abandon(old_address, size_of(x)+/*refcount*/1); - -//: When abandoning addresses we'll save them to a 'free list', segregated by size. - -:(before "End routine Fields") -map free_list; - -:(code) -void abandon(int address, int size) { - trace(9999, "abandon") << "saving in free-list of size " << size << end(); -//? Total_free += size; -//? Num_free++; -//? cerr << "abandon: " << size << '\n'; - // clear memory - for (int curr = address; curr < address+size; ++curr) - put(Memory, curr, 0); - // append existing free list to address - put(Memory, address, get_or_insert(Current_routine->free_list, size)); - put(Current_routine->free_list, size, address); -} - -:(before "ensure_space(size)" following "case ALLOCATE") -if (get_or_insert(Current_routine->free_list, size)) { - trace(9999, "abandon") << "picking up space from free-list of size " << size << end(); - int result = get_or_insert(Current_routine->free_list, size); - trace(9999, "mem") << "new alloc from free list: " << result << end(); - put(Current_routine->free_list, size, get_or_insert(Memory, result)); - for (int curr = result+1; curr < result+size; ++curr) { - if (get_or_insert(Memory, curr) != 0) { - raise << maybe(current_recipe_name()) << "memory in free list was not zeroed out: " << curr << '/' << result << "; somebody wrote to us after free!!!\n" << end(); - break; // always fatal - } - } - if (SIZE(current_instruction().ingredients) > 1) - put(Memory, result+/*skip refcount*/1, ingredients.at(1).at(0)); - else - put(Memory, result, 0); - products.resize(1); - products.at(0).push_back(result); - break; -} - -:(scenario new_differing_size_no_reclaim) -def main [ - 1:address:number <- new number:type - 2:number <- copy 1:address:number - 1:address:number <- copy 0 # abandon - 3:address:array:number <- new number:type, 2 # different size - 4:boolean <- equal 2:number, 3:address:array:number -] -# no reuse -+mem: storing 0 in location 4 - -:(scenario new_reclaim_array) -def main [ - 1:address:array:number <- new number:type, 2 - 2:number <- copy 1:address:array:number - 1:address:array:number <- copy 0 # abandon - 3:address:array:number <- new number:type, 2 # same size - 4:boolean <- equal 2:number, 3:address:array:number -] -# reuse -+mem: storing 1 in location 4 - -:(scenario refcounts_overwrite) -def main [ - 1:address:number <- new number:type - # over-writing one allocation with another - 1:address:number <- new number:type - 1:address:number <- copy 0 -] -+run: {1: ("address" "number")} <- new {number: "type"} -+mem: incrementing refcount of 1000: 0 -> 1 -+run: {1: ("address" "number")} <- new {number: "type"} -+mem: automatically abandoning 1000 - -:(scenario refcounts_call_2) -def main [ - 1:address:number <- new number:type - # passing in addresses to recipes increments refcount - foo 1:address:number - 1:address:number <- copy 0 -] -def foo [ - 2:address:number <- next-ingredient - # return does NOT yet decrement refcount; memory must be explicitly managed - 2:address:number <- copy 0 -] -+run: {1: ("address" "number")} <- new {number: "type"} -+mem: incrementing refcount of 1000: 0 -> 1 -+run: {2: ("address" "number")} <- next-ingredient -+mem: incrementing refcount of 1000: 1 -> 2 -+run: {2: ("address" "number")} <- copy {0: "literal"} -+mem: decrementing refcount of 1000: 2 -> 1 -+run: {1: ("address" "number")} <- copy {0: "literal"} -+mem: decrementing refcount of 1000: 1 -> 0 -+mem: automatically abandoning 1000 - -:(scenario refcounts_array) -def main [ - 1:number <- copy 30 - # allocate an array - 10:address:array:number <- new number:type, 20 - 11:number <- copy 10:address:array:number # doesn't increment refcount - # allocate another array in its place, implicitly freeing the previous allocation - 10:address:array:number <- new number:type, 25 -] -+run: {10: ("address" "array" "number")} <- new {number: "type"}, {25: "literal"} -# abandoned array is of old size (20, not 25) -+abandon: saving in free-list of size 22 -- cgit 1.4.1-2-gfad0