Browse Source

Optimize: vm (remove boundary checks)

AnnulusGames 1 year ago
parent
commit
a381f6f6dd
2 changed files with 10 additions and 4 deletions
  1. 6 0
      src/Lua/Internal/MemoryMarshalEx.cs
  2. 4 4
      src/Lua/Runtime/LuaVirtualMachine.cs

+ 6 - 0
src/Lua/Internal/MemoryMarshalEx.cs

@@ -21,4 +21,10 @@ internal static class MemoryMarshalEx
     {
         return ref Unsafe.Add(ref MemoryMarshal.GetReference(array), index);
     }
+
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    public static ref T UnsafeElementAt<T>(ReadOnlySpan<T> array, int index)
+    {
+        return ref Unsafe.Add(ref MemoryMarshal.GetReference(array), index);
+    }
 }

+ 4 - 4
src/Lua/Runtime/LuaVirtualMachine.cs

@@ -52,7 +52,7 @@ public static partial class LuaVirtualMachine
                     case OpCode.GetUpVal:
                         {
                             stack.EnsureCapacity(RA + 1);
-                            var upValue = closure.UpValues[instruction.B];
+                            var upValue = MemoryMarshalEx.UnsafeElementAt(closure.UpValues, instruction.B);
                             stack.UnsafeGet(RA) = upValue.GetValue();
                             stack.NotifyTop(RA + 1);
                             break;
@@ -61,7 +61,7 @@ public static partial class LuaVirtualMachine
                         {
                             stack.EnsureCapacity(RA + 1);
                             var vc = RK(stack, chunk, instruction.C, frame.Base);
-                            var upValue = closure.UpValues[instruction.B];
+                            var upValue = MemoryMarshalEx.UnsafeElementAt(closure.UpValues, instruction.B);
                             var table = upValue.GetValue();
                             await GetTableValue(state, thread, chunk, rootChunk, pc, table, vc, resultBuffer.AsMemory(), cancellationToken);
                             var value = resultBuffer[0];
@@ -85,14 +85,14 @@ public static partial class LuaVirtualMachine
                             var vb = RK(stack, chunk, instruction.B, frame.Base);
                             var vc = RK(stack, chunk, instruction.C, frame.Base);
 
-                            var upValue = closure.UpValues[instruction.A];
+                            var upValue = MemoryMarshalEx.UnsafeElementAt(closure.UpValues, instruction.A);
                             var table = upValue.GetValue();
                             await SetTableValue(state, thread, chunk, rootChunk, pc, table, vb, vc, resultBuffer.AsMemory(), cancellationToken);
                             break;
                         }
                     case OpCode.SetUpVal:
                         {
-                            var upValue = closure.UpValues[instruction.B];
+                            var upValue = MemoryMarshalEx.UnsafeElementAt(closure.UpValues, instruction.B);
                             upValue.SetValue(stack.UnsafeGet(RA));
                             break;
                         }