Skip to content

Instantly share code, notes, and snippets.

@lizmat
Created January 12, 2018 23:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lizmat/ce7b04adff53450c7deaab4051a3045b to your computer and use it in GitHub Desktop.
Save lizmat/ce7b04adff53450c7deaab4051a3045b to your computer and use it in GitHub Desktop.
trying to optimize the exit_handler
diff --git a/src/Perl6/Metamodel/BOOTSTRAP.nqp b/src/Perl6/Metamodel/BOOTSTRAP.nqp
index 5176e0c..e80b938 100644
--- a/src/Perl6/Metamodel/BOOTSTRAP.nqp
+++ b/src/Perl6/Metamodel/BOOTSTRAP.nqp
@@ -3236,23 +3236,17 @@ nqp::sethllconfig('perl6', nqp::hash(
$result
},
'exit_handler', -> $coderef, $resultish {
- my %phasers :=
- nqp::getattr(nqp::getcodeobj($coderef),Block,'$!phasers');
- unless nqp::isnull(%phasers) || nqp::p6inpre() {
- my @leaves := nqp::atkey(%phasers, '!LEAVE-ORDER');
- my @posts := nqp::atkey(%phasers, 'POST');
- my @exceptions;
- unless nqp::isnull(@leaves) {
- my @keeps := nqp::atkey(%phasers, 'KEEP');
- my @undos := nqp::atkey(%phasers, 'UNDO');
- my int $n := nqp::elems(@leaves);
-
- # only have a single LEAVEish phaser, so no frills needed
- if nqp::isnull(@keeps)
- && nqp::isnull(@undos)
- && nqp::isnull(@posts)
- && $n == 1
- {
+ unless nqp::p6inpre() {
+ my %phasers :=
+ nqp::getattr(nqp::getcodeobj($coderef),Block,'$!phasers');
+ my @leaves := nqp::atkey(%phasers,'!LEAVE-ORDER');
+
+ # fast path: only the one LEAVE phaser
+ if nqp::elems(%phasers) == 1
+ && nqp::not_i(nqp::isnull(@leaves))
+ && nqp::elems(@leaves) == 1 {
+ unless nqp::isnull(@leaves) { # dummy if for extra scope
+ unless nqp::isnull(@leaves) { # dummy if for extra scope
#?if jvm
nqp::decont(nqp::atpos(@leaves,0))();
#?endif
@@ -3262,71 +3256,78 @@ nqp::sethllconfig('perl6', nqp::hash(
#?endif
# don't bother to CATCH, there can only be one exception
}
+ }
+ }
- # slow path here
- else {
- my int $i := -1;
- my int $run;
- my $phaser;
- while ++$i < $n {
- $phaser := nqp::decont(nqp::atpos(@leaves, $i));
- $run := 1;
- unless nqp::isnull(@keeps) {
- for @keeps {
- if nqp::eqaddr(nqp::decont($_),$phaser) {
- $run := !nqp::isnull($resultish) &&
- nqp::isconcrete($resultish) &&
- $resultish.defined;
- last;
- }
+ # slow path if we have any leaves
+ elsif nqp::not_i(nqp::isnull(@leaves)) {
+ my @exceptions;
+ my @keeps := nqp::atkey(%phasers, 'KEEP');
+ my @undos := nqp::atkey(%phasers, 'UNDO');
+ my int $n := nqp::elems(@leaves);
+
+ my int $i := -1;
+ my int $run;
+ my $phaser;
+ while ++$i < $n {
+ $phaser := nqp::decont(nqp::atpos(@leaves, $i));
+ $run := 1;
+ unless nqp::isnull(@keeps) {
+ for @keeps {
+ if nqp::decont($_) =:= $phaser {
+ $run := !nqp::isnull($resultish) &&
+ nqp::isconcrete($resultish) &&
+ $resultish.defined;
+ last;
}
}
- unless nqp::isnull(@undos) {
- for @undos {
- if nqp::eqaddr(nqp::decont($_),$phaser) {
- $run := nqp::isnull($resultish) ||
- !nqp::isconcrete($resultish) ||
- !$resultish.defined;
- last;
- }
+ }
+ unless nqp::isnull(@undos) {
+ for @undos {
+ if nqp::decont($_) =:= $phaser {
+ $run := nqp::isnull($resultish) ||
+ !nqp::isconcrete($resultish) ||
+ !$resultish.defined;
+ last;
}
}
- if $run {
+ }
+ if $run {
#?if jvm
- $phaser();
+ $phaser();
#?endif
#?if moar
- nqp::p6capturelexwhere($phaser.clone())();
+ nqp::p6capturelexwhere($phaser.clone())();
#?endif
- CATCH { nqp::push(@exceptions, $_) }
- }
+ CATCH { nqp::push(@exceptions, $_) }
}
}
- }
- unless nqp::isnull(@posts) {
- my $value := nqp::ifnull($resultish,Mu);
- my int $n := nqp::elems(@posts);
- my int $i := -1;
- while ++$i < $n {
+ my @posts := nqp::atkey(%phasers, 'POST');
+ unless nqp::isnull(@posts) {
+ my $value := nqp::ifnull($resultish,Mu);
+ my int $n := nqp::elems(@posts);
+ my int $i := -1;
+ while ++$i < $n {
#?if jvm
- nqp::atpos(@posts, $i)($value));
+ nqp::atpos(@posts, $i)($value));
#?endif
#?if moar
- nqp::p6capturelexwhere(nqp::atpos(@posts,$i).clone)($value);
+ nqp::p6capturelexwhere(nqp::atpos(@posts,$i).clone)($value);
#?endif
- CATCH { nqp::push(@exceptions, $_); last; }
+ CATCH { nqp::push(@exceptions, $_); last; }
+ }
}
- }
- if @exceptions {
- if nqp::elems(@exceptions) > 1 {
- my %ex := nqp::gethllsym('perl6', 'P6EX');
- if !nqp::isnull(%ex) && nqp::existskey(%ex, 'X::PhaserExceptions') {
- nqp::atkey(%ex, 'X::PhaserExceptions')(@exceptions);
+ if @exceptions {
+ if nqp::elems(@exceptions) > 1 {
+ my %ex := nqp::gethllsym('perl6', 'P6EX');
+ if !nqp::isnull(%ex) && nqp::existskey(%ex, 'X::PhaserExceptions') {
+ nqp::atkey(%ex, 'X::PhaserExceptions')(@exceptions);
+ }
}
+ nqp::rethrow(@exceptions[0]);
}
- nqp::rethrow(@exceptions[0]);
}
}
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment