Skip to content
Browse files

Implement a new STD-level role composition cache

  • Loading branch information...
1 parent 4c94673 commit ddbbcc43477445e04626336daf74ff6c52ca4e06 @sorear committed Jan 27, 2012
Showing with 42 additions and 6 deletions.
  1. +12 −0 src/CompilerBlob.cs
  2. +6 −0 src/NieczaBackendDotnet.pm6
  3. +21 −3 src/NieczaFrontendSTD.pm6
  4. +3 −3 src/niecza
View
12 src/CompilerBlob.cs
@@ -213,5 +213,17 @@ public class Downcaller {
public static string ExecName() {
return Assembly.GetEntryAssembly().Location;
}
+
+ static Dictionary<P6any,Dictionary<P6any,Variable>> role_cache =
+ new Dictionary<P6any,Dictionary<P6any,Variable>>();
+ public static Variable CacheSlot(P6any a1, P6any a2) {
+ Dictionary<P6any,Variable> subcache;
+ if (!role_cache.TryGetValue(a1, out subcache))
+ role_cache[a1] = subcache = new Dictionary<P6any,Variable>();
+ Variable var;
+ if (!subcache.TryGetValue(a2, out var))
+ subcache[a2] = var = Kernel.NewMuScalar(Kernel.TrueV.Fetch());
+ return var;
+ }
}
}
View
6 src/NieczaBackendDotnet.pm6
@@ -75,6 +75,12 @@ sub downcall(*@args) {
Q:CgOp { (rawscall Niecza.Downcaller,CompilerBlob.DownCall {@args}) }
}
+method cached_but($cls, $role) {
+ # TODO: Object hashes!
+ my $slot := Q:CgOp { (rawscall Niecza.Downcaller,CompilerBlob.CacheSlot (@ {$cls}) (@ {$role})) };
+ defined($slot) ?? ($slot = ($cls but $role)) !! $slot
+}
+
sub gethash($str) {
Q:CgOp { (box Str (rawscall Niecza.Downcaller,CompilerBlob.DoHash (obj_getstr {$str}))) }
}
View
24 src/NieczaFrontendSTD.pm6
@@ -1,4 +1,4 @@
-our $Actions;
+our ($Actions, $Backend);
class NieczaFrontendSTD;
@@ -63,6 +63,15 @@ method default_O($cat, $sym) {
}
}
+sub rolecache($key, $thunk) {
+ state %cache;
+ (%cache{$key}:exists) ?? %cache{$key} !! (%cache{$key} := $thunk())
+}
+
+method balanced ($start,$stop) { self.mixin( rolecache("B$start\0$stop", {STD::startstop[$start,$stop]}) ); }
+method unbalanced ($stop) { self.mixin( rolecache("U$stop", {STD::stop[$stop]}) ); }
+method unitstop ($stop) { self.mixin( rolecache("N$stop", {STD::unitstop[$stop]}) ); }
+
# MOP will be used to install $*rx into appropriate method field
role sym_categorical[$name,$cat,$sym] {
$*name = $name;
@@ -85,13 +94,21 @@ role bracket_categorical[$name,$cat,$sym1,$sym2] {
}
method add_categorical($name) {
+ state %cat_cache;
+
# Signature extension, not categorical
if $name ~~ /^\w+\:\(/ {
return self;
}
# CORE names are hardcoded
return self if $*UNITNAME eq 'CORE';
return self unless ($name ~~ /^(\w+)\: \< (.*) \> /);
+
+ if %cat_cache{$name}:exists {
+ %*LANG<MAIN> = $Backend.cached_but(self.WHAT, %cat_cache{$name});
+ return self.cursor_fresh(%*LANG<MAIN>);
+ }
+
my $cat = ~$0;
my $sym = ~$1;
my ($role, $*rxm, $*name);
@@ -104,6 +121,7 @@ method add_categorical($name) {
} else {
$role = OUR::sym_categorical["{$cat}:sym<$sym>", $cat, $sym];
}
+ %cat_cache{$name} := $role;
# $*name will be set if the role blocks are run. If $*name is not set,
# then a cached role was reused and there is no need to fix up method names.
@@ -113,7 +131,7 @@ method add_categorical($name) {
Q:CgOp { (rnull (_invalidate (obj_llhow (@ {$role})))) };
}
- %*LANG<MAIN> = self.WHAT but $role;
+ %*LANG<MAIN> = $Backend.cached_but(self.WHAT, $role);
self.cursor_fresh(%*LANG<MAIN>);
}
@@ -162,7 +180,7 @@ method cursor_force($pos) {
self.cursor($pos);
}
-method mixin($role) { self.cursor_fresh(self.WHAT but $role) }
+method mixin($role) { self.cursor_fresh($Backend.cached_but(self.WHAT, $role)) }
method mark_sinks(@sl) { #OK not used
#NYI
View
6 src/niecza
@@ -381,9 +381,9 @@ GetOptions(:!permute,
);
my @*INC;
-my $backend;
+our $Backend;
if $bcnd eq 'dotnet' || $bcnd eq 'mono' {
- $backend = NieczaBackendDotnet.new(obj_dir => $odir, safemode => $safe);
+ $Backend = NieczaBackendDotnet.new(obj_dir => $odir, safemode => $safe);
}
else {
note "Backend '$bcnd' not supported";
@@ -398,7 +398,7 @@ my $c = NieczaCompiler.new(
lang => $lang,
safemode => $safe,
),
- backend => $backend,
+ backend => $Backend,
verbose => $verb,
);

0 comments on commit ddbbcc4

Please sign in to comment.
Something went wrong with that request. Please try again.