]> git.vpit.fr Git - perl/modules/autovivification.git/commitdiff
Use the op free hook to clean up pointer table entries when available opfreehook
authorVincent Pit <vince@profvince.com>
Fri, 11 Jul 2014 23:06:46 +0000 (01:06 +0200)
committerVincent Pit <vince@profvince.com>
Fri, 11 Jul 2014 23:06:46 +0000 (01:06 +0200)
autovivification.xs

index a6bf2af1c79124370f9a643ee8800b810ea5a81e..27f44c7ae74cbe41a260d648ff0b205aead3d468 100644 (file)
 # 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