Create generic instances cache (#3259)
* First attempt to create generic instances cache * Change TypeScope equality check and add instance cache clearing * Move instance cache clearing call to CodeCompletion Compile funciton Шаблонные типы в instance_cache не должны пересекаться для различных модулей. Для улучшения производительности вызов очистки кэша расположен перед вызовом компиляции всех модулей. * Squashed commit of the following: commit771ea7b445Author: Ivan Bondarev <ibond84@googlemail.com> Date: Sun Apr 6 14:32:17 2025 +0200 #3230 commit28a1a03e8dAuthor: Ivan Bondarev <ibond84@googlemail.com> Date: Sun Apr 6 11:35:09 2025 +0200 #3251 commitaf7abc770bAuthor: samuraiGH <87191377+samuraiGH@users.noreply.github.com> Date: Sun Apr 6 08:33:34 2025 +0300 synchronization of namespaces and folders for TeacherControlPlugin (#3262) commitaae723b982Author: AlexanderZemlyak <92867056+AlexanderZemlyak@users.noreply.github.com> Date: Thu Apr 3 12:00:04 2025 +0300 Create default syntax tree converter class (#3216) Для удобства разработчиков простых языков, которым не требуются дополнительные обходы синтаксического дерева. commitf9cc90e50fAuthor: Sun Serega <sunserega2@gmail.com> Date: Thu Apr 3 11:59:46 2025 +0300 fix errors (#3260) commitf85bfad60fAuthor: AlexanderZemlyak <92867056+AlexanderZemlyak@users.noreply.github.com> Date: Thu Apr 3 11:58:19 2025 +0300 Intellisense memory leaks fix (#3257) * Fix memory leaks found for PABCSystem.pas Memory leaks of Interface and Implementation Unit Scopes fixed * Change open_files and recomp_files variables type to be Dictionary (not HashTable) * open_files Check simplification * Move TypeTable.Clear call to CodeCompletion Compile method * Fix incorrect dictionary iteration * Add one more dictionary keys copying
This commit is contained in:
parent
69149f8c44
commit
2e27beef48
|
|
@ -121,6 +121,8 @@ namespace CodeCompletion
|
|||
#endif
|
||||
}
|
||||
|
||||
TypeScope.instance_cache.Clear();
|
||||
|
||||
// очистка кэша и данных от старых компиляций, чтобы при новой компиляции не появились ссылки на старые данные
|
||||
TypeTable.Clear();
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ namespace CodeCompletion
|
|||
public void Convert(compilation_unit cu)
|
||||
{
|
||||
method_call_cache.Clear();
|
||||
|
||||
try
|
||||
{
|
||||
cu.visit(this);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.Parsers;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.TreeRealization;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using SymbolTable;
|
||||
using PascalABCCompiler.TreeRealization;
|
||||
using PascalABCCompiler.SyntaxTree;
|
||||
using PascalABCCompiler.Parsers;
|
||||
using System.Linq;
|
||||
using PascalABCCompiler;
|
||||
using PascalABCCompiler.TreeConverter;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CodeCompletion
|
||||
{
|
||||
|
|
@ -3589,8 +3586,23 @@ namespace CodeCompletion
|
|||
|
||||
public override TypeScope GetInstance(List<TypeScope> gen_args, bool exact = false)
|
||||
{
|
||||
|
||||
if ((elementType is UnknownScope || elementType is TemplateParameterScope) && gen_args.Count > 0)
|
||||
return new ArrayScope(gen_args[gen_args.Count-1], Rank > 1?indexes:null);
|
||||
{
|
||||
InstanceCreationContext info = new InstanceCreationContext(this, gen_args, exact);
|
||||
|
||||
if (instance_cache.TryGetValue(info, out var instance))
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
var arrayScope = new ArrayScope(gen_args[gen_args.Count - 1], Rank > 1 ? indexes : null);
|
||||
|
||||
instance_cache[info] = arrayScope;
|
||||
|
||||
return arrayScope;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -4102,6 +4114,41 @@ namespace CodeCompletion
|
|||
}
|
||||
}
|
||||
|
||||
internal struct InstanceCreationContext : IEquatable<InstanceCreationContext>
|
||||
{
|
||||
public TypeScope originalType;
|
||||
public List<TypeScope> genericArguments;
|
||||
public bool exact;
|
||||
|
||||
public InstanceCreationContext(TypeScope originalType, List<TypeScope> genericArguments, bool exact)
|
||||
{
|
||||
this.originalType = originalType;
|
||||
this.genericArguments = genericArguments;
|
||||
this.exact = exact;
|
||||
}
|
||||
|
||||
private struct ScopeComparer : IEqualityComparer<TypeScope>
|
||||
{
|
||||
public bool Equals(TypeScope t1, TypeScope t2) => t1.IsEqual(t2);
|
||||
|
||||
public int GetHashCode(TypeScope t) => t.GetDescription().GetHashCode();
|
||||
}
|
||||
|
||||
public bool Equals(InstanceCreationContext otherInfo)
|
||||
{
|
||||
|
||||
return this.originalType.IsEqual(otherInfo.originalType) &&
|
||||
this.genericArguments.SequenceEqual(otherInfo.genericArguments, new ScopeComparer()) &&
|
||||
this.exact == otherInfo.exact;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return string.Join("", genericArguments.Select(arg => arg.si != null ? arg.GetDescription() : "")
|
||||
.Concat(new string[] { originalType.GetDescription(), exact.ToString() })).GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
//opisanie tipa (klassa, zapisi) ot nego est nasledniki. sdelal ih dlja udobstva.
|
||||
public class TypeScope : SymScope, ITypeScope
|
||||
{
|
||||
|
|
@ -4122,7 +4169,7 @@ namespace CodeCompletion
|
|||
public bool is_final;
|
||||
public bool aliased = false;
|
||||
internal bool lazy_instance = false;
|
||||
private static Dictionary<TypeScope, List<TypeScope>> instance_cache = new Dictionary<TypeScope, List<TypeScope>>();
|
||||
internal static Dictionary<InstanceCreationContext, TypeScope> instance_cache = new Dictionary<InstanceCreationContext, TypeScope>();
|
||||
|
||||
public TypeScope() { }
|
||||
public TypeScope(SymbolKind kind, SymScope topScope, SymScope baseScope)
|
||||
|
|
@ -4475,7 +4522,16 @@ namespace CodeCompletion
|
|||
|
||||
public virtual TypeScope GetInstance(List<TypeScope> gen_args, bool exact = false)
|
||||
{
|
||||
|
||||
InstanceCreationContext info = new InstanceCreationContext(this, gen_args, exact);
|
||||
|
||||
if (instance_cache.TryGetValue(info, out var instance))
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
TypeScope ts = new TypeScope(this.kind, this.topScope, this.baseScope);
|
||||
|
||||
ts.original_type = this;
|
||||
ts.loc = this.loc;
|
||||
ts.other_partials = this.other_partials;
|
||||
|
|
@ -4590,6 +4646,9 @@ namespace CodeCompletion
|
|||
new_ps.nextProc = procs[ps.nextProc] as ProcScope;
|
||||
}
|
||||
}
|
||||
|
||||
instance_cache[info] = ts;
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
|
@ -5784,9 +5843,17 @@ namespace CodeCompletion
|
|||
|
||||
public override TypeScope GetInstance(List<TypeScope> gen_args, bool exact = false)
|
||||
{
|
||||
Type t = this.ctn;
|
||||
if (!ctn.IsGenericType)
|
||||
return this;
|
||||
|
||||
InstanceCreationContext info = new InstanceCreationContext(this, gen_args, exact);
|
||||
|
||||
if (instance_cache.TryGetValue(info, out var instance))
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
Type t = this.ctn;
|
||||
if (!ctn.IsGenericTypeDefinition)
|
||||
{
|
||||
t = PascalABCCompiler.NetHelper.NetHelper.FindType(this.ctn.Namespace + "." + this.ctn.Name);
|
||||
|
|
@ -5885,6 +5952,9 @@ namespace CodeCompletion
|
|||
for (int i = 0; i < this.implemented_interfaces.Count; i++)
|
||||
sc.implemented_interfaces.Add(this.implemented_interfaces[i].GetInstance(gen_args));
|
||||
sc.si.description = sc.GetDescription();
|
||||
|
||||
instance_cache[info] = sc;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using Languages.Integration;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace VisualPascalABC
|
||||
{
|
||||
|
|
@ -98,7 +97,7 @@ namespace VisualPascalABC
|
|||
{
|
||||
try
|
||||
{
|
||||
foreach (string s in open_files.Keys)
|
||||
foreach (string s in open_files.Keys.ToArray())
|
||||
{
|
||||
if (ProjectFactory.Instance.CurrentProject.ContainsSourceFile(s))
|
||||
open_files[s] = true;
|
||||
|
|
@ -147,7 +146,7 @@ namespace VisualPascalABC
|
|||
{
|
||||
Dictionary<string, string> recomp_files = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
bool is_comp = false;
|
||||
foreach (string FileName in open_files.Keys)
|
||||
foreach (string FileName in open_files.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA
|
||||
{
|
||||
|
||||
if (open_files[FileName])
|
||||
|
|
@ -181,7 +180,7 @@ namespace VisualPascalABC
|
|||
CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
|
||||
}
|
||||
}
|
||||
foreach (string FileName in open_files.Keys)
|
||||
foreach (string FileName in open_files.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA
|
||||
{
|
||||
CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter;
|
||||
CodeCompletion.SymScope ss = null;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace VisualPascalABC
|
||||
{
|
||||
|
|
@ -98,7 +98,7 @@ namespace VisualPascalABC
|
|||
{
|
||||
try
|
||||
{
|
||||
foreach (string s in open_files.Keys)
|
||||
foreach (string s in open_files.Keys.ToArray())
|
||||
{
|
||||
if (ProjectFactory.Instance.CurrentProject.ContainsSourceFile(s))
|
||||
open_files[s] = true;
|
||||
|
|
@ -151,7 +151,7 @@ namespace VisualPascalABC
|
|||
{
|
||||
Dictionary<string, string> recomp_files = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
bool is_comp = false;
|
||||
foreach (string FileName in open_files.Keys)
|
||||
foreach (string FileName in open_files.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA
|
||||
{
|
||||
|
||||
if (open_files[FileName])
|
||||
|
|
@ -185,7 +185,7 @@ namespace VisualPascalABC
|
|||
CodeCompletion.CodeCompletionController.comp_modules[FileName] = dc;
|
||||
}
|
||||
}
|
||||
foreach (string FileName in open_files.Keys)
|
||||
foreach (string FileName in open_files.Keys.ToArray()) // копирование ключей обязательно, иначе будет InvalidOperationException EVA
|
||||
{
|
||||
CodeCompletion.DomConverter dc = CodeCompletion.CodeCompletionController.comp_modules[FileName] as CodeCompletion.DomConverter;
|
||||
CodeCompletion.SymScope ss = null;
|
||||
|
|
|
|||
Loading…
Reference in a new issue