Adds API for inserting initialization instrumentation.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Wed, 9 Feb 2011 22:20:55 +0000 (17:20 -0500)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Wed, 9 Feb 2011 22:20:55 +0000 (17:20 -0500)
src/tracecut.c
src/tracecut.h

index 1c44509a318fb2cb071a4c412def5f253b2f3761..2c44f6ebdb75c094f9807497012951f005d49915 100644 (file)
@@ -104,6 +104,32 @@ static struct tc_tracecut *tracecut_list = NULL;
    illegal to modify any existing tracecut objects. */
 static int tc_in_compilation = 0;
 
+/* Go through the master list of tracecuts and give each a consecutive
+   index. */
+static void
+assign_tracecut_indices ()
+{
+  int next_tracecut_index = 0;
+  struct tc_tracecut *tc;
+
+  for (tc = tracecut_list; tc != NULL; tc = tc->next)
+    tc->index = next_tracecut_index++;
+}
+
+/* Choose an index for every tracecut object.  After that, tracecut
+   objects are frozen because setting tc_in_compilation to true makes
+   it illegal to modify them. */
+static void
+freeze_tracecuts (void)
+{
+  if (!tc_in_compilation)
+    {
+      assign_tracecut_indices ();
+      tc_in_compilation = 1;
+    }
+
+}
+
 static struct tc_param *
 lookup_param (struct tc_tracecut *tc, const char *name)
 {
@@ -401,18 +427,6 @@ tc_free_tracecut (struct tc_tracecut *tc)
   free(tc);
 }
 
-/* Go through the master list of tracecuts and give each a consecutive
-   index. */
-static void
-assign_tracecut_indices ()
-{
-  int next_tracecut_index = 0;
-  struct tc_tracecut *tc;
-
-  for (tc = tracecut_list; tc != NULL; tc = tc->next)
-    tc->index = next_tracecut_index++;
-}
-
 /* Add an advice call to the tracecut runtime notifying it that an
    event occurred and that _tc_capture_*_param() calls will follow
    to specify the event's params. */
@@ -540,19 +554,69 @@ add_instrumentation_for_tracecut (struct tc_tracecut *tc)
     }
 }
 
-static unsigned int
-tracecut_pass (void)
+/* Return the number of tracecuts in the master tracecut list. */
+static int
+get_num_tracecuts()
 {
   struct tc_tracecut *tc;
+  int num_tracecuts = 0;
 
-  if (!tc_in_compilation)
+  for (tc = tracecut_list; tc != NULL; tc = tc->next)
+    num_tracecuts++;
+
+  return num_tracecuts;
+}
+
+void
+tc_insert_tracecut_init_advice (struct aop_joinpoint *jp)
+{
+  int num_tracecuts;
+  struct tc_tracecut *tc;
+
+  freeze_tracecuts ();
+
+  /* If there are no tracecuts, there's nothing to initialize! */
+  num_tracecuts = get_num_tracecuts();
+  if (num_tracecuts == 0)
+    return;
+
+  /* _tc_init(num_tracecuts); */
+  aop_insert_advice (jp, "_tc_init", AOP_INSERT_BEFORE,
+                    AOP_INT_CST (num_tracecuts), AOP_TERM_ARG);
+
+  for (tc = tracecut_list; tc != NULL; tc = tc->next)
     {
-      /* Choose an index for every tracecut object.  After that,
-        tracecut objects are frozen because setting tc_in_compilation
-        to true makes it illegal to modify them. */
-      assign_tracecut_indices ();
-      tc_in_compilation = 1;
+      struct tc_call_symbol *symbol;
+      int num_params, num_symbols;
+
+      /* _tc_new_tracecut(tc_index, num_params, num_symbols); */
+      num_params = tc->next_param_index;
+      num_symbols = tc->next_symbol_index;
+      aop_insert_advice (jp, "_tc_new_tracecut", AOP_INSERT_BEFORE,
+                        AOP_INT_CST (tc->index), AOP_INT_CST (num_params),
+                        AOP_INT_CST (num_symbols), AOP_TERM_ARG);
+
+      for (symbol = tc->symbol_list; symbol != NULL; symbol = symbol->next)
+       {
+         /* _tc_name_symbol(tc_index, symbol_index, symbol_name); */
+         aop_insert_advice (jp, "_tc_name_symbol", AOP_INSERT_BEFORE,
+                            AOP_INT_CST (tc->index),
+                            AOP_INT_CST (symbol->index),
+                            AOP_STR_CST (symbol->name), AOP_TERM_ARG);
+       }
+
+      /* _tc_compile_tracecut(tc_index) */
+      aop_insert_advice (jp, "_tc_compile_tracecut", AOP_INSERT_BEFORE,
+                        AOP_INT_CST (tc->index), AOP_TERM_ARG);
     }
+}
+
+static unsigned int
+tracecut_pass (void)
+{
+  struct tc_tracecut *tc;
+
+  freeze_tracecuts ();
 
   for (tc = tracecut_list; tc != NULL; tc = tc->next)
     add_instrumentation_for_tracecut (tc);
index b9557663741887494e17c25683073e9b0aaa3918..ecaff9ae6cc2333eeabd675fece72abb6047fa93 100644 (file)
@@ -40,6 +40,7 @@
  * All tracecut functions have a <code>tc_</code> prefix.
  */
 
+struct aop_joinpoint;
 struct aop_type;
 struct tc_tracecut;
 
@@ -98,6 +99,8 @@ enum tc_error tc_bind_to_return_value (struct tc_tracecut *tc,
 extern struct tc_tracecut *tc_create_tracecut (void);
 extern void tc_free_tracecut (struct tc_tracecut *tc);
 
+extern void tc_insert_tracecut_init_advice (struct aop_joinpoint *jp);
+
 extern void tc_register_tracecut_pass (void);
 
 #endif