Ejemplo n.º 1
0
        private void DoRefreshProject(UndoableChange.ReanalysisScope reanalysisRequired)
        {
            if (reanalysisRequired != UndoableChange.ReanalysisScope.DisplayOnly)
            {
                mGenerationLog = new CommonUtil.DebugLog();
                mGenerationLog.SetMinPriority(CommonUtil.DebugLog.Priority.Debug);
                mGenerationLog.SetShowRelTime(true);

                mReanalysisTimer.StartTask("Call DisasmProject.Analyze()");
                mProject.Analyze(reanalysisRequired, mGenerationLog, mReanalysisTimer);
                mReanalysisTimer.EndTask("Call DisasmProject.Analyze()");
            }

            if (mGenerationLog != null)
            {
                //mReanalysisTimer.StartTask("Save _log");
                //mGenerationLog.WriteToFile(@"C:\Src\WorkBench\SourceGen\TestData\_log.txt");
                //mReanalysisTimer.EndTask("Save _log");

#if false
                if (mShowAnalyzerOutputDialog != null)
                {
                    mShowAnalyzerOutputDialog.BodyText = mGenerationLog.WriteToString();
                }
#endif
            }

            mReanalysisTimer.StartTask("Generate DisplayList");
            mDisplayList.GenerateAll();
            mReanalysisTimer.EndTask("Generate DisplayList");
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Refreshes the project after something of substance has changed.  Some
        /// re-analysis will be done, followed by a complete rebuild of the DisplayList.
        /// </summary>
        /// <param name="reanalysisRequired">Indicates whether reanalysis is required, and
        ///   what level.</param>
        private void RefreshProject(UndoableChange.ReanalysisScope reanalysisRequired)
        {
            Debug.Assert(reanalysisRequired != UndoableChange.ReanalysisScope.None);

            // NOTE: my goal is to arrange things so that reanalysis (data-only, and ideally
            // code+data) takes less than 100ms.  With that response time there's no need for
            // background processing and progress bars.  Since we need to do data-only
            // reanalysis after many common operations, the program becomes unpleasant to
            // use if we miss this goal, and progress bars won't make it less so.

            // Changing the CPU type or whether undocumented instructions are supported
            // invalidates the Formatter's mnemonic cache.  We can change these values
            // through undo/redo, so we need to check it here.
            if (mOutputFormatterCpuDef != mProject.CpuDef)      // reference equality is fine
            {
                Debug.WriteLine("CpuDef has changed, resetting formatter (now " +
                                mProject.CpuDef + ")");
                mOutputFormatter = new Formatter(mFormatterConfig);
                mDisplayList.SetFormatter(mOutputFormatter);
                mDisplayList.SetPseudoOpNames(mPseudoOpNames);
                mOutputFormatterCpuDef = mProject.CpuDef;
            }

#if false
            if (mDisplayList.Count > 200000)
            {
                string prevStatus = toolStripStatusLabel.Text;

                // The Windows stuff can take 50-100ms, potentially longer than the actual
                // work, so don't bother unless the file is very large.
                try {
                    mReanalysisTimer.StartTask("Do Windows stuff");
                    Application.UseWaitCursor = true;
                    Cursor.Current            = Cursors.WaitCursor;
                    toolStripStatusLabel.Text = Res.Strings.STATUS_RECALCULATING;
                    Refresh();      // redraw status label
                    mReanalysisTimer.EndTask("Do Windows stuff");

                    DoRefreshProject(reanalysisRequired);
                } finally {
                    Application.UseWaitCursor = false;
                    toolStripStatusLabel.Text = prevStatus;
                }
            }
            else
            {
                DoRefreshProject(reanalysisRequired);
            }
#endif

            if (FormatDescriptor.DebugCreateCount != 0)
            {
                Debug.WriteLine("FormatDescriptor total=" + FormatDescriptor.DebugCreateCount +
                                " prefab=" + FormatDescriptor.DebugPrefabCount + " (" +
                                (FormatDescriptor.DebugPrefabCount * 100) / FormatDescriptor.DebugCreateCount +
                                "%)");
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Applies the changes to the project, and updates the display.
        ///
        /// This is called by the undo/redo commands.  Don't call this directly from the
        /// various UI-driven functions, as this does not add the change to the undo stack.
        /// </summary>
        /// <param name="cs">Set of changes to apply.</param>
        /// <param name="backward">If set, undo the changes instead.</param>
        private void ApplyChanges(ChangeSet cs, bool backward)
        {
            mReanalysisTimer.Clear();
            mReanalysisTimer.StartTask("ProjectView.ApplyChanges()");

            mReanalysisTimer.StartTask("Save selection");
#if false
            int topItem = codeListView.TopItem.Index;
#else
            int topItem = 0;
#endif
            int topOffset = mDisplayList[topItem].FileOffset;
            DisplayListGen.SavedSelection savedSel = DisplayListGen.SavedSelection.Generate(
                mDisplayList, mCodeViewSelection, topOffset);
            //savedSel.DebugDump();
            mReanalysisTimer.EndTask("Save selection");

            mReanalysisTimer.StartTask("Apply changes");
            UndoableChange.ReanalysisScope needReanalysis = mProject.ApplyChanges(cs, backward,
                                                                                  out RangeSet affectedOffsets);
            mReanalysisTimer.EndTask("Apply changes");

            string refreshTaskStr = "Refresh w/reanalysis=" + needReanalysis;
            mReanalysisTimer.StartTask(refreshTaskStr);
            if (needReanalysis != UndoableChange.ReanalysisScope.None)
            {
                Debug.WriteLine("Refreshing project (" + needReanalysis + ")");
                RefreshProject(needReanalysis);
            }
            else
            {
                Debug.WriteLine("Refreshing " + affectedOffsets.Count + " offsets");
                RefreshCodeListViewEntries(affectedOffsets);
                mProject.Validate();    // shouldn't matter w/o reanalysis, but do it anyway
            }
            mReanalysisTimer.EndTask(refreshTaskStr);

            VirtualListViewSelection newSel = savedSel.Restore(mDisplayList, out int topIndex);
            //newSel.DebugDump();

            // Refresh the various windows, and restore the selection.
            mReanalysisTimer.StartTask("Invalidate controls");
#if false
            InvalidateControls(newSel);
#endif
            mReanalysisTimer.EndTask("Invalidate controls");

            // This apparently has to be done after the EndUpdate, and inside try/catch.
            // See https://stackoverflow.com/questions/626315/ for notes.
            try {
                Debug.WriteLine("Setting TopItem to index=" + topIndex);
#if false
                codeListView.TopItem = codeListView.Items[topIndex];
#endif
            } catch (NullReferenceException) {
                Debug.WriteLine("Caught an NRE from TopItem");
            }

            mReanalysisTimer.EndTask("ProjectView.ApplyChanges()");

            //mReanalysisTimer.DumpTimes("ProjectView timers:", mGenerationLog);
#if false
            if (mShowAnalysisTimersDialog != null)
            {
                string timerStr = mReanalysisTimer.DumpToString("ProjectView timers:");
                mShowAnalysisTimersDialog.BodyText = timerStr;
            }
#endif

            // Lines may have moved around.  Update the selection highlight.  It's important
            // we do it here, and not down in DoRefreshProject(), because at that point the
            // ListView's selection index could be referencing a line off the end.
#if false
            UpdateSelectionHighlight();
#endif
        }