1 # Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. 2 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 # 4 # This code is free software; you can redistribute it and/or modify it 5 # under the terms of the GNU General Public License version 2 only, as 6 # published by the Free Software Foundation. 7 # 8 # This code is distributed in the hope that it will be useful, but WITHOUT 9 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 # version 2 for more details (a copy is included in the LICENSE file that 12 # accompanied this code). 13 # 14 # You should have received a copy of the GNU General Public License version 15 # 2 along with this work; if not, write to the Free Software Foundation, 16 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 # 18 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 # or visit www.oracle.com if you need additional information or have any 20 # questions. 21 22 #=============================================================================== 23 # Leyden-premain + spring-petclinic warmup (https://github.com/spring-projects/spring-petclinic) 24 # 25 # Build spring-petclinic: 26 # make app 27 # 28 # Build all leyden optimization artifacts (this is using the older "4 step training run" which will be simplified): 29 # make aot 30 # 31 # Uses JMeter to drive the load to the petclinic application. 32 # Duration of the load and number of threads used by JMeter to drive the load 33 # is controlled by JMETER_DURATION and JMETER_THREADS variables respectively. 34 # JMETER_CPUS and APP_CPUS variables control the cpus to be used for running the jmeter and app respectively. 35 # 36 # Run warmup with baseline 37 # make -f WarmupMakefile warmup-bl 38 # 39 # Run warmup with only preload optimizations 40 # make -f WarmupMakefile warmup-preload 41 # 42 # Run warmup with training data generated for the startup 43 # make -f WarmupMakefile warmup-st 44 # 45 # Run warmup with training data generated by the jmeter load 46 # make -f WarmupMakefile warmup-lt 47 # 48 # Run with startup training data and aot 49 # make -f WarmupMakefile warmup-st-aot 50 # 51 # Run with startup training data and aot 52 # make -f WarmupMakefile warmup-lt-aot 53 # 54 # Run all configurations 55 # make -f WarmupMakefile run 56 # 57 # Use warmup_result.sh to process the generated jmeter log files to create CSV files 58 # that can be used for plotting throughput graphs 59 # 60 # Set the following to point to JDK 17 and your Leyden JDK build. 61 # 62 # *** NOTE: JDK 17 (or 21??) is needed to build spring-petclinic-3.2.0-SNAPSHOT.jar 63 JDK17_HOME = /jdk3/official/jdk17 64 #baseline java 65 BL_HOME = /jdk3/official/jdk-latest 66 PREMAIN_HOME = /jdk3/bld/le4/images/jdk 67 #=============================================================================== 68 69 # Usually there's no need to change the following 70 JAR_CMD = ${JDK17_HOME}/bin/jar 71 JDK17_JAVA = ${JDK17_HOME}/bin/java 72 PREMAIN_JAVA = ${PREMAIN_HOME}/bin/java 73 BL_JAVA = ${BL_HOME}/bin/java 74 PC_REPO = petclinic-snapshot-warmup 75 PC_JAVA_SOURCES = ${PC_REPO}/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java 76 PC_APP_JAR = ${PC_REPO}/target/spring-petclinic-3.2.0-SNAPSHOT.jar 77 PC_APP_UNPACKED = ${PC_REPO}/target/unpacked 78 JMETER_DIR = apache-jmeter-5.5 79 JMETER_BIN = ${JMETER_DIR}/bin/jmeter 80 JMETER_ZIP = ${JMETER_DIR}.zip 81 JMETER_URL = https://archive.apache.org/dist/jmeter/binaries/${JMETER_ZIP} 82 83 # This is for uploading to artifactory, to be tested with 84 # ../../runtime/cds/appcds/leyden/SpringPetClinic.java 85 PC_APP_UNPACKED_ZIP = ${PC_REPO}/target/spring-petclinic-3.2.0.zip 86 87 PC_MAIN_CLASS = org.springframework.samples.petclinic.PetClinicApplication 88 PC_CLASSLIST = spring-petclinic.classlist 89 PC_STATIC_JSA = spring-petclinic.static.jsa 90 PC_DYNAMIC_ST_JSA = spring-petclinic.dynamic-st.jsa 91 PC_DYNAMIC_LT_JSA = spring-petclinic.dynamic-lt.jsa 92 PC_DYNAMIC_NOTRAINING_JSA = spring-petclinic.dynamic-notraining.jsa 93 PC_ST_CACHED_CODE = spring-petclinic.code-st.jsa 94 PC_LT_CACHED_CODE = spring-petclinic.code-lt.jsa 95 96 PC_BL_CLASSLIST = spring-petclinic.bl_classlist 97 PC_STATIC_BL_JSA = spring-petclinic.static_bl.jsa 98 PC_DYNAMIC_BL_JSA = spring-petclinic.dynamic_bl.jsa 99 100 PC_CDS_PREIMAGE = spring-petclinic.cds.preimage 101 PC_CDS = spring-petclinic.cds 102 103 JMETER_DURATION = 180 104 JMETER_THREADS = 1 105 JMETER_CPUS = 12-13 106 APP_CPUS = 14-19 107 108 # TODO: should we add -Dspring.context.exit=onRefresh to command line?? 109 # This will make the JVM quit after printing this line: 110 # 111 # 4:21.639 ... o.s.b.a.e.web.EndpointLinksResolver : Exposing 13 endpoint(s) beneath base path '/actuator' 112 # 113 # Whereas -DautoQuit=true will make it exit after printing the following (a little bit of application code is executed) 114 # 115 # 4:21.665 ... o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '' 116 # 4:21.666 ... o.s.s.petclinic.PetClinicApplication : Started PetClinicApplication in 1.358 seconds (process running for 1.584) 117 # #### Booted and returned in 1453ms 118 # 4:21.692 ... j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 119 # 4:21.693 ... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 120 # 4:21.694 ... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. 121 HEAP_SIZE = -Xmx2g 122 UNPACKED_CMDLINE = $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath -DautoQuit=true -Dspring.aot.enabled=true -Dspring.output.ansi.enabled=NEVER ${PC_MAIN_CLASS} 123 124 all: check git app aot 125 126 check: 127 @if ${JDK17_JAVA} --version | grep -q '17.*LTS'; then \ 128 true; \ 129 else \ 130 echo JDK17_HOME should point to JDK 17; \ 131 exit 1; \ 132 fi 133 @if ${PREMAIN_JAVA} -XX:+PrintFlagsFinal --version | grep -q CDSManualFinalImage; then \ 134 true; \ 135 else \ 136 echo PREMAIN_HOME should point to your build of https://github.com/openjdk/leyden/tree/premain; \ 137 exit 1; \ 138 fi 139 140 # A bunch of quick targets so you can type "make list" to create the classlist, etc 141 git: ${PC_JAVA_SOURCES} 142 app: ${PC_APP_JAR} 143 jmeter: ${JMETER_BIN} 144 unpack: ${PC_APP_UNPACKED} 145 146 # The "4 step training run" workflow -- this will soon be replaced with the new workflow in ../javac_new_workflow/ 147 list: ${PC_CLASSLIST} 148 static: ${PC_STATIC_JSA} 149 dynamic: ${PC_DYNAMIC_ST_JSA} 150 aot: ${PC_ST_CACHED_CODE} 151 152 # Check out this specific version of spring-petclinic that we have been testing with. 153 # https://github.com/spring-projects/spring-petclinic/commit/80fd11067c4662486e4c635deceba927375b621c 154 # Author: Dave Syer <dsyer@vmware.com> 155 # Date: Wed Jan 10 05:01:00 2024 156 # Upgrade to Boot 3.2.1 157 ${PC_JAVA_SOURCES}: 158 rm -rf ${PC_REPO} 159 git clone https://github.com/spring-projects/spring-petclinic ${PC_REPO} 160 cd ${PC_REPO}; git reset --hard 80fd11067c4662486e4c635deceba927375b621c 161 cd ${PC_REPO}; git apply ../premain-patch-noautoquit.diff 162 163 ${JMETER_BIN}: 164 rm -fr ${JMETER_DIR} 165 wget ${JMETER_URL} 166 unzip -q ${JMETER_ZIP} 167 ls -l $@ 168 169 # Need to touch ${PC_APP_JAR} as mvn wants to set it the release date of 3.2.0-SNAPSHOT 170 ${PC_APP_JAR}: ${PC_JAVA_SOURCES} 171 cd ${PC_REPO}; JAVA_HOME=${JDK17_HOME} mvn -Dmaven.test.skip=true package 172 if test -f ${PC_APP_JAR}; then \ 173 touch ${PC_APP_JAR}; \ 174 fi 175 176 ${PC_APP_UNPACKED}: ${PC_APP_JAR} 177 rm -rf ${PC_APP_UNPACKED} 178 mkdir -p ${PC_APP_UNPACKED} 179 cd ${PC_APP_UNPACKED} && \ 180 ${JAR_CMD} xf ../spring-petclinic-3.2.0-SNAPSHOT.jar && \ 181 ${JAR_CMD} cf classes.jar META-INF org && \ 182 cd BOOT-INF/classes/ && \ 183 ${JAR_CMD} cf classes.jar * 184 echo ${PC_APP_UNPACKED}/classes.jar $$(find ${PC_APP_UNPACKED}/BOOT-INF -name \*.jar | sort) \ 185 | sed -e 's/ /:/g' > ${PC_APP_UNPACKED}/classpath 186 ${JAR_CMD} cf0 ${PC_APP_UNPACKED_ZIP} ${PC_APP_UNPACKED} 187 $(MAKE) -f WarmupMakefile run17 188 189 #uncomment this to see the generated classes for dynamic proxies 190 #SAVE_GEN_FILES=-Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true 191 192 define wait-for-startup 193 tail -n+0 -f $@.out | sed --quiet '/Booted and returned/ q' 194 endef 195 196 define exit-app 197 cp application.pid app.pid 198 curl -X POST localhost:8080/actuator/shutdown 199 tail -f --pid=`cat app.pid` /dev/null 200 endef 201 202 # petclinic_test_plan.jmx is derived from https://github.com/spring-projects/spring-petclinic/blob/main/src/test/jmeter/petclinic_test_plan.jmx 203 define run-jmeter 204 taskset -c "${JMETER_CPUS}" ${JMETER_BIN} -JDURATION=${JMETER_DURATION} -JTHREADS=${JMETER_THREADS} -Dsummariser.interval=6 -n -t petclinic_test_plan.jmx | tee tput-$@.log 205 endef 206 207 ${PC_BL_CLASSLIST}: ${PC_APP_UNPACKED} 208 ${BL_JAVA} -Xshare:off -XX:DumpLoadedClassList=${PC_BL_CLASSLIST} \ 209 -Xlog:class+load=debug:file=$@.log ${SAVE_GEN_FILES} \ 210 ${UNPACKED_CMDLINE} &> $@.out & 211 $(wait-for-startup) 212 $(exit-app) 213 wc -lc $@ 214 215 ${PC_CLASSLIST}: ${PC_APP_UNPACKED} 216 ${PREMAIN_JAVA} -Xshare:off -XX:DumpLoadedClassList=${PC_CLASSLIST} \ 217 -Xlog:class+load=debug:file=$@.log ${SAVE_GEN_FILES} \ 218 ${UNPACKED_CMDLINE} &> $@.out & 219 $(wait-for-startup) 220 $(run-jmeter) 221 $(exit-app) 222 wc -lc $@ 223 224 ${PC_STATIC_BL_JSA}: ${PC_BL_CLASSLIST} 225 rm -f ${PC_STATIC_BL_JSA}.log 226 ${BL_JAVA} -Xshare:dump -XX:SharedClassListFile=${PC_BL_CLASSLIST} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \ 227 -XX:SharedArchiveFile=${PC_STATIC_BL_JSA} -Xlog:cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log 228 ls -l $@ 229 230 ${PC_STATIC_JSA}: ${PC_CLASSLIST} 231 rm -f ${PC_STATIC_JSA}.log 232 ${PREMAIN_JAVA} -Xshare:dump -XX:SharedClassListFile=${PC_CLASSLIST} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \ 233 -XX:+AOTClassLinking -XX:+ArchiveDynamicProxies -XX:+ArchiveReflectionData \ 234 -XX:+ArchiveLoaderLookupCache -Dcds.debug.archived.packages=1 \ 235 -XX:SharedArchiveFile=${PC_STATIC_JSA} -Xlog:cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log 236 ls -l $@ 237 238 ${PC_DYNAMIC_BL_JSA}: ${PC_STATIC_BL_JSA} 239 rm -f ${PC_DYNAMIC_BL_JSA} ${PC_DYNAMIC_BL_JSA}.log 240 ${BL_JAVA} -XX:SharedArchiveFile=${PC_STATIC_BL_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_BL_JSA} \ 241 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=$@.log \ 242 ${UNPACKED_CMDLINE} &> $@.out & 243 $(wait-for-startup) 244 $(exit-app) 245 ls -l $@ 246 247 ${PC_DYNAMIC_NOTRAINING_JSA}: ${PC_STATIC_JSA} 248 rm -f ${PC_DYNAMIC_NOTRAINING_JSA} ${PC_DYNAMIC_NOTRAINING_JSA}.log 249 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_NOTRAINING_JSA} \ 250 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=$@.log \ 251 ${UNPACKED_CMDLINE} &> $@.out & 252 $(wait-for-startup) 253 $(exit-app) 254 ls -l $@ 255 256 ${PC_DYNAMIC_ST_JSA}: ${PC_STATIC_JSA} 257 rm -f ${PC_DYNAMIC_ST_JSA} ${PC_DYNAMIC_ST_JSA}.log 258 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_ST_JSA} \ 259 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=$@.log \ 260 -XX:+RecordTraining ${UNPACKED_CMDLINE} &> $@.out & 261 $(wait-for-startup) 262 $(exit-app) 263 ls -l $@ 264 265 ${PC_DYNAMIC_LT_JSA}: ${PC_STATIC_JSA} 266 rm -f ${PC_DYNAMIC_LT_JSA} ${PC_DYNAMIC_LT_JSA}.log 267 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_LT_JSA} \ 268 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=$@.log \ 269 -XX:+RecordTraining ${UNPACKED_CMDLINE} &> $@.out & 270 $(wait-for-startup) 271 $(run-jmeter) 272 $(exit-app) 273 ls -l $@ 274 275 ${PC_ST_CACHED_CODE}: ${PC_DYNAMIC_ST_JSA} 276 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_ST_JSA} -XX:+ReplayTraining -XX:+StoreCachedCode \ 277 -XX:CachedCodeFile=${PC_ST_CACHED_CODE} -XX:CachedCodeMaxSize=512M ${UNPACKED_CMDLINE} &> $@.out & 278 $(wait-for-startup) 279 $(exit-app) 280 ls -l $@ 281 282 ${PC_LT_CACHED_CODE}: ${PC_DYNAMIC_LT_JSA} 283 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_LT_JSA} -XX:+ReplayTraining -XX:+StoreCachedCode \ 284 -Xlog:scc,cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log \ 285 -XX:CachedCodeFile=${PC_LT_CACHED_CODE} -XX:CachedCodeMaxSize=512M ${UNPACKED_CMDLINE} &> $@.out & 286 $(wait-for-startup) 287 $(run-jmeter) 288 $(exit-app) 289 ls -l $@ 290 291 ${PC_CDS_PREIMAGE}: ${PC_APP_UNPACKED} 292 rm -f ${PC_CDS_PREIMAGE} ${PC_CDS} 293 ${PREMAIN_JAVA} -XX:+AOTClassLinking \ 294 -XX:+ArchiveReflectionData \ 295 -XX:+ArchiveDynamicProxies -XX:+ArchiveLoaderLookupCache -XX:CachedCodeMaxSize=512M \ 296 -XX:+UnlockDiagnosticVMOptions -XX:+CDSManualFinalImage -XX:CacheDataStore=${PC_CDS} \ 297 -Xlog:cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log \ 298 ${UNPACKED_CMDLINE} &> $@.out & 299 $(wait-for-startup) 300 $(run-jmeter) 301 $(exit-app) 302 ls -l $@ 303 304 ${PC_CDS}: ${PC_CDS_PREIMAGE} 305 rm -f ${PC_CDS} 306 ${PREMAIN_JAVA} -XX:+AOTClassLinking -XX:CachedCodeMaxSize=512M \ 307 -XX:+UnlockDiagnosticVMOptions -XX:CDSPreimage=${PC_CDS_PREIMAGE} -XX:CacheDataStore=${PC_CDS} \ 308 -Xlog:scc,cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log \ 309 -XX:-AssemblyStepInlining \ 310 ${UNPACKED_CMDLINE} &> $@.out 311 ls -l $@ 312 ls -l $@.code 313 314 warmup-bl: ${PC_DYNAMIC_BL_JSA} ${JMETER_BIN} 315 time taskset -c "${APP_CPUS}" ${BL_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_BL_JSA} \ 316 ${UNPACKED_CMDLINE} &> $@.out & 317 $(wait-for-startup) 318 $(run-jmeter) 319 $(exit-app) 320 321 # run with dynamic archive without training data 322 warmup-preload: ${PC_DYNAMIC_NOTRAINING_JSA} ${JMETER_BIN} 323 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_NOTRAINING_JSA} \ 324 ${UNPACKED_CMDLINE} &> $@.out & 325 $(wait-for-startup) 326 $(run-jmeter) 327 $(exit-app) 328 329 # run with dynamic archive with startup training data 330 warmup-st: ${PC_DYNAMIC_ST_JSA} ${JMETER_BIN} 331 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_ST_JSA} -XX:+ReplayTraining \ 332 ${UNPACKED_CMDLINE} &> $@.out & 333 $(wait-for-startup) 334 $(run-jmeter) 335 $(exit-app) 336 337 # run with dynamic archive with load training data 338 warmup-lt: ${PC_DYNAMIC_LT_JSA} ${JMETER_BIN} 339 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_LT_JSA} -XX:+ReplayTraining \ 340 ${UNPACKED_CMDLINE} &> $@.out & 341 $(wait-for-startup) 342 $(run-jmeter) 343 $(exit-app) 344 345 # run with startup training data and aot code 346 warmup-st-aot: ${PC_ST_CACHED_CODE} ${JMETER_BIN} 347 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_ST_JSA} -XX:+ReplayTraining -XX:+LoadCachedCode \ 348 -XX:CachedCodeFile=${PC_ST_CACHED_CODE} ${UNPACKED_CMDLINE} &> $@.out & 349 $(wait-for-startup) 350 $(run-jmeter) 351 $(exit-app) 352 353 # run with load training data and aot code 354 warmup-lt-aot: ${PC_LT_CACHED_CODE} ${JMETER_BIN} 355 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_LT_JSA} -XX:+ReplayTraining -XX:+LoadCachedCode \ 356 -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:-TraceDeoptimization \ 357 -Xlog:init -XX:CachedCodeFile=${PC_LT_CACHED_CODE} ${UNPACKED_CMDLINE} &> $@.out & 358 $(wait-for-startup) 359 $(run-jmeter) 360 $(exit-app) 361 362 # run with new single-step workflow 363 warmup-lt-aot-new: ${PC_CDS} 364 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:CacheDataStore=${PC_CDS} \ 365 -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation \ 366 -Xlog:init ${UNPACKED_CMDLINE} &> $@.out & 367 $(wait-for-startup) 368 $(run-jmeter) 369 $(exit-app) 370 371 run: warmup-bl warmup-preload warmup-st warmup-lt warmup-st-aot warmup-lt-aot warmup-lt-aot-new 372 373 run17: ${PC_APP_UNPACKED} 374 time ${JDK17_JAVA} ${UNPACKED_CMDLINE} &> $@.out & 375 $(wait-for-startup) 376 $(exit-app) 377 378 379 clean: clean0 380 rm -rf *~ ${PC_REPO} 381 382 # clean the the leyden artifacts 383 clean0: 384 rm -fv spring-petclinic.* *.out tput-*.log app.pid