start working on preloading generic code paths for JIT
parent
f6d93c7579
commit
629e23e98c
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue