Optimized, runs 6.5x faster now.

This commit is contained in:
kudzu_cp 2009-07-22 18:49:35 +00:00
parent e52ef0a16c
commit c4a33100ee
2 changed files with 49 additions and 76 deletions

View file

@ -15,9 +15,9 @@ namespace Cosmos.Compiler
/// </summary> /// </summary>
public partial class Scanner public partial class Scanner
{ {
private HashSet<string> mMethodNames = new HashSet<string>(StringComparer.InvariantCulture); private HashSet<MethodBase> mMethodsSet = new HashSet<MethodBase>();
private List<MethodBase> mMethods = new List<MethodBase>(); private List<MethodBase> mMethods = new List<MethodBase>();
private HashSet<string> mTypeNames = new HashSet<string>(StringComparer.InvariantCulture); private HashSet<Type> mTypesSet = new HashSet<Type>();
private List<Type> mTypes = new List<Type>(); private List<Type> mTypes = new List<Type>();
private Func<Op>[] mOps; private Func<Op>[] mOps;
@ -29,14 +29,10 @@ namespace Cosmos.Compiler
} }
set set
{ {
if(value != mOps) if(value != mOps) {
{ if(value == null) {
if(value == null)
{
throw new Exception("Cannot set Ops to null"); throw new Exception("Cannot set Ops to null");
} } else if (value.Length != 0xFE1F) {
if(value.Length != 0xFE1F)
{
throw new Exception("Element count mismatch!"); throw new Exception("Element count mismatch!");
} }
mOps = value; mOps = value;
@ -51,9 +47,8 @@ namespace Cosmos.Compiler
//File.WriteAllLines(@"e:\cosmos.dbg", mMethodNames.ToArray()); //File.WriteAllLines(@"e:\cosmos.dbg", mMethodNames.ToArray());
} }
private void ScanList() private void ScanList() {
{ // Cannot use foreach, the list changes as we go
// dont use a foreach here, the list will change.
for(int i = 0; i < mMethods.Count; i++) for(int i = 0; i < mMethods.Count; i++)
{ {
ScanMethod(mMethods[i]); ScanMethod(mMethods[i]);
@ -62,22 +57,16 @@ namespace Cosmos.Compiler
private void ScanMethod(MethodBase aMethodBase) private void ScanMethod(MethodBase aMethodBase)
{ {
if ((aMethodBase.Attributes & MethodAttributes.PinvokeImpl) != 0) {
// pinvoke methods dont have an embedded implementation // pinvoke methods dont have an embedded implementation
if ((aMethodBase.Attributes & MethodAttributes.PinvokeImpl) != 0)
{
// pinvoke
return; return;
} } else if (aMethodBase.IsAbstract) {
else if (aMethodBase.IsAbstract)
{
// abstract methods dont have an implementation // abstract methods dont have an implementation
return; return;
} }
var xImplFlags = aMethodBase.GetMethodImplementationFlags(); var xImplFlags = aMethodBase.GetMethodImplementationFlags();
if ((xImplFlags & MethodImplAttributes.Native) != 0) if ((xImplFlags & MethodImplAttributes.Native) != 0) {
{
// native implementations cannot be compiled // native implementations cannot be compiled
return; return;
} }
@ -85,23 +74,26 @@ namespace Cosmos.Compiler
try try
{ {
var xBody = aMethodBase.GetMethodBody(); var xBody = aMethodBase.GetMethodBody();
if (xBody == null) if (xBody == null) {
{
return; return;
} }
using(var xReader = new ILReader(aMethodBase, xBody)) using(var xReader = new ILReader(aMethodBase, xBody)) {
{ while(xReader.Read()) {
while(xReader.Read()) // Kudzu:
{ // Uncomment for debugging - has a small but noticable
InstructionCount++; // 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]; var xCreate = mOps[(ushort) xReader.OpCode];
if(xCreate==null) if(xCreate == null) {
{
LogMissingOp(xReader.OpCode); LogMissingOp(xReader.OpCode);
continue; continue;
} }
var xOp = xCreate(); var xOp = xCreate();
QueueMethodCallCount = 0;
xOp.Scan(xReader, this); xOp.Scan(xReader, this);
// TEMP // TEMP
//if (xReader.OperandValueMethod!=null) //if (xReader.OperandValueMethod!=null)
@ -113,53 +105,35 @@ namespace Cosmos.Compiler
//} //}
} }
} }
}catch(Exception E) } catch(Exception E) {
{
throw new Exception("Error getting body!", E); throw new Exception("Error getting body!", E);
} }
} }
public void QueueMethod(MethodBase aMethod) {
private int QueueMethodCallCount = 0; if (!mMethodsSet.Contains(aMethod)) {
public void QueueMethod(MethodBase aMethod) mMethodsSet.Add(aMethod);
{
QueueMethodCallCount++;
var xName = aMethod.GetFullName();
if (!mMethodNames.Contains(xName))
{
mMethodNames.Add(xName);
mMethods.Add(aMethod); mMethods.Add(aMethod);
QueueType(aMethod.DeclaringType); QueueType(aMethod.DeclaringType);
} }
} }
public void QueueType(Type type) public void QueueType(Type aType) {
{ if (aType != null) {
if(type == null) if (!mTypesSet.Contains(aType)) {
{ mTypesSet.Add(aType);
return; mTypes.Add(aType);
} QueueType(aType.BaseType);
if (!mTypeNames.Contains(type.GetFullName())) foreach (var xMethod in aType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
{ if (xMethod.DeclaringType == aType) {
QueueType(type.BaseType); if (xMethod.IsVirtual) {
foreach (
var xMethod in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
if (xMethod.DeclaringType != type)
{
continue;
}
if (xMethod.IsVirtual)
{
QueueMethod(xMethod); QueueMethod(xMethod);
} }
} }
mTypeNames.Add(type.GetFullName());
mTypes.Add(type);
} }
} }
}
//private void }
public int MethodCount public int MethodCount
{ {

View file

@ -10,7 +10,6 @@ using System.Collections.ObjectModel;
using Cosmos.Compiler; using Cosmos.Compiler;
using Cosmos.Compiler.IL; using Cosmos.Compiler.IL;
namespace TestApp { namespace TestApp {
class Program { class Program {
static void Main(string[] args) static void Main(string[] args)