public static void TestA(int a, ref int b, out int c, out QuickDebugTestObject d, ref QuickDebugTestStruct e) { b = b + 1; c = b * 2; d = new QuickDebugTestObject(); d.Value = a; e.Value = a; }
public static bool TestReflectionHelperRefJmp() { int a = 1; int b = 0; int c = 0; QuickDebugTestObject d = null; QuickDebugTestStruct e = new QuickDebugTestStruct(); Console.WriteLine($"args: {a} {b} {c} {(d == null ? "null" : d.ToString())} {e}"); typeof(QuickDebugTest).GetMethod("TestA").CreateJmpDelegate <d_TestA>()(a, ref b, out c, out d, ref e); Console.WriteLine($"args after Test via ReflectionHelper using jmp: {a} {b} {c} {(d == null ? "null" : d.ToString())} {e}"); return (a == 1 && b == 1 && c == 2 && d?.Value == 1 && e.Value == 1 ); }
public static bool TestRuntimeDetourHelper() { MethodInfo m_PrintA = typeof(QuickDebugTest).GetMethod("PrintA"); MethodInfo m_PrintB = typeof(QuickDebugTest).GetMethod("PrintB"); MethodInfo m_PrintC = typeof(QuickDebugTest).GetMethod("PrintC"); MethodInfo m_PrintATrampoline = typeof(QuickDebugTest).GetMethod("PrintATrampoline"); PrintA(); // A d_PrintA t_FromB = m_PrintA.Detour <d_PrintA>(m_PrintB); PrintA(); // B t_FromB(); // A unsafe { m_PrintATrampoline.Detour( RuntimeDetour.CreateTrampoline(m_PrintA) ); PrintATrampoline(); // A } d_PrintA t_FromC = m_PrintA.Detour <d_PrintA>((Action)PrintC); PrintA(); // C t_FromC(); // B m_PrintA.GetOrigTrampoline <d_PrintA>()(); // A m_PrintB.Detour(m_PrintC); PrintB(); // C m_PrintB.Detour((Action)PrintD); PrintB(); // D m_PrintA.Undetour(); m_PrintA.Undetour(); PrintA(); // A m_PrintA.Detour(m_PrintB); m_PrintA.Detour((Action)PrintD); PrintA(); // D m_PrintA.Undetour(1); PrintA(); // D m_PrintA.Undetour(1); PrintA(); // A MethodInfo m_PrintQDTO = typeof(QuickDebugTestObject).GetMethod("PrintQDTO"); MethodInfo m_PrintQDTODetour = typeof(QuickDebugTest).GetMethod("PrintQDTODetour"); MethodInfo m_PrintQDTOTrampoline = typeof(QuickDebugTest).GetMethod("PrintQDTOTrampoline"); QuickDebugTestObject qdto = new QuickDebugTestObject(); qdto.PrintQDTO(); // QDTO d_PrintQDTO t_FromQDTO = m_PrintQDTO.Detour <d_PrintQDTO>(m_PrintQDTODetour); qdto.PrintQDTO(); // QDTO Detour t_FromQDTO(qdto); // QDTO unsafe { m_PrintQDTOTrampoline.Detour( RuntimeDetour.CreateTrampoline(m_PrintQDTO) ); PrintQDTOTrampoline(qdto); // QDTO } return(true); }
public static bool TestReflectionHelperTime() { object[] args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; Console.WriteLine($"Initial args: {args[0]} {args[1]} {args[2]} {(args[3] == null ? "null" : args[3])} {args[4]}"); MethodInfo method = typeof(QuickDebugTest).GetMethod("TestA"); const long runs = 1000000000; Console.WriteLine("Test-running Stopwatch"); Stopwatch sw = new Stopwatch(); sw.Start(); sw.Stop(); TimeSpan timeNewBox = sw.Elapsed; TimeSpan timeLocals = sw.Elapsed; TimeSpan timeMutable = sw.Elapsed; TimeSpan timeJmp = sw.Elapsed; sw.Reset(); Console.WriteLine("Generating local-less delegate"); DynamicMethodDelegate dmdNewBox = method.CreateDelegate(directBoxValueAccess: false); Console.WriteLine("Test-running dmdNewBox"); args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; dmdNewBox(null, args); if (!( (int)args[0] == 1 && (int)args[1] == 1 && (int)args[2] == 2 && ((QuickDebugTestObject)args[3])?.Value == 1 && ((QuickDebugTestStruct)args[4]).Value == 1 )) { return(false); } args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; Console.WriteLine($"Timing dmdNewBox {runs} runs"); sw.Start(); for (long i = runs; i > -1; --i) { dmdNewBox(null, args); } sw.Stop(); args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; timeNewBox = sw.Elapsed; sw.Reset(); Console.WriteLine($"time: {timeNewBox}"); Console.WriteLine("Generating mutability-ignoring delegate"); DynamicMethodDelegate dmdMutable = method.CreateDelegate(directBoxValueAccess: true); Console.WriteLine("Test-running dmdMutable"); args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; dmdMutable(null, args); if (!( (int)args[0] == 1 && (int)args[1] == 1 && (int)args[2] == 2 && ((QuickDebugTestObject)args[3])?.Value == 1 && ((QuickDebugTestStruct)args[4]).Value == 1 )) { return(false); } args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; Console.WriteLine($"Timing dmdMutable {runs} runs"); sw.Start(); for (long i = runs; i > -1; --i) { dmdMutable(null, args); } sw.Stop(); args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; timeMutable = sw.Elapsed; sw.Reset(); Console.WriteLine($"time: {timeMutable}"); /* * Console.WriteLine("Generating localed delegate"); * DynamicMethodDelegate dmdLocals = method.CreateDelegateUsingLocals(); * Console.WriteLine("Test-running dmdLocals"); * args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; * dmdLocals(null, args); * if (!( * (int) args[0] == 1 && * (int) args[1] == 1 && * (int) args[2] == 2 && * ((QuickDebugTestObject) args[3])?.Value == 1 && * ((QuickDebugTestStruct) args[4]).Value == 1 * )) return false; * args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; * * Console.WriteLine($"Timing dmdLocals {runs} runs"); * sw.Start(); * for (long i = runs; i > -1; --i) { * dmdLocals(null, args); * } * sw.Stop(); * args = new object[] { 1, 0, 0, null, new QuickDebugTestStruct() }; * timeLocals = sw.Elapsed; * sw.Reset(); * Console.WriteLine($"time: {timeLocals}"); */ Console.WriteLine("Generating jmp delegate"); d_TestA dmdJmp = method.CreateJmpDelegate <d_TestA>(); Console.WriteLine("Test-running dmdJmp"); int a = 1; int b = 0; int c = 0; QuickDebugTestObject d = null; QuickDebugTestStruct e = new QuickDebugTestStruct(); dmdJmp(a, ref b, out c, out d, ref e); if (!( a == 1 && b == 1 && c == 2 && d?.Value == 1 && e.Value == 1 )) { return(false); } Console.WriteLine($"Timing dmdJmp {runs} runs"); sw.Start(); for (long i = runs; i > -1; --i) { dmdJmp(a, ref b, out c, out d, ref e); } sw.Stop(); timeJmp = sw.Elapsed; sw.Reset(); Console.WriteLine($"time: {timeJmp}"); Console.WriteLine($"newbox / jmp: {(double) timeNewBox.Ticks / (double) timeJmp.Ticks}"); Console.WriteLine($"jmp / newbox: {(double) timeJmp.Ticks / (double) timeNewBox.Ticks}"); Console.WriteLine($"newbox / mutable: {(double) timeNewBox.Ticks / (double) timeMutable.Ticks}"); Console.WriteLine($"mutable / newbox: {(double) timeMutable.Ticks / (double) timeNewBox.Ticks}"); Console.WriteLine($"jmp / mutable: {(double) timeJmp.Ticks / (double) timeMutable.Ticks}"); Console.WriteLine($"mutable / jmp: {(double) timeMutable.Ticks / (double) timeJmp.Ticks}"); Console.WriteLine("Pass"); return(true); }
public static void PrintQDTOTrampoline(QuickDebugTestObject qdto) => Console.WriteLine("SHOULD BE DETOURED");
public static void PrintQDTODetour(QuickDebugTestObject qdto) => Console.WriteLine("QDTO Detoured");