<aspect xmlns:src="http://www.sdml.info/srcML/src" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cpp="http://www.sdml.info/srcML/cpp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://control.ee.ethz.ch/XWeaver/AspectX" xsi:schemaLocation="http://control.ee.ethz.ch/XWeaver/AspectX ../../../../src/xsd/aspectX.xsd" name="Profiling">
        
<description>Sample aspect program to insert <i>profiling</i> instructions to the base code.
            
<i>Profiling</i> a system means collecting the information about the time spent by each operation in the system. 
            
            This sample aspect demonstrates how profiling instructions can be added to the base code.
            For each method, the time that the program spend executing the method body is computed
            and reported to the user at the end of the program execution.
                
<author>A. Pasetti, O. Rohlik</author>
                
        
</description>
        
        
<pointcut name="targetConstructor" type="src:constructor">
                
<description>Points to all constructors in the base code.</description>
        
</pointcut>
        
        
<pointcut name="targetClass" type="src:class">
                
<description>Points to all classes.</description>
        
</pointcut>

        
<pointcut name="targetClassImplementationUnit" type="src:unit">
                
<description>Points to all the units (source files) that contain implementations of the methods 
                    defined in the classes specified by the 
<code>targetClass</code> pointcut. 
        
</description>
            
<restriction type="isDefinitionOf">
                
<pointcutRef ref="targetClass" type="src:class" />
            
</restriction>                
        
</pointcut>        
        
        
<pointcut name="targetMethod" type="src:function">
                
<description>Points to all method definitions that are 
                    in the units (source files) specified by the pointcut 
                    
<code>targetClassImplementationUnit</code>.
                    Thus, it points to all 
<i>method</i> definitions (but not to 
            definitions of constructors, destructors and C functions).
                
</description>
                
<restriction type="within">
                    
<pointcutRef ref="targetClassImplementationUnit" type="src:unit" />
                
</restriction>
        
</pointcut>
    
        
<pointcut name="targetMethodReturn" type="src:return">
                
<description>Points to the return statements that must be modified. It only target the return
                    statements of 
<i>methods</i>.
                
</description>
                
<restriction type="within">
                    
<pointcutRef ref="targetMethod" type="src:function" />
                
</restriction>
        
</pointcut>
        
        
<pointcut name="targetMainFunction" type="src:function" constraint="src:name='main'">
                
<description>Points to the <code>main()</code> function.</description>
        
</pointcut>

    
<pointcut name="targetMainReturn" type="src:return">
        
<description>
            Points to return statements in the 
<code>main()</code> function.
        
</description>
        
<restriction type="within">
            
<pointcutRef ref="targetMainFunction" type="src:function" />
        
</restriction>
    
</pointcut>

    
<advice name="addProfilingVariables" type="add">
        
<description>
            Insert declarations to each class. 
            
<p />
            Set of new private member variables is added to the declaration of every class. 
            For each method one member variable is defined. Its name is derived from the name of the method.
            Member variables have form 
<code>_profiling_XXX</code> where <code>XXX</code> 
            stands for the method name. For example, the name of 
<code>_profiling_test</code> member variable 
            is derived from the name of the 
<code>test()</code> method.
            
<p />
            Two constructs of the XSL language are used to insert the variables: 
<code>xsl:for-each</code>
                        and 
<code>xsl:value-of</code>. The <code>xsl:for-each</code> instruction locates all method 
                        declarations. Then the 
<code>xsl:value-of</code> instruction is used to 
                        extract the names of the methods and to write them to the base code.
            
<p />
            The advice also inserts the declaration of the public method 
<code>_profilingReport()</code>.        
        
</description>
        
<pointcutRef ref="targetClass" type="src:class" />
        
<codeModifier type="declaration">
            
<accessModifier type="public" />
            
<text>void _profilingReport();</text>
        
</codeModifier>
        
<codeModifier type="declaration">
            
<accessModifier type="private" />
            
<text><xsl:for-each select="/src:unit/src:class//src:function_decl">long _profiling_<xsl:value-of select="src:name" />;
</xsl:for-each></text>
        
</codeModifier>
    
</advice>
                
    
<advice type="before" name="insertReporterCall">
                
<description>
                    Insert call of method 
<code>_profilingReport()</code> at the end of execution of the
                    
<code>main()</code> function. More precisely, it inserts the function call before 
                    every 
<code>return</code> statement of the <code>main()</code> function.
        
</description>
                
<pointcutRef ref="targetMainReturn" type="src:return" />
                
<codeModifier type="codeFragment">
                    
<text>sc._profilingReport();</text>
                
</codeModifier>
        
</advice>                
                        
        
<advice type="begin" name="insertVariableDeclaration">
            
<description>Insert the code that reads the current time and saves it 
                to the local variable 
<code>_profilingMethodStart</code>.
            
</description>
                
<pointcutRef ref="targetMethod" type="src:function" />
                
<codeModifier type="codeFragment">
                    
<text>long _profilingMethodStart = MicroTime::getMicroTime(); // added by aspect</text>
                
</codeModifier>
        
</advice>
                        
    
<advice type="before" name="insertBeforeReturn">
                
<description>
                    Insert code that computes the time the program spent executing the current method. It uses the current time and 
                    the value of the local variable 
<code>_profilingMethodStart</code>. The computed amount of time is added to
                    the respective member variable 
<code>_profiling_XXX</code> where XXX stands for the name of the current method.
                    This code is inserted before every return statement.
        
</description>
                
<pointcutRef ref="targetMethodReturn" type="src:return" />
                
<codeModifier type="codeFragment">
                    
<text>_profiling_${functionName} += MicroTime::getMicroTime() - _profilingMethodStart; // added by aspect</text>
                
</codeModifier>
        
</advice>

        
<advice type="end" name="insertTraceAtEnd">
                
<description>
                    Insert code that computes the time the program spent executing the current method. It uses the current time and 
                    the value of the local variable 
<code>_profilingMethodStart</code>. The computed amount of time is added to
                    the respective member variable 
<code>_profiling_XXX</code> where XXX stands for the name of the current method.
                    This code is inserted at the very end of every class method.
        
</description>
                
<pointcutRef ref="targetMethod" type="src:function" />
                
<codeModifier type="codeFragment">
                    
<text>_profiling_${functionName} += MicroTime::getMicroTime() - _profilingMethodStart; // added by aspect (and may be not accessible)</text>
                    
<text />
                
</codeModifier>
        
</advice>
        
        
<advice type="add" name="addInclude">
                
<description>
                    Add the necessary 
<code>#include</code> statements.
                    It adds the header file of 
<code>MicroTime</code> class that is used to measure time with accuracy of 
                    one microsecond. It also includes the 
<code>iostream</code> library and declares 
                    the 
<code>std</code> namespace needed for I/O operations.
        
</description>
                
<pointcutRef ref="targetClassImplementationUnit" type="src:unit" />
                
<codeModifier type="include">
                        
<text>#include "MicroTime.h"
#include &lt;iostream&gt;
using namespace std; // code WOVEN by ASPECT
</text>
                
</codeModifier>
        
</advice>
        
    
<advice name="addProfilingReportMethod" type="add">
        
<description>
            Insert the definition of 
<code>_profilingReport()</code> method. The method lists all
            methods defined in the class. For every method it outputs the total execution time in microseconds.
            
<p />
            Two constructs of the XSL language are used to access the
            member variables that stores the execution time for each method: 
<code>xsl:for-each</code>
                        and 
<code>xsl:value-of</code>. The <code>xsl:for-each</code> instruction locates all method 
                        definitions. Then the 
<code>xsl:value-of</code> instruction is used to 
                        extract the local names of the methods and to write them to the base code.
        
</description>
        
<pointcutRef ref="targetClassImplementationUnit" type="src:unit" />
        
<codeModifier type="definition"><text>void SampleClass::_profilingReport() {
    cout &lt;&lt; "Profiling report" &lt;&lt; endl;
    cout &lt;&lt; "================" &lt;&lt; endl;
</text>
<text>    <xsl:for-each select="/src:unit/src:function">cout &lt;&lt; "Time spent in method '<xsl:value-of select="src:name/src:name[2]" />': " &lt;&lt; _profiling_<xsl:value-of select="src:name/src:name[2]" /> &lt;&lt; endl;
</xsl:for-each>
</text></codeModifier>
    
</advice>

        
<advice type="begin" name="addProfilingVariableInitialization">
            
<description>
                Insert the initialization code of all profiling member variables 
                to the class constructor. The two XSL constructs (
<code>xsl:for-each</code>
                        and 
<code>xsl:value-of</code>) are used to set all profiling member variables to zero.
        
</description>
                
<pointcutRef ref="targetConstructor" type="src:constructor" />
                
<codeModifier type="codeFragment"><text><xsl:for-each select="parent::src:unit/src:function">_profiling_<xsl:value-of select="src:name/src:name[2]" /> = 0;
</xsl:for-each></text> 
                
</codeModifier>
        
</advice>        

</aspect>






































v