From b7dc083c47d05133e90d62e8b587c747dab89267 Mon Sep 17 00:00:00 2001 From: Nick Ing-Simmons Date: Fri, 14 May 1999 21:04:22 +0000 Subject: [PATCH] Experimental "slab" allocator for ops. To try it -DPL_OP_SLAB_ALLOC for op.c This is for proof of concept only, it leaks memory (ops are not free'd) so don't use in embedded apps. If this minimalist version does not show performance gain then whole idea is worthless. Nick see's approx 12% speed up vs perlmalloc running perl -Ilib -MCPAN -e '' Solaris2.6, gcc-2.8.1 but numbers are not repeatable. p4raw-id: //depot/perl@3424 --- op.c | 79 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/op.c b/op.c index 919d9d8170ce..94c0b392d1e1 100644 --- a/op.c +++ b/op.c @@ -22,8 +22,31 @@ #define CHECKCALL this->*PL_check #else #define CHECKCALL *PL_check +#endif + +/* #define PL_OP_SLAB_ALLOC */ + +#ifdef PL_OP_SLAB_ALLOC +#define SLAB_SIZE 8192 +static char *PL_OpPtr = NULL; +static int PL_OpSpace = 0; +#define NewOp(m,var,c,type) do { if ((PL_OpSpace -= c*sizeof(type)) >= 0) \ + var = (type *)(PL_OpPtr -= c*sizeof(type)); \ + else \ + var = (type *) Slab_Alloc(m,c*sizeof(type)); \ + } while (0) + +static void * +Slab_Alloc(int m, size_t sz) +{ + Newz(m,PL_OpPtr,SLAB_SIZE,char); + PL_OpSpace = SLAB_SIZE - sz; + return PL_OpPtr += PL_OpSpace; +} + +#else +#define NewOp(m, var, c, type) Newz(m, var, c, type) #endif - /* * In the following definition, the ", Nullop" is just to make the compiler * think the expression is of the right type: croak actually does a Siglongjmp. @@ -706,7 +729,13 @@ op_free(OP *o) if (o->op_targ > 0) pad_free(o->op_targ); +#ifdef PL_OP_SLAB_ALLOC + if ((char *) o == PL_OpPtr) + { + } +#else Safefree(o); +#endif } STATIC void @@ -1999,8 +2028,11 @@ append_list(I32 type, LISTOP *first, LISTOP *last) first->op_children += last->op_children; if (first->op_children) first->op_flags |= OPf_KIDS; - - Safefree(last); + +#ifdef PL_OP_SLAB_ALLOC +#else + Safefree(last); +#endif return (OP*)first; } @@ -2055,7 +2087,7 @@ newLISTOP(I32 type, I32 flags, OP *first, OP *last) { LISTOP *listop; - Newz(1101, listop, 1, LISTOP); + NewOp(1101, listop, 1, LISTOP); listop->op_type = type; listop->op_ppaddr = PL_ppaddr[type]; @@ -2089,7 +2121,7 @@ OP * newOP(I32 type, I32 flags) { OP *o; - Newz(1101, o, 1, OP); + NewOp(1101, o, 1, OP); o->op_type = type; o->op_ppaddr = PL_ppaddr[type]; o->op_flags = flags; @@ -2113,7 +2145,7 @@ newUNOP(I32 type, I32 flags, OP *first) if (PL_opargs[type] & OA_MARK) first = force_list(first); - Newz(1101, unop, 1, UNOP); + NewOp(1101, unop, 1, UNOP); unop->op_type = type; unop->op_ppaddr = PL_ppaddr[type]; unop->op_first = first; @@ -2130,7 +2162,7 @@ OP * newBINOP(I32 type, I32 flags, OP *first, OP *last) { BINOP *binop; - Newz(1101, binop, 1, BINOP); + NewOp(1101, binop, 1, BINOP); if (!first) first = newOP(OP_NULL, 0); @@ -2427,7 +2459,7 @@ newPMOP(I32 type, I32 flags) dTHR; PMOP *pmop; - Newz(1101, pmop, 1, PMOP); + NewOp(1101, pmop, 1, PMOP); pmop->op_type = type; pmop->op_ppaddr = PL_ppaddr[type]; pmop->op_flags = flags; @@ -2482,7 +2514,7 @@ pmruntime(OP *o, OP *expr, OP *repl) ? OP_REGCRESET : OP_REGCMAYBE),0,expr); - Newz(1101, rcop, 1, LOGOP); + NewOp(1101, rcop, 1, LOGOP); rcop->op_type = OP_REGCOMP; rcop->op_ppaddr = PL_ppaddr[OP_REGCOMP]; rcop->op_first = scalar(expr); @@ -2577,7 +2609,7 @@ pmruntime(OP *o, OP *expr, OP *repl) pm->op_pmflags |= PMf_MAYBE_CONST; pm->op_pmpermflags |= PMf_MAYBE_CONST; } - Newz(1101, rcop, 1, LOGOP); + NewOp(1101, rcop, 1, LOGOP); rcop->op_type = OP_SUBSTCONT; rcop->op_ppaddr = PL_ppaddr[OP_SUBSTCONT]; rcop->op_first = scalar(repl); @@ -2602,7 +2634,7 @@ OP * newSVOP(I32 type, I32 flags, SV *sv) { SVOP *svop; - Newz(1101, svop, 1, SVOP); + NewOp(1101, svop, 1, SVOP); svop->op_type = type; svop->op_ppaddr = PL_ppaddr[type]; svop->op_sv = sv; @@ -2620,7 +2652,7 @@ newGVOP(I32 type, I32 flags, GV *gv) { dTHR; GVOP *gvop; - Newz(1101, gvop, 1, GVOP); + NewOp(1101, gvop, 1, GVOP); gvop->op_type = type; gvop->op_ppaddr = PL_ppaddr[type]; gvop->op_gv = (GV*)SvREFCNT_inc(gv); @@ -2637,7 +2669,7 @@ OP * newPVOP(I32 type, I32 flags, char *pv) { PVOP *pvop; - Newz(1101, pvop, 1, PVOP); + NewOp(1101, pvop, 1, PVOP); pvop->op_type = type; pvop->op_ppaddr = PL_ppaddr[type]; pvop->op_pv = pv; @@ -2975,7 +3007,7 @@ newSTATEOP(I32 flags, char *label, OP *o) U32 seq = intro_my(); register COP *cop; - Newz(1101, cop, 1, COP); + NewOp(1101, cop, 1, COP); if (PERLDB_LINE && PL_curcop->cop_line && PL_curstash != PL_debstash) { cop->op_type = OP_DBSTATE; cop->op_ppaddr = PL_ppaddr[ OP_DBSTATE ]; @@ -3142,7 +3174,7 @@ new_logop(I32 type, I32 flags, OP** firstp, OP** otherp) if (type == OP_ANDASSIGN || type == OP_ORASSIGN) other->op_private |= OPpASSIGN_BACKWARDS; /* other is an OP_SASSIGN */ - Newz(1101, logop, 1, LOGOP); + NewOp(1101, logop, 1, LOGOP); logop->op_type = type; logop->op_ppaddr = PL_ppaddr[type]; @@ -3191,7 +3223,7 @@ newCONDOP(I32 flags, OP *first, OP *trueop, OP *falseop) list(trueop); scalar(falseop); } - Newz(1101, condop, 1, CONDOP); + NewOp(1101, condop, 1, CONDOP); condop->op_type = OP_COND_EXPR; condop->op_ppaddr = PL_ppaddr[OP_COND_EXPR]; @@ -3224,7 +3256,7 @@ newRANGE(I32 flags, OP *left, OP *right) OP *flop; OP *o; - Newz(1101, condop, 1, CONDOP); + NewOp(1101, condop, 1, CONDOP); condop->op_type = OP_RANGE; condop->op_ppaddr = PL_ppaddr[OP_RANGE]; @@ -3385,7 +3417,7 @@ newWHILEOP(I32 flags, I32 debuggable, LOOP *loop, I32 whileline, OP *expr, OP *b o = listop; if (!loop) { - Newz(1101,loop,1,LOOP); + NewOp(1101,loop,1,LOOP); loop->op_type = OP_ENTERLOOP; loop->op_ppaddr = PL_ppaddr[OP_ENTERLOOP]; loop->op_private = 0; @@ -3411,6 +3443,7 @@ OP * newFOROP(I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *block,OP *cont) { LOOP *loop; + LOOP *tmp; OP *wop; int padoff = 0; I32 iterflags = 0; @@ -3482,7 +3515,13 @@ newFOROP(I32 flags,char *label,line_t forline,OP *sv,OP *expr,OP *block,OP *cont loop = (LOOP*)list(convert(OP_ENTERITER, iterflags, append_elem(OP_LIST, expr, scalar(sv)))); assert(!loop->op_next); +#ifdef PL_OP_SLAB_ALLOC + NewOp(1234,tmp,1,LOOP); + Copy(loop,tmp,1,LOOP); + loop = tmp; +#else Renew(loop, 1, LOOP); +#endif loop->op_targ = padoff; wop = newWHILEOP(flags, 1, loop, forline, newOP(OP_ITER, 0), block, cont); PL_copline = forline; @@ -4466,7 +4505,7 @@ ck_eval(OP *o) cUNOPo->op_first = 0; op_free(o); - Newz(1101, enter, 1, LOGOP); + NewOp(1101, enter, 1, LOGOP); enter->op_type = OP_ENTERTRY; enter->op_ppaddr = PL_ppaddr[OP_ENTERTRY]; enter->op_private = 0; @@ -4877,7 +4916,7 @@ ck_grep(OP *o) OPCODE type = o->op_type == OP_GREPSTART ? OP_GREPWHILE : OP_MAPWHILE; o->op_ppaddr = PL_ppaddr[OP_GREPSTART]; - Newz(1101, gwop, 1, LOGOP); + NewOp(1101, gwop, 1, LOGOP); if (o->op_flags & OPf_STACKED) { OP* k;