This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
make opslot_slab an offset in current slab
[perl5.git] / op.h
diff --git a/op.h b/op.h
index ad6cf7f..9a6d6fb 100644 (file)
--- a/op.h
+++ b/op.h
@@ -691,15 +691,16 @@ least an C<UNOP>.
 struct opslot {
     /* keep opslot_next first */
     OPSLOT *   opslot_next;            /* next slot */
-    OPSLAB *   opslot_slab;            /* owner */
+    U16         opslot_offset;      /* offset from start of slab (in ptr units) */
     OP         opslot_op;              /* the op itself */
 };
 
 struct opslab {
     OPSLOT *   opslab_first;           /* first op in this slab */
     OPSLAB *   opslab_next;            /* next slab */
+    OPSLAB *   opslab_head;            /* first slab in chain */
     OP *       opslab_freed;           /* chain of freed ops */
-    size_t     opslab_refcnt;          /* number of ops */
+    size_t     opslab_refcnt;          /* number of ops (head slab only) */
 # ifdef PERL_DEBUG_READONLY_OPS
     U16                opslab_size;            /* size of slab in pointers */
     bool       opslab_readonly;
@@ -711,7 +712,11 @@ struct opslab {
 # define OPSLOT_HEADER_P       (OPSLOT_HEADER/sizeof(I32 *))
 # define OpSLOT(o)             (assert_(o->op_slabbed) \
                                 (OPSLOT *)(((char *)o)-OPSLOT_HEADER))
-# define OpSLAB(o)             OpSLOT(o)->opslot_slab
+
+/* the first (head) opslab of the chain in which this op is allocated */
+# define OpSLAB(o) \
+    (((OPSLAB*)( (I32**)OpSLOT(o) - OpSLOT(o)->opslot_offset))->opslab_head)
+
 # define OpslabREFCNT_dec(slab)      \
        (((slab)->opslab_refcnt == 1) \
         ? opslab_free_nopad(slab)     \