Forráskód Böngészése

Optimize: return LuaThread.GetCurrentFrame by ref readonly

Akeit0 9 hónapja
szülő
commit
cc68459647

+ 14 - 1
src/Lua/Internal/FastStackCore.cs

@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Runtime.InteropServices;
 
 
@@ -100,6 +101,17 @@ public struct FastStackCore<T>
         return result;
         return result;
     }
     }
 
 
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    internal ref T PeekRef()
+    {
+        if (tail == 0)
+        {
+            ThrowForEmptyStack();
+        }
+
+        return ref array[tail - 1]!;
+    }
+
 
 
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     public void EnsureCapacity(int capacity)
     public void EnsureCapacity(int capacity)
@@ -130,7 +142,8 @@ public struct FastStackCore<T>
         array.AsSpan(0, tail).Clear();
         array.AsSpan(0, tail).Clear();
         tail = 0;
         tail = 0;
     }
     }
-    
+
+    [DoesNotReturn]
     void ThrowForEmptyStack()
     void ThrowForEmptyStack()
     {
     {
         throw new InvalidOperationException("Empty stack");
         throw new InvalidOperationException("Empty stack");

+ 1 - 2
src/Lua/LuaFunctionExecutionContext.cs

@@ -118,8 +118,7 @@ public readonly record struct LuaFunctionExecutionContext
 
 
     public CsClosure? GetCsClosure()
     public CsClosure? GetCsClosure()
     {
     {
-        var stack = Thread.CallStack[^1];
-        return stack.Function as CsClosure;
+        return Thread.GetCurrentFrame().Function as CsClosure;
     }
     }
 
 
     internal void ThrowBadArgument(int index, string message)
     internal void ThrowBadArgument(int index, string message)

+ 16 - 5
src/Lua/LuaThread.cs

@@ -28,10 +28,21 @@ public abstract class LuaThread
         get => LineAndCountHookMask.Flag1;
         get => LineAndCountHookMask.Flag1;
         set => LineAndCountHookMask.Flag1 = value;
         set => LineAndCountHookMask.Flag1 = value;
     }
     }
-   
+
     internal BitFlags2 LineAndCountHookMask;
     internal BitFlags2 LineAndCountHookMask;
-     internal bool IsCallHookEnabled { get => CallOrReturnHookMask.Flag0; set => CallOrReturnHookMask.Flag0 = value; }
-    internal bool IsReturnHookEnabled { get => CallOrReturnHookMask.Flag1; set => CallOrReturnHookMask.Flag1 = value; }
+
+    internal bool IsCallHookEnabled
+    {
+        get => CallOrReturnHookMask.Flag0;
+        set => CallOrReturnHookMask.Flag0 = value;
+    }
+
+    internal bool IsReturnHookEnabled
+    {
+        get => CallOrReturnHookMask.Flag1;
+        set => CallOrReturnHookMask.Flag1 = value;
+    }
+
     internal BitFlags2 CallOrReturnHookMask;
     internal BitFlags2 CallOrReturnHookMask;
     internal bool IsInHook;
     internal bool IsInHook;
     internal int HookCount;
     internal int HookCount;
@@ -39,9 +50,9 @@ public abstract class LuaThread
     internal int LastPc;
     internal int LastPc;
     internal LuaFunction? Hook { get; set; }
     internal LuaFunction? Hook { get; set; }
 
 
-    public CallStackFrame GetCurrentFrame()
+    public ref readonly CallStackFrame GetCurrentFrame()
     {
     {
-        return callStack.Peek();
+        return ref callStack.PeekRef();
     }
     }
 
 
     public ReadOnlySpan<LuaValue> GetStackValues()
     public ReadOnlySpan<LuaValue> GetStackValues()

+ 2 - 2
src/Lua/Runtime/Closure.cs

@@ -48,7 +48,7 @@ public sealed class Closure : LuaFunction
     {
     {
         if (description.IsInRegister)
         if (description.IsInRegister)
         {
         {
-            return state.GetOrAddUpValue(thread, thread.GetCallStackFrames()[^1].Base + description.Index);
+            return state.GetOrAddUpValue(thread, thread.GetCurrentFrame().Base + description.Index);
         }
         }
 
 
         if (description.Index == -1) // -1 is global environment
         if (description.Index == -1) // -1 is global environment
@@ -56,7 +56,7 @@ public sealed class Closure : LuaFunction
             return envUpValue;
             return envUpValue;
         }
         }
 
 
-        if (thread.GetCallStackFrames()[^1].Function is Closure parentClosure)
+        if (thread.GetCurrentFrame().Function is Closure parentClosure)
         {
         {
             return parentClosure.UpValues[description.Index];
             return parentClosure.UpValues[description.Index];
         }
         }

+ 20 - 24
src/Lua/Runtime/LuaVirtualMachine.Debug.cs

@@ -128,11 +128,9 @@ public static partial class LuaVirtualMachine
 
 
     internal static async ValueTask<int> ExecuteCallHook(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken, bool isTailCall = false)
     internal static async ValueTask<int> ExecuteCallHook(LuaFunctionExecutionContext context, Memory<LuaValue> buffer, CancellationToken cancellationToken, bool isTailCall = false)
     {
     {
-        var topFrame = context.Thread.GetCurrentFrame();
         var argCount = context.ArgumentCount;
         var argCount = context.ArgumentCount;
         var hook = context.Thread.Hook!;
         var hook = context.Thread.Hook!;
         var stack = context.Thread.Stack;
         var stack = context.Thread.Stack;
-        CallStackFrame frame;
         if (context.Thread.IsCallHookEnabled)
         if (context.Thread.IsCallHookEnabled)
         {
         {
             stack.Push((isTailCall ? "tail call" : "call"));
             stack.Push((isTailCall ? "tail call" : "call"));
@@ -145,14 +143,14 @@ public static partial class LuaVirtualMachine
                 ArgumentCount = 2,
                 ArgumentCount = 2,
                 FrameBase = context.Thread.Stack.Count - 2,
                 FrameBase = context.Thread.Stack.Count - 2,
             };
             };
-            frame = new()
+            CallStackFrame frame = new()
             {
             {
                 Base = funcContext.FrameBase,
                 Base = funcContext.FrameBase,
                 VariableArgumentCount = hook.GetVariableArgumentCount(2),
                 VariableArgumentCount = hook.GetVariableArgumentCount(2),
                 Function = hook,
                 Function = hook,
                 CallerInstructionIndex = 0,
                 CallerInstructionIndex = 0,
+                Flags = CallStackFrameFlags.InHook
             };
             };
-            frame.Flags |= CallStackFrameFlags.InHook;
 
 
             context.Thread.PushCallStackFrame(frame);
             context.Thread.PushCallStackFrame(frame);
             try
             try
@@ -167,21 +165,19 @@ public static partial class LuaVirtualMachine
             }
             }
         }
         }
 
 
-        frame = topFrame;
-
-        var task = frame.Function.Func(new()
-        {
-            State = context.State,
-            Thread = context.Thread,
-            ArgumentCount = argCount,
-            FrameBase = frame.Base,
-        }, buffer, cancellationToken);
-        if (isTailCall || !context.Thread.IsReturnHookEnabled)
-        {
-            return await task;
-        }
-
         {
         {
+            var frame = context.Thread.GetCurrentFrame();
+            var task = frame.Function.Func(new()
+            {
+                State = context.State,
+                Thread = context.Thread,
+                ArgumentCount = argCount,
+                FrameBase = frame.Base,
+            }, buffer, cancellationToken);
+            if (isTailCall || !context.Thread.IsReturnHookEnabled)
+            {
+                return await task;
+            }
             var result = await task;
             var result = await task;
             stack.Push("return");
             stack.Push("return");
             stack.Push(LuaValue.Nil);
             stack.Push(LuaValue.Nil);
@@ -192,16 +188,16 @@ public static partial class LuaVirtualMachine
                 ArgumentCount = 2,
                 ArgumentCount = 2,
                 FrameBase = context.Thread.Stack.Count - 2,
                 FrameBase = context.Thread.Stack.Count - 2,
             };
             };
-            frame = new()
+           
+
+            context.Thread.PushCallStackFrame( new()
             {
             {
                 Base = funcContext.FrameBase,
                 Base = funcContext.FrameBase,
                 VariableArgumentCount = hook.GetVariableArgumentCount(2),
                 VariableArgumentCount = hook.GetVariableArgumentCount(2),
                 Function = hook,
                 Function = hook,
-                CallerInstructionIndex = 0
-            };
-            frame.Flags |= CallStackFrameFlags.InHook;
-
-            context.Thread.PushCallStackFrame(frame);
+                CallerInstructionIndex = 0,
+                Flags = CallStackFrameFlags.InHook
+            });
             try
             try
             {
             {
                 context.Thread.IsInHook = true;
                 context.Thread.IsInHook = true;

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

@@ -265,7 +265,7 @@ public static partial class LuaVirtualMachine
     internal static ValueTask<int> ExecuteClosureAsync(LuaState luaState, Memory<LuaValue> buffer, CancellationToken cancellationToken)
     internal static ValueTask<int> ExecuteClosureAsync(LuaState luaState, Memory<LuaValue> buffer, CancellationToken cancellationToken)
     {
     {
         var thread = luaState.CurrentThread;
         var thread = luaState.CurrentThread;
-        ref readonly var frame = ref thread.GetCallStackFrames()[^1];
+        ref readonly var frame = ref thread.GetCurrentFrame();
         var resultBuffer = LuaValueArrayPool.Rent1024();
         var resultBuffer = LuaValueArrayPool.Rent1024();
 
 
         var context = new VirtualMachineExecutionContext(luaState, thread.Stack, resultBuffer, buffer, thread, in frame,
         var context = new VirtualMachineExecutionContext(luaState, thread.Stack, resultBuffer, buffer, thread, in frame,