start working on preloading generic code paths for JIT

pull/5/head
thatcosmonaut 2019-12-16 14:51:12 -08:00
parent f6d93c7579
commit 629e23e98c
3 changed files with 55 additions and 1 deletions

View File

@ -0,0 +1,35 @@
using System;
using System.Reflection;
namespace Encompass
{
internal class UberEngine : Engine
{
public override void Update(double dt)
{
foreach (var type in readTypes)
{
var instanceParam = new object[] { Activator.CreateInstance(type) };
CallMethodByName(type, "ReadComponent", null);
CallMethodByName(type, "ReadComponentIncludingEntity", null);
CallMethodByName(type, "ReadComponents", null);
CallMethodByName(type, "ReadComponentsIncludingEntity", null);
CallMethodByName(type, "GetComponent", null);
CallMethodByName(type, "SetComponent", instanceParam);
CallMethodByName(type, "HasComponent", null);
CallMethodByName(type, "SomeComponent", null);
CallMethodByName(type, "RemoveComponent", null);
CallMethodByName(type, "DestroyWith", null);
CallMethodByName(type, "DestroyAllWith", null);
}
}
private void CallMethodByName(Type type, string methodName, object[] parameters)
{
var readComponentMethod = typeof(WorldBuilder).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
var genericReadComponentMethod = readComponentMethod.MakeGenericMethod(type);
genericReadComponentMethod.Invoke(this, parameters);
}
}
}

View File

@ -149,6 +149,9 @@ namespace Encompass
typeToReaders[receiveType].Add(engine); typeToReaders[receiveType].Add(engine);
} }
// System.Runtime.CompilerServices.RuntimeHelpers.PrepareMethod(typeof(TEngine).GetRuntimeMethod("Update", new Type[] { typeof(double) }).MethodHandle);
// typeof(TEngine).GetMethod("Update", new Type[] { typeof(double) }).MethodHandle.GetFunctionPointer();
return engine; return engine;
} }
@ -367,5 +370,21 @@ namespace Encompass
return world; return world;
} }
/// <summary>
/// This is necessary because Encompass heavily uses generic methods with value types,
/// so the first time any code path runs the JIT gets smashed. This method warms up the runtime.
/// </summary>
private void PreloadJIT(IEnumerable<Type> componentTypes)
{
var dummyWorldBuilder = new WorldBuilder();
dummyWorldBuilder.AddEngine(new UberEngine());
var dummyWorld = dummyWorldBuilder.Build();
dummyWorld.Update(1);
dummyWorld.Draw();
}
} }
} }