Skip to content

Commit 8c47b5b

Browse files
committed
OPSLOT: replace opslot_next with opslot_size
Currently, each allocated opslot has a pointer to the opslot that was allocated immediately above it. Replace this with a U16 opslot_size field giving the size of the opslot. The next opslot can then be found by adding slot->opslot_size * sizeof(void*) to slot. This saves space.
1 parent c63fff6 commit 8c47b5b

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

op.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ Perl_Slab_Alloc(pTHX_ size_t sz)
310310
(I32**)OpSLOT(o) - OpSLOT(o)->opslot_offset,
311311
(void*)head_slab));
312312

313-
while (o && DIFF(OpSLOT(o), OpSLOT(o)->opslot_next) < sz) {
313+
while (o && OpSLOT(o)->opslot_size < sz) {
314314
DEBUG_S_warn((aTHX_ "Alas! too small"));
315315
o = *(too = &o->op_next);
316316
if (o) { DEBUG_S_warn((aTHX_ "found another free op at %p", (void*)o)); }
@@ -325,7 +325,7 @@ Perl_Slab_Alloc(pTHX_ size_t sz)
325325

326326
#define INIT_OPSLOT(s) \
327327
slot->opslot_offset = DIFF(slab2, slot) ; \
328-
slot->opslot_next = ((OPSLOT*)( (I32**)slot + s )); \
328+
slot->opslot_size = s; \
329329
slab2->opslab_free_space -= s; \
330330
o = &slot->opslot_op; \
331331
o->op_slabbed = 1
@@ -535,7 +535,9 @@ Perl_opslab_force_free(pTHX_ OPSLAB *slab)
535535
((I32**)&slab2->opslab_slots + slab2->opslab_free_space);
536536
OPSLOT *end = (OPSLOT*)
537537
((I32**)slab2 + slab2->opslab_size);
538-
for (; slot <= end -1; slot = slot->opslot_next) {
538+
for (; slot <= end -1;
539+
slot = (OPSLOT*) ((I32**)slot + slot->opslot_size) )
540+
{
539541
if (slot->opslot_op.op_type != OP_FREED
540542
&& !(slot->opslot_op.op_savefree
541543
#ifdef DEBUGGING
@@ -9281,10 +9283,13 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
92819283
/* for my $x () sets OPpLVAL_INTRO;
92829284
* for our $x () sets OPpOUR_INTRO */
92839285
loop->op_private = (U8)iterpflags;
9286+
9287+
/* upgrade loop from a LISTOP to a LOOPOP;
9288+
* keep it in-place if there's space */
92849289
if (loop->op_slabbed
9285-
&& DIFF(loop, OpSLOT(loop)->opslot_next)
9286-
< SIZE_TO_PSIZE(sizeof(LOOP)))
9290+
&& OpSLOT(loop)->opslot_size < SIZE_TO_PSIZE(sizeof(LOOP)))
92879291
{
9292+
/* no space; allocate new op */
92889293
LOOP *tmp;
92899294
NewOp(1234,tmp,1,LOOP);
92909295
Copy(loop,tmp,1,LISTOP);
@@ -9295,6 +9300,7 @@ Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block, OP *cont)
92959300
}
92969301
else if (!loop->op_slabbed)
92979302
{
9303+
/* loop was malloc()ed */
92989304
loop = (LOOP*)PerlMemShared_realloc(loop, sizeof(LOOP));
92999305
OpLASTSIB_set(loop->op_last, (OP*)loop);
93009306
}

op.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -689,8 +689,7 @@ least an C<UNOP>.
689689

690690
#ifdef PERL_CORE
691691
struct opslot {
692-
/* keep opslot_next first */
693-
OPSLOT * opslot_next; /* next slot */
692+
U16 opslot_size; /* size of this slot (in pointers) */
694693
U16 opslot_offset; /* offset from start of slab (in ptr units) */
695694
OP opslot_op; /* the op itself */
696695
};

0 commit comments

Comments
 (0)