From: Ketan Dixit Date: Wed, 24 Mar 2010 00:43:33 +0000 (-0400) Subject: Added function entry/exit pointcuts and support for one step method to define pointcu... X-Git-Tag: release-v1.0~118^2 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=dc2dd50a4a6531a54a71dca2f55a7cec26261a75;p=interaspect.git Added function entry/exit pointcuts and support for one step method to define pointcut and advice --- diff --git a/src/Makefile.am b/src/Makefile.am index 3555dbe..1d5a579 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ lib_LTLIBRARIES = libinteraspect.la -libinteraspect_la_SOURCES = aop-pc-assign.c aop-main.c aop-type.c aop-weave.c +libinteraspect_la_SOURCES = aop-pc-assign.c aop-main.c aop-type.c aop-weave.c aop-pc-entry.c aop-pc-exit.c libinteraspect_la_CFLAGS = -Wall -Werror -fvisibility=hidden -prefer-pic libinteraspect_la_LDFLAGS = -static -prefer-pic -version-info 1:0:0 libinteraspect_la_CPPFLAGS = -DHAVE_CONFIG_H -DIN_GCC -I$(gcc_includes) diff --git a/src/aop-main.c b/src/aop-main.c index eb79f19..d59b422 100644 --- a/src/aop-main.c +++ b/src/aop-main.c @@ -54,11 +54,12 @@ static const char *aop_plugin_name; void -aop_join_on (struct aop_pointcut *pc, join_callback callback) +aop_join_on (struct aop_pointcut *pc, join_callback callback, + void *callback_param) { aop_assert (pc != NULL && pc->join_on != NULL); - pc->join_on (pc, callback); + pc->join_on (pc, callback, callback_param); } /* Store a list of all struct opt_pass objects we create so that we @@ -130,7 +131,7 @@ cleanup_passes () static void aop_cleanup (void *event_date, void *data) { - cleanup_passes(); + cleanup_passes (); } /* GCC calls this to initialize a plug-in. Once InterAspect @@ -166,3 +167,9 @@ aop_abort (const char *filename, int lineno, const char *function) fprintf (stderr, "Assertion failure within InterAspect plug-in:\n"); fancy_abort(filename, lineno, function); } + +const char * +aop_capture_function_name (struct aop_joinpoint *jp) +{ + return IDENTIFIER_POINTER (DECL_NAME (current_function_decl)); +} diff --git a/src/aop-pc-assign.c b/src/aop-pc-assign.c index 6e9a25b..c816172 100644 --- a/src/aop-pc-assign.c +++ b/src/aop-pc-assign.c @@ -78,7 +78,8 @@ stmt_matches_pointcut (struct aop_pointcut *pc, gimple stmt) } static void -op_join_on_assign (struct aop_pointcut *pc, join_callback cb) +op_join_on_assign (struct aop_pointcut *pc, join_callback cb, + void *callback_param) { basic_block bb; @@ -98,7 +99,7 @@ op_join_on_assign (struct aop_pointcut *pc, join_callback cb) jp.pc = pc; jp.gsi = &gsi; - cb (&jp); + cb (&jp, callback_param); } } } diff --git a/src/aop-pc-entry.c b/src/aop-pc-entry.c new file mode 100644 index 0000000..995536b --- /dev/null +++ b/src/aop-pc-entry.c @@ -0,0 +1,70 @@ +/* This program is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* Whether we want them or not (we don't), Autoconf _insists_ on + defining these. Since GCC's config.h (which we must include) also + defines them, we have to undef them here. */ +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aop.h" +#include "aop-pointcut.h" +#include "aop-type.h" + + +static void +op_join_on_function_entry (struct aop_pointcut *pc, join_callback cb, + void *callback_param) +{ + basic_block bb; + aop_assert (pc->kind == ATP_ENTRY); + + FOR_EACH_BB(bb) + { + gimple_stmt_iterator gsi; + + for (gsi = gsi_start_bb (bb) ; !gsi_end_p (gsi) ; gsi_next (&gsi)) + { + struct aop_joinpoint jp; + jp.pc = pc; + jp.gsi = &gsi; + cb (&jp, callback_param); + return; + } + } +} + +struct aop_pointcut * +aop_match_function_entry () +{ + struct aop_pointcut *pc; + + pc = ggc_alloc (sizeof (struct aop_pointcut *)); + pc->kind = ATP_ENTRY; + pc->join_on = op_join_on_function_entry; + + return pc; +} diff --git a/src/aop-pc-exit.c b/src/aop-pc-exit.c new file mode 100644 index 0000000..54d18ec --- /dev/null +++ b/src/aop-pc-exit.c @@ -0,0 +1,75 @@ +/* This program is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* Whether we want them or not (we don't), Autoconf _insists_ on + defining these. Since GCC's config.h (which we must include) also + defines them, we have to undef them here. */ +#undef PACKAGE_BUGREPORT +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "aop.h" +#include "aop-pointcut.h" +#include "aop-type.h" + + +static void +op_join_on_function_exit (struct aop_pointcut *pc, join_callback cb, + void *callback_param) +{ + basic_block bb; + gimple stmt; + aop_assert (pc->kind == ATP_EXIT); + + FOR_EACH_BB(bb) + { + gimple_stmt_iterator gsi; + for (gsi = gsi_start_bb(bb) ; !gsi_end_p(gsi) ; gsi_next(&gsi)) + { + stmt = gsi_stmt (gsi); + + if (gimple_code (stmt) == GIMPLE_RETURN) + { + struct aop_joinpoint jp; + jp.pc = pc; + jp.gsi = &gsi; + cb (&jp, callback_param); + } + } + } +} + +struct aop_pointcut * +aop_match_function_exit () +{ + struct aop_pointcut *pc; + + pc = ggc_alloc (sizeof (struct aop_pointcut *)); + pc->kind = ATP_EXIT; + pc->join_on = op_join_on_function_exit; + + return pc; +} diff --git a/src/aop-pointcut.h b/src/aop-pointcut.h index fae1b39..3982c8f 100644 --- a/src/aop-pointcut.h +++ b/src/aop-pointcut.h @@ -22,6 +22,8 @@ struct aop_type; enum aop_pckind { ATP_ASSIGN, + ATP_ENTRY, + ATP_EXIT, }; struct aop_pc_assign { @@ -37,7 +39,7 @@ struct aop_pc_assign { struct aop_pointcut { enum aop_pckind kind; - void (*join_on) (struct aop_pointcut *, join_callback); + void (*join_on) (struct aop_pointcut *, join_callback, void *); union { struct aop_pc_assign pc_assign; diff --git a/src/aop.h b/src/aop.h index 33a2f56..79389c2 100644 --- a/src/aop.h +++ b/src/aop.h @@ -52,7 +52,7 @@ struct aop_pointcut; struct aop_type; typedef unsigned int (*pass_callback) (); -typedef void (*join_callback) (struct aop_joinpoint *); +typedef void (*join_callback) (struct aop_joinpoint *, void *callback_param); extern struct aop_pointcut *aop_match_assignment_by_type (struct aop_type *type); @@ -61,7 +61,8 @@ extern const char *aop_capture_lhs_name (struct aop_joinpoint *jp); extern void aop_do_weave (struct aop_joinpoint *jp, const char *name, ...); extern void aop_register_pass (const char *pass_name, pass_callback callback); -extern void aop_join_on (struct aop_pointcut *pc, join_callback callback); +extern void aop_join_on (struct aop_pointcut *pc, join_callback callback, + void *callback_param); extern void aop_main (); extern void aop_abort (const char *filename, int lineno, const char *function) @@ -79,4 +80,9 @@ enum aop_argkind { #define AOP_STR_CST(VAL) ATA_STR_CST, VAL #define AOP_DYNVAL(VAL) ATA_DYNVAL, VAL + +const char *aop_capture_function_name (struct aop_joinpoint *jp); +struct aop_pointcut *aop_match_function_entry (); +struct aop_pointcut *aop_match_function_exit (); + #endif