summaryrefslogtreecommitdiff
path: root/op.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2019-07-13 18:43:30 +0100
committerDavid Mitchell <davem@iabyn.com>2019-08-05 11:29:47 +0100
commit17b8f3a1378b3c300c2e4ab298a8418f720a6b84 (patch)
tree4bdfa2419f6c8a4429e3a23506f1de87761364f3 /op.h
parentbffbea3881b5993aeb432b80f7e06740077faa0d (diff)
downloadperl-17b8f3a1378b3c300c2e4ab298a8418f720a6b84.tar.gz
make opslot_slab an offset in current slab
Each OPSLOT allocated within an OPSLAB contains a pointer, opslot_slab, which points back to the first (head) slab of the slab chain (i.e. not necessarily to the slab which the op is contained in). This commit changes the pointer to be a 16-bit offset from the start of the current slab, and adds a pointer at the start of each slab which points back to the head slab. The mapping from an op to the head slab is now a two-step process: use the op's slot's opslot_offset field to find the start of the current slab, then use that slab's new opslab_head pointer to find the head slab. The advantage of this is that it reduces the storage per op. (It probably doesn't make any practical difference yet, due to alignment issues, but that will will be sorted shortly in this branch.)
Diffstat (limited to 'op.h')
-rw-r--r--op.h11
1 files changed, 8 insertions, 3 deletions
diff --git a/op.h b/op.h
index ad6cf7fe49..9a6d6fb25a 100644
--- 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) \