gojimmypi / VerilogLanguageExtension

Verilog Language Extension for Visual Studio
https://marketplace.visualstudio.com/items?itemName=gojimmypi.gojimmypi-verilog-language-extension
MIT License
18 stars 3 forks source link

fix poor performance on big files #23

Open gojimmypi opened 4 years ago

gojimmypi commented 4 years ago

as noted in https://github.com/gojimmypi/VerilogLanguageExtension/issues/21#issuecomment-620237275 - performance on large files is really poor due to excessive re-parsing of the entire buffer,

gojimmypi commented 4 years ago

I think the key to the threaded work-around, is to redraw the viewport upon completion of the VerilogGlobals.Reparse thread in ViewLayoutChanged.

I tried doing something like this from a stackoverflow example of adding a callback upon completion:

        private void Start()
        {
            System.Diagnostics.Debug.WriteLine("1. Call thread task");

            StartMyLongRunningTask();

            System.Diagnostics.Debug.WriteLine("2. Do something else");
        }

        private void StartMyLongRunningTask()
        {

            System.Threading.ThreadStart starter = myLongRunningTask;

            starter += () =>
            {
                myLongRunningTaskDone();
            };

            System.Threading.Thread _thread = new System.Threading.Thread(starter) { IsBackground = true };
            _thread.Start();
        }

        private void myLongRunningTaskDone()
        {
            System.Diagnostics.Debug.WriteLine("3. Task callback result");
        }

        private void myLongRunningTask()
        {
            string thisFile = VerilogLanguage.VerilogGlobals.GetDocumentPath(SourceBuffer.CurrentSnapshot);
            VerilogGlobals.Reparse(SourceBuffer, thisFile); // note that above, we are checking that the e.After is the same as the _buffer
        }

        // Step 4: The event handlers both call the UpdateAtCaretPosition method.
        void ViewLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
        {
            // If a new snapshot wasn't generated, then skip this layout   
            if (e.NewSnapshot != e.OldSnapshot)
            {
                UpdateAtCaretPosition(View.Caret.Position);
                string thisFile = VerilogLanguage.VerilogGlobals.GetDocumentPath(View.TextSnapshot);
                ParseStatusController.NeedReparse_SetValue(thisFile, true);
                StartMyLongRunningTask();
            }
        }

But it crashes at file-open time, logged to this file:

C:\Users\gojimmypi\AppData\Roaming\Microsoft\VisualStudio\15.0_428c78f4Exp\ActivityLog.xml

In the (VS2017) ActivityLog.xml file, with this message as shown at the end:

  <entry>
    <record>939</record>
    <time>2020/05/03 15:03:46.711</time>
    <type>Information</type>
    <source>VisualStudio</source>
    <description>Begin package load [Visual Studio XML Editor Package]</description>
    <guid>{87569308-4813-40A0-9CD0-D7A30838CA3F}</guid>
  </entry>
  <entry>
    <record>940</record>
    <time>2020/05/03 15:03:46.746</time>
    <type>Information</type>
    <source>VisualStudio</source>
    <description>End package load [Visual Studio XML Editor Package]</description>
    <guid>{87569308-4813-40A0-9CD0-D7A30838CA3F}</guid>
  </entry>
  <entry>
    <record>941</record>
    <time>2020/05/03 15:03:47.338</time>
    <type>Error</type>
    <source>Microsoft.VisualStudio.CommonIDE.ExtensibilityHosting.VsShellComponentModelHost</source>
    <description>A MEF Component threw an exception at runtime: System.ArgumentException: Field &apos;ClassificationTypeRegistry&apos; defined on type &apos;VerilogLanguage.VerilogToken.VerilogClassifierProvider&apos; is not a field on the target object which is of type &apos;VerilogLanguage.Highlighting.HighlightWordTaggerProvider&apos;.&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.CheckConsistency(Object target)&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, StackCrawlMark&amp; stackMark)&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.SetImportingMember(Object part, MemberInfo member, Object value)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.SatisfyImports()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.SatisfyImmediateImports()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()</description>
  </entry>
  <entry>
    <record>942</record>
    <time>2020/05/03 15:03:47.353</time>
    <type>Error</type>
    <source>Editor or Editor Extension</source>
    <description>System.ArgumentException: Field &apos;ClassificationTypeRegistry&apos; defined on type &apos;VerilogLanguage.VerilogToken.VerilogClassifierProvider&apos; is not a field on the target object which is of type &apos;VerilogLanguage.Highlighting.HighlightWordTaggerProvider&apos;.&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.CheckConsistency(Object target)&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, StackCrawlMark&amp; stackMark)&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.SetImportingMember(Object part, MemberInfo member, Object value)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.SatisfyImports()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.SatisfyImmediateImports()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.DelegateServices.&lt;&gt;c__DisplayClass2_0`1.&lt;As&gt;b__0()&#x000D;&#x000A;   at System.Lazy`1.CreateValue()&#x000D;&#x000A;   at System.Lazy`1.LazyInitValue()&#x000D;&#x000A;   at System.Lazy`1.get_Value()&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.GatherTaggers(ITextBuffer textBuffer)&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at Microsoft.VisualStudio.Telemetry.WindowsErrorReporting.WatsonReport.GetClrWatsonExceptionInfo(Exception exceptionObject)</description>
  </entry>
  <entry>
    <record>943</record>
    <time>2020/05/03 15:03:47.649</time>
    <type>Error</type>
    <source>Editor or Editor Extension</source>
    <description>System.ArgumentException: Field &apos;ClassificationTypeRegistry&apos; defined on type &apos;VerilogLanguage.VerilogToken.VerilogClassifierProvider&apos; is not a field on the target object which is of type &apos;VerilogLanguage.Highlighting.HighlightWordTaggerProvider&apos;.&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.CheckConsistency(Object target)&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, StackCrawlMark&amp; stackMark)&#x000D;&#x000A;   at System.Reflection.RtFieldInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.SetImportingMember(Object part, MemberInfo member, Object value)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.SatisfyImports()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.SatisfyImmediateImports()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.DelegateServices.&lt;&gt;c__DisplayClass2_0`1.&lt;As&gt;b__0()&#x000D;&#x000A;   at System.Lazy`1.CreateValue()&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()&#x000D;&#x000A;   at System.Lazy`1.get_Value()&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.GatherTaggers(ITextBuffer textBuffer)&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at Microsoft.VisualStudio.Telemetry.WindowsErrorReporting.WatsonReport.GetClrWatsonExceptionInfo(Exception exceptionObject)</description>
  </entry>
  <entry>
    <record>944</record>
    <time>2020/05/03 15:03:47.801</time>
    <type>Information</type>
    <source>MruList</source>
    <description>Entering OnAddVerbInvoked</description>
  </entry>
  <entry>
    <record>945</record>
    <time>2020/05/03 15:03:47.801</time>
    <type>Information</type>
    <source>MruList</source>
    <description>Entering AddItem. Persistence data for item: C:\workspace\VerilogLanguageExtension\TestFiles\picorv32.v</description>
  </entry>
  <entry>
    <record>946</record>
    <time>2020/05/03 15:03:47.801</time>
    <type>Information</type>
    <source>MruList</source>
    <description>Entering TryPromoteItem</description>
  </entry>
  <entry>
    <record>947</record>
    <time>2020/05/03 15:03:47.801</time>
    <type>Information</type>
    <source>MruList</source>
    <description>Entering PromoteItemAt and found the index of the item to be 0</description>
  </entry>
  <entry>
    <record>948</record>
    <time>2020/05/03 15:03:47.930</time>
    <type>Error</type>
    <source>Microsoft.VisualStudio.CommonIDE.ExtensibilityHosting.VsShellComponentModelHost</source>
    <description>A MEF Component threw an exception at runtime: System.NotSupportedException: Cannot instantiate with unsupported importing constructor of type: RuntimeMethodInfo&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ReflectionHelpers.Instantiate(MethodBase ctorOrFactoryMethod, Object[] arguments)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.CreateValue()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.Create()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()</description>
  </entry>
  <entry>
    <record>949</record>
    <time>2020/05/03 15:03:47.932</time>
    <type>Error</type>
    <source>Editor or Editor Extension</source>
    <description>System.NotSupportedException: Cannot instantiate with unsupported importing constructor of type: RuntimeMethodInfo&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ReflectionHelpers.Instantiate(MethodBase ctorOrFactoryMethod, Object[] arguments)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.CreateValue()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.Create()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.&lt;&gt;c__DisplayClass15_0.&lt;GetExportedValueHelper&gt;b__0()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.DelegateServices.&lt;&gt;c__DisplayClass2_0`1.&lt;As&gt;b__0()&#x000D;&#x000A;   at System.Lazy`1.CreateValue()&#x000D;&#x000A;   at System.Lazy`1.LazyInitValue()&#x000D;&#x000A;   at System.Lazy`1.get_Value()&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.GatherTaggers(ITextBuffer textBuffer)&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at Microsoft.VisualStudio.Telemetry.WindowsErrorReporting.WatsonReport.GetClrWatsonExceptionInfo(Exception exceptionObject)</description>
  </entry>
  <entry>
    <record>950</record>
    <time>2020/05/03 15:03:48.313</time>
    <type>Error</type>
    <source>SccDisplayInformation.SolutionOptions</source>
    <description>Unable to load solution user option &apos;SccProvider.Solution.LoadCount&apos;</description>
  </entry>
</activity>

It seems the errors occur long before the extension is started, even without calling StartMyLongRunningTask() ... but immediately upon opening a Verilog file.

The objective is to invoke the TagsChanges like this:

                TagsChanged?.Invoke(this, new SnapshotSpanEventArgs(
                                new SnapshotSpan(buffer.CurrentSnapshot,
                                      new Span(0, buffer.CurrentSnapshot.Length - 1))));

The curious thing is that even with none of the callback code referenced... the error still occurs. I had breakpoints on all of myLongRunningTaskDone, etc... but none of them where hit when the error pops up. I thought perhaps the void Start might help to cause the error, but even commenting that out, the errors still occur.

Perhaps I'll try a different completion callback...