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

Comparing Faster/Faster.pm (file contents):
Revision 1.18 by root, Fri Mar 10 19:52:07 2006 UTC vs.
Revision 1.19 by root, Fri Mar 10 22:18:39 2006 UTC

25immensely, but rarely cause bugs). 25immensely, but rarely cause bugs).
26 26
27Usage is very easy, just C<use Faster> and every function called from then 27Usage is very easy, just C<use Faster> and every function called from then
28on will be compiled. 28on will be compiled.
29 29
30Right now, Faster will leave ltos of F<*.c>, F<*.o> and F<*.so> files in 30Right now, Faster will leave lots of F<*.c>, F<*.o> and F<*.so> files in
31F</tmp>, and it will even create those temporary files in an insecure 31F</tmp>, and it will even create those temporary files in an insecure
32manner, so watch out. 32manner, so watch out.
33 33
34=over 4 34=over 4
35 35
38package Faster; 38package Faster;
39 39
40use strict; 40use strict;
41use Config; 41use Config;
42use B (); 42use B ();
43use Digest::MD5 (); 43#use Digest::MD5 ();
44use DynaLoader (); 44use DynaLoader ();
45 45
46BEGIN { 46BEGIN {
47 our $VERSION = '0.01'; 47 our $VERSION = '0.01';
48 48
58 58
59# we don't need no steenking PIC on x86 59# we don't need no steenking PIC on x86
60$COMPILE =~ s/-f(?:PIC|pic)//g 60$COMPILE =~ s/-f(?:PIC|pic)//g
61 if $Config{archname} =~ /^(i[3456]86)-/; 61 if $Config{archname} =~ /^(i[3456]86)-/;
62 62
63my $opt_assert = 1; 63my $opt_assert = 0;
64 64
65our $source; 65our $source;
66 66
67our @ops; 67our @ops;
68our $op; 68our $op;
135 unstack noasync 135 unstack noasync
136 leaveloop noasync 136 leaveloop noasync
137 aelem noasync 137 aelem noasync
138 aelemfast noasync 138 aelemfast noasync
139 helem noasync 139 helem noasync
140 delete noasync
141 exists noasync
140 pushre noasync 142 pushre noasync
141 subst noasync 143 subst noasync
142 const noasync extend=1 144 const noasync extend=1
143 list noasync 145 list noasync
144 join noasync 146 join noasync
548 #warn $source; 550 #warn $source;
549 551
550 $source 552 $source
551} 553}
552 554
555my $uid = "aaaaaaa0";
556
553sub source2ptr { 557sub source2ptr {
554 my ($source) = @_; 558 my (@source) = @_;
555 559
556 my $md5 = Digest::MD5::md5_hex $source; 560 my $stem = "/tmp/Faster-$$-" . $uid++;
557 $source =~ s/%%%FUNC%%%/Faster_$md5/;
558 561
559 my $stem = "/tmp/$md5";
560
561 unless (-e "$stem$_so") {
562 open FILE, ">:raw", "$stem.c"; 562 open FILE, ">:raw", "$stem.c";
563 print FILE <<EOF; 563 print FILE <<EOF;
564#define PERL_NO_GET_CONTEXT 564#define PERL_NO_GET_CONTEXT
565 565
566#include <assert.h> 566#include <assert.h>
567 567
568#include "EXTERN.h" 568#include "EXTERN.h"
569#include "perl.h" 569#include "perl.h"
570#include "XSUB.h" 570#include "XSUB.h"
571 571
572#define RUNOPS_TILL(op) \\ 572#define RUNOPS_TILL(op) \\
573 while (nextop != (op)) \\ 573while (nextop != (op)) \\
574 { \\ 574 { \\
575 PERL_ASYNC_CHECK (); \\ 575 PERL_ASYNC_CHECK (); \\
576 PL_op = nextop; nextop = (PL_op->op_ppaddr)(aTHX); \\ 576 PL_op = nextop; nextop = (PL_op->op_ppaddr)(aTHX); \\
577 } 577 }
578 578
579EOF 579EOF
580 for (@source) {
581 my $func = $uid++;
582 $_ =~ s/%%%FUNC%%%/$func/g;
580 print FILE $source; 583 print FILE $_;
581 close FILE; 584 $_ = $func;
582 system "$COMPILE -o $stem$_o $stem.c";
583 system "$LINK -o $stem$_so $stem$_o $LIBS";
584 } 585 }
585 586
586# warn $source; 587 close FILE;
588 system "$COMPILE -o $stem$_o $stem.c";
589 #d#unlink "$stem.c";
590 system "$LINK -o $stem$_so $stem$_o $LIBS";
591 unlink "$stem$_o";
592
587 my $so = DynaLoader::dl_load_file "$stem$_so" 593 my $so = DynaLoader::dl_load_file "$stem$_so"
588 or die "$stem$_so: $!"; 594 or die "$stem$_so: $!";
589 595
590 DynaLoader::dl_find_symbol $so, "Faster_$md5" 596 #unlink "$stem$_so";
591 or die "Faster_$md5: $!" 597
598 map +(DynaLoader::dl_find_symbol $so, $_), @source
592} 599}
600
601my %ignore;
593 602
594sub entersub { 603sub entersub {
595 my ($cv) = @_; 604 my ($cv) = @_;
596 605
597 # always compile the whole stash 606 my $pkg = $cv->STASH->NAME;
598# my @stash = $cv->STASH->ARRAY; 607
599# warn join ":", @stash; 608 return if $ignore{$pkg};
600# exit; 609
610 warn "compiling ", $cv->STASH->NAME;#d#
601 611
602 eval { 612 eval {
603 my $source = cv2c $cv; 613 my @cv;
614 my @cv_source;
604 615
616 # always compile the whole stash
617 my %stash = $cv->STASH->ARRAY;
618 while (my ($k, $v) = each %stash) {
619 $v->isa (B::GV::)
620 or next;
621
622 my $cv = $v->CV;
623
624 if ($cv->isa (B::CV::)
625 && ${$cv->START}
626 && $cv->START->name ne "null") {
627 push @cv, $cv;
628 push @cv_source, cv2c $cv;
629 }
630 }
631
605 my $ptr = source2ptr $source; 632 my @ptr = source2ptr @cv_source;
606 633
634 for (0 .. $#cv) {
607 patch_cv $cv, $ptr; 635 patch_cv $cv[$_], $ptr[$_];
636 }
608 }; 637 };
609 638
610 warn $@ if $@; 639 if ($@) {
640 $ignore{$pkg}++;
641 warn $@;
642 }
611} 643}
612 644
613hook_entersub; 645hook_entersub;
614 646
6151; 6471;
621Perl will check much less often for asynchronous signals in 653Perl will check much less often for asynchronous signals in
622Faster-compiled code. It tries to check on every function call, loop 654Faster-compiled code. It tries to check on every function call, loop
623iteration and every I/O operator, though. 655iteration and every I/O operator, though.
624 656
625The following things will disable Faster. If you manage to enable them at 657The following things will disable Faster. If you manage to enable them at
626runtime, bad things will happen. 658runtime, bad things will happen. Enabling them at startup will be fine,
659though.
627 660
628 enabled tainting 661 enabled tainting
629 enabled debugging 662 enabled debugging
630 663
631This will dramatically reduce Faster's performance: 664Thread-enabled builds of perl will dramatically reduce Faster's
665performance, but you don't care about speed if you enable threads anyway.
632 666
633 threads (but you don't care about speed if you use threads anyway)
634
635These constructs will force the use of the interpreter as soon as they are 667These constructs will force the use of the interpreter for the currently
636being executed, for the rest of the currently executed: 668executed function as soon as they are being encountered during execution.
637 669
638 .., ... (flipflop operators)
639 goto 670 goto
640 next, redo (but not well-behaved last's) 671 next, redo (but not well-behaved last's)
641 eval 672 eval
642 require 673 require
643 any use of formats 674 any use of formats
675 .., ... (flipflop operators)
644 676
645=head1 AUTHOR 677=head1 AUTHOR
646 678
647 Marc Lehmann <schmorp@schmorp.de> 679 Marc Lehmann <schmorp@schmorp.de>
648 http://home.schmorp.de/ 680 http://home.schmorp.de/

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines