Skip to content

Commit 30d7816

Browse files
Merge branch 'topic/lal.1026.context_creation_and_memory_cost' into 'master'
Improve context creation and the memory consumption Closes eng/libadalang/libadalang#1026 See merge request eng/ide/ada_language_server!1775
2 parents ef80236 + 04c4528 commit 30d7816

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2035
-70
lines changed

source/ada/lsp-ada_contexts.adb

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ with GPR2.Build.Source.Sets;
3434
with VSS.Strings.Conversions;
3535

3636
with Libadalang.Common; use Libadalang.Common;
37-
with Libadalang.Project_Provider;
3837
with Langkit_Support.Slocs;
3938

4039
with Utils.Command_Lines.Common;
@@ -48,7 +47,8 @@ with LSP.Ada_Projects;
4847

4948
package body LSP.Ada_Contexts is
5049

51-
Indexing_Trace : constant Trace_Handle := Create ("ALS.INDEXING", Off);
50+
Indexing_Debug_Trace : constant Trace_Handle :=
51+
Create ("ALS.INDEXING.DEBUG", Off);
5252

5353
use type Libadalang.Analysis.Analysis_Unit;
5454

@@ -575,10 +575,10 @@ package body LSP.Ada_Contexts is
575575
------------------
576576

577577
procedure Load_Project
578-
(Self : in out Context;
579-
Tree : GPR2.Project.Tree.Object;
580-
Root : GPR2.Project.View.Object;
581-
Charset : String)
578+
(Self : in out Context;
579+
Provider : Libadalang.Project_Provider.GPR2_Provider_And_Projects;
580+
Tree : GPR2.Project.Tree.Object;
581+
Charset : String)
582582
is
583583
procedure Update_Source_Files;
584584
-- Update the value of Self.Source_Files
@@ -677,12 +677,14 @@ package body LSP.Ada_Contexts is
677677

678678
begin
679679
Self.Source_Files.Clear;
680-
681-
Process_Closure (Root, Add_Sources_From_View'Access);
682-
683680
Self.Source_Dirs.Clear;
684681

685-
Process_Closure (Root, Add_Dirs_From_View'Access);
682+
-- Iterate on all the projects coexisting inside the Provider
683+
-- By design there is no source collision so merge them.
684+
for Project of Provider.Projects loop
685+
Process_Closure (Project, Add_Sources_From_View'Access);
686+
Process_Closure (Project, Add_Dirs_From_View'Access);
687+
end loop;
686688

687689
Self.Extension_Set.Clear;
688690

@@ -725,7 +727,7 @@ package body LSP.Ada_Contexts is
725727

726728
-- Initialize an gnatpp command line object
727729

728-
if Root.Check_Attribute
730+
if Provider.Projects.First_Element.Check_Attribute
729731
(Name => LSP.Ada_Projects.Pretty_Printer.Switches,
730732
Index => LSP.Ada_Projects.Pretty_Printer.Ada_Index,
731733
Result => Attribute)
@@ -776,13 +778,11 @@ package body LSP.Ada_Contexts is
776778
-- sharing the same name. For example for GNATTest stubs.
777779
Self.Id := VSS.Strings.Conversions.To_Virtual_String
778780
(URIs.Conversions.From_File
779-
(String (Root.Path_Name.Value)));
781+
(String (Provider.Projects.First_Element.Path_Name.Value)));
780782
Self.Tree := Tree;
781783
Self.Charset := Ada.Strings.Unbounded.To_Unbounded_String (Charset);
782784

783-
Self.Unit_Provider :=
784-
Libadalang.Project_Provider.Create_Project_Unit_Provider
785-
(Tree => Tree, Project => Root);
785+
Self.Unit_Provider := Provider.Provider;
786786

787787
Self.Event_Handler := Libadalang.Analysis.Create_Event_Handler_Reference
788788
(LSP_Context_Event_Handler_Type'(Tracer => Self.Tracer));
@@ -791,7 +791,11 @@ package body LSP.Ada_Contexts is
791791
Update_Source_Files;
792792

793793
Pretty_Printer_Setup;
794-
Self.Format_Options := Gnatformat.Configuration.From_Project (Root);
794+
-- Choose the first project in case of aggregate context, assuming
795+
-- they all share the gnatformat options.
796+
Self.Format_Options :=
797+
Gnatformat.Configuration.From_Project
798+
(Provider.Projects.First_Element);
795799
end Load_Project;
796800

797801
------------
@@ -846,7 +850,7 @@ package body LSP.Ada_Contexts is
846850
-- Add a trace before the call to Get_AU, so we can see in the traces
847851
-- the memory being consumed by Get_AU + Indexing for this file.
848852
Trace
849-
(Indexing_Trace,
853+
(Indexing_Debug_Trace,
850854
"Indexing " & (if PLE then "(PLE) " else "") &
851855
File.Display_Full_Name);
852856

@@ -856,7 +860,7 @@ package body LSP.Ada_Contexts is
856860
Unit := Self.Get_AU (File, Reparse => Reparse);
857861

858862
if Unit = Libadalang.Analysis.No_Analysis_Unit then
859-
Trace (Indexing_Trace, "No AU found: not indexing");
863+
Trace (Indexing_Debug_Trace, "No AU found: not indexing");
860864
return;
861865
end if;
862866

@@ -867,12 +871,24 @@ package body LSP.Ada_Contexts is
867871
end if;
868872

869873
Trace
870-
(Indexing_Trace,
874+
(Indexing_Debug_Trace,
871875
"Done indexing." & Integer'Image (Unit.Diagnostics'Length) &
872876
" diagnostic(s) found.");
873877
end;
874878
end Index_File;
875879

880+
---------------------------
881+
-- Add_Invisible_Symbols --
882+
---------------------------
883+
884+
procedure Add_Invisible_Symbols
885+
(Self : in out Context;
886+
File : GNATCOLL.VFS.Virtual_File;
887+
Unit : Libadalang.Analysis.Analysis_Unit) is
888+
begin
889+
Self.Source_Files.Index_File (File, Unit);
890+
end Add_Invisible_Symbols;
891+
876892
------------------
877893
-- Include_File --
878894
------------------
@@ -970,14 +986,17 @@ package body LSP.Ada_Contexts is
970986
begin
971987
Is_Known := False;
972988

973-
if View.Check_Attribute
989+
if View.Is_Defined then
990+
991+
if View.Check_Attribute
974992
(Name => Attribute,
975993
Index => Attribute_Index,
976994
Result => Attribute_Value)
977-
then
978-
Is_List_Attribute := (Attribute_Value.Kind = List);
979-
Is_Known := True;
980-
return Convert (Attribute_Value.Values);
995+
then
996+
Is_List_Attribute := (Attribute_Value.Kind = List);
997+
Is_Known := True;
998+
return Convert (Attribute_Value.Values);
999+
end if;
9811000
end if;
9821001

9831002
return [];

source/ada/lsp-ada_contexts.ads

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ with Laltools.Common;
3333

3434
with Libadalang.Analysis;
3535
with Libadalang.Common;
36+
with Libadalang.Project_Provider;
3637

3738
with Utils.Command_Lines;
3839
with Pp.Command_Lines;
@@ -66,10 +67,10 @@ package LSP.Ada_Contexts is
6667
-- in particular.
6768

6869
procedure Load_Project
69-
(Self : in out Context;
70-
Tree : GPR2.Project.Tree.Object;
71-
Root : GPR2.Project.View.Object;
72-
Charset : String);
70+
(Self : in out Context;
71+
Provider : Libadalang.Project_Provider.GPR2_Provider_And_Projects;
72+
Tree : GPR2.Project.Tree.Object;
73+
Charset : String);
7374
-- Use the given project tree, and root project within this project
7475
-- tree, as project for this context. Root must be a non-aggregate
7576
-- project tree representing the root of a hierarchy inside Tree.
@@ -232,6 +233,13 @@ package LSP.Ada_Contexts is
232233
-- If PLE is True, Populate_Lexical_Env is called at the end, which will
233234
-- increase the speed of semantic requests.
234235

236+
procedure Add_Invisible_Symbols
237+
(Self : in out Context;
238+
File : GNATCOLL.VFS.Virtual_File;
239+
Unit : Libadalang.Analysis.Analysis_Unit);
240+
-- Add invisible symbols present in Unit to the given context's cache,
241+
-- even if Unit is not known by this context.
242+
235243
procedure Include_File
236244
(Self : in out Context; File : GNATCOLL.VFS.Virtual_File);
237245
-- Includes File in Self's source files
@@ -342,7 +350,7 @@ private
342350
-- Indicate that this is a "fallback" context, ie the context
343351
-- holding any file, in the case no valid project was loaded.
344352

345-
Tree : GPR2.Project.Tree.Object;
353+
Tree : GPR2.Project.Tree.Object := GPR2.Project.Tree.Undefined;
346354
-- The loaded project tree: we need to keep a reference to this
347355
-- in order to figure out which files are Ada and which are not.
348356

source/ada/lsp-ada_handlers-project_loading.adb

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pragma Warnings (Off, "unit ""GPR2.Build.Source.Sets"" is not referenced");
3535
with GPR2.Build.Source.Sets;
3636

3737
with Libadalang.Preprocessing;
38+
with Libadalang.Project_Provider;
3839
with LSP.Ada_Contexts;
3940
with LSP.Ada_Context_Sets;
4041
with LSP.Ada_Documents; use LSP.Ada_Documents;
@@ -349,9 +350,23 @@ package body LSP.Ada_Handlers.Project_Loading is
349350
end if;
350351

351352
Reload_Implicit_Project_Dirs (Self);
352-
C.Load_Project (Self.Project_Tree,
353-
Self.Project_Tree.Root_Project,
354-
"iso-8859-1");
353+
354+
-- Create a basic GPR2_Provider_And_Projects containing only the
355+
-- implicit project and load it.
356+
declare
357+
Provider : Libadalang.Project_Provider.GPR2_Provider_And_Projects :=
358+
(Provider =>
359+
Libadalang.Project_Provider.Create_Project_Unit_Provider
360+
(Tree => Self.Project_Tree,
361+
Project => Self.Project_Tree.Root_Project),
362+
Projects => <>);
363+
begin
364+
Provider.Projects.Append (Self.Project_Tree.Root_Project);
365+
C.Load_Project
366+
(Provider => Provider,
367+
Tree => Self.Project_Tree,
368+
Charset => "iso-8859-1");
369+
end;
355370

356371
Update_Project_Predefined_Sources (Self);
357372

@@ -373,6 +388,7 @@ package body LSP.Ada_Handlers.Project_Loading is
373388
Environment : GPR2.Environment.Object;
374389
Charset : VSS.Strings.Virtual_String)
375390
is
391+
use Libadalang.Project_Provider;
376392
use type VSS.Strings.Virtual_String;
377393
use type GNATCOLL.VFS.Virtual_File;
378394

@@ -384,8 +400,11 @@ package body LSP.Ada_Handlers.Project_Loading is
384400
Root : GNATCOLL.VFS.Virtual_File;
385401

386402
procedure Create_Context_For_Non_Aggregate
387-
(View : GPR2.Project.View.Object);
403+
(View : GPR2.Project.View.Object;
404+
Provider : GPR2_Provider_And_Projects);
388405
-- Create a new context for the given project view.
406+
-- It will use the same LAL provider (Provider.Provider) for the all the
407+
-- subprojects (Provider.Projects)
389408

390409
procedure Log_GPR2_Diagnostics;
391410
-- Log the GPR2 messages
@@ -395,7 +414,8 @@ package body LSP.Ada_Handlers.Project_Loading is
395414
--------------------------------------
396415

397416
procedure Create_Context_For_Non_Aggregate
398-
(View : GPR2.Project.View.Object)
417+
(View : GPR2.Project.View.Object;
418+
Provider : GPR2_Provider_And_Projects)
399419
is
400420
use LSP.Ada_Context_Sets;
401421
use LSP.Ada_Contexts;
@@ -453,12 +473,12 @@ package body LSP.Ada_Handlers.Project_Loading is
453473
Follow_Symlinks => Self.Configuration.Follow_Symlinks);
454474

455475
C.Load_Project
456-
(Tree => Self.Project_Tree,
457-
Root => View,
458-
Charset => VSS.Strings.Conversions.To_UTF_8_String (Charset));
476+
(Provider => Provider,
477+
Tree => Self.Project_Tree,
478+
Charset => VSS.Strings.Conversions.To_UTF_8_String (Charset));
459479

460480
Tracer.Trace ("Prepend Context Id: "
461-
& VSS.Strings.Conversions.To_UTF_8_String (C.Id));
481+
& VSS.Strings.Conversions.To_UTF_8_String (C.Id));
462482
Self.Contexts.Prepend (C);
463483
end Create_Context_For_Non_Aggregate;
464484

@@ -599,12 +619,33 @@ package body LSP.Ada_Handlers.Project_Loading is
599619
Update_Project_Predefined_Sources (Self);
600620

601621
if Self.Project_Tree.Root_Project.Kind in GPR2.Aggregate_Kind then
602-
for View of Self.Project_Tree.Root_Project.Aggregated loop
603-
Create_Context_For_Non_Aggregate (View);
604-
end loop;
622+
-- For aggregated root project, use LAL to create sets of
623+
-- aggregated projects and sub-projects which can coexist in
624+
-- the same LAL provider to reduce the memory footprint.
625+
declare
626+
Providers : GPR2_Provider_And_Projects_Array_Access :=
627+
Create_Project_Unit_Providers (Self.Project_Tree);
628+
begin
629+
for Provider of Providers.all loop
630+
Create_Context_For_Non_Aggregate
631+
(View => Self.Project_Tree.Root_Project,
632+
Provider => Provider);
633+
end loop;
634+
Free (Providers);
635+
end;
605636
else
606-
Create_Context_For_Non_Aggregate
607-
(Self.Project_Tree.Root_Project);
637+
declare
638+
Provider : GPR2_Provider_And_Projects :=
639+
(Provider => Create_Project_Unit_Provider
640+
(Tree => Self.Project_Tree,
641+
Project => Self.Project_Tree.Root_Project),
642+
Projects => <>);
643+
begin
644+
Provider.Projects.Append (Self.Project_Tree.Root_Project);
645+
Create_Context_For_Non_Aggregate
646+
(View => Self.Project_Tree.Root_Project,
647+
Provider => Provider);
648+
end;
608649
end if;
609650
end if;
610651

@@ -680,17 +721,16 @@ package body LSP.Ada_Handlers.Project_Loading is
680721
end loop;
681722
end loop;
682723

683-
if Runtime_Indexing.Is_Active then
724+
-- Avoid indexing the runtime in case of aggregate projects:
725+
-- runtime files are present in all contexts, indexing them
726+
-- in all contexts would cost too much memory
727+
if Runtime_Indexing.Is_Active
728+
and then Self.Project_Tree.Is_Defined
729+
and then Self.Project_Tree.Root_Project.Kind not in GPR2.Aggregate_Kind
730+
then
684731
-- Mark all the predefined sources too (runtime)
685732
for F in Self.Project_Predefined_Sources.Iterate loop
686-
declare
687-
File : GNATCOLL.VFS.Virtual_File
688-
renames LSP.Ada_File_Sets.File_Sets.Element (F);
689-
begin
690-
for Context of Self.Contexts.Each_Context loop
691-
Files.Include (File);
692-
end loop;
693-
end;
733+
Files.Include (LSP.Ada_File_Sets.File_Sets.Element (F));
694734
end loop;
695735
end if;
696736

source/ada/lsp-ada_handlers-renaming.adb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ package body LSP.Ada_Handlers.Renaming is
173173
elsif Versioned_Documents then
174174

175175
Result.documentChanges.Append (Item);
176+
-- Here we should avoid/remove duplicates
176177

177178
else
178179

@@ -183,7 +184,12 @@ package body LSP.Ada_Handlers.Renaming is
183184
end if;
184185

185186
for X of Item.Variant_1.edits loop
186-
Result.changes (URI).Append (X.TextEdit);
187+
-- Search if this exact textEdit was already added by
188+
-- another context
189+
if not Result.changes (URI).Find (X.TextEdit).Has_Element
190+
then
191+
Result.changes (URI).Append (X.TextEdit);
192+
end if;
187193
end loop;
188194
end if;
189195
end Append;

0 commit comments

Comments
 (0)