55 Generic Advice: On the Combination of AOP with Generative Programming in AspectC++ DanielLohmann,GeorgBlaschke,andOlafSpinczyk Friedrich-Alexander-UniversityErlangen-Nuremberg,Germany {dl,gb,os}@cs.fau.de Abstract. Besides object-orientation, generic types or templates and aspect- oriented programming (AOP) gain increasing popularity as they provide addi- tionaldimensionsofdecomposition.Mostmodernprogramminglanguageslike Ada, Eiffel,and C++ already have built-insupport for templates. For Java and C#similarextensionswillbeavailableinthenearfuture.Eventhoughpromis- ing, the combination of aspects with generic and generative programming is still a widely unexplored field. This paper presents our extensions to the As- pectC++language,anaspect-orientedC++derivate.Bytheseextensionsaspects cannowaffectgenericcodeandexploitthepotentialsofgenericcodeandtem- plate metaprogramming in their implementations. This allows aspects to inject template metaprograms transparently into the component code. A case study demonstratesthatthisfeatureenablesthedevelopmentofhighlyexpressiveand efficient generic aspect implementations in AspectC++. A discussion whether these concepts are applicable in the context of other aspect-oriented language extensionslikeAspectJroundsupourcontribution. 1 Introduction Besidesobject-orientation,mostmodernprogramminglanguagesoffergenerictypesor templates to providean additionaldimension of decomposition.Languageslike Ada, EiffelandC++alreadyhavebuilt-insupportfortemplates.FortheJavalanguage,spe- cialextensionsforgenerictypeshavebeenproposed[6]andwillsoonbeavailablein Java 1.5 implementations [4]. Template support has also been proposed for the next version of the C# language and the .NET framework [12]. We are convincedthat for along-termandbroadacceptanceofAOPitisnecessarytoprovidenativesupportfor templateconstructsincurrentAOPlanguages. As AspectC++ [17] supportsAOP in the contextof C++, which offers highly so- phisticated template features, it is an ideal exampleto study the relation of these two worlds. To familiarize the readerwith the terminologyused throughoutthis paperwe startwithaverybriefintroductionofthemostimportantAspectC++languageconcepts. 1.1 AspectC++ConceptsandTerminology AspectC++ is a generalpurpose aspect-orientedlanguage extension to C++ designed bytheauthorsandothers.Itisaimedtosupportthewell-knownAspectJprogramming styleinareaswithstrongerdemandsonruntimeefficiencyandcodedensity. G.KarsaiandE.Visser(Eds.):GPCE2004,LNCS3286,pp.55–74,2004. (cid:1)c Springer-VerlagBerlinHeidelberg2004 56 DanielLohmann,GeorgBlaschke,andOlafSpinczyk TheAspectC++terminologyisstronglyinfluencedbytheterminologyintroduced byAspectJ[13].Themostrelevanttermsarejoinpointandadvice.Ajoinpointdenotes aspecificweavingpositioninthetargetcode(oftencalledcomponentcode,too).Join- pointsareusuallygiveninadeclarativewaybyajoinpointdescriptionlanguage.Each setofjoinpoints,whichisdescribedinthislanguage,iscalledapointcut.InAspectC++ thesentencesofthejoinpointdescriptionlanguagearecalledpointcutexpressions.For examplethepointcutexpression call("% Service::%(...)") describesall calls to memberfunctionsof the class Service1. The aspectcode that is actuallywovenintothetargetcodeatthejoinpointsiscalledadvice.Adviceisboundto asetofjoinpoints(givenbyapointcutexpression).Forexamplebydefiningtheadvice advicecall("% Service::%(...)") :before() { cout << "Service function invocation" << endl; } theprogramwillprintamessagebeforeanycalltoamemberfunctionofService.The advicecodeitselfhasaccesstoitscontext,i.e.thejoinpointwhichitaffects,atruntime by a joinpoint API. Very similar to the predefined this-pointer in C++, AspectC++ providesapointercalledtjp,whichprovidesthecontextinformation.Forexamplethe advice advicecall("% Service::%(...)") :before() { cout <<tjp->signature() << " invocation" << endl; } printsamessagethatcontainsthenameofthefunctionthatisgoingtobecalled. 1.2 DimensionsofInterest Thecombinationofaspectsandtemplateshastwogeneraldimensionsofinterest.First, thereisthedimensionofusingaspectsfortheinstrumentationofgenericcode.Second, there is the dimension of using generic code in aspects, that is, to generalize aspect implementationsbyutilizinggenericcode.Wewillseethatforthefirstitisnecessary toextendthejoinpointdescriptionlanguagewhilethesecondleadstospecificjoinpoint APIrequirements. Dimension 1: Using Aspects for the Instrumentationof Generic Code. The most common and popular applications of templates are generic algorithms and container classes, as provided by the C++ standard library STL. To support the modular im- plementationofcrosscuttingconcernsinsidetemplatelibraries,atemplate-awareAOP languageshouldbeabletoweaveaspectcodeintotemplateclassesandfunctions.This means,forexample,thatwewanttobeabletorunadvicecodebeforeand/oraftercalls toorexecutionsofgenericclassesorfunctions.Furthermore,itwouldbedesirabletobe abletoaffectevenindividualtemplateinstances.Forexample,wemightwanttotrack elementadditionstoaspecificinstanceofagenericcontainer.Openquestionsare: 1%and...arewildcardsymbolsinAspectC++(as*and..inAspectJ). GenericAdvice:OntheCombinationofAOPwithGPinAspectC++ 57 – Which extensionsto the joinpointlanguagesare necessary to describe these new kindsofjoinpoints? – Which implementation issues for aspect weavers and compilers arise from such extensions? Astoday’saspect-orientedprogramminglanguagesofferawiderangeoflanguagefea- tures,findingacommon(language-independent)answerforthesequestionsisdifficult. However, this paper will answer them in the context of C++/AspectC++ and discuss theminthecontextofotheraspectlanguagesthatsupportsimilarlanguagefeatures. Dimension2:UsingGenericCodeinAspects. Genericprogrammingprovidesanad- ditionaldimensionforseparationofconcerns(SoC).Thus,wealsowanttousetemplate codein aspectimplementations.Thisseemseasy atfirst sight.However,an advanced utilization of generic code in advice implementationsincorporates(static) type infor- mationfromtheadvicecontext.Forexample,considera reusablecachingaspect,im- plementedbyadvicecodethatusesagenericcontainertostoreargument/resultpairsof functioninvocations.Toinstantiatethecontainertemplatefromwithintheadvicecode, theaffectedfunctionargumenttypesandresulttypeareneeded,whichinturndepend onthejoinpointtheadvicecodeaffects.Asinthiscasedifferentadvicecodeversions havetobegenerated,itisreasonabletounderstandtheadviceasbeinginstantiatedfor eachjoinpointdependingonthetypesitneedsforcodegeneration.Wewilluseanew termforthisspecialkindofadvice: Wecalladviceagenericadvice,ifitsimplementation dependsonjoinpoint-specificstatictypeinformation. Astemplatesareinstantiatedatcompiletime,thetypeinformation,whichisoffered bytherun-timejoinpointAPIofcurrentaspectlanguages,isnotsufficient.Instead,we need a compile-time joinpoint API that provides static type information (e.g. the pa- rametertypesoftheaffectedfunction)abouttheadviceinstantiationcontext.Thetype informationprovidedbythecompile-timejoinpointAPImaythenbeusedtoinstantiate templates.Openquestionsconcerningdimension2are: – Howshouldaspectlanguagessupporttheusageofgenericcodeinaspects? – WhichinformationshouldbeprovidedbyastaticjoinpointAPI? Besidesgenericprogramming,C++templatesarealsothebaseforotheradvancedand powerfulSoCconceptslikepolicy-baseddesign[2]andgenerativeprogramming[9]that are implementedby templatemetaprogramming[18].The ability to use templatecon- structsinadvicecodepromisestoforgethelinkbetweenAOPandtheseadvancedSoC concepts. Aspects may provide great benefit for generative programmingand policy- based design by enabling the non-invasive intrusion of template metaprograms. At the same time, generative techniques may be used to implement highly flexible and runtime-efficientaspectimplementations. 58 DanielLohmann,GeorgBlaschke,andOlafSpinczyk 1.3 Objectives InthispaperwediscussthecombinationofaspectsandtemplatesinAspectC++.From the discussion in this introduction we conclude that weaving in template instances is a consequent and probably useful extension of the target scope of aspects. However, providingadvicecode with the necessary contextinformationto exploitthe powerof genericcodeandmetaprogramsimprovestheexpressivepowerofaspectimplementa- tionssignificantly.Thispromisestobethemoreinterestingresearchtopic2.Thus,our workcoversbothdimensionsbutconcentratesonthesecond.Bypresentingacasestudy we will demonstratethe powerof the genericadvice featureand the consequencesin termsofcodequalityandperformance. 1.4 Outline The rest is this paper is structured as follows. It starts in section 2 with a description ofthetemplatesupportincorporatedintotheAspectC++languageandcompiler.This is followedby a case study in section 3 thatshows howgenerativetechniquescan be used for the implementation of a highly flexible and efficient aspect. Furthermore, it evaluatesthe performanceandqualityofthe solution,whichwe claim to be unreach- ablealonewithpuretemplatetechniquesorclassic AOP. Section4discusseswhether similar aspect-orientedlanguage extensions for base languagesother than C++ could implement the same concepts. Finally, an overview of related work is given and the resultsofthispaperaresummarized. 2 TemplateSupport inAspectC++ ThissectiondescribesourintegrationoftemplatesupportintoAspectC++.Itisstruc- tured according to the two dimensions3 identified in the introduction. Each of these partsstartswithadescriptionoftemplate-relatedC++features,whicharerelevantfor the integration, continues with a presentation of our extensions to AspectC++ on the language-level,andendswithadiscussionofimplementationissues. 2.1 Dimension1:UsingAspectsfortheInstrumentationofGenericCode Onepossiblecombinationofaspectswithtemplatesistheapplicationofadvicetotem- plateclassesandfunctionsasdiscussedin1.2. Relevant Language Features. C++ templates provide a specific kind of polymor- phism which is often referred to as parametric polymorphism. While subclass poly- morphism (based on interface inheritance) defines a runtime substitutability between objectinstances,parametricpolymorphismdefinesa compile-timesubstitutabilitybe- tweentypes.AformaltemplateparametercanbesubstitutedbyatypeT1thatprovides 2Itisalsomoreappropriateforaconferenceongenerativeprogramming. 3Infact,thepartonthesecond dimensionisdivided into2aand2btohandletheveryC++- specifictemplatemetaprogrammingfeatureseparately. GenericAdvice:OntheCombinationofAOPwithGPinAspectC++ 59 a specific (static) interface. This interface is defined by the set of operations, types and constants used in the template implementation.Note that, in contrast to subclass polymorphism,theparametricsubstitutabilityoftypesT1andT2doesnotleadtoany runtime relationship between object instances of T1 and T2. Templates do not break type-safetyandinduce,inprinciple,noruntimeoverheadatall. InC++,thebasiclanguageelementsforgenericprogrammingaretemplateclasses andtemplatefunctions.Forexample,theC++standardlibraryclass template< class T, class U > structpair{ T first; U second; pair() : first(), second() {} pair(const T& x, const U& y) : first(x), second(y) {} ... }; definesasimple2-Tuplethatcanbeinstantiatedwithanytwotypes,e.gpair< int, int >orpair< Foo, pair< Bar, int > >thatprovideatleastadefaultorcopyconstructor. Extensions to the Joinpoint Language. Weaving in generic code requires the pro- grammersto describethe set of relevanttemplate instances. Thus, the first step to in- tegrate template support into AspectC++ was to extend the joinpoint description lan- guage. In AspectC++ joinpoints that should be affected by advice are described by so- calledpointcutexpressions.Forexample call("% Service::%(...)") && cflow(execution("void error %(...)")) describesallcallstomemberfunctionsoftheclassService.Bycombining(&&opera- tion)thesejoinpointswiththecflowpointcutfunctionthesejoinpointsbecomecondi- tional.Theyareonlyaffectedbyadviceiftheflowofcontrolalreadypassedafunction withanamebeginningwitherror .Usersmaydefinepointcutexpressionsofarbitrary complexitytodescribethecrosscuttingnatureoftheiraspects.Alistofallbuilt-inpoint- cutfunctionsofAspectC++isavailableintheAspectC++LanguageQuickReference Sheet4. Thecoreofthejoinpointlanguagearematch-expressions.InAspectC++theseex- pressionsarequotedstringswhere%and...canbeusedaswildcards.Theycanbeun- derstoodasregularexpressionsmatchedagainstthenamesofknownprogramentities like functionsor classes. To supportadvicefor template class and functioninstances, the signatures of these instances just have to be considered when match expressions areevaluated.InC++thesignaturesoftemplateinstancesarewell-definedandcandi- rectlybeusedtoextendthesetofknownprogramentitiesformatching.Forexample, ifafunctioninstantiatestemplateclasseswiththesignaturesset<int>andset<float>, thematch-expression"% set<int>::%(...)"willonlymatchthememberfunctionsof set<int>.Ofcourse,itisalsopossibletomatchthememberfunctionsofallinstances byusing"% set<...>::%(...)". 4TheAspectC++compileranddocumentationareavailablefromwww.aspectc.org. 60 DanielLohmann,GeorgBlaschke,andOlafSpinczyk ImplementationIssues. Whilethisextensionisstraightforwardonthelanguagelevel it has severe consequenceson the weaver implementation.The weaver has to be able todistinguishtemplateinstancesduringtheweavingprocess.OurAspectC++compiler transformsAspectC++sourcecodeintoC++code5.Thus,thecompilerhastoperform a full template instantiation analysis of the given source code to distinguish template instancesandtocomparetheirsignatureswithmatch-expressions.Tobeabletoaffect onlycertaininstancesourcompilerusestheexplicittemplatespecializationfeatureof C++.Forexample,ifadviceaffectsonlytheinstanceset<int>thetemplatecodeofset iscopied,manipulatedaccordingtotheadvice,anddeclaredasaspecializationofset forint6. 2.2 Dimension2a:UsingGenericCodeinAspects Templatesinstances,likepair<int, int>intheexampleabove,canalsobeusedinas- pectcode.However,foramoreelaborateandcontextdependentutilizationoftemplates inadvicecode,additionalsupportbytheaspectlanguageisnecessary. RelevantLanguageFeatures. Genericadviceusestypeinformationfromitsinstanti- ationcontext(thejoinpoints).Forexample,itmayinstantiateagenericcontainerwith theresulttypeofthefunctiontheadviceisappliedto.Forthis,theargumentandresult typeshavetobeaccessibletotheadvicecodeatcompiletime. ThesuitableC++languageconceptforthispurposeistypealiases.InC++,atype aliasisdefinedusingthetypedefkeyword.Typealiasescanbeusedtotransporttype informationthroughothertypesortemplates: template< class T, class U > struct pair { typedef T first type; typedef U second type; ... }; template<class PAIR>typename PAIR::first type&get first(PAIR& p) { return p.first; } TheStaticJoinpointAPI. Tosupporttheimplementationofgenericadvicecodethe AspectC++ joinpointAPIhadto beextended.Itnowprovidesstatic typeinformation aboutalltypesthatarerelevantforthejoinpoint. Table1givesanoverviewaboutthenewjoinpointAPI.Theupperpart(typesand enumerators) provides compile-time type information, which can be used by generic codeormetaprogramsinstantiatedbyadvice. The methodsin the lower partof table 1 can only be called at runtime. However, notethatthenewfunctionArg<i>::ReferredType *arg()nowoffersastaticallytyped 5AspectC++isbasedonourPUMAC++transformationframeworkwhichisbeeingdeveloped inlinewithAspectC++,butmaybeusedforotherpurposesaswell. 6C++doesnotsupporttheexplicitspecializationfortemplatefunctions.However,wecanwork aroundthisproblembydefiningahelpertemplateclass. GenericAdvice:OntheCombinationofAOPwithGPinAspectC++ 61 Table1.TheAspectC++JoinpointAPI typesandenumerators: That objecttype Target targettype(call) Arg<i>::Type argumenttype ARGS numberofarguments Result resulttype staticmethods: const char *signature() signatureofthefunctionorattribute unsigned id() identificationofthejoinpoint AC::JPType jptype() typeofjoinpoint AC::Type type() typeofthefunctionorattribute AC::Type argtype(int) typesofthearguments int args() numberofarguments AC::Type resulttype() resulttype non-staticmethods: void proceed() executejoinpointcode AC::Action &action() Actionstructure That *that() objectreferredtobythis Target *target() targetobjectofacall void *arg(int) actualargument Arg<i>::ReferredType*arg() argumentwithstaticindex Result *result() resultvalue interface to access argument values if the argument index is known at compile time. AC::Typeisaspecialdatatypethatprovidestypeinformationatruntime,butcannotbe usedtoinstantiatetemplates. Inthefuture,additionaltypeinformation,e.g.typesofclassmembersandtemplate arguments,willbeaddedtothejoinpointAPI,asthismightallowfurtherusefulappli- cations. Implementation Issues. AspectC++ generates a C++ class with a unique name for eachjoinpointthatisaffectedbyadvicecode.Advicecodeistransformedintoatem- platememberfunctionoftheaspect,whichinturnistransformedtoaclass.Theunique joinpointclass is passed as a template argumentto the advice code. Thus, the advice codeisgenericandcanaccessalltypedefinitions(C++typedefs)insidethejoinpoint classwithJoinPoint::Typename.Indirectlythesetypescanalsobeusedbyusingthe type-safe argumentand result accessor function. The following code fragmentshows advicecodeafteritstransformationintoatemplatefunction. class ServiceMonitor { // ... template<class JoinPoint> void a0 after (JoinPoint *tjp) { cout << "Result: " << *tjp->result () << endl; } }; 62 DanielLohmann,GeorgBlaschke,andOlafSpinczyk As required for generic advice the C++ compiler will instantiate the advice code with JoinPoint as a code generation parameter. Depending on the result type of tjp->result() for the joinpoint the right output operator will be selected at compile time. 2.3 Dimension2b:UsingTemplateMetaprogramsinAspects TheC++templatelanguageprovideselaboratefeaturesthatmakeitaTuring-complete functionallanguageforstaticmetaprogrammingonitsown.AC++templatemetapro- gram works on types and constants and is executedby the compiler at compile time. GenerativeAdviceisaspecialformofgenericadvicethatusesjoinpoint-specifictype informationfortheinstantiationoftemplatemetaprograms. Relevant Language Features. In addition to types, C++ supportsnon-typetemplate parameters, also frequently referred to as value template parameters. Value template parametersallowtoinstantiateatemplateaccordingtoacompile-timeconstant.Apart fromthedefinitionofcompile-timeconstants,valuetemplateparametersarefrequently usedforarithmeticsandloopingintemplatemetaprogramming. A language that provides a case discrimination and a loop construct is Touring- complete. In the C++ template metalanguage,case discrimination is realized by tem- plate specialization. Loops are implemented by recursive instantiation of templates. These language features, in conjunction with non-type template parameters, are the building blocks of template metaprograms7. This is shown in the most popular (and simple)exampleofatemplatemetaprogramthatcalculatesthefactorialofanintegerat compile-time: template< int N > struct fac { enum{ res = N *fac< N - 1 >::res }; // loop by rec. instantiation }; // condition to terminate recursion by specialization for case 0 template<>struct fac< 0 >{ enum{ res = 1 }; }; // using fac const fac 5 = fac< 5 >::res; Thefac<int>templatedependsonvaluetemplateparametersandcalculatesthefacto- rialbyrecursiveinstantiationofitself.Therecursionisterminatedbyaspecialization forthecasefac<0>. Type Sequences. With adequate support by the static joinpoint API metaprograms would be able to iterate over type sequences like the argument types of a joinpoint at compile time. However, these sequences have to be provided in a “metaprogram- friendly” way. Just generating ArgType0, ArgType1, ..., ArgTypeN would not allow 7Non-typetemplateparametersare,strictlyspeaking,notamandatoryfeaturefortheTuring- completeness of the C++ template language. They “just” allow one to use the built-in C++ operatorsetforarithmeticexpressions. GenericAdvice:OntheCombinationofAOPwithGPinAspectC++ 63 metaprograms to iterate over these types. For this purpose the generated joinpoint- specificclassescontainatemplateclass Arg<I>whichcontainsathetypeinformation th fortheI argumentastypedefs. Implementation Issues. Sequences of types can be implemented by recursive tem- plate definitions as in the Loki[1] Typelist. For the AspectC++ we decided for an implementationwithlessdemandsontheback-endcompilerbasedonexplicittemplate specialization.Thefollowingcodeshowsthegeneratedtypeforacalljoinpointinthe main()function8. struct TJP main 0 { typedef float Result; typedef void That; typedef ::Service Target; enum { ARGS = 2 }; template <int I> struct Arg {}; template <> struct Arg<0> { typedef bool Type; typedef bool ReferredType; }; template <> struct Arg<1> { typedef int & Type; typedef int ReferredType; }; Result * result; inline Result *result() {return result;} }; With this type as a template argumentfor generic advice the advice programmercan nowuseametaprogramsimilartothefactorialcalculationtohandleeachargumentin atype-safeway.Afurtherexamplewillbegiveninthenextsection. 3 Caching asa GenerativeAspect – ACaseStudy In this section we demonstrate how the possibility to exploit generic/generative pro- grammingtechniquesfor aspect implementationscan lead to a veryhigh levelof ab- straction. Our example is a simple caching policy for function invocations. The im- plementation idea is straightforward: before executing the function body, a cache is searched for the passed argument values. If an entry is found, the corresponding re- sultisreturnedimmediately,otherwisethefunctionbodyisexecutedandthecacheis updated. Cachingisatypicalexampleforacrosscuttingpolicy.However,beforeweextended AspectC++ it was notpossibleto implementthis in a traditionalaspect-orientedway. To be generic, the aspect must be able to copy function argumentsof arbitrary types intothecache.AsC++lacksgoodreflectioncapabilities,itisnotpossibletodothisat runtime. A cachingpolicyfor functioninvocationsis also noteasy to implementusing so- phisticated template techniqueslike policy-baseddesign[2].To achieve this, it would 8Thegeneratedcodedependsonthecompilerusedastheac++back-end. 64 DanielLohmann,GeorgBlaschke,andOlafSpinczyk benecessarytohaveagenericwaytoexposethesignature(parametertypes)ofafunc- tion at compile time and the invocation context(actual parameter values) at runtime, whichisnotavailable.Fortunately,exactlythisinformationisprovidedbythecompile- timeandrun-timejoinpointAPIinAspectC++.Hence,itisnowpossibletoimplement context-dependentpolicies,likecaching,usinggenerativetechniquestogetherwithas- pects. In the following, we present the implementation of such a generativecaching as- pect.We introducethe examplewithan in-place“handcrafted”cacheimplementation forasinglefunction.AtypicalAOPimplementationofthissimplein-placecachegives readers, who are not familiar with AOP, an idea about implementing such a policy by an aspect. We then generalizethe AOP implementationto make it independenton thenumberandtypesoffunctionargumentsusingtemplatemetaprogrammingandthe staticjoinpointAPI.Thisgenerativeaspectisapplicabletoanyfunctionwithanynum- berofarguments.Finally,weevaluateoursolutionandprovideadetailedperformance analysis. 3.1 Scenario Consider an application that uses the class Calc (Figure 1). Our goal is to improve the overall application execution speed. With the help of a tracing aspect we fig- ured out that the application spends most time in the computational intensive func- tions Calc::Expensive(), Calc::AlsoExpensive() and Calc::VeryExpensive(). Fur- thermore,wedetectedthatthesefunctionsareoftencalledseveraltimesinorderwith exactlythesamearguments.Therefore,wedecidedtoimprovetheexecutionspeedby usingasimpleone-elementcache. Figure1demonstratestheimplementationprincipleofsuchacacheforthefunction Calc::Expensive(). It uses a local class Cache that implementsthe caching function- alityandofferstwomethods,namelyCache::Lookup()(line28)andCache::Update() (line 32), to access and write the cached data. Cache is instantiated as a static object (line41)soitstaysresidentbetweenfunctioninvocations. However, as caching is useful only in certain application scenarios and we have to write almost the same code for Calc::AlsoExpensive() and Calc::VeryExpensive()again,wewanttoimplementthisbyareusableaspect. 3.2 DevelopmentofaCachingAspect The Simple Caching Aspect. Figure 2 shows a typical AOP “translation” of the caching strategy. The class Cache has become an inner class of the aspect Caching. TheaspectgivesaroundadvicefortheexecutionofCalc::Expensive(), Cacheisnow instantiatedin the advicebody(line22).On eachinvocation,the functionparameters arefirstlookedupinthecacheand,iffound,thecachedresultisreturned(lines25–27). Otherwisetheyarecalculatedbyinvokingtheoriginalfunctionandstoredtogetherwith theresultinthecache(lines28–34). Thisimplementationofacachingaspectisquitestraightforward.Itusesmethodsof theruntimejoinpointAPI(tjp->arg()andtjp->result())toaccesstheactualparam- eterandresultvaluesofafunctioninvocation.However,ithasthemajordrawbackthat
Description: