Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move assign process, including LISTSTORE, off CPS
  • Loading branch information
sorear committed May 30, 2011
1 parent 5ef2e84 commit 5c3490f
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 102 deletions.
5 changes: 1 addition & 4 deletions lib/Builtins.cs
Expand Up @@ -28,10 +28,7 @@ public class Builtins {
if (!lhs.islist) {
lhs.Store(rhs);
} else {
Frame n = lhs.Fetch().InvokeMethod(Kernel.GetInferiorRoot(),
"LISTSTORE",
new Variable[2] { lhs, Kernel.NewROScalar(rhs) }, null);
Kernel.RunInferior(n);
lhs.Fetch().mo.mro_LISTSTORE.Get(lhs, Kernel.NewROScalar(rhs));
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/CLRBackend.cs
Expand Up @@ -3854,7 +3854,7 @@ class NamProcessor {
thandlers["fetch"] = Methody(null, Tokens.Variable_Fetch);
thandlers["bget"] = FieldGet(Tokens.BValue, "v");
thandlers["default_new"] = Methody(null, Tokens.Kernel.GetMethod("DefaultNew"));
thandlers["assign"] = Methody(Tokens.Void, Tokens.Kernel.GetMethod("Assign"));
thandlers["assign"] = Methody(null, Tokens.Kernel.GetMethod("Assign"));
thandlers["cotake"] = Methody(Tokens.Variable, Tokens.Kernel.GetMethod("CoTake"));
thandlers["take"] = Methody(Tokens.Variable, Tokens.Kernel.GetMethod("Take"));
thandlers["startgather"] = Methody(Tokens.Frame, Tokens.Kernel.GetMethod("GatherHelper"));
Expand Down
58 changes: 1 addition & 57 deletions lib/CORE.setting
Expand Up @@ -363,7 +363,7 @@ sub exit($status = 0) { Q:CgOp {
(rnull [exit (cast int (obj_getnum {$status}))])
} }
sub infix:<=>(\$a, \$b) { Q:CgOp { (prog [assign {$a} {$b}] {$a}) } }
sub infix:<=>(\$a, \$b) { $a = $b }

sub chars($str) { chars($str) }
sub substr($str, $start, $len = chars($str) - $start) { substr($str, $start, $len) }
Expand Down Expand Up @@ -607,28 +607,6 @@ my class Parcel is Cool {
method Numeric() { + @(self) }
method Str () { ~ @(self) }
method Bool () { ? @(self) }
method LISTSTORE(\$in) {
Q:CgOp {
(letn i (i 0)
vals (start_iter {$in})
tgts (unbox fvarlist (@ {self}))
ntgt (fvarlist_length (l tgts))
tgt (null var)
(whileloop 0 0 (< (l i) (l ntgt))
(prog
(l tgt (fvarlist_item (l i) (l tgts)))
(l i (+ (l i) (i 1)))
(ternary (var_islist (l tgt))
(letn ob (obj_newblank (class_ref mo List))
(iter_to_list (l ob) (l vals))
(l vals (vvarlist_new_empty))
(sink (methodcall (l tgt) LISTSTORE (newrwlistvar (l ob)))))
(assign (l tgt) (ternary (iter_hasflat (l vals))
(vvarlist_shift (l vals)) {Any})))))
{self})
};
}
}
constant Nil = Q:CgOp { (newrwlistvar (@ (box Parcel (fvarlist_new)))) };
Expand Down Expand Up @@ -761,20 +739,6 @@ my class List is Cool {
}
my class Array is List {
method LISTSTORE(\$in) {
Q:CgOp {
(letn iter (vvarlist_new_empty)
into (vvarlist_new_empty)
sobj (@ {self})
(vvarlist_push (l iter) {$in})
(whileloop 0 0 (iter_hasflat (l iter))
(vvarlist_push (l into) (vvarlist_shift (l iter))))
(setslot items (l sobj) (iter_copy_elems (l into)))
(setslot rest (l sobj) (l iter))
(newrwlistvar (l sobj)))
};
}

method perl(\$self:) {
$self // return $self.typename;
"[" ~ $self.map(*.perl).join(', ') ~ "]" ~ ($self.flattens ?? ".list" !! "");
Expand Down Expand Up @@ -809,26 +773,6 @@ my class Hash {
%new
}
method LISTSTORE(\$in) {
Q:CgOp {
(letn iter (vvarlist_new_empty)
into (varhash_new)
sobj (@ {self})
(vvarlist_push (l iter) {$in})
(whileloop 0 0 (iter_hasflat (l iter))
(letn elt (@ (vvarlist_shift (l iter)))
(ternary (obj_isa (l elt) (class_ref mo Pair))
(varhash_setindex (obj_getstr (getslot key var (l elt)))
(l into) (nsw (@ (getslot value var (l elt)))))
(ternary (iter_hasflat (l iter))
(varhash_setindex (obj_getstr (ns (l elt))) (l into)
(nsw (@ (vvarlist_shift (l iter)))))
(sink (die "Unmatched key in Hash.LISTSTORE"))))))
(setbox (l sobj) (l into))
(newrwlistvar (l sobj)))
};
}

# Rakudo extensions compatibility - DO NOT USE
method delete($key) { self.{$key}:delete }
method exists($key) { self.{$key}:exists }
Expand Down
101 changes: 86 additions & 15 deletions lib/Kernel.cs
Expand Up @@ -856,11 +856,7 @@ public class SubInfo {
else
nvar = Kernel.NewTypedScalar(type);

if (nvar.islist)
Kernel.RunInferior(Kernel.Assign(Kernel.GetInferiorRoot(), nvar, src));
else
nvar.Store(src.Fetch());
src = nvar;
src = Kernel.Assign(nvar, src);
} else {
bool islist = ((flags & SIG_F_BINDLIST) != 0);
bool rw = ((flags & SIG_F_READWRITE) != 0) && !islist;
Expand Down Expand Up @@ -1360,6 +1356,41 @@ class CtxAnyList : ContextHandler<Variable> {
}
}

class IxParcelLISTSTORE : IndexHandler {
public override Variable Get(Variable lhs, Variable rhs) {
VarDeque src = Builtins.start_iter(rhs);
P6any lhs_o = lhs.Fetch();
if (!lhs_o.IsDefined())
throw new NieczaException("assigning to undefined parcel");

Variable[] dsts = Kernel.UnboxAny<Variable[]>(lhs_o);
P6any[] srcs = new P6any[dsts.Length];

for (int i = 0; i < dsts.Length; i++) {
Variable d = dsts[i];
if (d.islist) {
srcs[i] = new P6opaque(Kernel.ListMO);
Kernel.IterToList(srcs[i], src);
src = new VarDeque();
} else {
srcs[i] = Kernel.IterHasFlat(src, true) ?
src.Shift().Fetch() : Kernel.AnyP;
}
}

for (int i = 0; i < dsts.Length; i++) {
Variable d = dsts[i];
if (d.islist) {
d.Fetch().mo.mro_LISTSTORE.Get(d,
Kernel.NewRWListVar(srcs[i]));
} else {
d.Store(srcs[i]);
}
}

return lhs;
}
}
class CtxParcelList : ContextHandler<Variable> {
public override Variable Get(Variable obj) {
P6any o = obj.Fetch();
Expand Down Expand Up @@ -1409,6 +1440,21 @@ class CtxParcelIterator : ContextHandler<VarDeque> {
}
}

class IxArrayLISTSTORE : IndexHandler {
public override Variable Get(Variable lhs, Variable rhs) {
P6any lhs_o = lhs.Fetch();
if (!lhs_o.IsDefined())
throw new NieczaException("LISTSTORE to undefined Array");
VarDeque iter = Builtins.start_iter(rhs);
VarDeque items = new VarDeque();
while (Kernel.IterHasFlat(iter, true))
items.Push(Kernel.NewRWScalar(Kernel.AnyMO,
iter.Shift().Fetch()));
lhs_o.SetSlot("items", items);
lhs_o.SetSlot("rest", iter); /*now empty*/
return lhs;
}
}
class CtxListIterator : ContextHandler<VarDeque> {
public override VarDeque Get(Variable obj) {
P6opaque d = (P6opaque) obj.Fetch();
Expand All @@ -1419,6 +1465,31 @@ class CtxListIterator : ContextHandler<VarDeque> {
}
}

class IxHashLISTSTORE : IndexHandler {
public override Variable Get(Variable lhs, Variable rhs) {
P6any lhs_o = lhs.Fetch();
if (!lhs_o.IsDefined())
throw new NieczaException("LISTSTORE to undefined Hash");
VarHash into = new VarHash();
VarDeque iter = Builtins.start_iter(rhs);
while (Kernel.IterHasFlat(iter, true)) {
P6any elt = iter.Shift().Fetch();
if (elt.mo.HasMRO(Kernel.PairMO)) {
Variable k = (Variable) elt.GetSlot("key");
Variable v = (Variable) elt.GetSlot("value");
into[k.Fetch().mo.mro_raw_Str.Get(k)] =
Kernel.NewRWScalar(Kernel.AnyMO, v.Fetch());
} else {
if (!Kernel.IterHasFlat(iter, true))
throw new NieczaException("Unmatched key in Hash.LISTSTORE");
into[elt.mo.mro_raw_Str.Get(Kernel.NewROScalar(elt))] =
Kernel.NewRWScalar(Kernel.AnyMO, iter.Shift().Fetch());
}
}
Kernel.SetBox<VarHash>(lhs_o, into);
return lhs;
}
}
class CtxHashIterator : ContextHandler<VarDeque> {
public override VarDeque Get(Variable obj) {
return Builtins.HashIterRaw(3, obj);
Expand Down Expand Up @@ -2370,18 +2441,16 @@ public class MMDCandidateLongname {
return rhs;
}

public static Frame Assign(Frame th, Variable lhs, Variable rhs) {
public static Variable Assign(Variable lhs, Variable rhs) {
if (!lhs.islist) {
if (!lhs.rw) {
return Kernel.Die(th, "assigning to readonly value");
}
if (!lhs.rw)
throw new NieczaException("assigning to readonly value");

lhs.Store(rhs.Fetch());
return th;
} else {
lhs.Fetch().mo.mro_LISTSTORE.Get(lhs, rhs);
}

return lhs.Fetch().InvokeMethod(th, "LISTSTORE", new Variable[2] { lhs, rhs }, null);

return lhs;
}

// ro, not rebindable
Expand Down Expand Up @@ -2518,8 +2587,7 @@ public class MMDCandidateLongname {
} else {
Variable obj = (kind == P6how.A_HASH) ? CreateHash() :
CreateArray();
if (vx != null)
RunInferior(Assign(GetInferiorRoot(), obj, vx));
if (vx != null) Assign(obj, vx);
n.SetSlot(a.name, obj);
}
}
Expand Down Expand Up @@ -3114,11 +3182,13 @@ class LastFrameNode {
ParcelMO = new STable("Parcel");
Handler_PandBox(ParcelMO, "iterator", new CtxParcelIterator(),
IteratorMO);
WrapHandler1(ParcelMO, "LISTSTORE", new IxParcelLISTSTORE());
Handler_Vonly(ParcelMO, "list", new CtxParcelList(), null);
ParcelMO.FillProtoClass(new string[] { });
ParcelMO.Invalidate();

ArrayMO = new STable("Array");
WrapHandler1(ArrayMO, "LISTSTORE", new IxArrayLISTSTORE());
ArrayMO.FillProtoClass(new string[] { "items", "rest" });
WrapHandler1(ArrayMO, "at-pos", new IxListAtPos(true));
ArrayMO.Invalidate();
Expand All @@ -3134,6 +3204,7 @@ class LastFrameNode {
ListMO.Invalidate();

HashMO = new STable("Hash");
WrapHandler1(HashMO, "LISTSTORE", new IxHashLISTSTORE());
WrapHandler1(HashMO, "exists-key", new IxHashExistsKey());
WrapHandler1(HashMO, "delete-key", new IxHashDeleteKey());
WrapHandler1(HashMO, "at-key", new IxHashAtKey());
Expand Down
5 changes: 4 additions & 1 deletion lib/ObjModel.cs
Expand Up @@ -454,6 +454,8 @@ public class STable {
= new IxCallMethod("exists-key");
public static readonly IndexHandler CallDeleteKey
= new IxCallMethod("delete-key");
public static readonly IndexHandler CallLISTSTORE
= new IxCallMethod("LISTSTORE");
public static readonly InvokeHandler CallINVOKE
= new InvokeCallMethod();

Expand All @@ -477,7 +479,7 @@ public class STable {
public ContextHandler<Variable[]> mro_raw_reify;
public ContextHandler<object> mro_to_clr;
public IndexHandler mro_at_pos, mro_at_key, mro_exists_key,
mro_delete_key;
mro_delete_key, mro_LISTSTORE;

public InvokeHandler mro_INVOKE;

Expand Down Expand Up @@ -510,6 +512,7 @@ public class STable {
internal void SetupVTables() {
mro_at_key = _GetVT("at-key") as IndexHandler ?? CallAtKey;
mro_at_pos = _GetVT("at-pos") as IndexHandler ?? CallAtPos;
mro_LISTSTORE = _GetVT("LISTSTORE") as IndexHandler ?? CallLISTSTORE;
mro_Bool = _GetVT("Bool") as ContextHandler<Variable> ?? CallBool;
mro_defined = _GetVT("defined") as ContextHandler<Variable> ?? CallDefined;
mro_delete_key = _GetVT("delete-key") as IndexHandler ?? CallDeleteKey;
Expand Down
1 change: 0 additions & 1 deletion perf/perf.TODO
Expand Up @@ -7,7 +7,6 @@ Experiment with "if non-overriden, then replace method" hooks

Experiment with making P6any: Variable

Make LISTSTORE off-loop?
push, shift, etc off-loop?

Avoid calling a function for trivial attribute (or parameter) defaults
Expand Down
24 changes: 16 additions & 8 deletions perf/std-20110528.pl6
Expand Up @@ -20,15 +20,23 @@ sub bench($name, $nr, $f) {
}

bench "nulling test", 1000000, sub () {};
{
my @l;
bench "iterate empty list", 1000000, sub () { for @l { } };
}
# {
# my @l;
# bench "iterate empty list", 1000000, sub () { for @l { } };
# }

my @x; my $y; my $z; my %h;
bench "scalar assign", 1000000, sub () { $y = 1; $y = 2; $y = 3; $y = 4; $y = 5; $y = 6; $y = 7; $y = 8; $y = 9; $y = 10 };
bench "list assign (Parcel)", 1000000, sub () { ($y,$z) = ($z,$y) };
bench "list assign (Array)", 1000000, sub () { @x = 1, 2, 3 };
bench "list assign (Hash)", 1000000, sub () { %h = "a", 1, "b", 2 };
bench 'head assign (&head)', 1000000, sub () { $y = head((1,2,3)) };
bench 'head assign (Parcel)', 1000000, sub () { ($y,) = (1,2,3) };

my %h; my $x;
bench "Hash.delete-key", 1000000, sub () { %h<foo>:delete };
bench "Any.delete-key", 1000000, sub () { $x<foo>:delete };
bench "Bool.Numeric", 1000000, sub () { +True };
# my %h; my $x;
# bench "Hash.delete-key", 1000000, sub () { %h<foo>:delete };
# bench "Any.delete-key", 1000000, sub () { $x<foo>:delete };
# bench "Bool.Numeric", 1000000, sub () { +True };

# my ($x, $y);
# bench "Parcel.LISTSTORE", 1000000, sub () { ($x,$y) = ($y,$x) };
Expand Down
16 changes: 1 addition & 15 deletions src/NieczaPassSimplifier.pm6
Expand Up @@ -103,21 +103,7 @@ our %funcs = (
sub do_assign($body, $nv, $invname, $op) {
return $op unless defined my $args = no_named_params($op);
return $op unless $args == 2;

if (!$nv) {
return ::Op::Assign.new(lhs => $args[0], rhs => $args[1]);
} elsif (defined(my $name = is_simple_var($args[0]))) {
return ::Op::StatementList.new(children => [
::Op::Assign.new(lhs => $args[0], rhs => $args[1]),
::Op::Lexical.new(name => $name)]);
} else {
my $id = ::GLOBAL::NieczaActions.gensym;
return ::Op::Let.new(var => $id, to => $args[0], in =>
::Op::StatementList.new(children => [
::Op::Assign.new(lhs => ::Op::LetVar.new(name => $id),
rhs => $args[1]),
::Op::LetVar.new(name => $id)]));
}
::Op::Assign.new(lhs => $args[0], rhs => $args[1]);
}

sub do_builtin($name, $expect) { sub ($body, $nv, $invname, $op) {
Expand Down

0 comments on commit 5c3490f

Please sign in to comment.