diff options
-rw-r--r-- | av.h | 2 | ||||
-rw-r--r-- | hv.h | 1 | ||||
-rw-r--r-- | intrpvar.h | 12 | ||||
-rw-r--r-- | sv.c | 91 | ||||
-rw-r--r-- | sv.h | 2 |
5 files changed, 66 insertions, 42 deletions
@@ -26,6 +26,8 @@ struct xpvav { HV* xmg_stash; /* class package */ }; +typedef struct xpvav xpvav_allocated; + /* SV** xav_alloc; */ #define xav_alloc xnv_u.xnv_s.xnv_p1 /* SV* xav_arylen; */ @@ -63,6 +63,7 @@ struct xpvhv { #define xhv_aux xnv_u.xnv_s.xnv_p1 #define xhv_keys xnv_u.xnv_s.xnv_u2.xnv_i2 +typedef struct xpvhv xpvhv_allocated; /* hash a key */ /* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins diff --git a/intrpvar.h b/intrpvar.h index c879e9edd0..7e243ddc58 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -253,12 +253,12 @@ PERLVAR(Ixiv_arenaroot, XPV*) /* list of allocated xiv areas */ PERLVAR(Ixiv_root, IV *) /* free xiv list */ PERLVAR(Ixnv_root, NV *) /* free xnv list */ PERLVAR(Ixrv_root, XRV *) /* free xrv list */ -PERLVAR(Ixpv_root, XPV *) /* free xpv list */ +PERLVAR(Ixpv_root, xpv_allocated *) /* free xpv list */ PERLVAR(Ixpviv_root, XPVIV *) /* free xpviv list */ PERLVAR(Ixpvnv_root, XPVNV *) /* free xpvnv list */ PERLVAR(Ixpvcv_root, XPVCV *) /* free xpvcv list */ -PERLVAR(Ixpvav_root, XPVAV *) /* free xpvav list */ -PERLVAR(Ixpvhv_root, XPVHV *) /* free xpvhv list */ +PERLVAR(Ixpvav_root, xpvav_allocated *) /* free xpvav list */ +PERLVAR(Ixpvhv_root, xpvhv_allocated *) /* free xpvhv list */ PERLVAR(Ixpvmg_root, XPVMG *) /* free xpvmg list */ PERLVAR(Ixpvgv_root, XPVGV *) /* free xpvgv list */ PERLVAR(Ixpvlv_root, XPVLV *) /* free xpvlv list */ @@ -433,12 +433,12 @@ PERLVARI(Ibeginav_save, AV*, Nullav) /* save BEGIN{}s when compiling */ PERLVAR(Ixnv_arenaroot, XPV*) /* list of allocated xnv areas */ PERLVAR(Ixrv_arenaroot, XPV*) /* list of allocated xrv areas */ -PERLVAR(Ixpv_arenaroot, XPV*) /* list of allocated xpv areas */ +PERLVAR(Ixpv_arenaroot, xpv_allocated *) /* list of allocated xpv areas */ PERLVAR(Ixpviv_arenaroot,XPVIV*) /* list of allocated xpviv areas */ PERLVAR(Ixpvnv_arenaroot,XPVNV*) /* list of allocated xpvnv areas */ PERLVAR(Ixpvcv_arenaroot,XPVCV*) /* list of allocated xpvcv areas */ -PERLVAR(Ixpvav_arenaroot,XPVAV*) /* list of allocated xpvav areas */ -PERLVAR(Ixpvhv_arenaroot,XPVHV*) /* list of allocated xpvhv areas */ +PERLVAR(Ixpvav_arenaroot,xpvav_allocated*) /* list of allocated xpvav areas */ +PERLVAR(Ixpvhv_arenaroot,xpvhv_allocated*) /* list of allocated xpvhv areas */ PERLVAR(Ixpvmg_arenaroot,XPVMG*) /* list of allocated xpvmg areas */ PERLVAR(Ixpvgv_arenaroot,XPVGV*) /* list of allocated xpvgv areas */ PERLVAR(Ixpvlv_arenaroot,XPVLV*) /* list of allocated xpvlv areas */ @@ -1153,19 +1153,19 @@ S_more_xnv(pTHX) STATIC void S_more_xpv(pTHX) { - XPV* xpv; - XPV* xpvend; - New(713, xpv, PERL_ARENA_SIZE/sizeof(XPV), XPV); - *((XPV**)xpv) = PL_xpv_arenaroot; + xpv_allocated* xpv; + xpv_allocated* xpvend; + New(713, xpv, PERL_ARENA_SIZE/sizeof(xpv_allocated), xpv_allocated); + *((xpv_allocated**)xpv) = PL_xpv_arenaroot; PL_xpv_arenaroot = xpv; - xpvend = &xpv[PERL_ARENA_SIZE / sizeof(XPV) - 1]; + xpvend = &xpv[PERL_ARENA_SIZE / sizeof(xpv_allocated) - 1]; PL_xpv_root = ++xpv; while (xpv < xpvend) { - *((XPV**)xpv) = xpv + 1; + *((xpv_allocated**)xpv) = xpv + 1; xpv++; } - *((XPV**)xpv) = 0; + *((xpv_allocated**)xpv) = 0; } /* allocate another arena's worth of struct xpviv */ @@ -1233,19 +1233,20 @@ S_more_xpvcv(pTHX) STATIC void S_more_xpvav(pTHX) { - XPVAV* xpvav; - XPVAV* xpvavend; - New(717, xpvav, PERL_ARENA_SIZE/sizeof(XPVAV), XPVAV); - *((XPVAV**)xpvav) = PL_xpvav_arenaroot; + xpvav_allocated* xpvav; + xpvav_allocated* xpvavend; + New(717, xpvav, PERL_ARENA_SIZE/sizeof(xpvav_allocated), + xpvav_allocated); + *((xpvav_allocated**)xpvav) = PL_xpvav_arenaroot; PL_xpvav_arenaroot = xpvav; - xpvavend = &xpvav[PERL_ARENA_SIZE / sizeof(XPVAV) - 1]; + xpvavend = &xpvav[PERL_ARENA_SIZE / sizeof(xpvav_allocated) - 1]; PL_xpvav_root = ++xpvav; while (xpvav < xpvavend) { - *((XPVAV**)xpvav) = xpvav + 1; + *((xpvav_allocated**)xpvav) = xpvav + 1; xpvav++; } - *((XPVAV**)xpvav) = 0; + *((xpvav_allocated**)xpvav) = 0; } /* allocate another arena's worth of struct xpvhv */ @@ -1253,19 +1254,20 @@ S_more_xpvav(pTHX) STATIC void S_more_xpvhv(pTHX) { - XPVHV* xpvhv; - XPVHV* xpvhvend; - New(718, xpvhv, PERL_ARENA_SIZE/sizeof(XPVHV), XPVHV); - *((XPVHV**)xpvhv) = PL_xpvhv_arenaroot; + xpvhv_allocated* xpvhv; + xpvhv_allocated* xpvhvend; + New(718, xpvhv, PERL_ARENA_SIZE/sizeof(xpvhv_allocated), + xpvhv_allocated); + *((xpvhv_allocated**)xpvhv) = PL_xpvhv_arenaroot; PL_xpvhv_arenaroot = xpvhv; - xpvhvend = &xpvhv[PERL_ARENA_SIZE / sizeof(XPVHV) - 1]; + xpvhvend = &xpvhv[PERL_ARENA_SIZE / sizeof(xpvhv_allocated) - 1]; PL_xpvhv_root = ++xpvhv; while (xpvhv < xpvhvend) { - *((XPVHV**)xpvhv) = xpvhv + 1; + *((xpvhv_allocated**)xpvhv) = xpvhv + 1; xpvhv++; } - *((XPVHV**)xpvhv) = 0; + *((xpvhv_allocated**)xpvhv) = 0; } /* allocate another arena's worth of struct xpvmg */ @@ -1380,14 +1382,20 @@ S_del_xnv(pTHX_ XPVNV *p) STATIC XPV* S_new_xpv(pTHX) { - XPV* xpv; + xpv_allocated* xpv; LOCK_SV_MUTEX; if (!PL_xpv_root) S_more_xpv(aTHX); xpv = PL_xpv_root; - PL_xpv_root = *(XPV**)xpv; + PL_xpv_root = *(xpv_allocated**)xpv; UNLOCK_SV_MUTEX; - return xpv; + /* If xpv_allocated is the same structure as XPV then the two OFFSETs + sum to zero, and the pointer is unchanged. If the allocated structure + is smaller (no initial IV actually allocated) then the net effect is + to subtract the size of the IV from the pointer, to return a new pointer + as if an initial IV were actually allocated. */ + return (XPV*)((char*)xpv - STRUCT_OFFSET(XPV, xpv_cur) + + STRUCT_OFFSET(xpv_allocated, xpv_cur)); } /* return a struct xpv to the free list */ @@ -1395,9 +1403,12 @@ S_new_xpv(pTHX) STATIC void S_del_xpv(pTHX_ XPV *p) { + xpv_allocated* xpv + = (xpv_allocated*)((char*)(p) + STRUCT_OFFSET(XPV, xpv_cur) + - STRUCT_OFFSET(xpv_allocated, xpv_cur)); LOCK_SV_MUTEX; - *(XPV**)p = PL_xpv_root; - PL_xpv_root = p; + *(xpv_allocated**)xpv = PL_xpv_root; + PL_xpv_root = xpv; UNLOCK_SV_MUTEX; } @@ -1484,14 +1495,15 @@ S_del_xpvcv(pTHX_ XPVCV *p) STATIC XPVAV* S_new_xpvav(pTHX) { - XPVAV* xpvav; + xpvav_allocated* xpvav; LOCK_SV_MUTEX; if (!PL_xpvav_root) S_more_xpvav(aTHX); xpvav = PL_xpvav_root; - PL_xpvav_root = *(XPVAV**)xpvav; + PL_xpvav_root = *(xpvav_allocated**)xpvav; UNLOCK_SV_MUTEX; - return xpvav; + return (XPVAV*)((char*)xpvav - STRUCT_OFFSET(XPVAV, xav_fill) + + STRUCT_OFFSET(xpvav_allocated, xav_fill)); } /* return a struct xpvav to the free list */ @@ -1499,9 +1511,12 @@ S_new_xpvav(pTHX) STATIC void S_del_xpvav(pTHX_ XPVAV *p) { + xpvav_allocated* xpvav + = (xpvav_allocated*)((char*)(p) + STRUCT_OFFSET(XPVAV, xav_fill) + - STRUCT_OFFSET(xpvav_allocated, xav_fill)); LOCK_SV_MUTEX; - *(XPVAV**)p = PL_xpvav_root; - PL_xpvav_root = p; + *(xpvav_allocated**)xpvav = PL_xpvav_root; + PL_xpvav_root = xpvav; UNLOCK_SV_MUTEX; } @@ -1510,14 +1525,15 @@ S_del_xpvav(pTHX_ XPVAV *p) STATIC XPVHV* S_new_xpvhv(pTHX) { - XPVHV* xpvhv; + xpvhv_allocated* xpvhv; LOCK_SV_MUTEX; if (!PL_xpvhv_root) S_more_xpvhv(aTHX); xpvhv = PL_xpvhv_root; - PL_xpvhv_root = *(XPVHV**)xpvhv; + PL_xpvhv_root = *(xpvhv_allocated**)xpvhv; UNLOCK_SV_MUTEX; - return xpvhv; + return (XPVHV*)((char*)xpvhv - STRUCT_OFFSET(XPVHV, xhv_fill) + + STRUCT_OFFSET(xpvhv_allocated, xhv_fill)); } /* return a struct xpvhv to the free list */ @@ -1525,9 +1541,12 @@ S_new_xpvhv(pTHX) STATIC void S_del_xpvhv(pTHX_ XPVHV *p) { + xpvhv_allocated* xpvhv + = (xpvhv_allocated*)((char*)(p) + STRUCT_OFFSET(XPVHV, xhv_fill) + - STRUCT_OFFSET(xpvhv_allocated, xhv_fill)); LOCK_SV_MUTEX; - *(XPVHV**)p = PL_xpvhv_root; - PL_xpvhv_root = p; + *(xpvhv_allocated**)xpvhv = PL_xpvhv_root; + PL_xpvhv_root = xpvhv; UNLOCK_SV_MUTEX; } @@ -280,6 +280,8 @@ struct xpv { STRLEN xpv_len; /* allocated size */ }; +typedef struct xpv xpv_allocated; + struct xpviv { IV xiv_iv; /* integer value or pv offset */ STRLEN xpv_cur; /* length of sv_pv as a C string */ |