ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Faster/Faster.pm
(Generate patch)

Comparing Faster/Faster.pm (file contents):
Revision 1.29 by root, Sun Mar 12 21:36:00 2006 UTC vs.
Revision 1.33 by root, Mon Mar 13 17:10:32 2006 UTC

8 8
9 perl -MFaster ... 9 perl -MFaster ...
10 10
11=head1 DESCRIPTION 11=head1 DESCRIPTION
12 12
13This module implements a very simple-minded JIT. It works by more or less 13This module implements a very simple-minded "JIT" (or actually AIT, ahead
14translating every function it sees into a C program, compiling it and then 14of time compiler). It works by more or less translating every function it
15replacing the function by the compiled code. 15sees into a C program, compiling it and then replacing the function by the
16compiled code.
16 17
17As a result, startup times are immense, as every function might lead to a 18As a result, startup times are immense, as every function might lead to a
18full-blown compilation. 19full-blown compilation.
19 20
20The speed improvements are also not great, you can expect 20% or so on 21The speed improvements are also not great, you can expect 20% or so on
21average, for code that runs very often. 22average, for code that runs very often. The reason for this is that data
23handling is mostly being done by the same old code, it just gets called
24a bit faster. Regexes and string operations won't get faster. Airhtmetic
25doresn't become any faster. Just the operands and other stuff is put on
26the stack faster, and the opcodes themselves have a bit less overhead.
22 27
23Faster is in the early stages of development. Due to its design its 28Faster is in the early stages of development. Due to its design its
24relatively safe to use (it will either work or simply slowdown the program 29relatively safe to use (it will either work or simply slowdown the program
25immensely, but rarely cause bugs). 30immensely, but rarely cause bugs).
26 31
32More intelligent algorithms (loop optimisation, type inference) could
33improve that easily, but requires a much more elaborate presentation and
34optimiser than what is in place. There are no plans to improve Faster in
35this way, yet, but it would provide a reasonably good place to start.
36
27Usage is very easy, just C<use Faster> and every function called from then 37Usage is very easy, just C<use Faster> and every function called from then
28on will be compiled. 38on will be compiled.
29 39
30Right now, Faster will leave lots of F<*.c>, F<*.o> and F<*.so> files in 40Right now, Faster can leave lots of F<*.c> and F<*.so> files in your
31your F<$FASTER_CACHEDIR> (by default F<$HOME/.perl-faster-cache>), and it 41F<$FASTER_CACHEDIR> (by default F<$HOME/.perl-faster-cache>), and it will
32will even create those temporary files in an insecure manner, so watch 42even create those temporary files in an insecure manner, so watch out.
33out.
34 43
35=over 4 44=over 4
36 45
37=cut 46=cut
38 47
71 80
72# we don't need no steenking PIC on x86 81# we don't need no steenking PIC on x86
73$COMPILE =~ s/-f(?:PIC|pic)//g 82$COMPILE =~ s/-f(?:PIC|pic)//g
74 if $Config{archname} =~ /^(i[3456]86)-/; 83 if $Config{archname} =~ /^(i[3456]86)-/;
75 84
76my $opt_assert = $ENV{FASTER_DEBUG}; 85my $opt_assert = $ENV{FASTER_DEBUG} > 1;
77my $verbose = $ENV{FASTER_VERBOSE}+0; 86my $verbose = $ENV{FASTER_VERBOSE}+0;
78 87
79warn "Faster: CACHEDIR is $CACHEDIR\n" if $verbose > 2; 88warn "Faster: CACHEDIR is $CACHEDIR\n" if $verbose > 2;
80 89
81our $source; 90our $source;
145# ops that do not need an ASYNC_CHECK 154# ops that do not need an ASYNC_CHECK
146my %f_noasync = map +($_ => undef), qw( 155my %f_noasync = map +($_ => undef), qw(
147 mapstart grepstart match entereval 156 mapstart grepstart match entereval
148 enteriter entersub leaveloop 157 enteriter entersub leaveloop
149 158
150 pushmark nextstate 159 pushmark nextstate caller
151 160
152 const stub unstack 161 const stub unstack
153 last next redo seq 162 last next redo goto seq
154 padsv padav padhv padany 163 padsv padav padhv padany
155 aassign sassign orassign 164 aassign sassign orassign
156 rv2av rv2cv rv2gv rv2hv refgen 165 rv2av rv2cv rv2gv rv2hv refgen
157 gv gvsv 166 gv gvsv
158 add subtract multiply divide 167 add subtract multiply divide
159 complement cond_expr and or not 168 complement cond_expr and or not
169 bit_and bit_or bit_xor
160 defined 170 defined
161 method method_named bless 171 method method_named bless
162 preinc postinc predec postdec 172 preinc postinc predec postdec
163 aelem aelemfast helem delete exists 173 aelem aelemfast helem delete exists
164 pushre subst list join split concat 174 pushre subst list lslice join split concat
165 length substr stringify ord 175 length substr stringify ord
166 push pop shift unshift 176 push pop shift unshift
167 eq ne gt lt ge le 177 eq ne gt lt ge le
168 regcomp regcreset regcmaybe 178 regcomp regcreset regcmaybe
169); 179);
225 235
226 out_next; 236 out_next;
227} 237}
228 238
229sub op_pushmark { 239sub op_pushmark {
230 $source .= " PUSHMARK (PL_stack_sp);\n"; 240 $source .= " faster_PUSHMARK (PL_stack_sp);\n";
231 241
232 out_next; 242 out_next;
233} 243}
234 244
235if ($Config{useithreads} ne "define") { 245if ($Config{useithreads} ne "define") {
515 local %op_regcomp; 525 local %op_regcomp;
516 526
517 my %opsseen; 527 my %opsseen;
518 my @todo = $cv->START; 528 my @todo = $cv->START;
519 my %op_target; 529 my %op_target;
530 my $numpushmark;
520 531
521 while (my $op = shift @todo) { 532 while (my $op = shift @todo) {
522 for (; $$op; $op = $op->next) { 533 for (; $$op; $op = $op->next) {
523 last if $opsseen{$$op}++; 534 last if $opsseen{$$op}++;
524 535
558 569
559 push @op_loop, \@targ; 570 push @op_loop, \@targ;
560 push @todo, @targ; 571 push @todo, @targ;
561 572
562 $op_target{$$_}++ for @targ; 573 $op_target{$$_}++ for @targ;
574
563 } elsif ($class eq "COP") { 575 } elsif ($class eq "COP") {
564 $insn->{bblock}++ if defined $op->label; 576 $insn->{bblock}++ if defined $op->label;
577
578 } else {
579 if ($name eq "pushmark") {
580 $numpushmark++;
581 }
565 } 582 }
566 } 583 }
567 } 584 }
568 585
569 $_->{bblock}++ for grep $op_target{${$_->{op}}}, @ops; 586 $_->{bblock}++ for grep $op_target{${$_->{op}}}, @ops;
571 local $source = <<EOF; 588 local $source = <<EOF;
572OP *%%%FUNC%%% (pTHX) 589OP *%%%FUNC%%% (pTHX)
573{ 590{
574 register OP *nextop = (OP *)${$ops[0]->{op}}L; 591 register OP *nextop = (OP *)${$ops[0]->{op}}L;
575EOF 592EOF
593
594 $source .= " faster_PUSHMARK_PREALLOC ($numpushmark);\n"
595 if $numpushmark;
576 596
577 while (@ops) { 597 while (@ops) {
578 $insn = shift @ops; 598 $insn = shift @ops;
579 599
580 $op = $insn->{op}; 600 $op = $insn->{op};
681 701
682#include "EXTERN.h" 702#include "EXTERN.h"
683#include "perl.h" 703#include "perl.h"
684#include "XSUB.h" 704#include "XSUB.h"
685 705
706#if 1
707# define faster_PUSHMARK_PREALLOC(count) while (PL_markstack_ptr + (count) >= PL_markstack_max) markstack_grow ()
708# define faster_PUSHMARK(p) *++PL_markstack_ptr = (p) - PL_stack_base
709#else
710# define faster_PUSHMARK_PREALLOC(count) 1
711# define faster_PUSHMARK(p) PUSHMARK(p)
712#endif
713
686#define RUNOPS_TILL(op) \\ 714#define RUNOPS_TILL(op) \\
687 while (nextop != (op)) \\ 715 while (nextop != (op)) \\
688 { \\ 716 { \\
689 PERL_ASYNC_CHECK (); \\ 717 PERL_ASYNC_CHECK (); \\
690 PL_op = nextop; nextop = (PL_op->op_ppaddr)(aTHX); \\ 718 PL_op = nextop; nextop = (PL_op->op_ppaddr)(aTHX); \\
701 $meta->{$f->{func}} = $f->{so} = $stem; 729 $meta->{$f->{func}} = $f->{so} = $stem;
702 } 730 }
703 731
704 close $fh; 732 close $fh;
705 system "$COMPILE -o $stem$_o $stem.c"; 733 system "$COMPILE -o $stem$_o $stem.c";
706 unlink "$stem.c"; 734 unlink "$stem.c" unless $ENV{FASTER_DEBUG} > 0;
707 system "$LINK -o $stem$_so $stem$_o $LIBS"; 735 system "$LINK -o $stem$_so $stem$_o $LIBS";
708 unlink "$stem$_o"; 736 unlink "$stem$_o";
709 } 737 }
710 738
711 for my $f (@func) { 739 for my $f (@func) {
801function is compiled into which shared object. 829function is compiled into which shared object.
802 830
803=item FASTER_DEBUG 831=item FASTER_DEBUG
804 832
805Add debugging code when set to values higher than C<0>. Currently, this 833Add debugging code when set to values higher than C<0>. Currently, this
806adds 1-3 C<assert>'s per perl op, to ensure that opcode order and C 834adds 1-3 C<assert>'s per perl op (FASTER_DEBUG > 1), to ensure that opcode
807execution order are compatible. 835order and C execution order are compatible.
808 836
809=item FASTER_CACHE 837=item FASTER_CACHE
810 838
811Set a persistent cache directory that caches compiled code fragments. The 839Set a persistent cache directory that caches compiled code fragments. The
812default is C<$HOME/.perl-faster-cache> if C<HOME> is set and a temporary 840default is C<$HOME/.perl-faster-cache> if C<HOME> is set and a temporary

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines