mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-20 04:48:53 +00:00
Optimized, runs 6.5x faster now.
This commit is contained in:
parent
e52ef0a16c
commit
c4a33100ee
2 changed files with 49 additions and 76 deletions
|
|
@ -15,10 +15,10 @@ namespace Cosmos.Compiler
|
|||
/// </summary>
|
||||
public partial class Scanner
|
||||
{
|
||||
private HashSet<string> mMethodNames = new HashSet<string>(StringComparer.InvariantCulture);
|
||||
private List<MethodBase> mMethods = new List<MethodBase>();
|
||||
private HashSet<string> mTypeNames = new HashSet<string>(StringComparer.InvariantCulture);
|
||||
private List<Type> mTypes = new List<Type>();
|
||||
private HashSet<MethodBase> mMethodsSet = new HashSet<MethodBase>();
|
||||
private List<MethodBase> mMethods = new List<MethodBase>();
|
||||
private HashSet<Type> mTypesSet = new HashSet<Type>();
|
||||
private List<Type> mTypes = new List<Type>();
|
||||
|
||||
private Func<Op>[] mOps;
|
||||
public Func<Op>[] Ops
|
||||
|
|
@ -29,14 +29,10 @@ namespace Cosmos.Compiler
|
|||
}
|
||||
set
|
||||
{
|
||||
if(value != mOps)
|
||||
{
|
||||
if(value == null)
|
||||
{
|
||||
if(value != mOps) {
|
||||
if(value == null) {
|
||||
throw new Exception("Cannot set Ops to null");
|
||||
}
|
||||
if(value.Length != 0xFE1F)
|
||||
{
|
||||
} else if (value.Length != 0xFE1F) {
|
||||
throw new Exception("Element count mismatch!");
|
||||
}
|
||||
mOps = value;
|
||||
|
|
@ -51,9 +47,8 @@ namespace Cosmos.Compiler
|
|||
//File.WriteAllLines(@"e:\cosmos.dbg", mMethodNames.ToArray());
|
||||
}
|
||||
|
||||
private void ScanList()
|
||||
{
|
||||
// dont use a foreach here, the list will change.
|
||||
private void ScanList() {
|
||||
// Cannot use foreach, the list changes as we go
|
||||
for(int i = 0; i < mMethods.Count; i++)
|
||||
{
|
||||
ScanMethod(mMethods[i]);
|
||||
|
|
@ -62,22 +57,16 @@ namespace Cosmos.Compiler
|
|||
|
||||
private void ScanMethod(MethodBase aMethodBase)
|
||||
{
|
||||
// pinvoke methods dont have an embedded implementation
|
||||
if ((aMethodBase.Attributes & MethodAttributes.PinvokeImpl) != 0)
|
||||
{
|
||||
// pinvoke
|
||||
return;
|
||||
}
|
||||
else if (aMethodBase.IsAbstract)
|
||||
{
|
||||
// abstract methods dont have an implementation
|
||||
|
||||
return;
|
||||
if ((aMethodBase.Attributes & MethodAttributes.PinvokeImpl) != 0) {
|
||||
// pinvoke methods dont have an embedded implementation
|
||||
return;
|
||||
} else if (aMethodBase.IsAbstract) {
|
||||
// abstract methods dont have an implementation
|
||||
return;
|
||||
}
|
||||
|
||||
var xImplFlags = aMethodBase.GetMethodImplementationFlags();
|
||||
if ((xImplFlags & MethodImplAttributes.Native) != 0)
|
||||
{
|
||||
if ((xImplFlags & MethodImplAttributes.Native) != 0) {
|
||||
// native implementations cannot be compiled
|
||||
return;
|
||||
}
|
||||
|
|
@ -85,23 +74,26 @@ namespace Cosmos.Compiler
|
|||
try
|
||||
{
|
||||
var xBody = aMethodBase.GetMethodBody();
|
||||
if (xBody == null)
|
||||
{
|
||||
if (xBody == null) {
|
||||
return;
|
||||
}
|
||||
using(var xReader = new ILReader(aMethodBase, xBody))
|
||||
{
|
||||
while(xReader.Read())
|
||||
{
|
||||
InstructionCount++;
|
||||
using(var xReader = new ILReader(aMethodBase, xBody)) {
|
||||
while(xReader.Read()) {
|
||||
// Kudzu:
|
||||
// Uncomment for debugging - has a small but noticable
|
||||
// impact on runtime. Could be coincidental, but ran
|
||||
// tests several times with and with out and without
|
||||
// was consistently 0.5 secs faster on the Atom.
|
||||
// Does not make much sense though as its only used 13000
|
||||
// times or so, so possibly the compiling in is affecting
|
||||
// some CPU cache hit or other?
|
||||
//InstructionCount++;
|
||||
var xCreate = mOps[(ushort) xReader.OpCode];
|
||||
if(xCreate==null)
|
||||
{
|
||||
if(xCreate == null) {
|
||||
LogMissingOp(xReader.OpCode);
|
||||
continue;
|
||||
}
|
||||
var xOp = xCreate();
|
||||
QueueMethodCallCount = 0;
|
||||
xOp.Scan(xReader, this);
|
||||
// TEMP
|
||||
//if (xReader.OperandValueMethod!=null)
|
||||
|
|
@ -113,54 +105,36 @@ namespace Cosmos.Compiler
|
|||
//}
|
||||
}
|
||||
}
|
||||
}catch(Exception E)
|
||||
{
|
||||
} catch(Exception E) {
|
||||
throw new Exception("Error getting body!", E);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int QueueMethodCallCount = 0;
|
||||
public void QueueMethod(MethodBase aMethod)
|
||||
{
|
||||
QueueMethodCallCount++;
|
||||
var xName = aMethod.GetFullName();
|
||||
if (!mMethodNames.Contains(xName))
|
||||
{
|
||||
mMethodNames.Add(xName);
|
||||
mMethods.Add(aMethod);
|
||||
QueueType(aMethod.DeclaringType);
|
||||
}
|
||||
public void QueueMethod(MethodBase aMethod) {
|
||||
if (!mMethodsSet.Contains(aMethod)) {
|
||||
mMethodsSet.Add(aMethod);
|
||||
mMethods.Add(aMethod);
|
||||
QueueType(aMethod.DeclaringType);
|
||||
}
|
||||
}
|
||||
|
||||
public void QueueType(Type type)
|
||||
{
|
||||
if(type == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!mTypeNames.Contains(type.GetFullName()))
|
||||
{
|
||||
QueueType(type.BaseType);
|
||||
foreach (
|
||||
var xMethod in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
|
||||
{
|
||||
if (xMethod.DeclaringType != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (xMethod.IsVirtual)
|
||||
{
|
||||
QueueMethod(xMethod);
|
||||
}
|
||||
public void QueueType(Type aType) {
|
||||
if (aType != null) {
|
||||
if (!mTypesSet.Contains(aType)) {
|
||||
mTypesSet.Add(aType);
|
||||
mTypes.Add(aType);
|
||||
QueueType(aType.BaseType);
|
||||
foreach (var xMethod in aType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
|
||||
if (xMethod.DeclaringType == aType) {
|
||||
if (xMethod.IsVirtual) {
|
||||
QueueMethod(xMethod);
|
||||
}
|
||||
}
|
||||
mTypeNames.Add(type.GetFullName());
|
||||
mTypes.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//private void
|
||||
|
||||
public int MethodCount
|
||||
{
|
||||
get
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ using System.Collections.ObjectModel;
|
|||
using Cosmos.Compiler;
|
||||
using Cosmos.Compiler.IL;
|
||||
|
||||
|
||||
namespace TestApp {
|
||||
class Program {
|
||||
static void Main(string[] args)
|
||||
|
|
|
|||
Loading…
Reference in a new issue