Skip to content

Commit

Permalink
Misc minor optimizations to compiler
Browse files Browse the repository at this point in the history
- Reduce garbage generation a little and cache some method lookups that happen frequently
  • Loading branch information
MerlinVR committed Jan 31, 2021
1 parent b8013fc commit 33de2e6
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 33 deletions.
21 changes: 11 additions & 10 deletions Assets/UdonSharp/Editor/UdonSharpAssemblyBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@

//#define USE_UDON_LABELS

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;

Expand Down Expand Up @@ -39,6 +41,8 @@ public string GetAssemblyStr(LabelTable labelTable = null)
}

#if !USE_UDON_LABELS
private static readonly char[] _trimChars = new[] {' ', '\n', '\r'};

private string ReplaceLabels(string assemblyString, LabelTable labelTable)
{
StringBuilder newAssemblyBuilder = new StringBuilder();
Expand All @@ -49,26 +53,27 @@ private string ReplaceLabels(string assemblyString, LabelTable labelTable)

while (currentLine != null)
{
string line = currentLine.TrimStart(' ', '\n', '\r');
if (line.StartsWith("JUMP_LABEL,"))
string line = currentLine.TrimStart(_trimChars);
if (line.StartsWith("JUMP_LABEL,", StringComparison.Ordinal))
{
int startIdx = line.IndexOf('[') + 1;
int endIdx = line.IndexOf(']');
string labelName = line.Substring(startIdx, endIdx - startIdx);
JumpLabel label = labelTable.GetLabel(labelName);
newAssemblyBuilder.Append($" JUMP, {label.AddresStr()}\n");
newAssemblyBuilder.AppendFormat(" JUMP, {0}\n", label.AddresStr());
}
else if (line.StartsWith("JUMP_IF_FALSE_LABEL,"))
else if (line.StartsWith("JUMP_IF_FALSE_LABEL,", StringComparison.Ordinal))
{
int startIdx = line.IndexOf('[') + 1;
int endIdx = line.IndexOf(']');
string labelName = line.Substring(startIdx, endIdx - startIdx);
JumpLabel label = labelTable.GetLabel(labelName);
newAssemblyBuilder.Append($" JUMP_IF_FALSE, {label.AddresStr()}\n");
newAssemblyBuilder.AppendFormat(" JUMP_IF_FALSE, {0}\n", label.AddresStr());
}
else
{
newAssemblyBuilder.Append(currentLine + "\n");
newAssemblyBuilder.Append(currentLine);
newAssemblyBuilder.Append("\n");
}

currentLine = reader.ReadLine();
Expand All @@ -86,10 +91,6 @@ public int GetExternStrCount()

public void AppendCommentedLine(string line, string comment, int indent = 2)
{
// Make sure the comment stays on the same line
comment.Replace('\n', ' ');
comment.Replace('\r', ' ');

//if (programCounter > 0)
// assemblyTextBuilder.AppendFormat(" # {0:X8}\n", programCounter);

Expand Down
6 changes: 3 additions & 3 deletions Assets/UdonSharp/Editor/UdonSharpClassDebugInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void UpdateSyntaxNode(SyntaxNode node)
if (debugSpans.Count == 0)
debugSpans.Add(new DebugLineSpan());

int nodeSpanStart = node.Span.Start;
int nodeSpanStart = node.SpanStart;

if (nodeSpanStart < mostRecentSpanStart || nodeSpanStart >= sourceText.Length)
return;
Expand All @@ -60,12 +60,12 @@ public void UpdateSyntaxNode(SyntaxNode node)
DebugLineSpan lastLineSpan = debugSpans.Last();

lastLineSpan.endInstruction = assemblyBuilder.programCounter - 1;
lastLineSpan.endSourceChar = node.SpanStart;
lastLineSpan.endSourceChar = nodeSpanStart;
//lastLineSpan.spanCodeSection = sourceText.Substring(lastLineSpan.startSourceChar, lastLineSpan.endSourceChar - lastLineSpan.startSourceChar);

DebugLineSpan nextLineSpan = new DebugLineSpan();
nextLineSpan.startInstruction = assemblyBuilder.programCounter;
nextLineSpan.startSourceChar = node.SpanStart;
nextLineSpan.startSourceChar = nodeSpanStart;

debugSpans.Add(nextLineSpan);

Expand Down
18 changes: 10 additions & 8 deletions Assets/UdonSharp/Editor/UdonSharpCompilationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,18 @@ private string BuildHeapDataBlock()
// Prettify the symbol order in the data block
// Reflection info goes first so that we can use it for knowing what script threw an error from in game logs
foreach (SymbolDefinition symbol in moduleSymbols.GetAllUniqueChildSymbols()
.OrderBy(e => e.declarationType.HasFlag(SymbolDeclTypeFlags.Reflection))
.ThenBy(e => e.declarationType.HasFlag(SymbolDeclTypeFlags.Public))
.ThenBy(e => e.declarationType.HasFlag(SymbolDeclTypeFlags.Private))
.ThenBy(e => e.declarationType.HasFlag(SymbolDeclTypeFlags.This))
.ThenBy(e => !e.declarationType.HasFlag(SymbolDeclTypeFlags.Internal))
.ThenBy(e => e.declarationType.HasFlag(SymbolDeclTypeFlags.Constant))
.OrderBy(e => (e.declarationType & SymbolDeclTypeFlags.Reflection) != 0)
.ThenBy(e => (e.declarationType & SymbolDeclTypeFlags.Public) != 0)
.ThenBy(e => (e.declarationType & SymbolDeclTypeFlags.Private) != 0)
.ThenBy(e => (e.declarationType & SymbolDeclTypeFlags.This) != 0)
.ThenBy(e => (e.declarationType & SymbolDeclTypeFlags.Internal) == 0)
.ThenBy(e => (e.declarationType &SymbolDeclTypeFlags.Constant) != 0)
.ThenByDescending(e => e.symbolCsType.Name)
.ThenByDescending(e => e.symbolUniqueName).Reverse())
//.ThenByDescending(e => e.symbolUniqueName)
.Reverse()
)
{
if (symbol.declarationType.HasFlag(SymbolDeclTypeFlags.This))
if ((symbol.declarationType & SymbolDeclTypeFlags.This) != 0)
builder.AppendLine($"{symbol.symbolUniqueName}: %{symbol.symbolResolvedTypeName}, this", 1);
else
builder.AppendLine($"{symbol.symbolUniqueName}: %{symbol.symbolResolvedTypeName}, null", 1);
Expand Down
15 changes: 12 additions & 3 deletions Assets/UdonSharp/Editor/UdonSharpExpressionCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2337,12 +2337,18 @@ private bool HandleLocalUdonBehaviourMethodLookup(string localUdonMethodName)
return true;
}

private static readonly PropertyInfo[] _componentProperties =
typeof(Component).GetProperties(BindingFlags.Instance | BindingFlags.Public);

private static readonly PropertyInfo[] _udonEventReceiverProperties =
typeof(VRC.Udon.Common.Interfaces.IUdonEventReceiver).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

private bool HandleLocalUdonBehaviourPropertyLookup(string localUdonPropertyName)
{
PropertyInfo[] foundProperties = typeof(Component).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(e => e.Name == localUdonPropertyName).ToArray();
PropertyInfo[] foundProperties = _componentProperties.Where(e => e.Name == localUdonPropertyName).ToArray();

if (localUdonPropertyName == "enabled")
foundProperties = typeof(VRC.Udon.Common.Interfaces.IUdonEventReceiver).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Where(e => e.Name == localUdonPropertyName).ToArray();
foundProperties = _udonEventReceiverProperties.Where(e => e.Name == localUdonPropertyName).ToArray();

if (foundProperties.Length == 0)
return false;
Expand Down Expand Up @@ -2586,6 +2592,9 @@ private bool HandleMemberFieldAccess(string fieldToken)
return true;
}

private static readonly MethodInfo[] _objectMethods =
typeof(object).GetMethods(BindingFlags.Public | BindingFlags.Instance);

private bool HandleMemberMethodLookup(string methodToken)
{
if (captureArchetype != ExpressionCaptureArchetype.LocalSymbol &&
Expand All @@ -2603,7 +2612,7 @@ private bool HandleMemberMethodLookup(string methodToken)
List<MethodInfo> foundMethodInfos = new List<MethodInfo>(returnType.GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(e => e.Name == methodToken));

if (returnType != typeof(object))
foundMethodInfos.AddRange(typeof(object).GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(e => e.Name == methodToken));
foundMethodInfos.AddRange(_objectMethods.Where(e => e.Name == methodToken));

if (foundMethodInfos.Count == 0)
return false;
Expand Down
9 changes: 5 additions & 4 deletions Assets/UdonSharp/Editor/UdonSharpResolverContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using UnityEngine;
using VRC.Udon.Editor;
using VRC.Udon.Graph;
Expand Down Expand Up @@ -427,18 +428,18 @@ public string GetUdonMethodName(MethodBase externMethod, bool validate = true, L
}

string paramStr = "";

if (methodParams.Length > 0)
{
paramStr += "_"; // Arg separator

paramStr = "_"; // Arg separator
foreach (ParameterInfo parameterInfo in methodParams)
{
paramStr += $"_{GetUdonTypeName(parameterInfo.ParameterType, true)}";
}
}
else if (externMethod is ConstructorInfo)
paramStr += "__";
paramStr = "__";

string returnStr = "";

Expand Down
15 changes: 10 additions & 5 deletions Assets/UdonSharp/Editor/UdonSharpUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -503,25 +503,30 @@ public static System.Type GetRootElementType(System.Type type)

private static Dictionary<System.Type, System.Type> GetInheritedTypeMap()
{
if (inheritedTypeMap != null)
return inheritedTypeMap;

lock (inheritedTypeMapLock)
{
if (inheritedTypeMap != null)
return inheritedTypeMap;

inheritedTypeMap = new Dictionary<System.Type, System.Type>();
Dictionary<System.Type, System.Type> typeMap = new Dictionary<System.Type, System.Type>();

IEnumerable<System.Type> typeList = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "VRCSDK3").GetTypes().Where(t => t != null && t.Namespace != null && t.Namespace.StartsWith("VRC.SDK3.Components"));

foreach (System.Type childType in typeList)
{
if (childType.BaseType != null && childType.BaseType.Namespace.StartsWith("VRC.SDKBase"))
{
inheritedTypeMap.Add(childType.BaseType, childType);
typeMap.Add(childType.BaseType, childType);
}
}

inheritedTypeMap.Add(typeof(VRC.SDK3.Video.Components.VRCUnityVideoPlayer), typeof(VRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer));
inheritedTypeMap.Add(typeof(VRC.SDK3.Video.Components.AVPro.VRCAVProVideoPlayer), typeof(VRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer));
typeMap.Add(typeof(VRC.SDK3.Video.Components.VRCUnityVideoPlayer), typeof(VRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer));
typeMap.Add(typeof(VRC.SDK3.Video.Components.AVPro.VRCAVProVideoPlayer), typeof(VRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer));

inheritedTypeMap = typeMap;
}

return inheritedTypeMap;
Expand Down

0 comments on commit 33de2e6

Please sign in to comment.