Updates test case.
struct tracecut {
int num_params;
int num_symbols;
+ int num_rules;
const char **symbol_names;
+ const char **rules;
struct tuple *tuple_list;
};
}
ADVICE_FUNC void
-_tc_new_tracecut (int tc_index, int num_params, int num_symbols)
+_tc_new_tracecut (int tc_index, int num_params, int num_symbols, int num_rules)
{
struct tracecut *tc;
tc->num_params = num_params;
tc->num_symbols = num_symbols;
+ tc->num_rules = num_rules;
if (tc->num_symbols > 0)
{
}
ADVICE_FUNC void
-_tc_compile_tracecut (int tc_index)
+_tc_compile_rule (int tc_index, int rule_index, const char *specification)
{
struct tracecut *tc;
struct tc_call_symbol *next;
};
+struct tc_rule {
+ const char *specification;
+ struct tc_rule *next;
+};
+
struct tc_tracecut {
int index;
struct tc_param *param_list;
struct tc_call_symbol *symbol_list;
+ struct tc_rule *rule_list;
/* Each param gets a unique index. */
int next_param_index;
return add_call_symbol_binding (tc, param_name, symbol_name, -1);
}
+/**
+ * Add a rule to a tracecut, specified as a regular expression. A
+ * tracecut regular expression can include any of the tracecut's
+ * symbols (expressed with <code>symbol_name</code> strings) combined
+ * with the standard <code>|</code>, <code>*</code>, <code>+</code>,
+ * and <code>?</code> operators and parenthesis for grouping.
+ * \param tc The tracecut to add the rule to.
+ * \param #TC_SUCCESS or
+ * - #TC_BAD_CONTEXT, when called after compilation has already
+ * started;
+ * - #TC_NOMEM, if memory runs out.
+ */
+enum tc_error
+tc_add_rule (struct tc_tracecut *tc, const char *specification)
+{
+ struct tc_rule *rule;
+
+ if (tc_in_compilation)
+ return TC_BAD_CONTEXT;
+
+ rule = (struct tc_rule *)malloc (sizeof (struct tc_rule));
+ if (rule == NULL)
+ return TC_NOMEM;
+
+ /* TODO: Check syntax*/
+ rule->specification = strdup (specification);
+ if (rule->specification == NULL)
+ {
+ free (rule);
+ return TC_NOMEM;
+ }
+
+ /* Add this to the tracecut's list of rules. */
+ rule->next = tc->rule_list;
+ tc->rule_list = rule;
+
+ return TC_SUCCESS;
+}
+
/**
* Create an empty tc_tracecut object. The caller is responsible for
* freeing the object using tc_free_tracecut(). (Do not use the
tc->next_symbol_index = 0;
tc->param_list = NULL;
tc->symbol_list = NULL;
+ tc->rule_list = NULL;
/* Insert this tracecut into the master list. */
tc->next = tracecut_list;
/* Return the number of tracecuts in the master tracecut list. */
static int
-get_num_tracecuts()
+get_num_tracecuts ()
{
struct tc_tracecut *tc;
int num_tracecuts = 0;
return num_tracecuts;
}
+/* Return the number of rules in a tracecut. */
+static int
+get_num_rules (struct tc_tracecut *tc)
+{
+ int num_rules = 0;
+ struct tc_rule *rule;
+
+ for (rule = tc->rule_list; rule != NULL; rule = rule->next)
+ num_rules++;
+
+ return num_rules;
+}
+
void
tc_insert_tracecut_init_advice (struct aop_joinpoint *jp)
{
for (tc = tracecut_list; tc != NULL; tc = tc->next)
{
+ int i;
struct tc_call_symbol *symbol;
- int num_params, num_symbols;
+ struct tc_rule *rule;
+ int num_params, num_symbols, num_rules;
- /* _tc_new_tracecut(tc_index, num_params, num_symbols); */
+ /* _tc_new_tracecut(tc_index, num_params, num_symbols, num_rules); */
num_params = tc->next_param_index;
num_symbols = tc->next_symbol_index;
+ num_rules = get_num_rules (tc);
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);
+ AOP_INT_CST (num_symbols), AOP_INT_CST(num_rules),
+ AOP_TERM_ARG);
for (symbol = tc->symbol_list; symbol != NULL; symbol = symbol->next)
{
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);
+ for (rule = tc->rule_list, i = 0; rule != NULL; rule = rule->next, i++)
+ {
+ /* _tc_compile_rule(tc_index, rule_index, specification) */
+ aop_insert_advice (jp, "_tc_compile_rule", AOP_INSERT_BEFORE,
+ AOP_INT_CST (tc->index), AOP_INT_CST(i),
+ AOP_STR_CST(rule->specification), AOP_TERM_ARG);
+ }
}
}
const char *func_name,
enum aop_insert_location location);
-enum tc_error tc_bind_to_call_param (struct tc_tracecut *tc,
- const char *param_name,
- const char *symbol_name,
- int call_param_index);
-enum tc_error tc_bind_to_return_value (struct tc_tracecut *tc,
- const char *param_name,
- const char *symbol_name);
+extern enum tc_error tc_bind_to_call_param (struct tc_tracecut *tc,
+ const char *param_name,
+ const char *symbol_name,
+ int call_param_index);
+extern enum tc_error tc_bind_to_return_value (struct tc_tracecut *tc,
+ const char *param_name,
+ const char *symbol_name);
+
+extern enum tc_error tc_add_rule (struct tc_tracecut *tc,
+ const char *specification);
extern struct tc_tracecut *tc_create_tracecut (void);
extern void tc_free_tracecut (struct tc_tracecut *tc);
tc_add_call_symbol(tc_foo, "dec", "dec_foo", AOP_INSERT_AFTER);
tc_bind_to_call_param(tc_foo, "foo", "dec", 0);
+ tc_add_rule(tc_foo, "get inc* dec");
+
/* Tracecut for bar objects. */
tc_bar = tc_create_tracecut();
tc_add_call_symbol(tc_bar, "half", "half_bar", AOP_INSERT_AFTER);
tc_bind_to_call_param(tc_bar, "bar", "half", 0);
+ tc_add_rule(tc_bar, "get double* half");
+
/* Tracecut for both objects. */
tc_both = tc_create_tracecut();
tc_bind_to_call_param(tc_both, "foo", "transfer", 0);
tc_bind_to_call_param(tc_both, "bar", "transfer", 1);
+ tc_add_rule(tc_both, "transfer transfer");
+
aop_register_pass("init_tracecut", init_pass);
tc_register_tracecut_pass();
}
printf("Name symbol -- tc: %d, symbol: %d, name: %s\n", tc, symbol_index, symbol_name);
}
-void _tc_compile_tracecut(int tc)
+void _tc_compile_rule(int tc, int rule_index, const char *specification)
{
- printf("Compile -- tc: %d\n", tc);
+ printf("Compile -- tc: %d, %d, %s\n", tc, rule_index, specification);
}
void _tc_event_begin(int tc)
Init -- n: 3
New tracecut -- tc: 0, params: 2, symbols: 2
Name symbol -- tc: 0, symbol: 0, name: transfer
- Compile -- tc: 0
+ Compile -- tc: 0, 0, transfer transfer
New tracecut -- tc: 1, params: 1, symbols: 1
Name symbol -- tc: 1, symbol: 2, name: half
Name symbol -- tc: 1, symbol: 1, name: double
Name symbol -- tc: 1, symbol: 0, name: get
- Compile -- tc: 1
+ Compile -- tc: 1, 0, get double* half
New tracecut -- tc: 2, params: 1, symbols: 1
Name symbol -- tc: 2, symbol: 2, name: dec
Name symbol -- tc: 2, symbol: 1, name: inc
Name symbol -- tc: 2, symbol: 0, name: get
- Compile -- tc: 2
+ Compile -- tc: 2, 0, get inc* dec
Beginning event -- tc: 2
Param -- tc: 2, symbol: 0, param: 0, value: 0x8
Transition event -- tc: 2, symbol: 0