package Ġch . u zh . ifi . se al . bench er . analysis . call graph . dyn . javac all graph Ċ Ċ import Ġarrow . core . Either Ċ import Ġarrow . core . get Or Handle Ċ import Ġch . u zh . ifi . se al . bench er . Benchmark Ċ import Ġch . u zh . ifi . se al . bench er . MF Ċ import Ġch . u zh . ifi . se al . bench er . Method Ċ import Ġch . u zh . ifi . se al . bench er . analysis . call graph . CG Executor Ċ import Ġch . u zh . ifi . se al . bench er . analysis . call graph . CG In clusions Ċ import Ġch . u zh . ifi . se al . bench er . analysis . call graph . Include All Ċ import Ġch . u zh . ifi . se al . bench er . analysis . call graph . Include Only Ċ import Ġch . u zh . ifi . se al . bench er . analysis . call graph . dyn . Abstract Dynamic Coverage Ċ import Ġch . u zh . ifi . se al . bench er . analysis . call graph . reach ability . RF Ċ import Ġch . u zh . ifi . se al . bench er . analysis . call graph . reach ability . Reach ability Result Ċ import Ġch . u zh . ifi . se al . bench er . analysis . finder . Method Finder Ċ import Ġch . u zh . ifi . se al . bench er . file Resource Ċ import Ġorg . apache . logging . log 4 j . Log Manager Ċ import Ġorg . apache . logging . log 4 j . Logger Ċ import Ġjava . io . BufferedReader Ċ import Ġjava . io . File Ċ import Ġjava . io . Reader Ċ import Ġjava . nio . file . Path Ċ import Ġjava . time . Duration Ċ import Ġkotlin . streams . as Sequence Ċ Ċ class ĠJava Call graph DC G ( ĊĠĠĠĠĠĠĠ Ġbenchmark Finder : ĠMethod Finder < Benchmark >, ĊĠĠĠĠĠĠĠ Ġone CG For Parameterized Bench marks : ĠBoolean Ġ= Ġtrue , ĊĠĠĠĠĠĠĠ Ġinclusion : ĠCG In clusions Ġ= ĠInclude All , ĊĠĠĠĠĠĠĠ Ġtime Out : ĠDuration Ġ= ĠDuration . of Minutes ( 1 0 ) Ċ ) Ġ: ĠAbstract Dynamic Coverage ( ĊĠĠĠĠĠĠĠ Ġbenchmark Finder Ġ= Ġbenchmark Finder , ĊĠĠĠĠĠĠĠ Ġone Coverage For Parameterized Bench marks Ġ= Ġone CG For Parameterized Bench marks , ĊĠĠĠĠĠĠĠ Ġtime Out Ġ= Ġtime Out Ċ ), ĠCG Executor Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġincl us ions String : ĠString Ġ= Ġincl us ions ( in clusion ) ĊĊĠĠĠ Ġoverride Ġfun Ġparse Reach ability Results ( r : ĠReader , Ġb : ĠBenchmark ): ĠEither < String , ĠSet < Reach ability Result >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbr Ġ= ĠBufferedReader ( r ) ĊĠĠĠĠĠĠĠ Ġval Ġb pm Ġ= Ġb . to Plain Method () ĊĠĠĠĠĠĠĠ Ġvar Ġbench Level Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġrs : ĠSet < Reach ability Result > Ġ= Ġbr . lines (). as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . startsWith (" START ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbench Level Ġ= Ġit . substring After ("_ "). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparse Reach ability Result ( bpm , Ġbench Level , Ġit ). get Or Handle Ġ{ Ġerr Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Could Ġnot Ġparse ĠRe ach ability Result : Ġ$ err ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit Ġas ĠRe ach ability Result Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toSet () ĊĊĠĠĠĠĠĠĠ Ġreturn ĠEither . Right ( rs ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Reach ability Results Call trace ( r : ĠBufferedReader , Ġb : ĠBenchmark ): ĠEither < String , ĠList < Reach ability Result >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbench Line Ġ= Ġcall trace Bench ( b ) ĊĠĠĠĠĠĠĠ Ġval Ġb pm Ġ= Ġb . to Plain Method () ĊĠĠĠĠĠĠĠ Ġvar Ġin Bench CG Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġvar Ġbench Level Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġrs : ĠList < Reach ability Result > Ġ= Ġr . lines (). as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . contains ( bench Line )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Bench CG Ġ= Ġ! in Bench CG ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbench Level Ġ= Ġparse Stack Depth ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Bench CG ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . startsWith ("> ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġparse Reach ability Result ( bpm , Ġbench Level , Ġit ). or Null () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit Ġas ĠRe ach ability Result Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toList () ĊĊĠĠĠĠĠĠĠ Ġreturn ĠEither . Right ( rs ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Stack Depth ( l : ĠString ): ĠInt Ġ= Ġl . substring After (" [" ). substring Before (" ]"). toInt () ĊĊĠĠĠ Ġprivate Ġval Ġchar Set Ġ= Ġset Of ('[ ', Ġ' ]', Ġ' :', Ġ' (', Ġ') ') ĊĊĠĠĠ Ġprivate Ġfun Ġparse Reach ability Result ( from : ĠMethod , Ġbench Level : ĠInt , Ġl : ĠString ): ĠEither < String , ĠRe ach ability Result > Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġstack Depth Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġval Ġbench Class Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠ Ġval Ġbench Method Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠ Ġval Ġbench Params Ġ= ĠStringBuilder () ĊĠĠĠĠĠĠĠ Ġvar Ġstate Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġloop @ Ġfor Ġ( c Ġin Ġl ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( c ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ'[' Ġ-> Ġstate ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ' ]' Ġ-> Ġstate ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ':' Ġ-> Ġstate ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ'(' Ġ-> Ġstate ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ')' Ġ-> Ġstate ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( char Set . contains ( c )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> Ġstack Depth Ġ= Ġc . toString (). toInt () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 4 Ġ-> Ġbench Class . append ( c ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 5 Ġ-> Ġbench Method . append ( c ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 6 Ġ-> Ġbench Params . append ( c ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 7 Ġ-> Ġbreak @ loop ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġb ps Ġ= Ġbench Params . toString () ĊĠĠĠĠĠĠĠ Ġval Ġps Ġ= Ġif Ġ( bps . isBlank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf () ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġb ps . split To Sequence ("," ). toList () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġr Ġ= ĠRF . reachable ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrom Ġ= Ġfrom , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġto Ġ= ĠMF . plain Method ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclazz Ġ= Ġbench Class . toString (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġbench Method . toString (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams Ġ= Ġps ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel Ġ= Ġstack Depth Ġ- Ġbench Level ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠEither . Right ( r ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġj vm Args ( b : ĠBenchmark ): ĠString Ġ= ĠString . format ( jvm Args , Ġj cg Agent Jar , Ġcall trace Bench ( b ), Ġincl us ions String ) ĊĊĠĠĠ Ġoverride Ġfun Ġresult FileName ( b : ĠBenchmark ): ĠString Ġ= Ġcall trace FileName ĊĊĠĠĠ Ġoverride Ġfun Ġtransform Result File ( jar : ĠPath , Ġdir : ĠFile , Ġb : ĠBenchmark , Ġresult File : ĠFile ): ĠEither < String , ĠFile > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEither . Right ( result File ) ĊĊĠĠĠ Ġprivate Ġfun Ġcall trace Bench ( b : ĠBenchmark , Ġescape Dollar : ĠBoolean Ġ= Ġfalse ): ĠString Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ b . clazz }:${ b . name }". let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( escape Dollar ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . replace ("$ ", Ġ"\\ $ ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġincl us ions ( i : ĠCG In clusions ): ĠString Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( i ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠInclude All Ġ-> Ġ" .* " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠInclude Only Ġ-> Ġi . includes . join ToString ( separator Ġ= Ġ", ") Ġ{ Ġ"$ it .* " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġlog : ĠLogger Ġ= ĠLog Manager . getLogger ( Java Call graph DC G :: class . java . canonical Name ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġ ĠJVM Ġarguments ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠ 1 . Ġjava - call graph Ġagent Ġjar Ġpath Ġ( e . g ., Ġj cg Agent Jar ) ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠ 2 . Ġbenchmark Ġof Ġformat : Ġclazz : method ( param 1 , param 2 ) Ġ( e . g ., Ġcall trace Bench ) ĊĠĠĠĠĠĠĠ Ġ// ĠĠĠ 3 . Ġcall Ġgraph Ġincl us ions Ġ( e . g ., Ġincl us ions String ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġj vm Args Ġ= Ġ"- java agent :% s = bench =% s ; incl =% s " ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġj cg Agent Jar Ġ= Ġ" j cg _ agent . jar . zip ". file Resource (). absolute Path ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval Ġcall trace FileName Ġ= Ġ" call trace . txt " ĊĠĠĠ Ġ} Ċ } Ċ