1 # Copyright (c) 2024, 2025, 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 $(error This makefile no longer works. Need to update it to use -XX:AOTCache flags) 70 71 # Usually there's no need to change the following 72 JAR_CMD = ${JDK17_HOME}/bin/jar 73 JDK17_JAVA = ${JDK17_HOME}/bin/java 74 PREMAIN_JAVA = ${PREMAIN_HOME}/bin/java 75 BL_JAVA = ${BL_HOME}/bin/java 76 PC_REPO = petclinic-snapshot-warmup 77 PC_JAVA_SOURCES = ${PC_REPO}/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java 78 PC_APP_JAR = ${PC_REPO}/target/spring-petclinic-3.2.0-SNAPSHOT.jar 79 PC_APP_UNPACKED = ${PC_REPO}/target/unpacked 80 JMETER_DIR = apache-jmeter-5.5 81 JMETER_BIN = ${JMETER_DIR}/bin/jmeter 82 JMETER_ZIP = ${JMETER_DIR}.zip 83 JMETER_URL = https://archive.apache.org/dist/jmeter/binaries/${JMETER_ZIP} 84 85 # This is for uploading to artifactory, to be tested with 86 # ../../runtime/cds/appcds/leyden/SpringPetClinic.java 87 PC_APP_UNPACKED_ZIP = ${PC_REPO}/target/spring-petclinic-3.2.0.zip 88 89 PC_MAIN_CLASS = org.springframework.samples.petclinic.PetClinicApplication 90 PC_CLASSLIST = spring-petclinic.classlist 91 PC_STATIC_JSA = spring-petclinic.static.jsa 92 PC_DYNAMIC_ST_JSA = spring-petclinic.dynamic-st.jsa 93 PC_DYNAMIC_LT_JSA = spring-petclinic.dynamic-lt.jsa 94 PC_DYNAMIC_NOTRAINING_JSA = spring-petclinic.dynamic-notraining.jsa 95 PC_ST_CACHED_CODE = spring-petclinic.code-st.jsa 96 PC_LT_CACHED_CODE = spring-petclinic.code-lt.jsa 97 98 PC_BL_CLASSLIST = spring-petclinic.bl_classlist 99 PC_STATIC_BL_JSA = spring-petclinic.static_bl.jsa 100 PC_DYNAMIC_BL_JSA = spring-petclinic.dynamic_bl.jsa 101 102 PC_CDS_PREIMAGE = spring-petclinic.cds.preimage 103 PC_CDS = spring-petclinic.cds 104 105 JMETER_DURATION = 180 106 JMETER_THREADS = 1 107 JMETER_CPUS = 12-13 108 APP_CPUS = 14-19 109 110 # TODO: should we add -Dspring.context.exit=onRefresh to command line?? 111 # This will make the JVM quit after printing this line: 112 # 113 # 4:21.639 ... o.s.b.a.e.web.EndpointLinksResolver : Exposing 13 endpoint(s) beneath base path '/actuator' 114 # 115 # Whereas -DautoQuit=true will make it exit after printing the following (a little bit of application code is executed) 116 # 117 # 4:21.665 ... o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '' 118 # 4:21.666 ... o.s.s.petclinic.PetClinicApplication : Started PetClinicApplication in 1.358 seconds (process running for 1.584) 119 # #### Booted and returned in 1453ms 120 # 4:21.692 ... j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 121 # 4:21.693 ... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 122 # 4:21.694 ... com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. 123 HEAP_SIZE = -Xmx2g 124 UNPACKED_CMDLINE = $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath -DautoQuit=true -Dspring.aot.enabled=true -Dspring.output.ansi.enabled=NEVER ${PC_MAIN_CLASS} 125 126 all: check git app aot 127 128 check: 129 @if ${JDK17_JAVA} --version | grep -q '17.*LTS'; then \ 130 true; \ 131 else \ 132 echo JDK17_HOME should point to JDK 17; \ 133 exit 1; \ 134 fi 135 @if ${PREMAIN_JAVA} -XX:+PrintFlagsFinal --version | grep -q CDSManualFinalImage; then \ 136 true; \ 137 else \ 138 echo PREMAIN_HOME should point to your build of https://github.com/openjdk/leyden/tree/premain; \ 139 exit 1; \ 140 fi 141 142 # A bunch of quick targets so you can type "make list" to create the classlist, etc 143 git: ${PC_JAVA_SOURCES} 144 app: ${PC_APP_JAR} 145 jmeter: ${JMETER_BIN} 146 unpack: ${PC_APP_UNPACKED} 147 148 # The "4 step training run" workflow -- this will soon be replaced with the new workflow in ../javac_new_workflow/ 149 list: ${PC_CLASSLIST} 150 static: ${PC_STATIC_JSA} 151 dynamic: ${PC_DYNAMIC_ST_JSA} 152 aot: ${PC_ST_CACHED_CODE} 153 154 # Check out this specific version of spring-petclinic that we have been testing with. 155 # https://github.com/spring-projects/spring-petclinic/commit/80fd11067c4662486e4c635deceba927375b621c 156 # Author: Dave Syer <dsyer@vmware.com> 157 # Date: Wed Jan 10 05:01:00 2024 158 # Upgrade to Boot 3.2.1 159 ${PC_JAVA_SOURCES}: 160 rm -rf ${PC_REPO} 161 git clone https://github.com/spring-projects/spring-petclinic ${PC_REPO} 162 cd ${PC_REPO}; git reset --hard 80fd11067c4662486e4c635deceba927375b621c 163 cd ${PC_REPO}; git apply ../premain-patch-noautoquit.diff 164 165 ${JMETER_BIN}: 166 rm -fr ${JMETER_DIR} 167 wget ${JMETER_URL} 168 unzip -q ${JMETER_ZIP} 169 ls -l $@ 170 171 # Need to touch ${PC_APP_JAR} as mvn wants to set it the release date of 3.2.0-SNAPSHOT 172 ${PC_APP_JAR}: ${PC_JAVA_SOURCES} 173 cd ${PC_REPO}; JAVA_HOME=${JDK17_HOME} mvn -Dmaven.test.skip=true package 174 if test -f ${PC_APP_JAR}; then \ 175 touch ${PC_APP_JAR}; \ 176 fi 177 178 ${PC_APP_UNPACKED}: ${PC_APP_JAR} 179 rm -rf ${PC_APP_UNPACKED} 180 mkdir -p ${PC_APP_UNPACKED} 181 cd ${PC_APP_UNPACKED} && \ 182 ${JAR_CMD} xf ../spring-petclinic-3.2.0-SNAPSHOT.jar && \ 183 ${JAR_CMD} cf classes.jar META-INF org && \ 184 cd BOOT-INF/classes/ && \ 185 ${JAR_CMD} cf classes.jar * 186 echo ${PC_APP_UNPACKED}/classes.jar $$(find ${PC_APP_UNPACKED}/BOOT-INF -name \*.jar | sort) \ 187 | sed -e 's/ /:/g' > ${PC_APP_UNPACKED}/classpath 188 ${JAR_CMD} cf0 ${PC_APP_UNPACKED_ZIP} ${PC_APP_UNPACKED} 189 $(MAKE) -f WarmupMakefile run17 190 191 #uncomment this to see the generated classes for dynamic proxies 192 #SAVE_GEN_FILES=-Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true 193 194 define wait-for-startup 195 tail -n+0 -f $@.out | sed --quiet '/Booted and returned/ q' 196 endef 197 198 define exit-app 199 cp application.pid app.pid 200 curl -X POST localhost:8080/actuator/shutdown 201 tail -f --pid=`cat app.pid` /dev/null 202 endef 203 204 # petclinic_test_plan.jmx is derived from https://github.com/spring-projects/spring-petclinic/blob/main/src/test/jmeter/petclinic_test_plan.jmx 205 define run-jmeter 206 taskset -c "${JMETER_CPUS}" ${JMETER_BIN} -JDURATION=${JMETER_DURATION} -JTHREADS=${JMETER_THREADS} -Dsummariser.interval=6 -n -t petclinic_test_plan.jmx | tee tput-$@.log 207 endef 208 209 ${PC_BL_CLASSLIST}: ${PC_APP_UNPACKED} 210 ${BL_JAVA} -Xshare:off -XX:DumpLoadedClassList=${PC_BL_CLASSLIST} \ 211 -Xlog:class+load=debug:file=$@.log ${SAVE_GEN_FILES} \ 212 ${UNPACKED_CMDLINE} &> $@.out & 213 $(wait-for-startup) 214 $(exit-app) 215 wc -lc $@ 216 217 ${PC_CLASSLIST}: ${PC_APP_UNPACKED} 218 ${PREMAIN_JAVA} -Xshare:off -XX:DumpLoadedClassList=${PC_CLASSLIST} \ 219 -Xlog:class+load=debug:file=$@.log ${SAVE_GEN_FILES} \ 220 ${UNPACKED_CMDLINE} &> $@.out & 221 $(wait-for-startup) 222 $(run-jmeter) 223 $(exit-app) 224 wc -lc $@ 225 226 ${PC_STATIC_BL_JSA}: ${PC_BL_CLASSLIST} 227 rm -f ${PC_STATIC_BL_JSA}.log 228 ${BL_JAVA} -Xshare:dump -XX:SharedClassListFile=${PC_BL_CLASSLIST} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \ 229 -XX:SharedArchiveFile=${PC_STATIC_BL_JSA} -Xlog:cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log 230 ls -l $@ 231 232 ${PC_STATIC_JSA}: ${PC_CLASSLIST} 233 rm -f ${PC_STATIC_JSA}.log 234 ${PREMAIN_JAVA} -Xshare:dump -XX:SharedClassListFile=${PC_CLASSLIST} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \ 235 -XX:+AOTClassLinking -XX:+ArchiveDynamicProxies -XX:+ArchiveReflectionData \ 236 -XX:+ArchiveLoaderLookupCache -Dcds.debug.archived.packages=1 \ 237 -XX:SharedArchiveFile=${PC_STATIC_JSA} -Xlog:cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log 238 ls -l $@ 239 240 ${PC_DYNAMIC_BL_JSA}: ${PC_STATIC_BL_JSA} 241 rm -f ${PC_DYNAMIC_BL_JSA} ${PC_DYNAMIC_BL_JSA}.log 242 ${BL_JAVA} -XX:SharedArchiveFile=${PC_STATIC_BL_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_BL_JSA} \ 243 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=$@.log \ 244 ${UNPACKED_CMDLINE} &> $@.out & 245 $(wait-for-startup) 246 $(exit-app) 247 ls -l $@ 248 249 ${PC_DYNAMIC_NOTRAINING_JSA}: ${PC_STATIC_JSA} 250 rm -f ${PC_DYNAMIC_NOTRAINING_JSA} ${PC_DYNAMIC_NOTRAINING_JSA}.log 251 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_NOTRAINING_JSA} \ 252 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=$@.log \ 253 ${UNPACKED_CMDLINE} &> $@.out & 254 $(wait-for-startup) 255 $(exit-app) 256 ls -l $@ 257 258 ${PC_DYNAMIC_ST_JSA}: ${PC_STATIC_JSA} 259 rm -f ${PC_DYNAMIC_ST_JSA} ${PC_DYNAMIC_ST_JSA}.log 260 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_ST_JSA} \ 261 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=$@.log \ 262 -XX:+UnlockDiagnosticVMOptions -XX:+AOTRecordTraining ${UNPACKED_CMDLINE} &> $@.out & 263 $(wait-for-startup) 264 $(exit-app) 265 ls -l $@ 266 267 ${PC_DYNAMIC_LT_JSA}: ${PC_STATIC_JSA} 268 rm -f ${PC_DYNAMIC_LT_JSA} ${PC_DYNAMIC_LT_JSA}.log 269 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA} -XX:ArchiveClassesAtExit=${PC_DYNAMIC_LT_JSA} \ 270 -Xlog:cds=debug,cds+class=debug,cds+resolve=debug:file=$@.log \ 271 -XX:+UnlockDiagnosticVMOptions -XX:+AOTRecordTraining ${UNPACKED_CMDLINE} &> $@.out & 272 $(wait-for-startup) 273 $(run-jmeter) 274 $(exit-app) 275 ls -l $@ 276 277 ${PC_ST_CACHED_CODE}: ${PC_DYNAMIC_ST_JSA} 278 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_ST_JSA} -XX:+UnlockDiagnosticVMOptions -XX:+AOTReplayTraining -XX:+StoreCachedCode \ 279 -XX:CachedCodeFile=${PC_ST_CACHED_CODE} -XX:CachedCodeMaxSize=512M ${UNPACKED_CMDLINE} &> $@.out & 280 $(wait-for-startup) 281 $(exit-app) 282 ls -l $@ 283 284 ${PC_LT_CACHED_CODE}: ${PC_DYNAMIC_LT_JSA} 285 ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_LT_JSA} -XX:+UnlockDiagnosticVMOptions -XX:+AOTReplayTraining -XX:+StoreCachedCode \ 286 -Xlog:aot+codecache=debug,cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log \ 287 -XX:CachedCodeFile=${PC_LT_CACHED_CODE} -XX:CachedCodeMaxSize=512M ${UNPACKED_CMDLINE} &> $@.out & 288 $(wait-for-startup) 289 $(run-jmeter) 290 $(exit-app) 291 ls -l $@ 292 293 ${PC_CDS_PREIMAGE}: ${PC_APP_UNPACKED} 294 rm -f ${PC_CDS_PREIMAGE} ${PC_CDS} 295 ${PREMAIN_JAVA} -XX:+AOTClassLinking \ 296 -XX:+ArchiveReflectionData \ 297 -XX:+ArchiveDynamicProxies -XX:+ArchiveLoaderLookupCache -XX:CachedCodeMaxSize=512M \ 298 -XX:+UnlockDiagnosticVMOptions -XX:+CDSManualFinalImage -XX:CacheDataStore=${PC_CDS} \ 299 -Xlog:cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log \ 300 ${UNPACKED_CMDLINE} &> $@.out & 301 $(wait-for-startup) 302 $(run-jmeter) 303 $(exit-app) 304 ls -l $@ 305 306 ${PC_CDS}: ${PC_CDS_PREIMAGE} 307 rm -f ${PC_CDS} 308 ${PREMAIN_JAVA} -XX:+AOTClassLinking -XX:CachedCodeMaxSize=512M \ 309 -XX:+UnlockDiagnosticVMOptions -XX:CDSPreimage=${PC_CDS_PREIMAGE} -XX:CacheDataStore=${PC_CDS} \ 310 -Xlog:aot+codecache=debug,cds=debug,cds+class=debug,cds+heap=warning,cds+resolve=debug:file=$@.log \ 311 -XX:-AssemblyStepInlining \ 312 ${UNPACKED_CMDLINE} &> $@.out 313 ls -l $@ 314 ls -l $@.code 315 316 warmup-bl: ${PC_DYNAMIC_BL_JSA} ${JMETER_BIN} 317 time taskset -c "${APP_CPUS}" ${BL_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_BL_JSA} \ 318 ${UNPACKED_CMDLINE} &> $@.out & 319 $(wait-for-startup) 320 $(run-jmeter) 321 $(exit-app) 322 323 # run with dynamic archive without training data 324 warmup-preload: ${PC_DYNAMIC_NOTRAINING_JSA} ${JMETER_BIN} 325 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_NOTRAINING_JSA} \ 326 ${UNPACKED_CMDLINE} &> $@.out & 327 $(wait-for-startup) 328 $(run-jmeter) 329 $(exit-app) 330 331 # run with dynamic archive with startup training data 332 warmup-st: ${PC_DYNAMIC_ST_JSA} ${JMETER_BIN} 333 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_ST_JSA} -XX:+UnlockDiagnosticVMOptions -XX:+AOTReplayTraining \ 334 ${UNPACKED_CMDLINE} &> $@.out & 335 $(wait-for-startup) 336 $(run-jmeter) 337 $(exit-app) 338 339 # run with dynamic archive with load training data 340 warmup-lt: ${PC_DYNAMIC_LT_JSA} ${JMETER_BIN} 341 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_LT_JSA} -XX:+UnlockDiagnosticVMOptions -XX:+AOTReplayTraining \ 342 ${UNPACKED_CMDLINE} &> $@.out & 343 $(wait-for-startup) 344 $(run-jmeter) 345 $(exit-app) 346 347 # run with startup training data and aot code 348 warmup-st-aot: ${PC_ST_CACHED_CODE} ${JMETER_BIN} 349 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_ST_JSA} -XX:+UnlockDiagnosticVMOptions -XX:+AOTReplayTraining -XX:+LoadCachedCode \ 350 -XX:CachedCodeFile=${PC_ST_CACHED_CODE} ${UNPACKED_CMDLINE} &> $@.out & 351 $(wait-for-startup) 352 $(run-jmeter) 353 $(exit-app) 354 355 # run with load training data and aot code 356 warmup-lt-aot: ${PC_LT_CACHED_CODE} ${JMETER_BIN} 357 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:SharedArchiveFile=${PC_DYNAMIC_LT_JSA} -XX:+UnlockDiagnosticVMOptions -XX:+AOTReplayTraining -XX:+LoadCachedCode \ 358 -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:-TraceDeoptimization \ 359 -Xlog:init -XX:CachedCodeFile=${PC_LT_CACHED_CODE} ${UNPACKED_CMDLINE} &> $@.out & 360 $(wait-for-startup) 361 $(run-jmeter) 362 $(exit-app) 363 364 # run with new single-step workflow 365 warmup-lt-aot-new: ${PC_CDS} 366 time taskset -c "${APP_CPUS}" ${PREMAIN_JAVA} -XX:CacheDataStore=${PC_CDS} \ 367 -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation \ 368 -Xlog:init ${UNPACKED_CMDLINE} &> $@.out & 369 $(wait-for-startup) 370 $(run-jmeter) 371 $(exit-app) 372 373 run: warmup-bl warmup-preload warmup-st warmup-lt warmup-st-aot warmup-lt-aot warmup-lt-aot-new 374 375 run17: ${PC_APP_UNPACKED} 376 time ${JDK17_JAVA} ${UNPACKED_CMDLINE} &> $@.out & 377 $(wait-for-startup) 378 $(exit-app) 379 380 381 clean: clean0 382 rm -rf *~ ${PC_REPO} 383 384 # clean the the leyden artifacts 385 clean0: 386 rm -fv spring-petclinic.* *.out tput-*.log app.pid