From: Vincent Pit Date: Fri, 11 Jul 2014 23:06:46 +0000 (+0200) Subject: Use the op free hook to clean up pointer table entries when available X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Fautovivification.git;a=commitdiff_plain;h=refs%2Fheads%2Fopfreehook Use the op free hook to clean up pointer table entries when available --- diff --git a/autovivification.xs b/autovivification.xs index a6bf2af..27f44c7 100644 --- a/autovivification.xs +++ b/autovivification.xs @@ -29,6 +29,10 @@ # define A_HAS_RPEEP A_HAS_PERL(5, 13, 5) #endif +#ifndef A_HAS_OPFREEHOOK +# define A_HAS_OPFREEHOOK A_HAS_PERL(5, 12, 0) +#endif + /* ... Thread safety and multiplicity ...................................... */ /* Always safe when the workaround isn't needed */ @@ -779,10 +783,13 @@ STATIC OP *a_ck_padany(pTHX_ OP *o) { o = a_old_ck_padany(aTHX_ o); hint = a_hint(); - if (hint & A_HINT_DO) + if (hint & A_HINT_DO) { a_map_store_root(o, o->op_ppaddr, hint); - else +#if !A_HAS_OPFREEHOOK + } else { a_map_delete(o); +#endif + } return o; } @@ -798,8 +805,11 @@ STATIC OP *a_ck_padsv(pTHX_ OP *o) { if (hint & A_HINT_DO) { a_map_store_root(o, o->op_ppaddr, hint); o->op_ppaddr = a_pp_deref; - } else +#if !A_HAS_OPFREEHOOK + } else { a_map_delete(o); +#endif + } return o; } @@ -839,8 +849,11 @@ STATIC OP *a_ck_deref(pTHX_ OP *o) { if (hint & A_HINT_DO) { a_map_store_root(o, o->op_ppaddr, hint); o->op_ppaddr = a_pp_deref; - } else +#if !A_HAS_OPFREEHOOK + } else { a_map_delete(o); +#endif + } return o; } @@ -873,8 +886,11 @@ STATIC OP *a_ck_rv2xv(pTHX_ OP *o) { if (hint & A_HINT_DO && !(hint & A_HINT_STRICT)) { a_map_store_root(o, o->op_ppaddr, hint); o->op_ppaddr = new_pp; - } else +#if !A_HAS_OPFREEHOOK + } else { a_map_delete(o); +#endif + } return o; } @@ -907,8 +923,11 @@ STATIC OP *a_ck_xslice(pTHX_ OP *o) { if (hint & A_HINT_DO) { a_map_store_root(o, 0, hint); - } else +#if !A_HAS_OPFREEHOOK + } else { a_map_delete(o); +#endif + } return o; } @@ -961,8 +980,11 @@ STATIC OP *a_ck_root(pTHX_ OP *o) { } else { a_map_cancel(o); } - } else +#if !A_HAS_OPFREEHOOK + } else { a_map_delete(o); +#endif + } return o; } @@ -1078,6 +1100,21 @@ STATIC void a_peep(pTHX_ OP *o) { ptable_seen_clear(seen); } +/* ... Our op free hook (when available) ................................... */ + +#if A_HAS_OPFREEHOOK + +STATIC void (*a_old_opfreehook)(pTHX_ OP *) = 0; + +STATIC void a_opfreehook(pTHX_ OP *o) { + a_map_delete(o); + + if (a_old_opfreehook) + a_old_opfreehook(aTHX_ o); +} + +#endif + /* --- Interpreter setup/teardown ------------------------------------------ */ STATIC U32 a_initialized = 0; @@ -1125,6 +1162,11 @@ STATIC void a_teardown(pTHX_ void *root) { #endif a_old_peep = 0; +#if A_HAS_OPFREEHOOK + PL_opfreehook = a_old_opfreehook; + a_old_opfreehook = 0; +#endif + a_initialized = 0; } @@ -1168,6 +1210,11 @@ STATIC void a_setup(pTHX) { PL_peepp = a_peep; #endif +#if A_HAS_OPFREEHOOK + a_old_opfreehook = PL_opfreehook; + PL_opfreehook = a_opfreehook; +#endif + #if A_MULTIPLICITY call_atexit(a_teardown, aTHX); #else