ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Faster/Faster.xs
Revision: 1.8
Committed: Sun Mar 12 17:03:39 2006 UTC (18 years, 2 months ago) by root
Branch: MAIN
Changes since 1.7: +28 -25 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5 root 1.3 typedef CV *B__CV;
6    
7 root 1.1 static OP *(*old_entersub)(pTHX);
8    
9     // this is, of course, a slower entersub
10     static OP *
11     faster_entersub (pTHX)
12     {
13 root 1.8 if (!PL_compcv) // only when not compiling, reduces recompiling due to op-address-shift
14     {
15     dSP;
16     dTOPss;
17 root 1.1
18 root 1.8 if (SvTYPE (sv) == SVt_PVGV)
19     sv = (SV *)GvCV (sv);
20 root 1.1
21 root 1.8 if (sv)
22 root 1.1 {
23 root 1.8 // only once for now
24     PL_op->op_ppaddr = old_entersub;
25 root 1.2
26 root 1.8 // only simple cv calls for now
27     if (!PL_perldb && !PL_tainting
28     && SvTYPE (sv) == SVt_PVCV && !CvXSUB (sv)
29     && CvSTART (sv) // must exist
30     && CvSTART (sv)->op_type != OP_NULL) // shield against compiling an already-compiled op
31     {
32     SV *bsv = newSViv (PTR2IV (sv));
33    
34     ENTER;
35     SAVETMPS;
36     PUSHMARK (SP);
37     // emulate B::CV typemap entry we don't have
38     XPUSHs (sv_2mortal (sv_bless (newRV_noinc (bsv), gv_stashpv ("B::CV", 1))));
39     PUTBACK;
40     call_pv ("Faster::entersub", G_VOID|G_DISCARD|G_EVAL);
41     SPAGAIN;
42     FREETMPS;
43     LEAVE;
44     }
45 root 1.1 }
46     }
47    
48     return old_entersub (aTHX);
49     }
50    
51     MODULE = Faster PACKAGE = Faster
52    
53 root 1.2 PROTOTYPES: ENABLE
54    
55     IV
56     ppaddr (int optype)
57     CODE:
58     RETVAL = optype == OP_ENTERSUB
59 root 1.6 ? (IV)old_entersub
60     : (IV)PL_ppaddr [optype];
61 root 1.2 OUTPUT:
62     RETVAL
63    
64 root 1.1 void
65     hook_entersub ()
66     CODE:
67     old_entersub = PL_ppaddr [OP_ENTERSUB];
68     PL_ppaddr [OP_ENTERSUB] = faster_entersub;
69    
70 root 1.3 void
71     patch_cv (B::CV cv, void *ptr)
72     CODE:
73     {
74     OP *op;
75    
76 root 1.7 if (!ptr)
77     croak ("NULL not allowed as code address for patch_cv");
78    
79 root 1.3 NewOp (0, op, 1, OP);
80    
81     op->op_sibling = CvSTART (cv);
82     op->op_type = OP_NULL;
83     op->op_ppaddr = ptr;
84    
85     CvSTART (cv) = op;
86     }
87    
88 root 1.1