1 # Copyright (c) 2023, 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 demo (https://github.com/spring-projects/spring-petclinic)
 24 #
 25 # Build spring-petclinic:
 26 #    make app
 27 #
 28 # Run with mainline, using only default CDS archive
 29 #    make run0.ml
 30 #
 31 # Run with mainline, using custom static CDS archive
 32 #    make runs.ml
 33 #
 34 # Run with mainline, using AOT cache (JEP 483)
 35 #    make runa.ml
 36 #
 37 # Run with leyden, using AOT cache (JEP 483 + all new Leyden optimizations)
 38 #    make runa
 39 
 40 # Set the following to point to youd "Build JDK", your JDK mainline build, and your Leyden JDK build.
 41 #
 42 #  *** NOTE: JDK 21 (or 17) is needed to build spring-petclinic-3.2.0-SNAPSHOT.jar
 43 BLDJDK_HOME   = /work/official/jdk21
 44 
 45 # Points to your build with https://github.com/openjdk/jdk
 46 # For comparison purposes, this build should be the latest version of the mainline that
 47 # has been merged into https://github.com/openjdk/leyden/tree/premain
 48 MAINLINE_HOME = /work/official/jdk24
 49 
 50 # Points to your build with https://github.com/openjdk/leyden/tree/premain
 51 PREMAIN_HOME = /work/bld/le4/images/jdk
 52 #===============================================================================
 53 
 54 LOG_INIT = -Xlog:init
 55 
 56 # Options passed to PREMAIN_JAVA. See compare_premain_builds below
 57 PM_OPTS =
 58 
 59 # Usually there's no need to change the following
 60 JAR_CMD          = ${BLDJDK_HOME}/bin/jar
 61 JAVAC_CMD        = ${BLDJDK_HOME}/bin/javac
 62 BLDJDK_JAVA      = ${BLDJDK_HOME}/bin/java
 63 MAINLINE_JAVA    = ${MAINLINE_HOME}/bin/java
 64 PREMAIN_JAVA     = ${PREMAIN_HOME}/bin/java ${PM_OPTS}
 65 PC_REPO          = petclinic-snapshot
 66 PC_JAVA_SOURCES = ${PC_REPO}/src/main/java/org/springframework/samples/petclinic/PetClinicApplication.java
 67 PC_APP_JAR       = ${PC_REPO}/target/spring-petclinic-3.2.0-SNAPSHOT.jar
 68 PC_APP_UNPACKED  = ${PC_REPO}/target/unpacked
 69 
 70 # This is for uploading to artifactory, to be tested with
 71 # ../../runtime/cds/appcds/leyden/SpringPetClinic.java
 72 PC_APP_UNPACKED_ZIP = ${PC_REPO}/target/spring-petclinic-3.2.0.zip
 73 
 74 PC_MAIN_CLASS    = org.springframework.samples.petclinic.PetClinicApplication
 75 
 76 # Note: you can add specify PM_VER (PreMain Version) for comparing the performance of different builds of premain.
 77 # See the compare_premain_builds target below
 78 
 79 PC_ML_AOTCONF    = spring-petclinic$(PM_VER).ml.aotconf
 80 PC_ML_AOT        = spring-petclinic$(PM_VER).ml.aot
 81 
 82 PC_AOTCONF       = spring-petclinic$(PM_VER).aotconf
 83 PC_AOT           = spring-petclinic$(PM_VER).aot
 84 
 85 # TODO: should we add -Dspring.context.exit=onRefresh to command line??
 86 # This will make the JVM quit after printing this line:
 87 #
 88 #    4:21.639 ... o.s.b.a.e.web.EndpointLinksResolver      : Exposing 13 endpoint(s) beneath base path '/actuator'
 89 #
 90 # Whereas -DautoQuit=true will make it exit after printing the following (a little bit of application code is executed)
 91 #
 92 #    4:21.665 ... o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path ''
 93 #    4:21.666 ... o.s.s.petclinic.PetClinicApplication     : Started PetClinicApplication in 1.358 seconds (process running for 1.584)
 94 #    #### Booted and returned in 1453ms
 95 #    4:21.692 ... j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
 96 #    4:21.693 ... com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
 97 #    4:21.694 ... com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
 98 HEAP_SIZE        = -Xmx2g
 99 UNPACKED_CMDLINE = $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath -DautoQuit=true -Dspring.aot.enabled=true -Dspring.output.ansi.enabled=NEVER ${PC_MAIN_CLASS}
100 DUMMY_CMDLINE    = $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath.dummy Dummy
101 
102 all: check git app aot
103 
104 check:
105 	@if ${PREMAIN_JAVA} -XX:+PrintFlagsFinal --version | grep -q CDSManualFinalImage; then \
106 	    true; \
107 	else \
108 	    echo PREMAIN_HOME should point to your build of https://github.com/openjdk/leyden/tree/premain; \
109 	    exit 1; \
110 	fi
111 
112 # A bunch of quick targets so you can type "make list" to create the classlist, etc
113 git: ${PC_JAVA_SOURCES}
114 app: ${PC_APP_JAR}
115 unpack: ${PC_APP_UNPACKED}
116 
117 
118 # Check out this specific version of spring-petclinic that we have been testing with.
119 # https://github.com/spring-projects/spring-petclinic/commit/80fd11067c4662486e4c635deceba927375b621c
120 #    Author: Dave Syer <dsyer@vmware.com>
121 #    Date:   Wed Jan 10 05:01:00 2024
122 #        Upgrade to Boot 3.2.1
123 ${PC_JAVA_SOURCES}:
124 	rm -rf ${PC_REPO}
125 	git clone https://github.com/spring-projects/spring-petclinic ${PC_REPO}
126 	cd ${PC_REPO}; git reset --hard 80fd11067c4662486e4c635deceba927375b621c
127 	cd ${PC_REPO}; git apply ../premain-patch.diff
128 
129 # Need to touch ${PC_APP_JAR} as mvn wants to set it the release date of 3.2.0-SNAPSHOT
130 ${PC_APP_JAR}: ${PC_JAVA_SOURCES}
131 	cd ${PC_REPO}; JAVA_HOME=${BLDJDK_HOME} mvn -Dmaven.test.skip=true package
132 	if test -f ${PC_APP_JAR}; then \
133 	    touch ${PC_APP_JAR}; \
134 	fi
135 
136 ${PC_APP_UNPACKED}: ${PC_APP_JAR}
137 	rm -rf ${PC_APP_UNPACKED}
138 	mkdir -p ${PC_APP_UNPACKED}
139 	cd ${PC_APP_UNPACKED} && \
140 	    ${JAR_CMD} xf ../spring-petclinic-3.2.0-SNAPSHOT.jar && \
141 	    ${JAR_CMD} cf classes.jar META-INF org && \
142             cd BOOT-INF/classes/ && \
143 	    ${JAR_CMD} cf classes.jar *
144 	echo ${PC_APP_UNPACKED}/classes.jar $$(find ${PC_APP_UNPACKED}/BOOT-INF -name \*.jar | sort) \
145 	    | sed -e 's/ /:/g' > ${PC_APP_UNPACKED}/classpath
146 	echo $$(cat ${PC_APP_UNPACKED}/classpath):Dummy.jar > ${PC_APP_UNPACKED}/classpath.dummy
147 	${JAR_CMD} cf0 ${PC_APP_UNPACKED_ZIP} ${PC_APP_UNPACKED}
148 	$(MAKE) runb
149 
150 
151 
152 # run mainline, default CDS archive only
153 run0.ml: ${PC_APP_UNPACKED}
154 	${MAINLINE_JAVA} ${LOG_INIT} ${UNPACKED_CMDLINE}
155 
156 # Run using "build JDK"
157 runb: ${PC_APP_UNPACKED}
158 	${BLDJDK_JAVA} ${UNPACKED_CMDLINE}
159 
160 # Running with mainline
161 PC_CLASSLIST_MAINLINE   = spring-petclinic.ml.classlist
162 PC_STATIC_JSA_MAINLINE  = spring-petclinic.static.ml.jsa
163 
164 list.ml:   ${PC_CLASSLIST_MAINLINE}
165 
166 static.ml: ${PC_STATIC_JSA_MAINLINE}
167 
168 ${PC_CLASSLIST_MAINLINE}: ${PC_APP_UNPACKED}
169 	${MAINLINE_JAVA} -Xshare:off -XX:DumpLoadedClassList=${PC_CLASSLIST_MAINLINE} \
170 	    -Xlog:class+load=debug:file=spring-petclinic.classload.ml.log \
171 	    ${UNPACKED_CMDLINE}
172 	wc -lc ${PC_CLASSLIST_MAINLINE}
173 
174 ${PC_STATIC_JSA_MAINLINE}: ${PC_CLASSLIST_MAINLINE}
175 	rm -f ${PC_STATIC_JSA_MAINLINE}.log
176 	${MAINLINE_JAVA} -Xshare:dump -XX:SharedClassListFile=${PC_CLASSLIST_MAINLINE} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \
177 	    -XX:SharedArchiveFile=${PC_STATIC_JSA_MAINLINE} \
178 	    -Xlog:cds=debug,cds+class=debug,cds+heap=warning:file=${PC_STATIC_JSA_MAINLINE}.log
179 	ls -l ${PC_STATIC_JSA_MAINLINE}
180 
181 runs.ml: ${PC_STATIC_JSA_MAINLINE}
182 	${MAINLINE_JAVA} -XX:SharedArchiveFile=${PC_STATIC_JSA_MAINLINE} \
183 		${UNPACKED_CMDLINE}
184 
185 clean.ml:
186 	rm -fv ${PC_CLASSLIST_MAINLINE}* ${PC_STATIC_JSA_MAINLINE}*
187 
188 #======================================== JDK 483 (mainline)
189 
190 aotconf.ml:   ${PC_ML_AOTCONF}
191 aot.ml:       ${PC_ML_AOT}
192 
193 ${PC_ML_AOTCONF}: ${PC_APP_UNPACKED}
194 	rm -f ${PC_ML_AOTCONF}.log
195 	${MAINLINE_JAVA} -XX:AOTMode=record -XX:AOTConfiguration=${PC_ML_AOTCONF} \
196 	    -Xlog:class+load=debug:file=${PC_ML_AOTCONF}.log \
197 	    ${UNPACKED_CMDLINE}
198 	ls -l ${PC_ML_AOTCONF}
199 
200 ${PC_ML_AOT}: ${PC_ML_AOTCONF}
201 	rm -f ${PC_ML_AOT}.log
202 	${MAINLINE_JAVA} -XX:AOTMode=create -XX:AOTConfiguration=${PC_ML_AOTCONF} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \
203 	    -XX:AOTCache=${PC_ML_AOT} \
204 	    -Xlog:cds=debug,cds+class=debug,cds+heap=warning:file=${PC_ML_AOT}.log
205 	ls -l ${PC_ML_AOT}
206 
207 runa.ml: ${PC_ML_AOT}
208 	${MAINLINE_JAVA} -XX:AOTMode=on -XX:AOTCache=${PC_ML_AOT} \
209 		${UNPACKED_CMDLINE}
210 
211 #======================================== JDK 483 (Leyden -- includes AOT profile/compiled code)
212 aotconf:   ${PC_AOTCONF}
213 aot:       ${PC_AOT}
214 
215 ${PC_AOTCONF}: ${PC_APP_UNPACKED}
216 	rm -f ${PC_AOTCONF}.log
217 	${PREMAIN_JAVA} -XX:AOTMode=record -XX:AOTConfiguration=${PC_AOTCONF} \
218 	    -Xlog:class+load=debug:file=${PC_AOTCONF}.log \
219 	    ${UNPACKED_CMDLINE}
220 	ls -l ${PC_AOTCONF}
221 
222 ${PC_AOT}: ${PC_AOTCONF}
223 	rm -f ${PC_AOT}.log
224 	${PREMAIN_JAVA} -XX:AOTMode=create -XX:AOTConfiguration=${PC_AOTCONF} $(HEAP_SIZE) -cp @${PC_APP_UNPACKED}/classpath \
225 	    -XX:AOTCache=${PC_AOT} \
226 	    -Xlog:cds=debug,cds+class=debug,cds+heap=warning:file=${PC_AOT}.log
227 	ls -l ${PC_AOT}
228 
229 runa: ${PC_AOT}
230 	${PREMAIN_JAVA} -XX:AOTMode=on -XX:AOTCache=${PC_AOT} \
231 		${UNPACKED_CMDLINE}
232 
233 #========================================
234 
235 clean: clean0
236 	rm -rf *~ ${PC_REPO} Dummy*.class Dummy.jar *.old.txt *.new.txt tmp.txt hs_err*
237 
238 # clean the the leyden artifacts
239 clean0:
240 	rm -fv spring-petclinic.* *.aot *.aotconf
241 
242 # clean the the leyden artifacts for the new workflow only
243 cleann:
244 	rm -fv spring-petclinic.cds.* *.aot *.aotconf
245 
246 include ../lib/Bench.gmk
247 
248 # Clean up the logs generated by compare_premain_builds, so you can see if one build includes
249 # more classes than another.
250 diff_training_logs:
251 	@for i in old new; do \
252 	    grep cds,class spring-petclinic.$$i.static.jsa.log | \
253 		sed -e 's/.*0x[0-9a-f]* ..... //g' \
254 		    -e 's/Lambda\/0x[0-9a-f]*/Lambda\/nnn/g' \
255 		    -e 's/MH\/0x[0-9a-f]*/MH\/nnn/g' | \
256 		sort > old-workflow-static-classes.$$i.txt; \
257 	    grep cds,class spring-petclinic.$$i.dynamic.jsa.log | \
258 		sed -e 's/.*0x[0-9a-f]* ..... //g' \
259 		    -e 's/Lambda\/0x[0-9a-f]*/Lambda\/nnn/g' \
260 		    -e 's/MH\/0x[0-9a-f]*/MH\/nnn/g' | \
261 		sort > old-workflow-dynamic-classes.$$i.txt; \
262 	    grep cds,class spring-petclinic.$$i.cds.log | \
263 		sed -e 's/.*0x[0-9a-f]* ..... //g' \
264 		    -e 's/Lambda\/0x[0-9a-f]*/Lambda\/nnn/g' \
265 		    -e 's/MH\/0x[0-9a-f]*/MH\/nnn/g' | \
266 		sort > new-workflow-classes.$$i.txt; \
267 	done
268 	@ls -l *.old.txt *.new.txt
269 	@echo '***'
270 	@echo "You can diff the above files to diagnose speed differences between two builds"
271 
272