[Jifty-commit] r5438 - in Runops-Trace/trunk: .

Jifty commits jifty-commit at lists.jifty.org
Sat May 10 11:34:38 EDT 2008


Author: nothingmuch
Date: Sat May 10 11:34:36 2008
New Revision: 5438

Modified:
   Runops-Trace/trunk/Trace.xs
   Runops-Trace/trunk/lib/Runops/Trace.pm

Log:
opmask

Modified: Runops-Trace/trunk/Trace.xs
==============================================================================
--- Runops-Trace/trunk/Trace.xs	(original)
+++ Runops-Trace/trunk/Trace.xs	Sat May 10 11:34:36 2008
@@ -38,24 +38,24 @@
 /* this is the modified runloop */
 int runops_trace(pTHX)
 {
-  while (PL_op) {
-
-    /* global flag controls all hooking behavior */
-    if (Runops_Trace_enabled) {
-
-      /* if we have a mask set, only trace unmasked ops */
-      if (!Runops_Trace_mask || Runops_Trace_mask[PL_op->op_type]) {
+  dVAR;
 
-        /* the hook may have assigned PL_op itself, in which case we just go to
-         * the next loop iteration */
-        if (Runops_Trace_hook && CALL_FPTR( Runops_Trace_hook) (aTHX))
-          continue;
-      }
+  while (PL_op) {
+    if ( Runops_Trace_enabled &&
+        /* if we have a mask set, only trace unmasked ops */
+        ( !Runops_Trace_mask || Runops_Trace_mask[PL_op->op_type] )
+       ){
+
+      /* the hook may have assigned PL_op itself, in which case we just go to
+       * the next loop iteration */
+      if (Runops_Trace_hook && CALL_FPTR( Runops_Trace_hook) (aTHX))
+        continue;
     }
 
+    /* this is pretty much the normal runops_standard */
     PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX);
 
-    PERL_ASYNC_CHECK();
+    PERL_ASYNC_CHECK(); /* FIXME is it OK that PERL_ASYNC_CHECK happens even after PL_op might be false? */
   }
 
   TAINT_NOT;
@@ -340,6 +340,64 @@
   Runops_Trace_threshold = t;
 }
 
+void
+Runops_Trace_mask_autocreate () {
+  if (!Runops_Trace_mask) {
+    int i;
+    Newx(Runops_Trace_mask, OPMASK_SIZE, bool);
+    for (i = 0; i < OPMASK_SIZE; i++) {
+      Runops_Trace_mask[i] = 1;
+    }
+  }
+}
+
+Runops_Trace_mask_all () {
+  if (!Runops_Trace_mask) {
+    Newxz(Runops_Trace_mask, OPMASK_SIZE, bool);
+  } else {
+    int i;
+    for (i = 0; i < OPMASK_SIZE; i++) {
+      Runops_Trace_mask[i] = 0;
+    }
+  }
+}
+
+Runops_Trace_mask_none () {
+  if (!Runops_Trace_mask) {
+    Runops_Trace_mask_autocreate();
+  } else {
+    int i;
+    for (i = 0; i < OPMASK_SIZE; i++) {
+      Runops_Trace_mask[i] = 1;
+    }
+  }
+}
+
+void
+Runops_Trace_mask_set_op_type (unsigned op_type, bool bit) {
+  if ( op_type < OPMASK_SIZE ) {
+    Runops_Trace_mask_autocreate();
+    Runops_Trace_mask[op_type] = bit;
+  } else {
+    croak("Invalid op_type %d", op_type);
+  }
+}
+
+void
+Runops_Trace_unmask_op_type (unsigned op_type) {
+  Runops_Trace_mask_set_op_type(op_type, 1);
+}
+
+void
+Runops_Trace_mask_op_type (unsigned op_type) {
+  Runops_Trace_mask_set_op_type(op_type, 0);
+}
+
+void
+Runops_Trace_clear_op_mask () {
+  Safefree(Runops_Trace_mask);
+  Runops_Trace_mask = NULL;
+}
 
 MODULE = Runops::Trace PACKAGE = Runops::Trace
 
@@ -353,6 +411,7 @@
 
 HV *
 get_op_counters()
+  PROTOTYPE:
   CODE:
 {
   if ( !Runops_Trace_op_counters )
@@ -365,6 +424,7 @@
 
 int
 tracing_enabled()
+  PROTOTYPE:
   CODE:
 {
   RETVAL = Runops_Trace_enabled;
@@ -374,6 +434,7 @@
 
 void
 enable_tracing()
+  PROTOTYPE:
   CODE:
 {
   Runops_Trace_enable();
@@ -381,6 +442,7 @@
 
 void
 disable_tracing()
+  PROTOTYPE:
   CODE:
 {
   Runops_Trace_disable();
@@ -388,6 +450,7 @@
 
 UV
 get_trace_threshold()
+  PROTOTYPE:
   CODE:
 {
   RETVAL = Runops_Trace_get_threshold();
@@ -397,13 +460,15 @@
 
 void
 set_trace_threshold(SV *a)
-    CODE:
+  PROTOTYPE: $
+  CODE:
 {
      Runops_Trace_set_threshold(SvUV(a));
 }
 
 void
 set_tracer(SV *hook)
+  PROTOTYPE: $
   CODE:
 {
   Runops_Trace_set_perl_hook(aTHX_ hook);
@@ -411,6 +476,7 @@
 
 SV *
 get_tracer()
+  PROTOTYPE:
   CODE:
 {
   RETVAL = Runops_Trace_perl_hook;
@@ -420,6 +486,7 @@
 
 void
 clear_tracer()
+  PROTOTYPE:
   CODE:
 {
   Runops_Trace_clear_perl_hook(aTHX);
@@ -428,6 +495,7 @@
 
 void
 ignore_hook_ret()
+  PROTOTYPE:
   CODE:
 {
   Runops_Trace_perl_ignore_ret = 1;
@@ -435,6 +503,7 @@
 
 void
 unignore_hook_ret()
+  PROTOTYPE:
   CODE:
 {
   Runops_Trace_perl_ignore_ret = 0;
@@ -467,3 +536,51 @@
   CODE:
     Runops_Trace_disable();
 
+void
+mask_op_type (unsigned op_type)
+  PROTOTYPE: $
+  CODE:
+{
+  Runops_Trace_mask_op_type(op_type);
+}
+
+void
+unmask_op_type (unsigned op_type)
+  PROTOTYPE: $
+  CODE:
+{
+  Runops_Trace_unmask_op_type(op_type);
+}
+
+void
+mask_all ()
+  PROTOTYPE:
+  CODE:
+{
+  Runops_Trace_mask_all();
+}
+
+void
+unmask_all ()
+  PROTOTYPE:
+  CODE:
+{
+  Runops_Trace_mask_none();
+}
+
+void
+mask_none ()
+  PROTOTYPE:
+  CODE:
+{
+  Runops_Trace_mask_none();
+}
+
+
+void
+clear_mask()
+  PROTOTYPE:
+  CODE:
+{
+  Runops_Trace_clear_op_mask();
+}

Modified: Runops-Trace/trunk/lib/Runops/Trace.pm
==============================================================================
--- Runops-Trace/trunk/lib/Runops/Trace.pm	(original)
+++ Runops-Trace/trunk/lib/Runops/Trace.pm	Sat May 10 11:34:36 2008
@@ -1,9 +1,12 @@
 package Runops::Trace;
 
+# vim:shiftwidth=4
+
 use strict;
 use warnings;
-use Digest::MD5 ();
-use File::Spec  ();
+use Digest::MD5  ();
+use File::Spec   ();
+use Scalar::Util ();
 
 our $VERSION = '0.09';
 
@@ -12,11 +15,11 @@
 Runops::Trace->bootstrap($VERSION);
 
 our @EXPORT_OK = qw(
-  trace_code checksum_code_path trace
+    trace_code checksum_code_path trace
 
-  set_tracer get_tracer clear_tracer enable_tracing disable_tracing tracing_enabled
+    set_tracer get_tracer clear_tracer enable_tracing disable_tracing tracing_enabled
 
-  set_trace_threshold get_trace_threshold get_op_counters
+    set_trace_threshold get_trace_threshold get_op_counters
 );
 
 our %EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
@@ -51,6 +54,27 @@
     return;
 }
 
+sub unmask_op {
+    unmask_op_type( _whatever_to_op_type(shift) );
+}
+
+sub mask_op {
+    mask_op_type( _whatever_to_op_type(shift) );
+}
+
+sub _whatever_to_op_type {
+    my $thingy = shift;
+
+    if ( ref $thingy ) {
+        return $thingy->type;
+    } elsif ( Scalar::Util::looks_like_number($thingy) ) {
+        return $thingy;
+    } else {
+        require B;
+        return B::opnumber($thingy);
+    }
+}
+
 1;
 
 __END__
@@ -129,6 +153,12 @@
 
 C<trace> uses this.
 
+The code reference will be called once per op. The first argument is the
+L<B::OP> object for C<PL_op>. The second argument is the operator's arity. This
+might later be changed if arity methods are included in L<B::OP> itself. The
+remaining arguments are the arguments for the operator taken from the stack,
+depending on the operator arity.
+
 =item CODEREF = get_tracer()
 
 Get the tracing sub (if any).
@@ -161,6 +191,28 @@
 
 This is useful for when you only want to trace a certain hot path.
 
+=item mask_all()
+
+Disable tracing of all ops.
+
+=item mask_none()
+
+=item unmask_all()
+
+Enable tracing of all ops.
+
+=item mask_op( OPTYPE )
+
+=item unmask_op( OPTYPE )
+
+Change the masking of a specific op.
+
+Takes a L<B::OP> object, an op type, or an op name.
+
+=item clear_mask()
+
+Like C<mask_none> was called, but removes the mask entirely.
+
 =back
 
 =head1 PERL HACKS COMPATIBILITY


More information about the Jifty-commit mailing list