-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathHACKING.txt
More file actions
192 lines (127 loc) · 9.58 KB
/
Copy pathHACKING.txt
File metadata and controls
192 lines (127 loc) · 9.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
Required Java Version:
----------------------
Building JMurmel needs at least Java8 with Flight Recorder classes (jdk.jfr.*).
Flight Recorder was backpatched to Java8, superold versions don't contain these,
e.g. jdk8u322-b06 from https://adoptium.net does, as do other builds.
(jdk.jfr.* is only needed to build, running an already built jmurmel.jar doesn't
require these).
JMurmel builds and runs with Java8 through 22-ea at the time of this writing.
Regardless of the Java version used to build,
by default jmurmel.jar will be built to be Java8 compatible.
Users of Java versions higher than 8 (e.g. 18) will probably do something like
mvn clean install -Djavac.target=18
Relevant source files:
----------------------
JMurmel:
The source file for JMurmel is lambda/src/main/java/io/github/jmurmel/LambdaJ.java
(and the Java files in lambda/src/main/java/io/github/jmurmel/jsr223 for JSR 223 support).
Yes, JMurmel is (more or less) one single source file :-)
Hacking JMurmel means changing the file LambdaJ.java and rebuilding (i.e. 'mvn clean install').
There are regular Java JUnit tests in lambda\src\test\java\io\github\jmurmel,
and LambdaJTest#runllFiles() will run all the Lisp files in lambda\src\test\lisp,
checking their result, output or error messages if any.
Also there is the file samples.murmel/murmel-test.lisp which contains tests for the core Murmel language.
After adding Murmel tests one should re-run the Murmel tests with something like
java -ea -jar lambda/target/jmurmel.jar samples.murmel/murmel-test.lisp
Mlib:
Murmel's default library "Mlib" (written in Murmel) is in the file samples.murmel-mlib/mlib.lisp.
Tests for "Mlib" (written in Murmel) are in samples.murmel-mlib/mlib-test.lisp.
After changing mlib.lisp and/ or adding Mlib tests one should re-run the Mlib tests with something like
java -ea -jar lambda/target/jmurmel.jar samples.murmel-mlib/mlib-test.lisp
Useful maven commandlines:
--------------------------
mvn clean install
do a clean build that will run on Java8, run all tests, (re-)recreate murmel-langref.md and mlib.md using sed and install to the local mavenrepo
mvn clean package
as above but don't run sed and don't install to the local mavenrepo
mvn clean install -Djavac.target=18
do a clean build that will run on Java18, run all tests, (re-)recreate murmel-langref.md and mlib.md using sed and install to the local mavenrepo
mvn install -pl lambda
just rebuild jmurmel.jar, run the unit tests in lambda/src/test/java and run the testfiles in lambda/src/test/lisp
mvn install -pl lambda -DskipTests
just rebuild jmurmel.jar w/o tests
mvn pmd:pmd -pl lambda
run PMD on JMurmel, results will be in lambda/target/site
mvn compile findbugs:findbugs findbugs:gui -pl lambda
build JMurmel, run findbugs and launch findbugs GUI
mvn package -Pcoverage -pl lambda
build JMurmel and run tests with JaCoCo, test execution coverage results will be in lambda/target/site/jacoco
mvn modernizer:modernizer
"Modernizer Maven Plugin detects uses of legacy APIs which modern Java versions supersede."
See https://github.com/gaul/modernizer-maven-plugin for more info
Note: starting with version 1.18.0 pitest requires Java11+. Use 1.17.4 on Java8.
mvn test -Ppitest -pl lambda
run mutation testing c/o https://pitest.org/, see lambda/target/pit-reports/index.html for test coverage results.
PIT likes Java heap memory, if it goes too slow then you might consider increasing the value for -Xmx in .mvn/jvm.config
mvn test -Ppitest -pl lambda -DwithHistory=true -DtargetClasses=io.github.jmurmel.LambdaJ$SExpressionReader
run mutation testing c/o https://pitest.org/ and only mutate the class SExpressionReader, do incremental processing if possible
useful when making changes in one class only and/ or changing/ adding tests that should test one class
mvn test -Ppitest -pl lambda -DwithHistory=true -DtargetClasses=io.github.jmurmel.LambdaJ$SExpressionReader -DtargetTests=io.github.jmurmel.ScannerTest
as above but only run one test class during mutation analysis
mvn test -Ppitest -pl lambda -DwithHistory=true -DtargetTests=io.github.jmurmel.CallJavaTest -DexcludedClasses=io.github.jmurmel.LambdaJ$SExpressionReader,io.github.jmurmel.LambdaJ$WellknownSymbol*,io.github.jmurmel.jsr223*
run mutation testing c/o https://pitest.org/
do not mutate the class SExpressionReader or any of the WellknownSymbol enums (there's a lot of them), do incremental processing if possible
only run the CallJavaTest test class during mutation analysis
Other useful commandlines:
--------------------------
doskey jm=java -ea -jar lambda/target/jmurmel.jar --libdir samples.murmel-mlib $*
Windows cmd alias to run JMurmel
alias jm="java -ea -jar lambda/target/jmurmel.jar --libdir samples.murmel-mlib"
Unix/Bash style alias that does the same
export JMURMEL=.../jmurmel
alias jm="rlwrap -C jm -i -q'\"' -b '\(\)' -f $JMURMEL/murmel.completions java -ea -jar $JMURMEL/lambda/target/jmurmel.jar --libdir $JMURMEL/samples.murmel-mlib"
Unix/Bash style alias that launches JMurmel with rlwrap and a TAB-completion file for Murmel.
(Ruthlessly stolen from https://github.com/elahtrebor/RLWRAP-SBCL-LISP-COMPLETIONS)
jm samples.murmel/murmel-test.lisp
interpret the tests in murmel-test.lisp
sbcl --script samples.murmel/murmel-test.lisp
run the tests in murmel-test.lisp using sbcl, useful after adding tests to murmel-tests.lib, this will check if the added tests check for valid Common Lisp behaviour
jm samples.murmel-mlib/mlib-test.lisp
interpret the tests in mlib-test.lisp, useful after making changes/ additions in mlib.lisp
sbcl --script samples.murmel-mlib/mlib-test.lisp
run the tests in mlib-test.lisp using sbcl, useful after adding tests to mlib-tests.lib, this will check if the added tests check for valid Common Lisp behaviour
jm --run samples.murmel/julia.lisp
compile and run the Julia sample
jm samples.murmel-mlib/benchmark/3.01_tak.lisp
interpret the single benchmark "TAK"
jm --run samples.murmel-mlib/benchmark/3.01_tak.lisp
compile and run the single benchmark "TAK"
cd samples.murmel-mlib/benchmark
sbcl --script 3.01_tak.lisp
run the single benchmark "TAK" using sbcl
sed -nf doc/langref-to-md.sed murmel-langref.lisp > murmel-langref.md
transform the Murmel language reference to markdown. (This is automatically done by "mvn install".)
sed -nf doc/mlib-to-md.sed samples.murmel-mlib/mlib.lisp > mlib.md
transform the Mlib reference to markdown. (This is automatically done by "mvn install".)
java -Xms1G -Xmx2G -XX:+PrintFlagsFinal -version | grep -e "Use.*GC " -e "Active" -e "[lnx]HeapSize"
display some memory and GC related settings of the currently used JVM
JITWatch (see https://github.com/AdoptOpenJDK/jitwatch/wiki/Instructions):
java -cp jitwatch-ui-1.4.7-shaded-win.jar org.adoptopenjdk.jitwatch.jarscan.JarScan --mode=maxMethodSize --limit=325 jmurmel\lambda\target\jmurmel.jar
lists methods >= 325 bytecodes. Interesting sizes include 35 (default MaxInlineSize), 325 (default MaxFreqInlineSize) and 8000 (methods larger than 8000 will never be JIT compiled).
See https://github.com/AdoptOpenJDK/jitwatch and https://github.com/AdoptOpenJDK/jitwatch/wiki/Instructions
Java 8:
java -XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -XX:LogFile=mylogfile.log -XX:+DebugNonSafepoints \
-jar ..\..\lambda\target\jmurmel.jar --libdir .. 00_tak_apo.lisp
run the benchmark 00_tak_apo in interpreter mode and create a logfile with JIT infos for analysis with jitwatch (see https://github.com/AdoptOpenJDK/jitwatch)
Java 9+:
java -XX:+UnlockDiagnosticVMOptions -Xlog:class+load=info -XX:+LogCompilation -XX:LogFile=mylogfile.log -XX:+DebugNonSafepoints -XX:+PrintAssembly \
-jar ..\..\lambda\target\jmurmel.jar --libdir .. 00_tak_apo.lisp
same as above but adds "-XX:+PrintAssembly" and uses "-Xlog:class+load=info" instead of Java8's "-XX:+LogCompilation"
AP-Loader - Loader for AsyncProfiler (see https://github.com/jvm-profiling-tools/ap-loader):
Java 9+ linux:
java -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -javaagent:ap-loader-all.jar=start,event=cpu,file=profile.html \
-jar lambda/target/jmurmel.jar --run --libdir samples.murmel-mlib/ samples.murmel-mlib/benchmark/3.08_destru.lisp
run the benchmark 3.08_destru in compiled mode and create a CPU flamegraph in "profile.html"
Java24 JEP 483 Ahead-of-time Class Loading & Linking;
training run
java -Xms100m -Xmx1g -XX:+UseParallelGC -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -jar jmurmel.jar --eval (write 1)
create cache
java -Xms100m -Xmx1g -XX:+UseParallelGC -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -jar jmurmel.jar --eval (write 1)
run using cache
java -Xms100m -Xmx1g -XX:+UseParallelGC -XX:AOTCache=app.aot -jar jmurmel.jar --eval (write 1)
run using cache and log class loading
java -verbose:class -Xms100m -Xmx1g -XX:+UseParallelGC -XX:AOTCache=app.aot -jar jmurmel.jar --eval (write 1)
Java24 JEP 483 Ahead-of-time Class Loading & JEP 450 Linking and compact object headers:
java -Xms100m -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders -XX:+UseParallelGC -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -jar jmurmel.jar --eval (write 1)
java -Xms100m -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders -XX:+UseParallelGC -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -jar jmurmel.jar --eval (write 1)
java -Xms100m -Xmx1g -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders -XX:+UseParallelGC -XX:AOTMode=on -XX:AOTCache=app.aot -jar jmurmel.jar --eval (write 1)