Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[dotnet] Integrate that multi-dispatch cache I designed on the train …
…a while back. Seems to help, or so says the (RedGate profiler)++.
  • Loading branch information
jnthn committed Oct 30, 2010
1 parent b3e555f commit 92997a3
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 5 deletions.
6 changes: 6 additions & 0 deletions dotnet/runtime/Metamodel/Representations/RakudoCodeRef.cs
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Text;
using Rakudo.Runtime;
using Rakudo.Runtime.MultiDispatch;
using Rakudo.Runtime.Exceptions;

namespace Rakudo.Metamodel.Representations
Expand Down Expand Up @@ -52,6 +53,11 @@ public sealed class Instance : RakudoObject
/// </summary>
public RakudoObject[] Dispatchees;

/// <summary>
/// Multiple dispatch cache, if we have one.
/// </summary>
internal DispatchCache MultiDispatchCache;

/// <summary>
/// The context currently using this sub.
/// </summary>
Expand Down
32 changes: 27 additions & 5 deletions dotnet/runtime/Runtime/MultiDispatch/MultiDispatcher.cs
Expand Up @@ -20,16 +20,24 @@ public static class MultiDispatcher
/// <param name="Candidates"></param>
/// <param name="Capture"></param>
/// <returns></returns>
public static RakudoCodeRef.Instance FindBestCandidate(RakudoCodeRef.Instance DispatchRoutine, RakudoObject Capture)
public static RakudoObject FindBestCandidate(RakudoCodeRef.Instance DispatchRoutine, RakudoObject Capture)
{
// Sort the candidates.
// XXX Cache this in the future.
var SortedCandidates = Sort(DispatchRoutine.Dispatchees);

// Extract the native capture.
// XXX Handle non-native captures too.
var NativeCapture = Capture as P6capture.Instance;

// First, try the dispatch cache.
if (DispatchRoutine.MultiDispatchCache != null && NativeCapture.Nameds == null)
{
var CacheResult = DispatchRoutine.MultiDispatchCache.Lookup(NativeCapture.Positionals);
if (CacheResult != null)
return CacheResult;
}

// Sort the candidates.
// XXX Cache this in the future.
var SortedCandidates = Sort(DispatchRoutine.Dispatchees);

// Now go through the sorted candidates and find the first one that
// matches.
var PossiblesList = new List<RakudoCodeRef.Instance>();
Expand All @@ -39,12 +47,26 @@ public static RakudoCodeRef.Instance FindBestCandidate(RakudoCodeRef.Instance Di
if (Candidate == null)
{
if (PossiblesList.Count == 1)
{
// We have an unambiguous first candidate. Cache if possible and
// return it.
if (NativeCapture.Nameds == null)
{
if (DispatchRoutine.MultiDispatchCache == null)
DispatchRoutine.MultiDispatchCache = new DispatchCache();
DispatchRoutine.MultiDispatchCache.Add(NativeCapture.Positionals, PossiblesList[0]);
}
return PossiblesList[0];
}
else if (PossiblesList.Count > 1)
{
// Here is where you'd handle constraints.
throw new Exception("Ambiguous dispatch: more than one candidate matches");
}
else
{
continue;
}
}

/* Check if it's admissable by arity. */
Expand Down

0 comments on commit 92997a3

Please sign in to comment.