do_clean_objs(pTHX_ SV *ref)
{
dVAR;
- if (SvROK(ref)) {
+ assert (SvROK(ref));
+ {
SV * const target = SvRV(ref);
if (SvOBJECT(target)) {
DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning object ref:\n "), sv_dump(ref)));
do_clean_named_objs(pTHX_ SV *sv)
{
dVAR;
- if (SvTYPE(sv) == SVt_PVGV && isGV_with_GP(sv) && GvGP(sv)) {
+ assert(SvTYPE(sv) == SVt_PVGV);
+ assert(isGV_with_GP(sv));
+ if (GvGP(sv)) {
if ((
#ifdef PERL_DONT_CREATE_GVSV
GvSV(sv) &&
visit(do_clean_objs, SVf_ROK, SVf_ROK);
#ifndef DISABLE_DESTRUCTOR_KLUDGE
/* some barnacles may yet remain, clinging to typeglobs */
- visit(do_clean_named_objs, SVt_PVGV, SVTYPEMASK);
+ visit(do_clean_named_objs, SVt_PVGV|SVpgv_GP, SVTYPEMASK|SVp_POK|SVpgv_GP);
#endif
PL_in_clean_objs = FALSE;
}
TBD: export properly for hv.c: S_more_he().
*/
void*
-Perl_get_arena(pTHX_ int arena_size)
+Perl_get_arena(pTHX_ size_t arena_size)
{
dVAR;
struct arena_desc* adesc;
adesc = &((*aroot)->set[curr]);
assert(!adesc->arena);
- Newxz(adesc->arena, arena_size, char);
+ Newx(adesc->arena, arena_size, char);
adesc->size = arena_size;
DEBUG_m(PerlIO_printf(Perl_debug_log, "arena %d added: %p size %d\n",
curr, (void*)adesc->arena, arena_size));
#define new_NOARENAZ(details) \
my_safecalloc((details)->body_size + (details)->offset)
-#if defined(DEBUGGING) && !defined(PERL_GLOBAL_STRUCT_PRIVATE)
-static bool done_sanity_check;
-#endif
-
STATIC void *
S_more_bodies (pTHX_ svtype sv_type)
{
const size_t body_size = bdp->body_size;
char *start;
const char *end;
-
- assert(bdp->arena_size);
-
#if defined(DEBUGGING) && !defined(PERL_GLOBAL_STRUCT_PRIVATE)
+ static bool done_sanity_check;
+
/* PERL_GLOBAL_STRUCT_PRIVATE cannot coexist with global
* variables like done_sanity_check. */
if (!done_sanity_check) {
}
#endif
+ assert(bdp->arena_size);
+
start = (char*) Perl_get_arena(aTHX_ bdp->arena_size);
end = start + bdp->arena_size - body_size;
break;
/* case SVt_BIND: */
+ case SVt_PVLV:
case SVt_PVGV:
if (isGV_with_GP(sstr) && dtype <= SVt_PVGV) {
glob_assign_glob(dstr, sstr, dtype);
/*FALLTHROUGH*/
case SVt_PVMG:
- case SVt_PVLV:
if (SvGMAGICAL(sstr) && (flags & SV_GMAGIC)) {
mg_get(sstr);
if (SvTYPE(sstr) != stype) {
SvNV_set(dstr, SvNVX(sstr));
}
if (sflags & SVp_IOK) {
- SvRELEASE_IVX(dstr);
+ SvOOK_off(dstr);
SvIV_set(dstr, SvIVX(sstr));
/* Must do this otherwise some other overloaded use of 0x80000000
gets confused. I guess SVpbm_VALID */
(which it can do by means other than releasing copy-on-write Svs)
or by changing the other copy-on-write SVs in the loop. */
STATIC void
-S_sv_release_COW(pTHX_ register SV *sv, const char *pvx, STRLEN len, SV *after)
+S_sv_release_COW(pTHX_ register SV *sv, const char *pvx, SV *after)
{
- if (len) { /* this SV was SvIsCOW_normal(sv) */
+ { /* this SV was SvIsCOW_normal(sv) */
/* we need to find the SV pointing to us. */
SV *current = SV_COW_NEXT_SV(after);
/* Make the SV before us point to the SV after us. */
SV_COW_NEXT_SV_SET(current, after);
}
- } else {
- unshare_hek(SvSHARED_HEK_FROM_PV(pvx));
}
}
-
-int
-Perl_sv_release_IVX(pTHX_ register SV *sv)
-{
- if (SvIsCOW(sv))
- sv_force_normal_flags(sv, 0);
- SvOOK_off(sv);
- return 0;
-}
#endif
/*
=for apidoc sv_force_normal_flags
const char * const pvx = SvPVX_const(sv);
const STRLEN len = SvLEN(sv);
const STRLEN cur = SvCUR(sv);
- SV * const next = SV_COW_NEXT_SV(sv); /* next COW sv in the loop. */
+ /* next COW sv in the loop. If len is 0 then this is a shared-hash
+ key scalar, so we mustn't attempt to call SV_COW_NEXT_SV(), as
+ we'll fail an assertion. */
+ SV * const next = len ? SV_COW_NEXT_SV(sv) : 0;
+
if (DEBUG_C_TEST) {
PerlIO_printf(Perl_debug_log,
"Copy on write: Force normal %ld\n",
SvCUR_set(sv, cur);
*SvEND(sv) = '\0';
}
- sv_release_COW(sv, pvx, len, next);
+ if (len) {
+ sv_release_COW(sv, pvx, next);
+ } else {
+ unshare_hek(SvSHARED_HEK_FROM_PV(pvx));
+ }
if (DEBUG_C_TEST) {
sv_dump(sv);
}
}
else if (LvTYPE(sv) != 't') /* unless tie: unrefcnted fake SV** */
SvREFCNT_dec(LvTARG(sv));
- goto freescalar;
case SVt_PVGV:
if (isGV_with_GP(sv)) {
gp_free((GV*)sv);
PerlIO_printf(Perl_debug_log, "Copy on write: clear\n");
sv_dump(sv);
}
- sv_release_COW(sv, SvPVX_const(sv), SvLEN(sv),
- SV_COW_NEXT_SV(sv));
+ if (SvLEN(sv)) {
+ sv_release_COW(sv, SvPVX_const(sv), SV_COW_NEXT_SV(sv));
+ } else {
+ unshare_hek(SvSHARED_HEK_FROM_PV(SvPVX_const(sv)));
+ }
+
/* And drop it here. */
SvFAKE_off(sv);
} else if (SvLEN(sv)) {
LvTARG(dstr) = (SV*)he_dup((HE*)LvTARG(dstr), 0, param);
else
LvTARG(dstr) = sv_dup_inc(LvTARG(dstr), param);
- break;
case SVt_PVGV:
if(isGV_with_GP(sstr)) {
if (GvNAME_HEK(dstr))
GvNAME_HEK(dstr) = hek_dup(GvNAME_HEK(dstr), param);
- }
-
- /* Don't call sv_add_backref here as it's going to be created
- as part of the magic cloning of the symbol table. */
- if(!SvVALID(dstr))
- GvSTASH(dstr) = hv_dup(GvSTASH(dstr), param);
- if(isGV_with_GP(sstr)) {
+ /* Don't call sv_add_backref here as it's going to be
+ created as part of the magic cloning of the symbol
+ table. */
/* Danger Will Robinson - GvGP(dstr) isn't initialised
at the point of this comment. */
+ GvSTASH(dstr) = hv_dup(GvSTASH(dstr), param);
GvGP(dstr) = gp_dup(GvGP(sstr), param);
(void)GpREFCNT_inc(GvGP(dstr));
} else