2767 - reclaim refcounts for local variables

This uncovered a second bug (besides 2766) -- I was manually doing the
work of 'new-fake-console' inside 'assume-console' but forgetting to
increment a refcount.
This commit is contained in:
Kartik K. Agaram 2016-03-12 20:41:35 -08:00
parent 194c4ed71d
commit d8f2d0b130
2 changed files with 36 additions and 0 deletions

View File

@ -211,6 +211,14 @@ def foo [
# both calls to foo should have received the same default-space
+mem: storing 1 in location 3
:(scenario local_scope_frees_up_allocations)
def main [
local-scope
x:address:shared:array:character <- new [abc]
]
+mem: clearing x:address:shared:array:character
//: todo: do this in a transform, rather than magically in the reply instruction
:(after "Falling Through End Of Recipe")
try_reclaim_locals();
:(after "Starting Reply")
@ -231,10 +239,36 @@ void try_reclaim_locals() {
if (exiting_recipe.steps.empty()) return;
const instruction& inst = exiting_recipe.steps.at(0);
if (inst.old_name != "local-scope") return;
// reclaim any local variables unless they're being returned
vector<double> zero;
zero.push_back(0);
for (long long int i = /*leave default space for last*/1; i < SIZE(exiting_recipe.steps); ++i) {
const instruction& inst = exiting_recipe.steps.at(i);
for (long long int i = 0; i < SIZE(inst.products); ++i) {
if (!is_mu_address(inst.products.at(i))) continue;
// local variables only
if (has_property(inst.products.at(i), "space")) continue;
if (has_property(inst.products.at(i), "lookup")) continue;
if (escaping(inst.products.at(i))) continue;
trace(9999, "mem") << "clearing " << inst.products.at(i).original_string << end();
write_memory(inst.products.at(i), zero);
}
}
abandon(current_call().default_space,
/*refcount*/1 + /*array length*/1 + /*number-of-locals*/Name[r][""]);
}
// is this reagent one of the values returned by the current (reply) instruction?
bool escaping(const reagent& r) {
// nothing escapes when you fall through past end of recipe
if (current_step_index() >= SIZE(Current_routine->steps())) return false;
for (long long i = 0; i < SIZE(current_instruction().ingredients); ++i) {
if (r == current_instruction().ingredients.at(i))
return true;
}
return false;
}
void rewrite_default_space_instruction(instruction& curr) {
if (!curr.ingredients.empty())
raise << to_string(curr) << " can't take any ingredients\n" << end();

View File

@ -119,6 +119,8 @@ case ASSUME_CONSOLE: {
long long int console_address = get_or_insert(Memory, CONSOLE);
trace(9999, "mem") << "storing console data in " << console_address+2 << end();
put(Memory, console_address+/*skip refcount*/1+/*offset of 'data' in container 'events'*/1, event_data_address);
// increment refcount for event data
put(Memory, event_data_address, 1);
break;
}