From 15d26c9ebd49913d0f33b4059eec2d2c928dbb97 Mon Sep 17 00:00:00 2001 From: Andy McFadden Date: Sat, 10 Aug 2019 17:13:25 -0700 Subject: [PATCH] Don't do plugin interface checks during code analysis The plugin objects are MarshalByRefObject stubs, which means they don't actually implement the interfaces we're checking for. There's some additional overhead to do the interface check. We can avoid it by doing the interface queries during initialization, and just checking some bit flags later on. Also, in the extension script info window, show a list of implemented interfaces. --- SourceGen/CodeAnalysis.cs | 29 +++++++++++++++++++++--- SourceGen/RuntimeData/Help/advanced.html | 4 ---- SourceGen/Sandbox/ScriptManager.cs | 14 ++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/SourceGen/CodeAnalysis.cs b/SourceGen/CodeAnalysis.cs index eec8f2b..99630a7 100644 --- a/SourceGen/CodeAnalysis.cs +++ b/SourceGen/CodeAnalysis.cs @@ -107,6 +107,10 @@ namespace SourceGen { /// private IPlugin[] mScriptArray; + [Flags] + private enum PluginCap { NONE = 0, JSR = 1 << 0, JSL = 1 << 1, BRK = 1 << 2 }; + private PluginCap[] mPluginCaps; + /// /// CPU to use when analyzing data. /// @@ -293,11 +297,26 @@ namespace SourceGen { if (mScriptManager == null) { // Currently happens for regression tests with no external files. mScriptArray = new IPlugin[0]; + mPluginCaps = new PluginCap[0]; return; } // Include all scripts. mScriptArray = mScriptManager.GetAllInstances().ToArray(); + mPluginCaps = new PluginCap[mScriptArray.Length]; + for (int i = 0; i < mScriptArray.Length; i++) { + PluginCap cap = PluginCap.NONE; + if (mScriptArray[i] is IPlugin_InlineJsr) { + cap |= PluginCap.JSR; + } + if (mScriptArray[i] is IPlugin_InlineJsl) { + cap |= PluginCap.JSL; + } + if (mScriptArray[i] is IPlugin_InlineBrk) { + cap |= PluginCap.BRK; + } + mPluginCaps[i] = cap; + } // Prep them. mScriptManager.PrepareScripts(mScriptSupport); @@ -909,13 +928,17 @@ namespace SourceGen { private bool CheckForInlineCall(OpDef op, int offset, bool noContinue) { for (int i = 0; i < mScriptArray.Length; i++) { IPlugin script = mScriptArray[i]; - if (op == OpDef.OpJSR_Abs && script is IPlugin_InlineJsr) { + // The IPlugin object is a MarshalByRefObject, which doesn't define the + // interface directly. A simple test showed it was fairly quick when the + // interface was implemented but a bit slow when it wasn't. For performance + // we query the capability flags instead. + if (op == OpDef.OpJSR_Abs && (mPluginCaps[i] & PluginCap.JSR) != 0) { ((IPlugin_InlineJsr)script).CheckJsr(offset, out bool noCont); noContinue |= noCont; - } else if (op == OpDef.OpJSR_AbsLong && script is IPlugin_InlineJsl) { + } else if (op == OpDef.OpJSR_AbsLong && (mPluginCaps[i] & PluginCap.JSL) != 0) { ((IPlugin_InlineJsl)script).CheckJsl(offset, out bool noCont); noContinue |= noCont; - } else if (op == OpDef.OpBRK_Implied && script is IPlugin_InlineBrk) { + } else if (op == OpDef.OpBRK_Implied && (mPluginCaps[i] & PluginCap.BRK) != 0) { ((IPlugin_InlineBrk)script).CheckBrk(offset, out bool noCont); noContinue &= noCont; } diff --git a/SourceGen/RuntimeData/Help/advanced.html b/SourceGen/RuntimeData/Help/advanced.html index 5185472..a612a5c 100644 --- a/SourceGen/RuntimeData/Help/advanced.html +++ b/SourceGen/RuntimeData/Help/advanced.html @@ -241,10 +241,6 @@ not help you debug 6502 projects.

provides a crude sense of where time is being spent.
  • Extension Script Info. Shows a bit about the currently-loaded extension scripts.
  • -
  • Toggle OwnerDraw. The code list and Notes windows use a ListView - control whose contents are drawn by the application. This menu item - toggles the OwnerDraw flag on and off. Useful for comparing the - owner-drawn output to the system-drawn output.
  • Toggle Comment Rulers. Adds a string of digits above every multi-line comment (long comment, note). Useful for confirming that the width limitation is being obeyed. These are added exactly diff --git a/SourceGen/Sandbox/ScriptManager.cs b/SourceGen/Sandbox/ScriptManager.cs index 4f56794..b166568 100644 --- a/SourceGen/Sandbox/ScriptManager.cs +++ b/SourceGen/Sandbox/ScriptManager.cs @@ -220,6 +220,20 @@ namespace SourceGen.Sandbox { } private void DebugGetScriptInfo(IPlugin plugin, StringBuilder sb) { sb.Append(plugin.Identifier); + sb.Append(":"); + + // The plugin is actually a MarshalByRefObject, so we can't use reflection + // to gather the list of interfaces. + // TODO(maybe): add a call that does the query on the remote site + if (plugin is PluginCommon.IPlugin_InlineJsr) { + sb.Append(" InlineJsr"); + } + if (plugin is PluginCommon.IPlugin_InlineJsl) { + sb.Append(" InlineJsl"); + } + if (plugin is PluginCommon.IPlugin_InlineBrk) { + sb.Append(" InlineBrk"); + } sb.Append("\r\n"); } }