From 4e836fe9a8aee77f5e17a5db4b232508755038d6 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Sun, 17 Mar 2024 16:48:16 +0000 Subject: [PATCH] OP_METHSTART, OP_INITFIELD: use shared mem for aux Allocate the aux structure for these two ops using PerlMemShared_malloc() rather then Newx(). OPs (and auxiliary structures) are shared between threads, and there's no guarantee that an OP will be freed by the same thread as the one which created it. Some OSes (Windows IIRC) get upset if memory is malloc()ed and free()d by different threads, since each thread has a separate malloc() pool. Hence we usually use PerlMemShared_malloc()/_free() to allocate such shared structs. These two recently-added ops were just using Newx(). This commit fixes them. No tests failures as far as I'm aware - this is more a theoretical thing where one thread compiles some code, creates a child, then exits. The child lives on, and when the child finally exits, the aux struct is freed to the wrong pool. --- class.c | 11 ++++++++--- op.c | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/class.c b/class.c index 97c3b2a98fdf..68189756348f 100644 --- a/class.c +++ b/class.c @@ -771,7 +771,8 @@ Perl_class_seal_stash(pTHX_ HV *stash) } UNOP_AUX_item *aux; - Newx(aux, 2, UNOP_AUX_item); + aux = (UNOP_AUX_item *)PerlMemShared_malloc( + sizeof(UNOP_AUX_item) * 2); aux[0].uv = fieldix; @@ -882,7 +883,10 @@ Perl_class_wrap_method_body(pTHX_ OP *o) UNOP_AUX_item *aux = NULL; if(av_count(fieldmap)) { - Newx(aux, 2 + av_count(fieldmap), UNOP_AUX_item); + aux = (UNOP_AUX_item *)PerlMemShared_malloc( + sizeof(UNOP_AUX_item) + * (2 + av_count(fieldmap)) + ); UNOP_AUX_item *ap = aux; @@ -985,7 +989,8 @@ apply_field_attribute_reader(pTHX_ PADNAME *pn, SV *value) OP *methstartop; { UNOP_AUX_item *aux; - Newx(aux, 2 + 2, UNOP_AUX_item); + aux = (UNOP_AUX_item *)PerlMemShared_malloc( + sizeof(UNOP_AUX_item) * (2 + 2)); UNOP_AUX_item *ap = aux; (ap++)->uv = 1; /* fieldcount */ diff --git a/op.c b/op.c index 051dcae02554..c71f9fdd1b47 100644 --- a/op.c +++ b/op.c @@ -1334,7 +1334,7 @@ Perl_op_clear(pTHX_ OP *o) { UNOP_AUX_item *aux = cUNOP_AUXo->op_aux; /* Every item in aux is a UV, so nothing in it to free */ - Safefree(aux); + PerlMemShared_free(aux); } break; @@ -1342,7 +1342,7 @@ Perl_op_clear(pTHX_ OP *o) { UNOP_AUX_item *aux = cUNOP_AUXo->op_aux; /* Every item in aux is a UV, so nothing in it to free */ - Safefree(aux); + PerlMemShared_free(aux); } break; }