Skip to content

Commit

Permalink
21699: Fixes bug where idempotent values containing nonidempotent val…
Browse files Browse the repository at this point in the history
…ues would not be correctly identified (#276)
  • Loading branch information
howsohazard authored Oct 1, 2024
1 parent b0a7797 commit e3114ac
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/Amalgam/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1235,4 +1235,6 @@ void Parser::PreevaluateNodes()

if(any_nodes_changed)
EvaluableNodeManager::UpdateFlagsForNodeTree(topNode);
else
EvaluableNodeManager::UpdateIdempotencyFlagsForNonCyclicNodeTree(topNode);
}
45 changes: 45 additions & 0 deletions src/Amalgam/evaluablenode/EvaluableNodeManagement.h
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,51 @@ class EvaluableNodeManager
UpdateFlagsForNodeTreeRecurse(tree, nullptr, nodeToParentNodeCache);
}

//updates idempotency flags for tree and returns true if tree is idempotent
//assumes there are no cycles
static bool UpdateIdempotencyFlagsForNonCyclicNodeTree(EvaluableNode *tree)
{
bool is_idempotent = (IsEvaluableNodeTypePotentiallyIdempotent(tree->GetType()) && (tree->GetNumLabels() == 0));

if(tree->IsAssociativeArray())
{
for(auto &[cn_id, cn] : tree->GetMappedChildNodesReference())
{
if(cn == nullptr)
continue;

bool cn_is_idempotent = UpdateIdempotencyFlagsForNonCyclicNodeTree(cn);

if(!cn_is_idempotent)
is_idempotent = false;
}

tree->SetIsIdempotent(is_idempotent);
return is_idempotent;
}
else if(!tree->IsImmediate())
{
for(auto cn : tree->GetOrderedChildNodesReference())
{
if(cn == nullptr)
continue;

auto cn_is_idempotent = UpdateIdempotencyFlagsForNonCyclicNodeTree(cn);

if(!cn_is_idempotent)
is_idempotent = false;
}

tree->SetIsIdempotent(is_idempotent);
return is_idempotent;
}
else //immediate value
{
tree->SetIsIdempotent(is_idempotent);
return is_idempotent;
}
}

//heuristic used to determine whether unused memory should be collected (e.g., by FreeAllNodesExcept*)
//force this inline because it occurs in inner loops
__forceinline bool RecommendGarbageCollection()
Expand Down

0 comments on commit e3114ac

Please sign in to comment.