From 1ca4b0f09e59d07aac423cd331228a838de0cf75 Mon Sep 17 00:00:00 2001 From: Luis Rivera Date: Fri, 28 Feb 2025 09:57:53 -0500 Subject: [PATCH 1/3] cleanup dependency graph from old nodes --- src/Engine/ProtoAssociative/CodeGen.cs | 11 +++-- src/Engine/ProtoCore/AssociativeGraph.cs | 42 ++++++++++++++++---- src/Engine/ProtoCore/CodeGen.cs | 2 +- src/Engine/ProtoImperative/CodeGen.cs | 2 +- src/Engine/ProtoScript/Runners/LiveRunner.cs | 3 ++ 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/Engine/ProtoAssociative/CodeGen.cs b/src/Engine/ProtoAssociative/CodeGen.cs index 051db64648a..3299abf38ab 100644 --- a/src/Engine/ProtoAssociative/CodeGen.cs +++ b/src/Engine/ProtoAssociative/CodeGen.cs @@ -2156,7 +2156,8 @@ public override int Emit(ProtoCore.AST.Node codeBlockNode, ProtoCore.Associative hasReturnStatement = EmitCodeBlock(codeblock.Body, ref inferedType, ProtoCore.CompilerDefinitions.SubCompilePass.UnboundIdentifier, false); if (compilePass == ProtoCore.CompilerDefinitions.CompilePass.GlobalScope && !hasReturnStatement) { - EmitReturnNull(); + var guidList = codeblock.Body.Select(x=> (x as BinaryExpressionNode)?.guid).Where(x=>x!=null).ToList(); + EmitReturnNull(guidList.Any() ? guidList.Last() : null); } compilePass++; @@ -5909,7 +5910,7 @@ private void EmitGroupExpressionNode(AssociativeNode node, ref ProtoCore.Type in } } - protected override void EmitReturnNull() + protected override void EmitReturnNull(Guid? guid = null) { int startpc = pc; @@ -5928,6 +5929,10 @@ protected override void EmitReturnNull() retNode.updateBlock.startpc = startpc; retNode.updateBlock.endpc = pc - 1; retNode.isReturn = true; + if (guid != null) + { + retNode.guid = (Guid)guid; + } PushGraphNode(retNode); } @@ -6130,4 +6135,4 @@ protected override void DfsTraverse(ProtoCore.AST.Node pNode, ref ProtoCore.Type int blockId = codeBlock.codeBlockId; } } -} \ No newline at end of file +} diff --git a/src/Engine/ProtoCore/AssociativeGraph.cs b/src/Engine/ProtoCore/AssociativeGraph.cs index f18433e6565..7f361d1430a 100644 --- a/src/Engine/ProtoCore/AssociativeGraph.cs +++ b/src/Engine/ProtoCore/AssociativeGraph.cs @@ -57,7 +57,12 @@ public static void BuildGraphNodeDependencies(List g { return; } - + for (int i = 0; i < graphNodesInScope.Count; ++i) + { + AssociativeGraph.GraphNode currentNode = graphNodesInScope[i]; + currentNode.ParentNodes.Clear(); + currentNode.ChildrenNodes.Clear(); + } // Get the current graphnode to check against the list // [a = 10] -> this one // c = 1 @@ -967,33 +972,32 @@ internal IEnumerable ClearCycles(IEnumerable graphNodes) Stack stack = new Stack(); stack.Push(this); - var visited = graphNodes.ToDictionary(node => node, node => false); + var visited = new HashSet(); - var guids = new List(); + var guids = new HashSet(); while(stack.Any()) { var node = stack.Pop(); - if (!visited[node]) + if (!visited.Contains(node.UID)) { guids.Add(node.guid); if (node.isCyclic) { node.isCyclic = false; node.isActive = true; - } - visited[node] = true; + visited.Add(node.UID); } foreach(var cNode in node.ChildrenNodes) { - if (!visited[cNode]) + if (!visited.Contains(cNode.UID)) { stack.Push(cNode); } } } - return guids; + return guids.ToList(); } public void PushDependent(GraphNode dependent) @@ -1500,6 +1504,28 @@ private ulong GetGraphNodeKey(int classIndex, int procIndex) return (((ulong)ci) << 32) | pi; } + public void Purge(List oldNodes) + { + HashSet oldGuids = []; + foreach (AST.AssociativeAST.AssociativeNode astNode in oldNodes) + { + var x = (astNode as AST.AssociativeAST.BinaryExpressionNode)?.guid; + if (x != null) + { + oldGuids.Add(x.Value); + } + } + if(oldGuids.Count == 0) + { + return; + } + List nodeList; + if(graphNodeMap.TryGetValue(GetGraphNodeKey(Constants.kInvalidPC, Constants.kInvalidPC), out nodeList)) + { + nodeList.RemoveAll(node => oldGuids.Contains(node.guid)); + } + } + public DependencyGraph(Core core) { this.core = core; diff --git a/src/Engine/ProtoCore/CodeGen.cs b/src/Engine/ProtoCore/CodeGen.cs index 860633c92a3..37b05cc2c2d 100644 --- a/src/Engine/ProtoCore/CodeGen.cs +++ b/src/Engine/ProtoCore/CodeGen.cs @@ -2363,7 +2363,7 @@ protected bool InsideFunction() // used to manully emit "return = null" instruction if a function or language block does not have a return statement // there is update code involved in associativen code gen, so it is not implemented here - protected abstract void EmitReturnNull(); + protected abstract void EmitReturnNull(Guid? guid = null); protected abstract void DfsTraverse(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.SubCompilePass subPass = ProtoCore.CompilerDefinitions.SubCompilePass.None, ProtoCore.AST.Node parentNode = null); diff --git a/src/Engine/ProtoImperative/CodeGen.cs b/src/Engine/ProtoImperative/CodeGen.cs index 769e61cb03e..fcd4fa2057b 100644 --- a/src/Engine/ProtoImperative/CodeGen.cs +++ b/src/Engine/ProtoImperative/CodeGen.cs @@ -2543,7 +2543,7 @@ private void EmitSetExpressionUID(int exprId) //AppendInstruction(instr); } - protected override void EmitReturnNull() + protected override void EmitReturnNull(Guid? guid = null) { EmitPushNull(); EmitReturnToRegister(); diff --git a/src/Engine/ProtoScript/Runners/LiveRunner.cs b/src/Engine/ProtoScript/Runners/LiveRunner.cs index a4908a75044..2e426f4725a 100644 --- a/src/Engine/ProtoScript/Runners/LiveRunner.cs +++ b/src/Engine/ProtoScript/Runners/LiveRunner.cs @@ -1660,6 +1660,7 @@ private void CompileAndExecuteForDeltaExecution(List astList) } ResetForDeltaExecution(); + runnerCore.CodeBlockList[(int)Language.Associative].instrStream.dependencyGraph.Purge(dispatchASTList); CompileAndExecute(dispatchASTList); PostExecution(); } @@ -1721,6 +1722,8 @@ private void SynchronizeInternal(GraphSyncData syncData) var guids = runtimeCore.ExecutedAstGuids.ToList(); executedAstGuids[syncData.SessionID] = guids; runtimeCore.RemoveExecutedAstGuids(); + + runnerCore.CodeBlockList[(int)Language.Associative].instrStream.dependencyGraph.Purge(changeSetComputer.csData.DeletedBinaryExprASTNodes); } } From 1a22533c6e74c5cc11b26fcba1663a91ebe17d70 Mon Sep 17 00:00:00 2001 From: Luis Rivera Date: Fri, 28 Feb 2025 10:09:20 -0500 Subject: [PATCH 2/3] public function as internal --- src/Engine/ProtoCore/AssociativeGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/ProtoCore/AssociativeGraph.cs b/src/Engine/ProtoCore/AssociativeGraph.cs index 7f361d1430a..115226cd4aa 100644 --- a/src/Engine/ProtoCore/AssociativeGraph.cs +++ b/src/Engine/ProtoCore/AssociativeGraph.cs @@ -1504,7 +1504,7 @@ private ulong GetGraphNodeKey(int classIndex, int procIndex) return (((ulong)ci) << 32) | pi; } - public void Purge(List oldNodes) + internal void Purge(List oldNodes) { HashSet oldGuids = []; foreach (AST.AssociativeAST.AssociativeNode astNode in oldNodes) From ed2bb46bde29310ce6e1ef056585d2073533cd3b Mon Sep 17 00:00:00 2001 From: Luis Rivera Date: Fri, 28 Feb 2025 11:27:23 -0500 Subject: [PATCH 3/3] preserve public API --- src/Engine/ProtoAssociative/CodeGen.cs | 6 +++++- src/Engine/ProtoCore/CodeGen.cs | 3 ++- src/Engine/ProtoImperative/CodeGen.cs | 5 +++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Engine/ProtoAssociative/CodeGen.cs b/src/Engine/ProtoAssociative/CodeGen.cs index 3299abf38ab..527f9270469 100644 --- a/src/Engine/ProtoAssociative/CodeGen.cs +++ b/src/Engine/ProtoAssociative/CodeGen.cs @@ -5910,7 +5910,7 @@ private void EmitGroupExpressionNode(AssociativeNode node, ref ProtoCore.Type in } } - protected override void EmitReturnNull(Guid? guid = null) + protected override void EmitReturnNull(Guid? guid) { int startpc = pc; @@ -5936,6 +5936,10 @@ protected override void EmitReturnNull(Guid? guid = null) PushGraphNode(retNode); } + protected override void EmitReturnNull() + { + EmitReturnNull(null); + } private ProtoCore.Type BuildArgumentTypeFromVarDeclNode(VarDeclNode argNode, GraphNode graphNode = null) { diff --git a/src/Engine/ProtoCore/CodeGen.cs b/src/Engine/ProtoCore/CodeGen.cs index 37b05cc2c2d..cd23f495027 100644 --- a/src/Engine/ProtoCore/CodeGen.cs +++ b/src/Engine/ProtoCore/CodeGen.cs @@ -2363,7 +2363,8 @@ protected bool InsideFunction() // used to manully emit "return = null" instruction if a function or language block does not have a return statement // there is update code involved in associativen code gen, so it is not implemented here - protected abstract void EmitReturnNull(Guid? guid = null); + protected abstract void EmitReturnNull(Guid? guid); + protected abstract void EmitReturnNull(); protected abstract void DfsTraverse(Node node, ref ProtoCore.Type inferedType, bool isBooleanOp = false, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.CompilerDefinitions.SubCompilePass subPass = ProtoCore.CompilerDefinitions.SubCompilePass.None, ProtoCore.AST.Node parentNode = null); diff --git a/src/Engine/ProtoImperative/CodeGen.cs b/src/Engine/ProtoImperative/CodeGen.cs index fcd4fa2057b..bed77a09d3a 100644 --- a/src/Engine/ProtoImperative/CodeGen.cs +++ b/src/Engine/ProtoImperative/CodeGen.cs @@ -2549,6 +2549,11 @@ protected override void EmitReturnNull(Guid? guid = null) EmitReturnToRegister(); } + protected override void EmitReturnNull() + { + EmitReturnNull(null); + } + protected void EmitGropuExpressionNode(ImperativeNode node, ref ProtoCore.Type inferedType) { GroupExpressionNode group = node as GroupExpressionNode;