From: Justin Seyster Date: Fri, 18 Jun 2010 02:10:49 +0000 (-0400) Subject: Cleaned up function entry pointcut. X-Git-Tag: release-v1.0~99 X-Git-Url: https://git.fsl.cs.stonybrook.edu/?a=commitdiff_plain;h=9dbd2efd7cf6b1fe7a22be88a871ed1b200b7321;p=interaspect.git Cleaned up function entry pointcut. Fixed bug because of uninitialized function_name field in the pointcut. Added a prepare function that guards against the case of adding to a function that begins with a label. Renamed the filter by name function. --- diff --git a/src/aop-pc-entry.c b/src/aop-pc-entry.c index b24bd02..6129435 100644 --- a/src/aop-pc-entry.c +++ b/src/aop-pc-entry.c @@ -41,9 +41,12 @@ static void op_join_on_function_entry (struct aop_pointcut *pc, join_callback cb, void *callback_param) { - basic_block bb; + struct aop_joinpoint jp; + gimple_stmt_iterator gsi; + aop_assert (pc->kind == ATP_ENTRY); + /* Filter this pointcut by function name if necessary. */ if(pc->pc_entry.function_name != NULL) { const char *func_name = @@ -52,20 +55,56 @@ op_join_on_function_entry (struct aop_pointcut *pc, join_callback cb, return; } - FOR_EACH_BB(bb) - { - gimple_stmt_iterator gsi; + /* Note that the gimple iterator gets initialized by + op_prepare_entry when it is time to insert advice. (We poison it + just to make sure that initialization is getting called.)*/ + memset (&gsi, 0xfa, sizeof (gimple_stmt_iterator)); + + jp.pc = pc; + jp.gsi = &gsi; + jp.is_prepared = false; + cb (&jp, callback_param); +} - for (gsi = gsi_start_bb (bb) ; !gsi_end_p (gsi) ; gsi_next (&gsi)) +/* There is no GIMPLE statement that is suitable as an anchor point + for inserting advice at the beginning of a function. + + The first GIMPLE statement in the function is no good because it + may be a label statement at the beginning of a basic block. + Inserting a statement before a label would cause a label in the + middle of a basic block, which is a no-no. + + We use the gsi_insert_on_edge_immediate() function to add a NOP + statement that is definitely legal. It serves as an anchor point + for inserting before and after advice! */ +static void +op_prepare_entry (struct aop_joinpoint *jp) +{ + gimple nop; + basic_block bb; + edge in_edge; + + aop_assert (jp->pc->kind = ATP_ENTRY); + + nop = gimple_build_nop (); + + in_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FUNCTION(cfun)); + gsi_insert_on_edge_immediate (in_edge, nop); + + /* Find an iterator pointing to the nop. */ + FOR_EACH_BB (bb) + { + for (*jp->gsi = gsi_start_bb (bb); + !gsi_end_p (*jp->gsi); + gsi_next (jp->gsi)) { - struct aop_joinpoint jp; - jp.pc = pc; - jp.gsi = &gsi; - jp.is_prepared = false; - cb (&jp, callback_param); - return; + if (gsi_stmt (*jp->gsi) == nop) + return; /* Found! */ } } + + /* We failed to found the statement we just inserted! */ + aop_assert (0); } struct aop_pointcut * @@ -76,12 +115,15 @@ aop_match_function_entry () pc->kind = ATP_ENTRY; pc->join_on = op_join_on_function_entry; pc->insert_before = op_default_insert_before; - pc->prepare_for_weave = op_default_prepare_for_weave; + pc->insert_after = op_default_insert_after; + pc->prepare_for_weave = op_prepare_entry; + + pc->pc_entry.function_name = NULL; return pc; } -void aop_filter_function_entry_pointcut(struct aop_pointcut *pc_function_entry, - const char *advice_function_entry) +void aop_filter_entry_by_name(struct aop_pointcut *pc_function_entry, + const char *advice_function_entry) { pc_function_entry->pc_entry.function_name = advice_function_entry; } diff --git a/src/aop.h b/src/aop.h index 8bc0b09..62692c1 100644 --- a/src/aop.h +++ b/src/aop.h @@ -96,8 +96,8 @@ extern const char *aop_capture_function_name (struct aop_joinpoint *jp); extern struct aop_pointcut *aop_match_function_entry (); extern struct aop_pointcut *aop_match_function_exit (); -extern void aop_filter_function_entry_pointcut( - struct aop_pointcut *pc_function_entry, const char *advice_function_entry); +extern void aop_filter_entry_by_name(struct aop_pointcut *pc_function_entry, + const char *advice_function_entry); extern struct aop_pointcut *aop_match_function_call ();