From: Justin Seyster Date: Thu, 9 Sep 2010 00:18:56 +0000 (-0400) Subject: Added noinstrument attribute (with test case). X-Git-Tag: release-v1.0~43 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=6844760bf365fb7f2874a712102bf6bf998cb802;p=interaspect.git Added noinstrument attribute (with test case). --- diff --git a/src/aop-main.c b/src/aop-main.c index 95b21ce..89210f8 100644 --- a/src/aop-main.c +++ b/src/aop-main.c @@ -59,6 +59,8 @@ //#define PAUSE_ON_START +#define NOINSTR_ATTR "noinstrument" + static const char *aop_plugin_name; static const struct plugin_argument *plugin_argv; @@ -155,6 +157,51 @@ aop_join_on_copy (struct aop_pointcut *pc, int copy, join_callback callback, } } +/* This is the "gate" function for all client plug-in passes that gets + to decide whether the pass will execute or not.*/ +static bool +noinstrument_gate () +{ + /* Execute the pass iff the current function is not annotated with + the noinstrument attribute. */ + return (lookup_attribute (NOINSTR_ATTR, DECL_ATTRIBUTES (cfun->decl)) + == NULL); +} + +/* Register an attribute only if it has not yet been registered. If + the user loads multiple InterAspect plug-ins, they will all try to + register the noinstrument attribute. We have to make sure we don't + attempt to call GCC's register_attribute multiple times, or it will + throw an assertion failure! */ +static void +register_attribute_once(const struct attribute_spec *attr) +{ + if (lookup_attribute_spec (get_identifier (attr->name)) == NULL) + register_attribute (attr); +} + +static tree +null_attrib_handler(tree *node, tree name, tree args, int flags, bool *no_add_attrs) +{ + return NULL_TREE; +} + +static struct attribute_spec noinstr_attr = { + .name = NOINSTR_ATTR, + .min_length = 0, + .max_length = 0, + .decl_required = false, + .type_required = false, + .function_type_required = false, + .handler = null_attrib_handler, +}; + +static void +register_plugin_attributes(void *event_data, void *data) +{ + register_attribute_once(&noinstr_attr); +} + /* This pass gets called before any passes that the client plug-in registers. It's here for any administrative details that need to take place before the instrumentation passes can execute. */ @@ -288,6 +335,7 @@ aop_register_pass (const char *pass_name, pass_callback callback) pass_aop->name = xstrdup (pass_name); pass_aop->execute = callback; + pass_aop->gate = noinstrument_gate; pass_info.pass = pass_aop; pass_info.reference_pass_name = "veclower"; @@ -364,6 +412,9 @@ plugin_init (struct plugin_name_args *plugin_info, init_type_table (); init_prototype_table (); + /* Register attributes. */ + register_callback(aop_plugin_name, PLUGIN_ATTRIBUTES, register_plugin_attributes, NULL); + /* Register our cleanup function. */ register_callback (aop_plugin_name, PLUGIN_FINISH, aop_cleanup, NULL); diff --git a/test/Makefile.am b/test/Makefile.am index 11005db..8add357 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -3,5 +3,5 @@ TESTS_ENVIRONMENT = $(PYTHON) $(srcdir)/run-testcase.py --with-gcc=$(CC) \ --with-ia-lib-dir=$(top_builddir)/src/.libs \ --with-ia-src-dir=$(top_srcdir) --with-tests-dir=$(srcdir) TESTS = int-types.xml float-types.xml pointer-types.xml struct-types.xml \ - reinst.xml + reinst.xml noinstrument.xml endif diff --git a/test/noinstrument-hooks.c b/test/noinstrument-hooks.c new file mode 100644 index 0000000..c7a0ea6 --- /dev/null +++ b/test/noinstrument-hooks.c @@ -0,0 +1,6 @@ +#include + +void _advice_foo() +{ + printf("In foo() advice.\n"); +} diff --git a/test/noinstrument-target.c b/test/noinstrument-target.c new file mode 100644 index 0000000..b7d0eef --- /dev/null +++ b/test/noinstrument-target.c @@ -0,0 +1,23 @@ +#include + +void foo() +{ + printf("Call to foo().\n"); +} + +void instrumented() +{ + foo(); +} + +__attribute__((noinstrument)) void uninsrumented() +{ + foo(); +} + +int run_test() +{ + instrumented(); + uninsrumented(); + return 0; +} diff --git a/test/noinstrument.xml b/test/noinstrument.xml new file mode 100644 index 0000000..85202a2 --- /dev/null +++ b/test/noinstrument.xml @@ -0,0 +1,13 @@ + + + + + + + + In foo() advice. + Call to foo(). + Call to foo(). + + + diff --git a/test/plugin-noinstrument.c b/test/plugin-noinstrument.c new file mode 100644 index 0000000..4c281b3 --- /dev/null +++ b/test/plugin-noinstrument.c @@ -0,0 +1,26 @@ +#include +#include +#include + +AOP_I_AM_GPL_COMPATIBLE(); + +static void plugin_join_on_foo(struct aop_joinpoint *jp, void *data) +{ + aop_insert_advice(jp, "_advice_foo", AOP_INSERT_BEFORE, AOP_TERM_ARG); +} + +static unsigned int plugin_noinstr() +{ + struct aop_pointcut *pc; + + pc = aop_match_function_call(); + aop_filter_call_pc_by_name (pc, "foo"); + aop_join_on(pc, plugin_join_on_foo, NULL); + + return 0; +} + +AOP_MAIN_PROTO aop_main() +{ + aop_register_pass("noinstr", plugin_noinstr); +}