Skip to content

Commit

Permalink
OP_METHSTART, OP_INITFIELD: use shared mem for aux
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
iabyn committed Mar 19, 2024
1 parent 6a2327b commit 4e836fe
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
11 changes: 8 additions & 3 deletions class.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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 */
Expand Down
4 changes: 2 additions & 2 deletions op.c
Original file line number Diff line number Diff line change
Expand Up @@ -1334,15 +1334,15 @@ 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;

case OP_INITFIELD:
{
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;
}
Expand Down

0 comments on commit 4e836fe

Please sign in to comment.