Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Sort multi candidates at compile time.
This is instead of doing so on the first call.
  • Loading branch information
jnthn committed Mar 14, 2013
1 parent 6993950 commit daabef9
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 3 deletions.
12 changes: 12 additions & 0 deletions src/Perl6/Actions.pm
Expand Up @@ -272,6 +272,7 @@ class Perl6::Actions is HLL::Actions does STDActions {

# Checks.
$*W.assert_stubs_defined($/);
$*W.sort_protos();

# Get the block for the unit mainline code.
my $unit := $*UNIT;
Expand Down Expand Up @@ -2140,6 +2141,11 @@ class Perl6::Actions is HLL::Actions does STDActions {
self.add_inlining_info_if_possible($/, $code, $block, @params);
}
}

# If it's a proto, add it to the sort-at-CHECK-time queue.
if $*MULTINESS eq 'proto' {
$*W.add_proto_to_sort($code);
}

my $closure := block_closure(reference_to_code_object($code, $past));
$closure<sink_past> := QAST::Op.new( :op('null') );
Expand Down Expand Up @@ -2177,6 +2183,7 @@ class Perl6::Actions is HLL::Actions does STDActions {
add_signature_binding_code($p_past, $p_sig, @p_params);
my $code := $*W.create_code_object($p_past, 'Sub', $p_sig, 1);
$*W.apply_trait($/, '&trait_mod:<is>', $code, :onlystar(1));
$*W.add_proto_to_sort($code);
$code
}

Expand Down Expand Up @@ -2399,6 +2406,11 @@ class Perl6::Actions is HLL::Actions does STDActions {
routine-type => 'method',
);
}

# If it's a proto, add it to the sort-at-CHECK-time queue.
if $*MULTINESS eq 'proto' {
$*W.add_proto_to_sort($code);
}

my $closure := block_closure(reference_to_code_object($code, $past));
$closure<sink_past> := QAST::Op.new( :op('null') );
Expand Down
8 changes: 6 additions & 2 deletions src/Perl6/Metamodel/BOOTSTRAP.pm
Expand Up @@ -631,7 +631,7 @@ BEGIN {
nqp::getattr(pir::perl6_decontainerize__PP($self),
Routine, '$!dispatchees')
}));
Routine.HOW.add_method(Routine, 'sort_dispatchees', static(sub ($self) {
Routine.HOW.add_method(Routine, '!sort_dispatchees_internal', static(sub ($self) {
my int $SLURPY_ARITY := nqp::bitshiftl_i(1, 30);
my int $EDGE_REMOVAL_TODO := -1;
my int $EDGE_REMOVED := -2;
Expand Down Expand Up @@ -924,6 +924,10 @@ BEGIN {

@result
}));
Routine.HOW.add_method(Routine, 'sort_dispatchees', static(sub ($self) {
nqp::bindattr(nqp::decont($self), Routine, '$!dispatch_order',
$self.'!sort_dispatchees_internal'());
}));
Routine.HOW.add_method(Routine, 'find_best_dispatchee', static(sub ($self, $capture, int $many = 0) {
my int $DEFCON_DEFINED := 1;
my int $DEFCON_UNDEFINED := 2;
Expand All @@ -945,7 +949,7 @@ BEGIN {
my @candidates := nqp::getattr($dcself, Routine, '$!dispatch_order');
if nqp::isnull(@candidates) {
nqp::scwbdisable();
@candidates := $dcself.sort_dispatchees();
@candidates := $dcself.'!sort_dispatchees_internal'();
nqp::bindattr($dcself, Routine, '$!dispatch_order', @candidates);
nqp::scwbenable();
}
Expand Down
8 changes: 8 additions & 0 deletions src/Perl6/Metamodel/MultiMethodContainer.pm
Expand Up @@ -39,6 +39,7 @@ role Perl6::Metamodel::MultiMethodContainer {
method incorporate_multi_candidates($obj) {
my $num_todo := +@!multi_methods_to_incorporate;
my $i := 0;
my @new_protos;
while $i != $num_todo {
# Get method name and code.
my $name := @!multi_methods_to_incorporate[$i].name;
Expand Down Expand Up @@ -77,6 +78,7 @@ role Perl6::Metamodel::MultiMethodContainer {
my $copy := $dispatcher.derive_dispatcher();
$copy.add_dispatchee($code);
self.add_method($obj, $name, $copy);
nqp::push(@new_protos, $copy);
$found := 1;
}
}
Expand All @@ -92,10 +94,16 @@ role Perl6::Metamodel::MultiMethodContainer {
$proto.set_name($name);
$proto.add_dispatchee($code);
self.add_method($obj, $name, $proto);
nqp::push(@new_protos, $proto);
}
}
$i := $i + 1;
}
for @new_protos {
if nqp::can($_, 'sort_dispatchees') {
$_.sort_dispatchees();
}
}
@!multi_methods_to_incorporate := [];
}
}
21 changes: 20 additions & 1 deletion src/Perl6/World.pm
Expand Up @@ -193,6 +193,10 @@ class Perl6::World is HLL::World {
# Array of stubs to check and the end of compilation.
has @!stub_check;

# Array of protos that can have their candidates pre-sorted at CHECK
# time.
has @!protos_to_sort;

# Cached constants that we've built.
has %!const_cache;

Expand All @@ -203,6 +207,7 @@ class Perl6::World is HLL::World {
@!BLOCKS := [];
@!CODES := [];
@!stub_check := [];
@!protos_to_sort := [];
@!CHECKs := [];
%!sub_id_to_code_object := {};
%!sub_id_to_static_lexpad := {};
Expand Down Expand Up @@ -280,7 +285,12 @@ class Perl6::World is HLL::World {

# Pushes a stub on the "stubs to check" list.
method add_stub_to_check($stub) {
@!stub_check[+@!stub_check] := $stub;
nqp::push(@!stub_check, $stub);
}

# Adds a proto to be sorted at CHECK time.
method add_proto_to_sort($proto) {
nqp::push(@!protos_to_sort, $proto);
}

# Checks for any stubs that weren't completed.
Expand All @@ -296,6 +306,15 @@ class Perl6::World is HLL::World {
}
}

# Sorts all protos.
method sort_protos() {
for @!protos_to_sort {
if nqp::can($_, 'sort_dispatchees') {
$_.sort_dispatchees();
}
}
}

# Loads a setting.
method load_setting($/, $setting_name) {
# Do nothing for the NULL setting.
Expand Down

0 comments on commit daabef9

Please sign in to comment.