summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2008-08-24 12:16:28 +0000
committerDave Mitchell <davem@fdisolutions.com>2008-08-24 12:16:28 +0000
commit990198f0755a90e7230c3598d2d36d7d5ef7d95e (patch)
treeb01047094c4e5de832a3ecef82d352e3cd3af738 /sv.c
parentb5920ff0f6b65443a39b58d7cf4cd21351bedd92 (diff)
downloadperl-990198f0755a90e7230c3598d2d36d7d5ef7d95e.tar.gz
Don't add freed SVF_BREAK scalars to the freed list.
This may still be referenced, so don't reuse. p4raw-id: //depot/perl@34220
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sv.c b/sv.c
index f56d70cdcc..6089a00c30 100644
--- a/sv.c
+++ b/sv.c
@@ -192,13 +192,23 @@ Perl_offer_nice_chunk(pTHX_ void *const chunk, const U32 chunk_size)
# define POSION_SV_HEAD(sv)
#endif
+/* Mark an SV head as unused, and add to free list.
+ *
+ * If SVf_BREAK is set, skip adding it to the free list, as this SV had
+ * its refcount artificially decremented during global destruction, so
+ * there may be dangling pointers to it. The last thing we want in that
+ * case is for it to be reused. */
+
#define plant_SV(p) \
STMT_START { \
+ const U32 old_flags = SvFLAGS(p); \
FREE_SV_DEBUG_FILE(p); \
POSION_SV_HEAD(p); \
- SvARENA_CHAIN(p) = (void *)PL_sv_root; \
SvFLAGS(p) = SVTYPEMASK; \
- PL_sv_root = (p); \
+ if (!(old_flags & SVf_BREAK)) { \
+ SvARENA_CHAIN(p) = (void *)PL_sv_root; \
+ PL_sv_root = (p); \
+ } \
--PL_sv_count; \
} STMT_END