Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make the method cache authoritative in some cases.
This makes it much cheaper for things that are doing can style checks,
which is the case for grammars without any actions, .? and so forth.
colomon++ for the profile that led to this.
  • Loading branch information
jnthn committed Oct 9, 2012
1 parent 870d189 commit f0acedf
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/Perl6/Metamodel/ClassHOW.pm
Expand Up @@ -66,6 +66,10 @@ class Perl6::Metamodel::ClassHOW
# and if it is calls $calculator with the object and method name to
# calculate an invokable object.
method add_fallback($obj, $condition, $calculator) {
# Adding a fallback means any method cache is no longer authoritative.
pir::set_method_cache_authoritativeness__vPi($obj, 0);

# Add it.
my %desc;
%desc<cond> := $condition;
%desc<calc> := $calculator;
Expand Down Expand Up @@ -201,6 +205,7 @@ class Perl6::Metamodel::ClassHOW
my $junction_type;
my $junction_autothreader;
method setup_junction_fallback($type, $autothreader) {
pir::set_method_cache_authoritativeness__vPi($type, 0);
$junction_type := $type;
$junction_autothreader := $autothreader;
}
Expand All @@ -225,4 +230,9 @@ class Perl6::Metamodel::ClassHOW
# Otherwise, didn't find anything.
nqp::null()
}

# Does the type have any fallbacks?
method has_fallbacks($obj) {
return nqp::istype($obj, $junction_type) || +@!fallbacks;
}
}
9 changes: 8 additions & 1 deletion src/Perl6/Metamodel/MROBasedMethodDispatch.pm
Expand Up @@ -23,20 +23,27 @@ role Perl6::Metamodel::MROBasedMethodDispatch {
# lower in the class hierarchy "shadowed" it.
my %cache;
my @mro_reversed;
my $authable := 1;
for self.mro($obj) {
@mro_reversed.unshift($_);
}
for @mro_reversed {
for $_.HOW.method_table($_) {
%cache{$_.key} := $_.value;
}
if nqp::can($_.HOW, 'is_composed') && !$_.HOW.is_composed($_) {
$authable := 0;
}
}

# Also add submethods.
for $obj.HOW.submethod_table($obj) {
%cache{$_.key} := $_.value;
}

pir::publish_method_cache__0PP($obj, %cache)
pir::publish_method_cache__0PP($obj, %cache);
unless nqp::can(self, 'has_fallbacks') && self.has_fallbacks($obj) {
pir::set_method_cache_authoritativeness__0Pi($obj, $authable);
}
}
}
3 changes: 3 additions & 0 deletions src/Perl6/Metamodel/MethodContainer.pm
Expand Up @@ -11,6 +11,9 @@ role Perl6::Metamodel::MethodContainer {

# Add a method.
method add_method($obj, $name, $code_obj) {
# Adding a method means any cache is no longer authoritative.
pir::set_method_cache_authoritativeness__vPi($obj, 0);

# Ensure we haven't already got it.
if nqp::existskey(%!methods, $name) || nqp::existskey(%!submethods, $name) {
nqp::die("Package '" ~ self.name($obj) ~ "' already has a method '" ~
Expand Down

0 comments on commit f0acedf

Please sign in to comment.