From: Justin Seyster Date: Thu, 23 Sep 2010 22:28:26 +0000 (-0400) Subject: Added in_param filtering to all pointcuts. X-Git-Tag: release-v1.0~40^2~2 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=43f0e90dbf0df11a4294562846e1b0ec6b5f84b7;p=interaspect.git Added in_param filtering to all pointcuts. --- diff --git a/src/aop-main.c b/src/aop-main.c index 89210f8..c69fb0c 100644 --- a/src/aop-main.c +++ b/src/aop-main.c @@ -109,6 +109,11 @@ aop_join_on (struct aop_pointcut *pc, join_callback callback, { aop_assert (pc != NULL && pc->join_on != NULL); + /* Filtering on in_params is universal across a function. Either + every join point in the function match or none do.*/ + if (!check_in_params (pc)) + return; + pc->join_on (pc, callback, callback_param); /* Call regimplification only if the pointcut needs it */ @@ -148,6 +153,11 @@ aop_join_on_copy (struct aop_pointcut *pc, int copy, join_callback callback, fatal_error ("(InterAspect) Attempt to use aop_join_on_copy() to join on a" " function that was not duplicated."); + /* Filtering on in_params is universal across a function. Either + every join point in the function match or none do.*/ + if (!check_in_params (pc)) + return; + pc->join_on_copy (pc, copy, callback, callback_param); /* Call regimplification only if the pointcut needs it */ diff --git a/src/aop-pc-entry.c b/src/aop-pc-entry.c index 49157fc..2fa9bad 100644 --- a/src/aop-pc-entry.c +++ b/src/aop-pc-entry.c @@ -87,7 +87,6 @@ is_function_entry_matching (struct aop_pointcut *pc) IDENTIFIER_POINTER (DECL_NAME (current_function_decl)); return (strcmp (func_name, pc->pc_entry.function_name) == 0); } - return check_in_params (pc); } /* We represent the function's entry as a control-flow graph edge. @@ -212,54 +211,6 @@ void aop_filter_entry_by_name(struct aop_pointcut *pc_function_entry, pc_function_entry->pc_entry.function_name = advice_function_entry; } -/** - * Filter a function entry pointcut to only include function entries - * with a parameter that matches a specified type. This filter removes join - * points when parameter n does not match type or when there is no - * parameter n. - * - * Filters on the same parameter do not stack on top of each other. - * If multiple parameter filters with the same n are applied a - * pointcut, only the last one will have any effect. - * - * Note that you must filter a parameter by its type in order to - * capture it with aop_capture_in_param(). - * \param pc The function call pointcut to filter. Function entry - * pointcuts are created with aop_match_function_entry(). - * \param n The index of the parameter to filter on. Parameters are - * indexed from zero. - * \param The parameter type to filter by. - */ -void -aop_filter_entry_by_in_param (struct aop_pointcut *pc, int n, - const struct aop_type *type) -{ - struct aop_param_desc *param = NULL; - struct aop_param_desc *iter; - - /* Is there already a filter for this parameter? */ - for (iter = pc->in_param_list_head ; iter != NULL ; iter = iter->next) - { - if (iter->param_index == n) - { - param = iter; - break; - } - } - - /* No? Then create one and add it to the list. */ - if (param == NULL) - { - param = ggc_alloc (sizeof (struct aop_param_desc)); - - param->next = pc->in_param_list_head; - pc->in_param_list_head = param; - } - - param->param_index = n; - param->type = type; -} - /* Close Doxygen defgroup block. */ /** * \} diff --git a/src/aop-pointcut.c b/src/aop-pointcut.c index ea4cfbc..c4f23e1 100644 --- a/src/aop-pointcut.c +++ b/src/aop-pointcut.c @@ -67,7 +67,6 @@ init_joinpoint (struct aop_joinpoint *jp, gimple_stmt_iterator *gsi, jp->file = file; jp->in_edge = NULL; jp->is_prepared = false; - } int @@ -82,6 +81,32 @@ aop_capture_file_name (struct aop_joinpoint *jp) return jp->file; } +/* Sometimes we want to capture a parameter some place that is not at + the beginning of the function. The parameter may change during the + function, so we save its value at function start to preserve it + until we need it. + + Returns the temporary variable holding the preserved parameter + value. */ +static tree +save_param(tree param) +{ + edge in_edge; + tree tmp_val; + gimple new_assign; + + aop_assert (TREE_CODE (param) == PARM_DECL); + + tmp_val = create_tmp_var (TREE_TYPE (param), "ia_preserved_param"); + new_assign = gimple_build_assign (tmp_val, stabilize_reference (param)); + + /* Insert the assignment at the very beginning of the function. */ + in_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)); + gsi_insert_on_edge_immediate (in_edge, new_assign); + + return tmp_val; +} + static tree op_get_in_param (struct aop_dynval *dv) { @@ -92,7 +117,6 @@ op_get_in_param (struct aop_dynval *dv) int index = 0; aop_assert (dv->kind == ADV_FUN_PARAM); - aop_assert (jp->pc->kind == ATP_ENTRY); stmt = jp->stmt; @@ -101,8 +125,7 @@ op_get_in_param (struct aop_dynval *dv) { if (index == dv->dynval_in_param.param_index) { - param = param_iter; - param = stabilize_reference (param); + param = save_param (param_iter); break; } index++; @@ -132,9 +155,6 @@ aop_capture_in_param (struct aop_joinpoint *jp, int n) struct aop_param_desc *param; pc = jp->pc; - if (pc->kind != ATP_ENTRY) - fatal_error ("(InterAspect) Attempt to capture parameter from an" - " unsupported join point."); /* Search for an aop_param_desc for this parameter, so that we know its type. */ @@ -197,3 +217,52 @@ check_in_params (struct aop_pointcut *pc) return true; } + +/** + * Filter a function entry pointcut to only include function entries + * with a parameter that matches a specified type. This filter removes join + * points when parameter n does not match type or when there is no + * parameter n. + * + * Filters on the same parameter do not stack on top of each other. + * If multiple parameter filters with the same n are applied a + * pointcut, only the last one will have any effect. + * + * Note that you must filter a parameter by its type in order to + * capture it with aop_capture_in_param(). + * \param pc The function call pointcut to filter. Function entry + * pointcuts are created with aop_match_function_entry(). + * \param n The index of the parameter to filter on. Parameters are + * indexed from zero. + * \param The parameter type to filter by. + */ +void +aop_filter_by_in_param (struct aop_pointcut *pc, int n, + const struct aop_type *type) +{ + struct aop_param_desc *param = NULL; + struct aop_param_desc *iter; + + /* Is there already a filter for this parameter? */ + for (iter = pc->in_param_list_head ; iter != NULL ; iter = iter->next) + { + if (iter->param_index == n) + { + param = iter; + break; + } + } + + /* No? Then create one and add it to the list. */ + if (param == NULL) + { + param = ggc_alloc (sizeof (struct aop_param_desc)); + + param->next = pc->in_param_list_head; + pc->in_param_list_head = param; + } + + param->param_index = n; + param->type = type; +} + diff --git a/src/aop.h b/src/aop.h index 2e5393d..b59b76b 100644 --- a/src/aop.h +++ b/src/aop.h @@ -254,8 +254,8 @@ enum aop_argkind { extern const char *aop_capture_function_name (struct aop_joinpoint *jp); extern struct aop_pointcut *aop_match_function_entry (); -extern void aop_filter_entry_by_in_param (struct aop_pointcut *pc, int n, - const struct aop_type *type); +extern void aop_filter_by_in_param (struct aop_pointcut *pc, int n, + const struct aop_type *type); extern struct aop_dynval *aop_capture_in_param (struct aop_joinpoint *jp, int param_index); diff --git a/test/plugin-inparam.c b/test/plugin-inparam.c index bb08381..0d83cf5 100644 --- a/test/plugin-inparam.c +++ b/test/plugin-inparam.c @@ -21,8 +21,8 @@ static unsigned int plugin_int() pc = aop_match_function_entry(); aop_filter_entry_by_name(pc, "foo"); - aop_filter_entry_by_in_param(pc, 0, aop_t_all_signed()); - aop_filter_entry_by_in_param(pc, 1, aop_t_all_fp()); + aop_filter_by_in_param(pc, 0, aop_t_all_signed()); + aop_filter_by_in_param(pc, 1, aop_t_all_fp()); aop_join_on(pc, plugin_join_on_call, "_advice_foo"); return 0;