Skip to content

Commit ca73285

Browse files
committed
Move placeholders into a new rhash magic type.
p4raw-id: //depot/perl@24525
1 parent 4325052 commit ca73285

File tree

9 files changed

+72
-19
lines changed

9 files changed

+72
-19
lines changed

dump.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,7 @@ Perl_gv_dump(pTHX_ GV *gv)
890890
static const struct { const char type; const char *name; } magic_names[] = {
891891
{ PERL_MAGIC_sv, "sv(\\0)" },
892892
{ PERL_MAGIC_arylen, "arylen(#)" },
893+
{ PERL_MAGIC_rhash, "rhash(%)" },
893894
{ PERL_MAGIC_glob, "glob(*)" },
894895
{ PERL_MAGIC_pos, "pos(.)" },
895896
{ PERL_MAGIC_symtab, "symtab(:)" },

embed.fnc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,11 @@ sM |HE* |hv_fetch_common|HV* tb|SV* key_sv|const char* key|STRLEN klen|int flags
13971397
Apd |void |hv_clear_placeholders|HV* hb
13981398

13991399
Apd |SV* |hv_scalar |HV* hv|
1400+
1401+
Apo |I32* |hv_placeholders_p |HV* hv
1402+
Apo |I32 |hv_placeholders_get |HV* hv
1403+
Apo |void |hv_placeholders_set |HV* hv|I32 ph
1404+
14001405
p |SV* |magic_scalarpack|HV* hv|MAGIC* mg
14011406
#ifdef PERL_IN_SV_C
14021407
sMd |SV* |find_uninit_var|OP* obase|SV* uninit_sv|bool top

ext/Storable/Storable.xs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ typedef double NV; /* Older perls lack the NV type */
107107
#define dVAR dNOOP
108108
#endif
109109

110+
#ifndef HvPLACEHOLDERS_get
111+
# define HvPLACEHOLDERS_get HvPLACEHOLDERS
112+
#endif
113+
110114
#ifdef DEBUGME
111115

112116
#ifndef DASSERT
@@ -2303,7 +2307,7 @@ static int store_hash(pTHX_ stcxt_t *cxt, HV *hv)
23032307

23042308
for (i = 0; i < len; i++) {
23052309
#ifdef HAS_RESTRICTED_HASHES
2306-
int placeholders = (int)HvPLACEHOLDERS(hv);
2310+
int placeholders = (int)HvPLACEHOLDERS_get(hv);
23072311
#endif
23082312
unsigned char flags = 0;
23092313
char *keyval;

global.sym

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,9 @@ Perl_save_set_svflags
675675
Perl_hv_assert
676676
Perl_hv_clear_placeholders
677677
Perl_hv_scalar
678+
Perl_hv_placeholders_p
679+
Perl_hv_placeholders_get
680+
Perl_hv_placeholders_set
678681
Perl_gv_fetchpvn_flags
679682
Perl_gv_fetchsv
680683
Perl_savesvpv

hv.c

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -680,11 +680,11 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
680680
}
681681
/* LVAL fetch which actaully needs a store. */
682682
val = NEWSV(61,0);
683-
xhv->xhv_placeholders--;
683+
HvPLACEHOLDERS(hv)--;
684684
} else {
685685
/* store */
686686
if (val != &PL_sv_placeholder)
687-
xhv->xhv_placeholders--;
687+
HvPLACEHOLDERS(hv)--;
688688
}
689689
HeVAL(entry) = val;
690690
} else if (action & HV_FETCH_ISSTORE) {
@@ -764,7 +764,7 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
764764
*oentry = entry;
765765

766766
if (val == &PL_sv_placeholder)
767-
xhv->xhv_placeholders++;
767+
HvPLACEHOLDERS(hv)++;
768768
if (masked_flags & HVhek_ENABLEHVKFLAGS)
769769
HvHASKFLAGS_on(hv);
770770

@@ -1022,7 +1022,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
10221022
HeVAL(entry) = &PL_sv_placeholder;
10231023
/* We'll be saving this slot, so the number of allocated keys
10241024
* doesn't go down, but the number placeholders goes up */
1025-
xhv->xhv_placeholders++; /* HvPLACEHOLDERS(hv)++ */
1025+
HvPLACEHOLDERS(hv)++;
10261026
} else {
10271027
*oentry = HeNEXT(entry);
10281028
if (i && !*oentry)
@@ -1466,15 +1466,15 @@ Perl_hv_clear(pTHX_ HV *hv)
14661466
}
14671467
SvREFCNT_dec(HeVAL(entry));
14681468
HeVAL(entry) = &PL_sv_placeholder;
1469-
xhv->xhv_placeholders++; /* HvPLACEHOLDERS(hv)++ */
1469+
HvPLACEHOLDERS(hv)++;
14701470
}
14711471
}
14721472
}
14731473
goto reset;
14741474
}
14751475

14761476
hfreeentries(hv);
1477-
xhv->xhv_placeholders = 0; /* HvPLACEHOLDERS(hv) = 0 */
1477+
HvPLACEHOLDERS_set(hv, 0);
14781478
if (xhv->xhv_array /* HvARRAY(hv) */)
14791479
(void)memzero(xhv->xhv_array /* HvARRAY(hv) */,
14801480
(xhv->xhv_max+1 /* HvMAX(hv)+1 */) * sizeof(HE*));
@@ -1615,7 +1615,7 @@ Perl_hv_undef(pTHX_ HV *hv)
16151615
}
16161616
xhv->xhv_max = 7; /* HvMAX(hv) = 7 (it's a normal hash) */
16171617
xhv->xhv_array = 0; /* HvARRAY(hv) = 0 */
1618-
xhv->xhv_placeholders = 0; /* HvPLACEHOLDERS(hv) = 0 */
1618+
HvPLACEHOLDERS_set(hv, 0);
16191619

16201620
if (SvRMAGICAL(hv))
16211621
mg_clear((SV*)hv);
@@ -2126,6 +2126,46 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
21262126
return HeKEY_hek(entry);
21272127
}
21282128

2129+
I32 *
2130+
Perl_hv_placeholders_p(pTHX_ HV *hv)
2131+
{
2132+
dVAR;
2133+
MAGIC *mg = mg_find((SV*)hv, PERL_MAGIC_rhash);
2134+
2135+
if (!mg) {
2136+
mg = sv_magicext((SV*)hv, 0, PERL_MAGIC_rhash, 0, 0, 0);
2137+
2138+
if (!mg) {
2139+
Perl_die(aTHX_ "panic: hv_placeholders_p");
2140+
}
2141+
}
2142+
return &(mg->mg_len);
2143+
}
2144+
2145+
2146+
I32
2147+
Perl_hv_placeholders_get(pTHX_ HV *hv)
2148+
{
2149+
dVAR;
2150+
MAGIC *mg = mg_find((SV*)hv, PERL_MAGIC_rhash);
2151+
2152+
return mg ? mg->mg_len : 0;
2153+
}
2154+
2155+
void
2156+
Perl_hv_placeholders_set(pTHX_ HV *hv, IV ph)
2157+
{
2158+
dVAR;
2159+
MAGIC *mg = mg_find((SV*)hv, PERL_MAGIC_rhash);
2160+
2161+
if (mg) {
2162+
mg->mg_len = ph;
2163+
} else if (ph) {
2164+
if (!sv_magicext((SV*)hv, 0, PERL_MAGIC_rhash, 0, 0, ph))
2165+
Perl_die(aTHX_ "panic: hv_placeholders_set");
2166+
}
2167+
/* else we don't need to add magic to record 0 placeholders. */
2168+
}
21292169

21302170
/*
21312171
=for apidoc hv_assert

hv.h

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ struct xpvhv {
3737
STRLEN xhv_max; /* subscript of last element of xhv_array */
3838
IV xhv_keys; /* how many elements in the array */
3939
NV xnv_nv; /* numeric value, if any */
40-
#define xhv_placeholders xnv_nv
4140
MAGIC* xmg_magic; /* magic for scalar array */
4241
HV* xmg_stash; /* class package */
4342

@@ -186,21 +185,17 @@ C<SV*>.
186185
/* the number of keys (including any placeholers) */
187186
#define XHvTOTALKEYS(xhv) ((xhv)->xhv_keys)
188187

189-
/* The number of placeholders in the enumerated-keys hash */
190-
#define XHvPLACEHOLDERS(xhv) ((xhv)->xhv_placeholders)
191-
192-
/* the number of keys that exist() (i.e. excluding placeholders) */
193-
#define XHvUSEDKEYS(xhv) (XHvTOTALKEYS(xhv) - (IV)XHvPLACEHOLDERS(xhv))
194-
195188
/*
196189
* HvKEYS gets the number of keys that actually exist(), and is provided
197190
* for backwards compatibility with old XS code. The core uses HvUSEDKEYS
198191
* (keys, excluding placeholdes) and HvTOTALKEYS (including placeholders)
199192
*/
200-
#define HvKEYS(hv) XHvUSEDKEYS((XPVHV*) SvANY(hv))
201-
#define HvUSEDKEYS(hv) XHvUSEDKEYS((XPVHV*) SvANY(hv))
193+
#define HvKEYS(hv) HvUSEDKEYS(hv)
194+
#define HvUSEDKEYS(hv) (HvTOTALKEYS(hv) - HvPLACEHOLDERS_get(hv))
202195
#define HvTOTALKEYS(hv) XHvTOTALKEYS((XPVHV*) SvANY(hv))
203-
#define HvPLACEHOLDERS(hv) XHvPLACEHOLDERS((XPVHV*) SvANY(hv))
196+
#define HvPLACEHOLDERS(hv) (*Perl_hv_placeholders_p(aTHX_ (HV*)hv))
197+
#define HvPLACEHOLDERS_get(hv) (SvMAGIC(hv) ? Perl_hv_placeholders_get(aTHX_ (HV*)hv) : 0)
198+
#define HvPLACEHOLDERS_set(hv,p) Perl_hv_placeholders_set(aTHX_ (HV*)hv, p)
204199

205200
#define HvSHAREKEYS(hv) (SvFLAGS(hv) & SVphv_SHAREKEYS)
206201
#define HvSHAREKEYS_on(hv) (SvFLAGS(hv) |= SVphv_SHAREKEYS)

perl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3170,6 +3170,7 @@ Gid_t getegid (void);
31703170
#define PERL_MAGIC_pos '.' /* pos() lvalue */
31713171
#define PERL_MAGIC_backref '<' /* for weak ref data */
31723172
#define PERL_MAGIC_symtab ':' /* extra data for symbol tables */
3173+
#define PERL_MAGIC_rhash '%' /* extra data for restricted hashes */
31733174
#define PERL_MAGIC_ext '~' /* Available for use by extensions */
31743175

31753176

proto.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2311,6 +2311,11 @@ STATIC HE* S_hv_fetch_common(pTHX_ HV* tb, SV* key_sv, const char* key, STRLEN k
23112311
PERL_CALLCONV void Perl_hv_clear_placeholders(pTHX_ HV* hb);
23122312

23132313
PERL_CALLCONV SV* Perl_hv_scalar(pTHX_ HV* hv);
2314+
2315+
PERL_CALLCONV I32* Perl_hv_placeholders_p(pTHX_ HV* hv);
2316+
PERL_CALLCONV I32 Perl_hv_placeholders_get(pTHX_ HV* hv);
2317+
PERL_CALLCONV void Perl_hv_placeholders_set(pTHX_ HV* hv, I32 ph);
2318+
23142319
PERL_CALLCONV SV* Perl_magic_scalarpack(pTHX_ HV* hv, MAGIC* mg);
23152320
#ifdef PERL_IN_SV_C
23162321
STATIC SV* S_find_uninit_var(pTHX_ OP* obase, SV* uninit_sv, bool top);

sv.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1976,7 +1976,6 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
19761976
HvFILL(sv) = 0;
19771977
HvMAX(sv) = 0;
19781978
HvTOTALKEYS(sv) = 0;
1979-
HvPLACEHOLDERS(sv) = 0;
19801979

19811980
/* Fall through... */
19821981
if (0) {

0 commit comments

Comments
 (0)