Compare commits

..

98 Commits

Author SHA1 Message Date
Anton Tarasov
435b54a065 JBR-2019 provide getWindowHandle method for jcef
(cherry picked from commit 7ae706b629)
2020-10-21 19:13:29 +03:00
Anton Tarasov
0e96a8bf28 JBR-2812 bundle jcef in jmod format instead of modular-sdk 2020-10-21 19:13:29 +03:00
Vitaly Provodin
27c35493d4 Add jogl and gluegen modules to support jcef osr mode 2020-10-07 14:55:46 +07:00
Vitaly Provodin
d21dad89ef JBR-2758 fix comments and artifat names 2020-10-07 11:21:12 +07:00
Vitaly Provodin
c5b54de94c JBR-2758 refactor building scripts to apply patches adding required modules instead of excluding 2020-10-02 06:31:41 +07:00
Magnus Ihse Bursie
9bb366c63f 8237879: make 4.3 breaks build
Reviewed-by: erikj, tbell
2020-10-02 06:31:41 +07:00
Alexey Ushakov
8670659e36 JBR-1412 [fwp to JBR11] JBR-1393 RubyMine is hanging after log in (macOS)
Modified version of JBR8 fix

(cherry picked from commit 434166fe63)
2020-09-29 20:39:54 +03:00
Alexey Ushakov
c039c5ac74 JRE-366 Add support for Awesome WM
Added detection of Awesome WM and handled similar to Sawfish WM

(cherry picked from commit 6742077ed198975949af567e8ef543f853397351)
(cherry picked from commit 2847be73c6)
2020-09-29 20:38:49 +03:00
Alexey Ushakov
27e089fc96 JRE-353 Fedora 25 + XMonad rendering issues
Added support for Xmonad WM

(cherry picked from commit c690c3c7fdf1390e6b1a8d388ff752a09391ae3c)
(cherry picked from commit 6851dc3441)
2020-09-29 20:38:43 +03:00
Alexey Ushakov
1de1a80c1c JRE-18 CCE in XRMaskFill.MaskFill
Throwing InvalidPipeException for incompatible surfaces

(cherry picked from commit 55dab103c24bf86cf025b9ce02b67e72508d41ba)
(cherry picked from commit 0a4fdad0f2)
2020-09-29 20:37:59 +03:00
Alexey Ushakov
352b0648bf JRE-12 CCE: XRTextRenderer.drawGlyphList (sun.java2d.NullSurfaceData cannot be cast to sun.java2d.xr.XRSurfaceData)
Throwing InvalidPipeException for incompatible surfaces

(cherry picked from commit f98f34c)
(cherry picked from commit fb2bbc47fe)
2020-09-29 20:37:40 +03:00
Anton Tarasov
34d8bfb9e4 JRE-119 [Add SwingUtilities2.scalePoint method to translate b/w different scales]
The method is used for popup window location settings.

(cherry picked from commit a7f295f8bc8aaa5bee4bedf1369aefd19152fcf5)
(cherry picked from commit dbc9f3cf91)
2020-09-29 19:23:16 +03:00
Anton Tarasov
fd7cbc336b JRE-1142 [jdk11] hidpi is not detected since Ubuntu 18.04
(cherry picked from commit be4f8c0d9d)
2020-09-29 19:23:15 +03:00
Anton Tarasov
2d6bf7e860 [jdk9] HiDPI scale is not detected on some linux desktops
(cherry picked from commit 9279d80110)
2020-09-29 19:23:14 +03:00
Anton Tarasov
0af3a883ae JRE-1111 [JDK11] java/beans/Beans/TypoInBeanDescription.java crashes at libawt_xawt.so+0x4a30d
(cherry picked from commit b89e6aed0b)
2020-09-29 19:23:13 +03:00
Anton Tarasov
1337f812ab Read org.gnome.desktop.interface/scaling-factor
(cherry picked from commit 277357ae73)
2020-09-29 19:23:13 +03:00
Anton Tarasov
a7f86d82a8 Do not scale base font in HiDPI mode on Linux
(cherry picked from commit 6fb2c36529)
2020-09-29 19:23:13 +03:00
Anton Tarasov
7acf2932d5 JRE-119 [Fix getCursorPos() to work in env with scale]
(cherry picked from commit cbcfb72202125cd9bab5d25e4f06b5ba3f684482)
(cherry picked from commit ca32a66f85)
2020-09-29 19:23:12 +03:00
Anton Tarasov
4219714cc7 JRE-616 [linux] notify when dpi correction factor is applied to fonts
(cherry picked from commit f57d41f3118bfd773c99ce32d58cfae16931be6a)
(cherry picked from commit 6246abc72f)
2020-09-29 19:23:12 +03:00
Anton Tarasov
f86ae84567 IDEA-153474 let JDK detect Xft.dpi value on non-GTK Linux DEs
Use the GTK method:

https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-get

to retrieve "gtk-xft-dpi" integer property of the X settings.

Add the property to JDK's GtkEngine & gtk2-interface.
Then read the property via GtkEngine from GTK LaF when "gnome.Xft/dpi" is undefined. It's assumed GTK LaF is forcedly installed.

(cherry picked from commit e05fc391ae0a3cc389e836441f882c0cf6ab3b99)
(cherry picked from commit fd615a5b45)
2020-09-29 19:23:12 +03:00
Vitaly Provodin
f0e8ecc703 updated JTreg exclude list 2020-09-25 12:44:44 +07:00
Phil Race
d832cc4821 8249142: java/awt/FontClass/CreateFont/DeleteFont.sh is unstable
Reviewed-by: serb
2020-09-25 12:44:13 +07:00
Rajan Halade
e11f3c0562 8251859: sun/security/validator/PKIXValAndRevCheckTests.java fails
Reviewed-by: jnimeh
2020-09-24 05:00:59 +07:00
Rajan Halade
37eb6c5965 8249176: Update GlobalSignR6CA test certificates
Reviewed-by: xuelei
2020-09-24 05:00:59 +07:00
Vitaly Provodin
725b1bf949 updated JTreg exclude list 2020-09-17 16:43:23 +07:00
Vitaly.Provodin
c983b91f00 add 32-sizes for native data types
(cherry picked from commit 3a79870da8)
2020-09-16 12:29:38 +03:00
Denis Konoplev
84b50505dd JBR-2347: Free memory on other exceptions, rethrow ThreadDead & log it
(cherry picked from commit 16ca839ed3)
2020-09-15 14:38:00 +03:00
Denis Konoplev
289934f497 JBR-2347: Don't free memory when thread is dead
(cherry picked from commit afb3303db5)
2020-09-15 14:37:29 +03:00
Denis Konoplev
af140d7861 JBR-2041: Project view tap fix, recovery? constants & logging
(cherry picked from commit 1e904db3b0)
2020-09-15 14:36:03 +03:00
Denis Konoplev
d3b9766e74 IDEA-229135: Fling animation stop on tap
(cherry picked from commit 7ce0f79561)
2020-09-15 14:35:01 +03:00
Denis Konoplev
cc8fcb9684 Windows touch screen support
(cherry picked from commit cab3f28907)
2020-09-15 14:33:49 +03:00
Denis Konoplev
b6844ac715 Turn off multitouch
(cherry picked from commit a2576ffa9a)
2020-09-15 14:33:20 +03:00
Denis Konoplev
0dd9e2c0b0 Check XInput extension && touch inertia
(cherry picked from commit cca7fb97f4)
2020-09-15 14:32:44 +03:00
Denis Konoplev
ed4181e524 Touch scroll handling
(cherry picked from commit 6dcec3dc31)
2020-09-15 14:32:06 +03:00
Denis Konoplev
062eb0688f XI2 Constants
(cherry picked from commit 588cd6ee73)
2020-09-15 14:31:15 +03:00
Denis Konoplev
e73b3a7f13 XLibWrapper XI2 functions
(cherry picked from commit d6bd1bfa2b)
2020-09-15 14:30:05 +03:00
Denis Konoplev
faa2f5a975 X11 native get put double
(cherry picked from commit f101bc1108)
2020-09-15 14:10:27 +03:00
Denis Konoplev
917488b0e0 Native data types
(cherry picked from commit 9504574dbb)
2020-09-15 14:09:32 +03:00
Denis Konoplev
2c98858a3b XI2 headers in xlib wrapper generator
(cherry picked from commit ef108067a1)
2020-09-15 14:06:46 +03:00
Vitaly Provodin
deea80ba16 JBR-2473 modify building scripts to add dcevm clauses, add git config to docker image
(cherry picked from commit 2620c62848)
2020-07-30 09:40:32 +07:00
Vitaly Provodin
e23a409cb7 JBR-2473 add initial set of DCEVM patches
(cherry picked from commit c0c0a96cf4)
2020-07-28 17:57:52 +07:00
Anton Tarasov
b52346b645 JBR-2016 add jcef module and export packages to it
(cherry picked from commit cf997f71c6)
2020-07-23 08:28:18 +07:00
Vitaly Provodin
ffb503424a updated JTreg exclude list 2020-06-10 15:08:29 +07:00
Prasanta Sadhukhan
5c98f296e1 8242526: PIT: javax/swing/JInternalFrame/8020708/bug8020708.java fails in mach5 ubuntu system
8233644: [TESTBUG] JInternalFrame test bug8020708.java is failing on macos

Reviewed-by: serb, pbansal, jdv
2020-06-08 10:27:30 +07:00
Nikita Gubarkov
7e7c22aef2 JBR-2466 Fixed configure from WSL 2020-06-05 20:36:35 +03:00
Nikita Gubarkov
1919ab7dc7 JBR-2465 Build failure with VS 2019 (16.5.0) due to C2039 and C2873 2020-06-05 19:53:36 +03:00
Yasumasa Suenaga
72bb0377bf JBR-2465 Backport: 8241087: Build failure with VS 2019 (16.5.0) due to C2039 and C2873
Reviewed-by: serb
2020-06-05 19:52:45 +03:00
Vitaly Provodin
9ec79f6621 updated JTreg exclude list 2020-06-03 17:24:43 +07:00
Prasanta Sadhukhan
6a59e22849 8236635: JTabbedPane preferred size calculation is wrong for SCROLL_TAB_LAYOUT
Reviewed-by: serb, pbansal
2020-06-03 17:24:07 +07:00
Sergey Bylokhov
40ed05e18a 8196181: sun/java2d/GdiRendering/InsetClipping.java fails
Reviewed-by: jdv
2020-06-03 06:18:22 +07:00
Erik Gahlin
8ef9248d62 8219686: jdk/jfr/event/runtime/TestShutdownEvent.java recording file length is 0
Reviewed-by: mgronlun, mseledtsov
2020-06-03 06:17:13 +07:00
Prasanta Sadhukhan
0e555a02fa 8226230: Test javax/swing/JInternalFrame/8020708/bug8020708.java fails on Ubuntu
Reviewed-by: serb
2020-06-02 08:23:51 +07:00
Vitaly Provodin
ec04f240d0 updated JTreg exclude list 2020-05-28 11:43:10 +07:00
Tejpal Rebari
7f16bf3d2a 8233559: [TESTBUG] TestNimbusOverride.java is failing on macos
Reviewed-by: psadhukhan, pbansal
2020-05-27 13:05:35 +07:00
Vyacheslav Moklev
01b1e43caf JBR-1274 Common Item Dialog sometimes crash the process
Prevent from freeing memory with CoTaskMemFree twice

(cherry picked from commit 94c75b0537)
2020-05-27 00:13:52 +03:00
Vyacheslav Moklev
a088ea7a22 JBR-1273 Common Item Dialog does not open when wrong path to directory is passed
Handle set directory / set file properly

(cherry picked from commit bff7dfddfb)
2020-05-26 23:48:46 +03:00
Vyacheslav Moklev
0e6072ffc4 JBR-1271 Wrong parent of native windows dialogs
Set a proper parent to a dialog window

(cherry picked from commit 6ecbc2736b)
2020-05-26 23:47:27 +03:00
Vyacheslav Moklev
fd420cda55 JBR-1269 Common Item Dialog does not appear on Alt+Tab or click in windows toolbar
JBR-1270 Common Item Dialog does not have an icon

Select a proper window handle

(cherry picked from commit 8cde9502f1)
2020-05-26 23:47:09 +03:00
Vyacheslav Moklev
8efe07ac52 JBR-1258 CommonItemDialog ignores directory to open
Fix parsing of directory path / file path

(cherry picked from commit 04112e6f90)
2020-05-26 23:37:46 +03:00
Vyacheslav Moklev
f685f2dac1 JBR-1257 CommonItemDialog modal window has no owner
Fix modality for Common Item Dialog

(cherry picked from commit e0c79eb54f)
2020-05-26 23:36:03 +03:00
Vyacheslav Moklev
5505211785 JRE-1216 Implement Windows native file dialogs with the new Common Item Dialog API
Add implementation of file dialogs with the new Common Items Dialog API

(cherry picked from commit 764909ce2a)
Also fixed memory leak of fileBuffer
2020-05-26 23:35:05 +03:00
Vitaly Provodin
feacdbe1ed updated JTreg exclude list 2020-05-23 07:06:28 +07:00
Eugene Petrenko
bd239e2e67 cds - add more logging to -Xshare:dump errors
log exception along with "Preload Warning: Verification failed" warning messages
advanced debug logging to diagnose listed class was not defined error from -Xshare:dump
more detailed error logging from the Xshare:dump phase

(cherry picked from commit 82dcb03358)
2020-05-22 18:20:11 +03:00
Vitaly Provodin
0baf10364a updated JTreg exclude list 2020-05-22 18:20:38 +07:00
Prasanta Sadhukhan
2e2fe0daa7 8239312: [macos] javax/swing/JFrame/NSTexturedJFrame/NSTexturedJFrame.java
Reviewed-by: serb
2020-05-22 18:19:48 +07:00
Sergey Bylokhov
6cab3cee0d 8235153: [TESTBUG] [macos 10.15] java/awt/Graphics/DrawImageBG/SystemBgColorTest.java fails
Reviewed-by: aivanov
2020-05-22 18:19:48 +07:00
Phil Race
48607c2bd8 8223935: PIT: java/awt/font/WindowsIndicFonts.java fails on windows10
Reviewed-by: serb, jdv
2020-05-22 18:18:25 +07:00
Eugene Petrenko
1d90a4efaf cds - log exception along with "Preload Warning: Verification failed" warning messages
(cherry picked from commit c3839647c6)
2020-05-21 20:59:18 +03:00
Vitaly Provodin
61315cec50 updated JTreg exclude list 2020-05-20 06:06:45 +07:00
Vitaly Provodin
6c277514cd JBR-2395 eliminate JavaFX from JBR (follow up x64 packaging) 2020-05-20 05:49:36 +07:00
Vitaly Provodin
b3f7acae0e JBR-2409 fix prameters for configure 2020-05-19 18:11:04 +07:00
Vitaly Provodin
d3d647482c JBR-2395 eliminate JavaFX from JBR (fix misprint) 2020-05-19 18:10:05 +07:00
Vitaly Provodin
a438190dd0 add git into image for Linux x86 2020-05-19 18:10:04 +07:00
Vitaly Provodin
077c459a42 JDK14: exclude dependencies on jcef in x86, fastdebug builds 2020-05-19 18:10:04 +07:00
Vitaly Provodin
88a9f6aac1 add docker files for Linux x64 and x86 2020-05-17 20:02:17 +07:00
Vitaly Provodin
77edf91292 8234596 remove of Pack200 Tools and API 2020-05-17 05:30:19 +07:00
Vitaly Provodin
1871da9d1c JBR-2395 eliminate JavaFX from JBR 2020-05-17 05:30:19 +07:00
Vitaly Provodin
b63167860a JBR-2396 fix CONF names 2020-05-17 05:30:19 +07:00
Vitaly Provodin
de199a7120 JBR-2394 replace --disable-debug-symbols with --with-native-debug-symbols=none 2020-05-17 05:30:19 +07:00
Vitaly Provodin
862d57aa49 add exec permitions to configure 2020-05-15 12:10:04 +07:00
Vitaly Provodin
405c69f3cb split checkout before building JBR+JFX or JBR+JCEF on two separate commands 2020-05-15 12:08:17 +07:00
Vitaly Provodin
d461bf7869 change BOOT_JDK, fix target names 2020-05-15 12:03:15 +07:00
Vitaly Provodin
9fa51d6334 change BOOT_JDK 2020-05-15 11:40:30 +07:00
Vitaly Provodin
69e522b1c6 JBR-2291 add vendor info into bundles 2020-05-15 11:38:10 +07:00
Vitaly Provodin
3105f0cd04 JBR-2324 address new layout in mac jcef 80.0.4+g74f7b0c+chromium-80.0.3987.122 2020-05-15 09:57:24 +07:00
Vitaly Provodin
59ce59ba82 JBR-2320 add jdk.attach module into JBR 2020-05-15 09:57:24 +07:00
Vitaly Provodin
8ca73521c2 JBR-2217 provide JCEF-only (no JavaFX) bundle for master/202 branches 2020-05-15 09:57:24 +07:00
Vitaly Provodin
d0f24cad2c JBR-2212 add scripts for linux_x86, linux_aarch64, linux_x64_fastdebug, osx_fastdebug, windows_x86 2020-05-15 09:57:24 +07:00
Vitaly Provodin
f7909316f1 JBR-1643 fix intermittent fialures of Windows builds at make/Init.gmk:304
combine images and test-image into one make invocation
2020-05-15 09:57:23 +07:00
Vitaly Provodin
d900c998b4 JBR-2181 create two separate JBR bundles with JFX and JFX+JCEF 2020-05-15 09:57:23 +07:00
Vitaly Provodin
18ce94e157 JBR-2148 modify signapp&build scripts to match to the new layout 2020-05-15 09:57:23 +07:00
Vitaly Provodin
768cbfdb61 JBR-2084 modify scripts to sign Contents/MacOS/libjli.dylib as a a normal file 2020-05-15 09:57:23 +07:00
Vitaly Provodin
7cb7464329 JBR-1821 notarize JBR bundles as a standalone app 2020-05-15 09:57:23 +07:00
Vitaly Provodin
ab19e95c30 JBR-2162 move building scripts from TC to JBR repo 2020-05-15 09:57:23 +07:00
Anton Tarasov
b8a4deee83 JBR-2016 add jcef module and export some sun.* packages to it 2020-05-15 09:57:23 +07:00
Vitaly Provodin
4de7d27f51 JBR-2014 add jdk.hotspot.agent module to jbr 2020-05-15 09:57:22 +07:00
Vitaly Provodin
ddab99867f JBR-1286 add jdk.compiler into JBR 2020-05-15 09:57:22 +07:00
Vitaly Provodin
57a54f2c11 JBR-1199 add JBR modules list for jlink 2020-05-15 09:57:17 +07:00
18038 changed files with 1363861 additions and 1157299 deletions

1
.gitignore vendored
View File

@@ -1,7 +1,6 @@
/build/
/dist/
/.idea/
/.vscode/
nbproject/private/
/webrev
/.src-rev

View File

@@ -1,7 +1,6 @@
^build/
^dist/
^.idea/
^.vscode/
nbproject/private/
^webrev
^.src-rev$

43
.hgtags
View File

@@ -599,54 +599,15 @@ c16ac7a2eba4e73cb4f7ee9294dd647860eebff0 jdk-14+21
438337c846fb071900ddb6922bddf8b3e895a514 jdk-14+24
17d242844fc9e7d18b3eac97426490a9c246119e jdk-14+25
288777cf0702914e5266bc1e5d380eed9032ca41 jdk-14+26
2c724dba4c3cf9516b2152e151c9aea66b21b30b jdk-15+0
91a3f092682fc715d991a87eb6ec6f28886d2035 jdk-14+27
63e17cf29bed191ea21020b4648c9cdf893f80f5 jdk-15+1
2069b4bfd23b56b6fc659fba8b75aaaa23debbe0 jdk-14+28
f33197adda9ad82fdef46ac0f7dc0126204f35b2 jdk-15+2
563fa900fa17c290ae516c7a3a69e8c069dde304 jdk-14+29
d05fcdf25717d85e80a3a39a6b719458b22be5fe jdk-15+3
d54ce919da90dab361995bb4d87be9851f00537a jdk-14+30
bb0a7975b31ded63d594ee8dbfc4d4ead587f79b jdk-15+4
d54ce919da90dab361995bb4d87be9851f00537a jdk-14+31
d54ce919da90dab361995bb4d87be9851f00537a jdk-14+31
decd3d2953b640f1043ee76953ff89238bff92e8 jdk-14+31
b97c1773ccafae4a8c16cc6aedb10b2a4f9a07ed jdk-15+5
2776da28515e087cc8849acf1e131a65ea7e77b6 jdk-14+32
ef7d53b4fccd4a0501b17d974e84f37aa99fa813 jdk-15+6
f728b6c7f4910d6bd6070cb4dde8393f4ba95113 jdk-14+33
e2bc57500c1b785837982f7ce8af6751387ed73b jdk-15+7
a96bc204e3b31ddbf909b20088964112f052927e jdk-14+34
c7d4f2849dbfb755fc5860b362a4044ea0c9e082 jdk-15+8
4a87bb7ebfd7f6a25ec59a5982fe3607242777f8 jdk-14+35
62b5bfef8d618e08e6f3a56cf1fb0e67e89e9cc2 jdk-15+9
bc54620a3848c26cff9766e5e2a6e5ddab98ed18 jdk-14+36
1bee69801aeea1a34261c93f35bc9de072a98704 jdk-15+10
b2dd4028a6de4e40dda8b76109e4b5c6b294f980 jdk-15+11
2ec0ff3042630ddbd3587e340fe0dd40391cb6c4 jdk-15+12
1c06a8ee8acad4d93c782626a233693a73de0add jdk-15+13
1d6ceb13e142665ea833fca01c8c8598e0ddd211 jdk-15+14
bc54620a3848c26cff9766e5e2a6e5ddab98ed18 jdk-14-ga
82b7c62cf4cc56828a8fb724f57087967232a2a7 jdk-15+15
5c7ec21f5d13f6eb5cd32288c69b8be2f9cac256 jdk-15+16
dd5198db2e5b1ebcafe065d987c03ba9fcb50fc3 jdk-15+17
44aef192b488a48cce12422394691a6b1d16b98e jdk-15+18
7cc27caabe6e342151e8baf549beb07a9c755ec2 jdk-15+19
46bca5e5e6fb26efd07245d26fe96a9c3260f51e jdk-15+20
12b55fad80f30d24b1f8fdb3b947ea6465ef9518 jdk-15+21
7223c6d610343fd8323af9d07d501e01fa1a7696 jdk-15+22
f143729ca00ec14a98ea5c7f73acba88da97746e jdk-15+23
497fd9f9129c4928fd5a876dd55e0daf6298b511 jdk-15+24
90b266a84c06f1b3dc0ed8767856793e8c1c357e jdk-15+25
0a32396f7a690015d22ca3328ac441a358295d90 jdk-15+26
93813843680bbe1b7efbca56c03fd137f20a2c31 jdk-16+0
93813843680bbe1b7efbca56c03fd137f20a2c31 jdk-15+27
4a485c89d5a08b495961835f5308a96038678aeb jdk-16+1
06c9f89459daba98395fad726100feb44f89ba71 jdk-15+28
bcbe7b8a77b8971bc221c0be1bd2abb6fb68c2d0 jdk-16+2
b58fc60580550a4a587cab729d8fd87223ad6932 jdk-15+29
76810b3a88c8c641ae3850a8dfd7c40c984aea9d jdk-16+3
6909e4a1f25bfe9a2727026f5845fc1fc44a36aa jdk-15+30
e2622818f0bd30e736252eba101fe7d2c27f400b jdk-16+4
a32f58c6b8be81877411767de7ba9c4cf087c1b5 jdk-15+31
143e258f64af490010eb7e0bacc1cfaeceff0993 jdk-16+5
2dad000726b8d5db9f3df647fb4949d88f269dd4 jdk-15+32
4a8fd81d64bafa523cddb45f82805536edace106 jdk-16+6

View File

@@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -74,7 +74,7 @@ if [ "x$TOPLEVEL_DIR" = "x" ] ; then
fi
MAKE_DIR="$SCRIPT_DIR/../make"
IDEA_MAKE="$MAKE_DIR/ide/idea/jdk"
IDEA_MAKE="$MAKE_DIR/idea"
IDEA_TEMPLATE="$IDEA_MAKE/template"
cp -r "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT"
@@ -113,14 +113,6 @@ if [ "x$SPEC" = "x" ] ; then
echo "FATAL: SPEC is empty" >&2; exit 1
fi
if [ -d "$TOPLEVEL_DIR/.hg" ] ; then
VCS_TYPE="hg4idea"
fi
if [ -d "$TOPLEVEL_DIR/.git" ] ; then
VCS_TYPE="Git"
fi
### Replace template variables
NUM_REPLACEMENTS=0
@@ -145,7 +137,6 @@ add_replacement() {
}
add_replacement "###MODULE_NAMES###" "$MODULE_NAMES"
add_replacement "###VCS_TYPE###" "$VCS_TYPE"
SPEC_DIR=`dirname $SPEC`
if [ "x$CYGPATH" = "x" ]; then
add_replacement "###BUILD_DIR###" "$SPEC_DIR"
@@ -197,15 +188,13 @@ CP=$ANT_HOME/lib/ant.jar
rm -rf $CLASSES; mkdir $CLASSES
if [ "x$CYGPATH" = "x" ] ; then ## CYGPATH may be set in env.cfg
JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java
JAVAC_SOURCE_PATH=$IDEA_OUTPUT/src
JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/JdkIdeaAntLogger.java
JAVAC_CLASSES=$CLASSES
JAVAC_CP=$CP
else
JAVAC_SOURCE_FILE=`cygpath -am $IDEA_OUTPUT/src/idea/IdeaLoggerWrapper.java`
JAVAC_SOURCE_PATH=`cygpath -am $IDEA_OUTPUT/src`
JAVAC_SOURCE_FILE=`cygpath -am $IDEA_OUTPUT/src/idea/JdkIdeaAntLogger.java`
JAVAC_CLASSES=`cygpath -am $CLASSES`
JAVAC_CP=`cygpath -am $CP`
fi
$BOOT_JDK/bin/javac -d $JAVAC_CLASSES -sourcepath $JAVAC_SOURCE_PATH -cp $JAVAC_CP $JAVAC_SOURCE_FILE
$BOOT_JDK/bin/javac -d $JAVAC_CLASSES -cp $JAVAC_CP $JAVAC_SOURCE_FILE

View File

@@ -0,0 +1,37 @@
#!/bin/bash
#
# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
fix() {
#convert tabs to spaces
find . -name $1 -exec sed -i "" 's/ / /g' {} \;
#remove trailing whitespace
find . -name $1 -exec sed -i "" 's/[ ]*$//' \{} \;
}
if [ ! -z $1 ]; then
fix $1;
else
fix "*.java"
fix "*.js"
fi

135
bin/nashorn/runopt.sh Normal file
View File

@@ -0,0 +1,135 @@
#!/bin/sh
#
# Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
###########################################################################################
# This is a helper script to evaluate nashorn with optimistic types
# it produces a flight recording for every run, and uses the best
# known flags for performance for the current configration
###########################################################################################
# Flags to enable assertions, we need the system assertions too, since
# this script runs Nashorn in the BCP to override any nashorn.jar that might
# reside in your $JAVA_HOME/jre/lib/ext/nashorn.jar
#
ENABLE_ASSERTIONS_FLAGS="-ea -esa"
# Flags to instrument lambdaform computation, caching, interpretation and compilation
# Default compile threshold for lambdaforms is 30
#
#LAMBDAFORM_FLAGS="\
# -Djava.lang.invoke.MethodHandle.COMPILE_THRESHOLD=3 \
# -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true \
# -Djava.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE=true \
# -Djava.lang.invoke.MethodHandle.TRACE_INTERPRETER=true"
# Flags to run trusted tests from the Nashorn test suite
#
#TRUSTED_TEST_FLAGS="\
#-Djava.security.manager \
#-Djava.security.policy=../build/nashorn.policy -Dnashorn.debug"
# Testing out new code optimizations using the generic hotspot "new code" parameter
#
#USE_NEW_CODE_FLAGS=-XX:+UnlockDiagnosticVMOptions -XX:+UseNewCode
#
#-Dnashorn.typeInfo.disabled=false \
# and for Nashorn options:
# --class-cache-size=0 --persistent-code-cache=false
# Unique timestamped file name for JFR recordings. For JFR, we also have to
# crank up the stack cutoff depth to 1024, because of ridiculously long lambda form
# stack traces.
#
# It is also recommended that you go into $JAVA_HOME/jre/lib/jfr/default.jfc and
# set the "method-sampling-interval" Normal and Maximum sample time as low as you
# can go (10 ms on most platforms). The default is normally higher. The increased
# sampling overhead is usually negligible for Nashorn runs, but the data is better
if [ -z $JFR_FILENAME ]; then
JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr"
fi
# Flight recorder
#
# see above - already in place, copy the flags down here to disable
ENABLE_FLIGHT_RECORDER_FLAGS="\
-XX:+FlightRecorder \
-XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=$JFR_FILENAME,stackdepth=1024"
# Type specialization and math intrinsic replacement should be enabled by default in 8u20 and nine,
# keeping this flag around for experimental reasons. Replace + with - to switch it off
#
#ENABLE_TYPE_SPECIALIZATION_FLAGS=-XX:+UseTypeSpeculation
# Same with math intrinsics. They should be enabled by default in 8u20 and 9, so
# this disables them if needed
#
#DISABLE_MATH_INTRINSICS_FLAGS=-XX:-UseMathExactIntrinsics
# Add timing to time the compilation phases.
#ENABLE_TIME_FLAGS=--log=time
# Add ShowHiddenFrames to get lambda form internals on the stack traces
#ENABLE_SHOW_HIDDEN_FRAMES_FLAGS=-XX:+ShowHiddenFrames
# Add print optoassembly to get an asm dump. This requires 1) a debug build, not product,
# That tired compilation is switched off, for C2 only output and that the number of
# compiler threads is set to 1 for determinsm.
#
#PRINT_ASM_FLAGS=-XX:+PrintOptoAssembly -XX:-TieredCompilation -XX:CICompilerCount=1 \
# Tier compile threasholds. Default value is 10. (1-100 is useful for experiments)
#TIER_COMPILATION_THRESHOLD_FLAGS=-XX:IncreaseFirstTierCompileThresholdAt=10
# Directory where to look for nashorn.jar in a dist folder. The default is "..", assuming
# that we run the script from the make dir
DIR=..
NASHORN_JAR=$DIR/dist/nashorn.jar
# The built Nashorn jar is placed first in the bootclasspath to override the JDK
# nashorn.jar in $JAVA_HOME/jre/lib/ext. Thus, we also need -esa, as assertions in
# nashorn count as system assertions in this configuration
# Type profiling default level is 111, 222 adds some compile time, but is faster
$JAVA_HOME/bin/java \
$ENABLE_ASSERTIONS_FLAGS \
$LAMBDAFORM_FLAGS \
$TRUSTED_FLAGS \
$USE_NEW_CODE_FLAGS \
$ENABLE_SHOW_HIDDEN_FRAMES_FLAGS \
$ENABLE_FLIGHT_RECORDER_FLAGS \
$ENABLE_TYPE_SPECIALIZATION_FLAGS \
$TIERED_COMPILATION_THRESOLD_FLAGS \
$DISABLE_MATH_INTRINSICS_FLAGS \
$PRINT_ASM_FLAGS \
-Xbootclasspath/p:$NASHORN_JAR \
-Xms2G -Xmx2G \
-XX:TypeProfileLevel=222 \
-cp $CLASSPATH:../build/test/classes/ \
jdk.nashorn.tools.Shell $ENABLE_TIME_FLAGS ${@}

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,7 @@ src/jdk.compiler : jdk/src/jdk.compiler langtools/src/jdk.compiler
src/jdk.crypto.cryptoki : jdk/src/jdk.crypto.cryptoki
src/jdk.crypto.ec : jdk/src/jdk.crypto.ec
src/jdk.crypto.mscapi : jdk/src/jdk.crypto.mscapi
src/jdk.crypto.ucrypto : jdk/src/jdk.crypto.ucrypto
src/jdk.dynalink : nashorn/src/jdk.dynalink
src/jdk.editpad : jdk/src/jdk.editpad
src/jdk.hotspot.agent : hotspot/src/jdk.hotspot.agent
@@ -87,6 +88,7 @@ src/jdk.naming.dns : jdk/src/jdk.naming.dns
src/jdk.naming.rmi : jdk/src/jdk.naming.rmi
src/jdk.net : jdk/src/jdk.net
src/jdk.pack : jdk/src/jdk.pack
src/jdk.rmic : corba/src/jdk.rmic jdk/src/jdk.rmic
src/jdk.scripting.nashorn : nashorn/src/jdk.scripting.nashorn
src/jdk.scripting.nashorn.shell : nashorn/src/jdk.scripting.nashorn.shell
src/jdk.sctp : jdk/src/jdk.sctp
@@ -100,11 +102,13 @@ src/jdk.zipfs : jdk/src/jdk.zipfs
src/langtools/sample : langtools/src/sample
src/linux : jdk/src/linux
src/sample : jdk/src/sample
src/solaris : jdk/src/solaris
src/hotspot/share : hotspot/src/share/vm
src/hotspot/cpu/aarch64 : hotspot/src/cpu/aarch64/vm
src/hotspot/cpu/arm : hotspot/src/cpu/arm/vm
src/hotspot/cpu/ppc : hotspot/src/cpu/ppc/vm
src/hotspot/cpu/s390 : hotspot/src/cpu/s390/vm
src/hotspot/cpu/sparc : hotspot/src/cpu/sparc/vm
src/hotspot/cpu/x86 : hotspot/src/cpu/x86/vm
src/hotspot/cpu/zero : hotspot/src/cpu/zero/vm
src/hotspot/os/aix : hotspot/src/os/aix/vm
@@ -112,6 +116,7 @@ src/hotspot/os/bsd : hotspot/src/os/bsd/vm
src/hotspot/os/linux : hotspot/src/os/linux/vm
src/hotspot/os/posix/dtrace : hotspot/src/os/posix/dtrace
src/hotspot/os/posix : hotspot/src/os/posix/vm
src/hotspot/os/solaris : hotspot/src/os/solaris/vm
src/hotspot/os/windows : hotspot/src/os/windows/vm
src/hotspot/os_cpu/aix_ppc : hotspot/src/os_cpu/aix_ppc/vm
src/hotspot/os_cpu/bsd_x86 : hotspot/src/os_cpu/bsd_x86/vm
@@ -120,8 +125,11 @@ src/hotspot/os_cpu/linux_aarch64 : hotspot/src/os_cpu/linux_aarch64/vm
src/hotspot/os_cpu/linux_arm : hotspot/src/os_cpu/linux_arm/vm
src/hotspot/os_cpu/linux_ppc : hotspot/src/os_cpu/linux_ppc/vm
src/hotspot/os_cpu/linux_s390 : hotspot/src/os_cpu/linux_s390/vm
src/hotspot/os_cpu/linux_sparc : hotspot/src/os_cpu/linux_sparc/vm
src/hotspot/os_cpu/linux_x86 : hotspot/src/os_cpu/linux_x86/vm
src/hotspot/os_cpu/linux_zero : hotspot/src/os_cpu/linux_zero/vm
src/hotspot/os_cpu/solaris_sparc : hotspot/src/os_cpu/solaris_sparc/vm
src/hotspot/os_cpu/solaris_x86 : hotspot/src/os_cpu/solaris_x86/vm
src/hotspot/os_cpu/windows_x86 : hotspot/src/os_cpu/windows_x86/vm
src/hotspot : hotspot/src
src/utils/IdealGraphVisualizer : hotspot/src/share/tools/IdealGraphVisualizer
@@ -132,6 +140,7 @@ src/utils/src/build : jdk/make/non-build-utils/src/build
make/BuildNashorn.gmk : nashorn/make/BuildNashorn.gmk
make/CompileDemos.gmk : jdk/make/CompileDemos.gmk
make/CompileInterimLangtools.gmk : langtools/make/CompileInterim.gmk
make/CompileInterimRmic.gmk : jdk/make/CompileInterimRmic.gmk
make/CompileModuleTools.gmk : jdk/make/CompileModuleTools.gmk
make/CompileToolsHotspot.gmk : hotspot/make/CompileTools.gmk
make/CompileToolsJdk.gmk : jdk/make/CompileTools.gmk
@@ -171,6 +180,7 @@ make/mapfiles/libjvm_dtrace : hotspot/make/mapfiles/libjvm_dtrace
make/mapfiles/libsaproc : hotspot/make/mapfiles/libsaproc
make/nashorn : nashorn/make
make/nb_native : common/nb_native
make/rmic : jdk/make/rmic
make/scripts/addNotices.sh : jdk/make/scripts/addNotices.sh
make/scripts/compare.sh : common/bin/compare.sh
make/scripts/compare_exceptions.sh.incl : common/bin/compare_exceptions.sh.incl

0
configure vendored Normal file → Executable file
View File

View File

@@ -30,11 +30,13 @@
</ul></li>
<li><a href="#build-hardware-requirements">Build Hardware Requirements</a><ul>
<li><a href="#building-on-x86">Building on x86</a></li>
<li><a href="#building-on-sparc">Building on sparc</a></li>
<li><a href="#building-on-aarch64">Building on aarch64</a></li>
<li><a href="#building-on-32-bit-arm">Building on 32-bit arm</a></li>
</ul></li>
<li><a href="#operating-system-requirements">Operating System Requirements</a><ul>
<li><a href="#windows">Windows</a></li>
<li><a href="#solaris">Solaris</a></li>
<li><a href="#macos">macOS</a></li>
<li><a href="#linux">Linux</a></li>
<li><a href="#aix">AIX</a></li>
@@ -43,6 +45,7 @@
<li><a href="#gcc">gcc</a></li>
<li><a href="#clang">clang</a></li>
<li><a href="#apple-xcode">Apple Xcode</a></li>
<li><a href="#oracle-solaris-studio">Oracle Solaris Studio</a></li>
<li><a href="#microsoft-visual-studio">Microsoft Visual Studio</a></li>
<li><a href="#ibm-xl-cc">IBM XL C/C++</a></li>
</ul></li>
@@ -154,15 +157,18 @@
<p>The JDK is a massive project, and require machines ranging from decent to powerful to be able to build in a reasonable amount of time, or to be able to complete a build at all.</p>
<p>We <em>strongly</em> recommend usage of an SSD disk for the build, since disk speed is one of the limiting factors for build performance.</p>
<h3 id="building-on-x86">Building on x86</h3>
<p>At a minimum, a machine with 2-4 cores is advisable, as well as 2-4 GB of RAM. (The more cores to use, the more memory you need.) At least 6 GB of free disk space is required.</p>
<p>At a minimum, a machine with 2-4 cores is advisable, as well as 2-4 GB of RAM. (The more cores to use, the more memory you need.) At least 6 GB of free disk space is required (8 GB minimum for building on Solaris).</p>
<p>Even for 32-bit builds, it is recommended to use a 64-bit build machine, and instead create a 32-bit target using <code>--with-target-bits=32</code>.</p>
<h3 id="building-on-sparc">Building on sparc</h3>
<p>At a minimum, a machine with 4 cores is advisable, as well as 4 GB of RAM. (The more cores to use, the more memory you need.) At least 8 GB of free disk space is required.</p>
<p>Note: The sparc port is deprecated.</p>
<h3 id="building-on-aarch64">Building on aarch64</h3>
<p>At a minimum, a machine with 8 cores is advisable, as well as 8 GB of RAM. (The more cores to use, the more memory you need.) At least 6 GB of free disk space is required.</p>
<p>If you do not have access to sufficiently powerful hardware, it is also possible to use <a href="#cross-compiling">cross-compiling</a>.</p>
<h3 id="building-on-32-bit-arm">Building on 32-bit arm</h3>
<p>This is not recommended. Instead, see the section on <a href="#cross-compiling">Cross-compiling</a>.</p>
<h2 id="operating-system-requirements">Operating System Requirements</h2>
<p>The mainline JDK project supports Linux, macOS, AIX and Windows. Support for other operating system, e.g. BSD, exists in separate &quot;port&quot; projects.</p>
<p>The mainline JDK project supports Linux, Solaris, macOS, AIX and Windows. Support for other operating system, e.g. BSD, exists in separate &quot;port&quot; projects.</p>
<p>In general, the JDK can be built on a wide range of versions of these operating systems, but the further you deviate from what is tested on a daily basis, the more likely you are to run into problems.</p>
<p>This table lists the OS versions used by Oracle when building the JDK. Such information is always subject to change, but this table is up to date at the time of writing.</p>
<table>
@@ -178,16 +184,20 @@
<td style="text-align: left;">Oracle Enterprise Linux 6.4 / 7.6</td>
</tr>
<tr class="even">
<td style="text-align: left;">Solaris</td>
<td style="text-align: left;">Solaris 11.3 SRU 20</td>
</tr>
<tr class="odd">
<td style="text-align: left;">macOS</td>
<td style="text-align: left;">Mac OS X 10.13 (High Sierra)</td>
</tr>
<tr class="odd">
<tr class="even">
<td style="text-align: left;">Windows</td>
<td style="text-align: left;">Windows Server 2012 R2</td>
</tr>
</tbody>
</table>
<p>The double version numbers for Linux are due to the hybrid model used at Oracle, where header files and external libraries from an older version are used when building on a more modern version of the OS.</p>
<p>The double version numbers for Linux and Solaris are due to the hybrid model used at Oracle, where header files and external libraries from an older version are used when building on a more modern version of the OS.</p>
<p>The Build Group has a wiki page with <a href="https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms">Supported Build Platforms</a>. From time to time, this is updated by contributors to list successes or failures of building on different platforms.</p>
<h3 id="windows">Windows</h3>
<p>Windows XP is not a supported platform, but all newer Windows should be able to build the JDK.</p>
@@ -213,6 +223,10 @@
<p>It's possible to build both Windows and Linux binaries from WSL. To build Windows binaries, you must use a Windows boot JDK (located in a Windows-accessible directory). To build Linux binaries, you must use a Linux boot JDK. The default behavior is to build for Windows. To build for Linux, pass <code>--build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu</code> to <code>configure</code>.</p>
<p>If building Windows binaries, the source code must be located in a Windows- accessible directory. This is because Windows executables (such as Visual Studio and the boot JDK) must be able to access the source code. Also, the drive where the source is stored must be mounted as case-insensitive by changing either /etc/fstab or /etc/wsl.conf in WSL. Individual directories may be corrected using the fsutil tool in case the source was cloned before changing the mount options.</p>
<p>Note that while it's possible to build on WSL, testing is still not fully supported.</p>
<h3 id="solaris">Solaris</h3>
<p>See <code>make/devkit/solaris11.1-package-list.txt</code> for a list of recommended packages to install when building on Solaris. The versions specified in this list is the versions used by the daily builds at Oracle, and is likely to work properly.</p>
<p>Older versions of Solaris shipped a broken version of <code>objcopy</code>. At least version 2.21.1 is needed, which is provided by Solaris 11 Update 1. Objcopy is needed if you want to have external debug symbols. Please make sure you are using at least version 2.21.1 of objcopy, or that you disable external debug symbols.</p>
<p>Note: The Solaris port is deprecated.</p>
<h3 id="macos">macOS</h3>
<p>Apple is using a quite aggressive scheme of pushing OS updates, and coupling these updates with required updates of Xcode. Unfortunately, this makes it difficult for a project such as the JDK to keep pace with a continuously updated machine running macOS. See the section on <a href="#apple-xcode">Apple Xcode</a> on some strategies to deal with this.</p>
<p>It is recommended that you use at least Mac OS X 10.13 (High Sierra). At the time of writing, the JDK has been successfully compiled on macOS 10.12 (Sierra).</p>
@@ -245,10 +259,14 @@
<td style="text-align: left;">Apple Xcode (using clang)</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Solaris</td>
<td style="text-align: left;">Oracle Solaris Studio</td>
</tr>
<tr class="even">
<td style="text-align: left;">AIX</td>
<td style="text-align: left;">IBM XL C/C++</td>
</tr>
<tr class="even">
<tr class="odd">
<td style="text-align: left;">Windows</td>
<td style="text-align: left;">Microsoft Visual Studio</td>
</tr>
@@ -265,22 +283,26 @@
<tbody>
<tr class="odd">
<td style="text-align: left;">Linux</td>
<td style="text-align: left;">gcc 9.2.0</td>
<td style="text-align: left;">gcc 8.3.0</td>
</tr>
<tr class="even">
<td style="text-align: left;">macOS</td>
<td style="text-align: left;">Apple Xcode 10.1 (using clang 10.0.0)</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Solaris</td>
<td style="text-align: left;">Oracle Solaris Studio 12.6 (with compiler version 5.15)</td>
</tr>
<tr class="even">
<td style="text-align: left;">Windows</td>
<td style="text-align: left;">Microsoft Visual Studio 2019 update 16.5.3</td>
<td style="text-align: left;">Microsoft Visual Studio 2017 update 15.9.16</td>
</tr>
</tbody>
</table>
<p>All compilers are expected to be able to compile to the C99 language standard, as some C99 features are used in the source code. Microsoft Visual Studio doesn't fully support C99 so in practice shared code is limited to using C99 features that it does support.</p>
<h3 id="gcc">gcc</h3>
<p>The minimum accepted version of gcc is 5.0. Older versions will generate a warning by <code>configure</code> and are unlikely to work.</p>
<p>The JDK is currently known to be able to compile with at least version 9.2 of gcc.</p>
<p>The minimum accepted version of gcc is 4.8. Older versions will generate a warning by <code>configure</code> and are unlikely to work.</p>
<p>The JDK is currently known to be able to compile with at least version 8.3 of gcc.</p>
<p>In general, any version between these two should be usable.</p>
<h3 id="clang">clang</h3>
<p>The minimum accepted version of clang is 3.2. Older versions will not be accepted by <code>configure</code>.</p>
@@ -291,6 +313,64 @@
<pre><code>xcode-select --install</code></pre>
<p>It is advisable to keep an older version of Xcode for building the JDK when updating Xcode. This <a href="http://iosdevelopertips.com/xcode/install-multiple-versions-of-xcode.html">blog page</a> has good suggestions on managing multiple Xcode versions. To use a specific version of Xcode, use <code>xcode-select -s</code> before running <code>configure</code>, or use <code>--with-toolchain-path</code> to point to the version of Xcode to use, e.g. <code>configure --with-toolchain-path=/Applications/Xcode8.app/Contents/Developer/usr/bin</code></p>
<p>If you have recently (inadvertently) updated your OS and/or Xcode version, and the JDK can no longer be built, please see the section on <a href="#problems-with-the-build-environment">Problems with the Build Environment</a>, and <a href="#getting-help">Getting Help</a> to find out if there are any recent, non-merged patches available for this update.</p>
<h3 id="oracle-solaris-studio">Oracle Solaris Studio</h3>
<p>The minimum accepted version of the Solaris Studio compilers is 5.13 (corresponding to Solaris Studio 12.4). Older versions will not be accepted by configure.</p>
<p>The Solaris Studio installation should contain at least these packages:</p>
<table>
<thead>
<tr class="header">
<th style="text-align: left;">Package</th>
<th style="text-align: left;">Version</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">developer/solarisstudio-124/backend</td>
<td style="text-align: left;">12.4-1.0.6.0</td>
</tr>
<tr class="even">
<td style="text-align: left;">developer/solarisstudio-124/c++</td>
<td style="text-align: left;">12.4-1.0.10.0</td>
</tr>
<tr class="odd">
<td style="text-align: left;">developer/solarisstudio-124/cc</td>
<td style="text-align: left;">12.4-1.0.4.0</td>
</tr>
<tr class="even">
<td style="text-align: left;">developer/solarisstudio-124/library/c++-libs</td>
<td style="text-align: left;">12.4-1.0.10.0</td>
</tr>
<tr class="odd">
<td style="text-align: left;">developer/solarisstudio-124/library/math-libs</td>
<td style="text-align: left;">12.4-1.0.0.1</td>
</tr>
<tr class="even">
<td style="text-align: left;">developer/solarisstudio-124/library/studio-gccrt</td>
<td style="text-align: left;">12.4-1.0.0.1</td>
</tr>
<tr class="odd">
<td style="text-align: left;">developer/solarisstudio-124/studio-common</td>
<td style="text-align: left;">12.4-1.0.0.1</td>
</tr>
<tr class="even">
<td style="text-align: left;">developer/solarisstudio-124/studio-ja</td>
<td style="text-align: left;">12.4-1.0.0.1</td>
</tr>
<tr class="odd">
<td style="text-align: left;">developer/solarisstudio-124/studio-legal</td>
<td style="text-align: left;">12.4-1.0.0.1</td>
</tr>
<tr class="even">
<td style="text-align: left;">developer/solarisstudio-124/studio-zhCN</td>
<td style="text-align: left;">12.4-1.0.0.1</td>
</tr>
</tbody>
</table>
<p>Compiling with Solaris Studio can sometimes be finicky. This is the exact version used by Oracle, which worked correctly at the time of writing:</p>
<pre><code>$ cc -V
cc: Sun C 5.13 SunOS_i386 2014/10/20
$ CC -V
CC: Sun C++ 5.13 SunOS_i386 151846-10 2015/10/30</code></pre>
<h3 id="microsoft-visual-studio">Microsoft Visual Studio</h3>
<p>The minimum accepted version of Visual Studio is 2010. Older versions will not be accepted by <code>configure</code>. The maximum accepted version of Visual Studio is 2019. Versions older than 2017 are unlikely to continue working for long.</p>
<p>If you have multiple versions of Visual Studio installed, <code>configure</code> will by default pick the latest. You can request a specific version to be used by setting <code>--with-toolchain-version</code>, e.g. <code>--with-toolchain-version=2015</code>.</p>
@@ -314,6 +394,7 @@
<ul>
<li>To install on an apt-based Linux, try running <code>sudo apt-get install libfreetype6-dev</code>.</li>
<li>To install on an rpm-based Linux, try running <code>sudo yum install freetype-devel</code>.</li>
<li>To install on Solaris, try running <code>pkg install system/library/freetype-2</code>.</li>
</ul>
<p>Use <code>--with-freetype-include=&lt;path&gt;</code> and <code>--with-freetype-lib=&lt;path&gt;</code> if <code>configure</code> does not automatically locate the platform FreeType files.</p>
<h3 id="cups">CUPS</h3>
@@ -321,13 +402,15 @@
<ul>
<li>To install on an apt-based Linux, try running <code>sudo apt-get install libcups2-dev</code>.</li>
<li>To install on an rpm-based Linux, try running <code>sudo yum install cups-devel</code>.</li>
<li>To install on Solaris, try running <code>pkg install print/cups</code>.</li>
</ul>
<p>Use <code>--with-cups=&lt;path&gt;</code> if <code>configure</code> does not properly locate your CUPS files.</p>
<h3 id="x11">X11</h3>
<p>Certain <a href="http://www.x.org/">X11</a> libraries and include files are required on Linux.</p>
<p>Certain <a href="http://www.x.org/">X11</a> libraries and include files are required on Linux and Solaris.</p>
<ul>
<li>To install on an apt-based Linux, try running <code>sudo apt-get install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev</code>.</li>
<li>To install on an rpm-based Linux, try running <code>sudo yum install libXtst-devel libXt-devel libXrender-devel libXrandr-devel libXi-devel</code>.</li>
<li>To install on Solaris, try running <code>pkg install x11/header/x11-protocols x11/library/libice x11/library/libpthread-stubs x11/library/libsm x11/library/libx11 x11/library/libxau x11/library/libxcb x11/library/libxdmcp x11/library/libxevie x11/library/libxext x11/library/libxrender x11/library/libxrandr x11/library/libxscrnsaver x11/library/libxtst x11/library/toolkit/libxt</code>.</li>
</ul>
<p>Use <code>--with-x=&lt;path&gt;</code> if <code>configure</code> does not properly locate your X11 files.</p>
<h3 id="alsa">ALSA</h3>
@@ -360,6 +443,7 @@
<p>At least version 3.81 of GNU Make must be used. For distributions supporting GNU Make 4.0 or above, we strongly recommend it. GNU Make 4.0 contains useful functionality to handle parallel building (supported by <code>--with-output-sync</code>) and speed and stability improvements.</p>
<p>Note that <code>configure</code> locates and verifies a properly functioning version of <code>make</code> and stores the path to this <code>make</code> binary in the configuration. If you start a build using <code>make</code> on the command line, you will be using the version of make found first in your <code>PATH</code>, and not necessarily the one stored in the configuration. This initial make will be used as &quot;bootstrap make&quot;, and in a second stage, the make located by <code>configure</code> will be called. Normally, this will present no issues, but if you have a very old <code>make</code>, or a non-GNU Make <code>make</code> in your path, this might cause issues.</p>
<p>If you want to override the default make found by <code>configure</code>, use the <code>MAKE</code> configure variable, e.g. <code>configure MAKE=/opt/gnu/make</code>.</p>
<p>On Solaris, it is common to call the GNU version of make by using <code>gmake</code>.</p>
<h3 id="gnu-bash">GNU Bash</h3>
<p>The JDK requires <a href="http://www.gnu.org/software/bash">GNU Bash</a>. No other shells are supported.</p>
<p>At least version 3.2 of GNU Bash must be used.</p>
@@ -389,7 +473,7 @@
<li><code>--with-version-string=&lt;string&gt;</code> - Specify the version string this build will be identified with.</li>
<li><code>--with-version-&lt;part&gt;=&lt;value&gt;</code> - A group of options, where <code>&lt;part&gt;</code> can be any of <code>pre</code>, <code>opt</code>, <code>build</code>, <code>major</code>, <code>minor</code>, <code>security</code> or <code>patch</code>. Use these options to modify just the corresponding part of the version string from the default, or the value provided by <code>--with-version-string</code>.</li>
<li><code>--with-jvm-variants=&lt;variant&gt;[,&lt;variant&gt;...]</code> - Build the specified variant (or variants) of Hotspot. Valid variants are: <code>server</code>, <code>client</code>, <code>minimal</code>, <code>core</code>, <code>zero</code>, <code>custom</code>. Note that not all variants are possible to combine in a single build.</li>
<li><code>--enable-jvm-feature-&lt;feature&gt;</code> or <code>--disable-jvm-feature-&lt;feature&gt;</code> - Include (or exclude) <code>&lt;feature&gt;</code> as a JVM feature in Hotspot. You can also specify a list of features to be enabled, separated by space or comma, as <code>--with-jvm-features=&lt;feature&gt;[,&lt;feature&gt;...]</code>. If you prefix <code>&lt;feature&gt;</code> with a <code>-</code>, it will be disabled. These options will modify the default list of features for the JVM variant(s) you are building. For the <code>custom</code> JVM variant, the default list is empty. A complete list of valid JVM features can be found using <code>bash configure --help</code>.</li>
<li><code>--with-jvm-features=&lt;feature&gt;[,&lt;feature&gt;...]</code> - Use the specified JVM features when building Hotspot. The list of features will be enabled on top of the default list. For the <code>custom</code> JVM variant, this default list is empty. A complete list of available JVM features can be found using <code>bash configure --help</code>.</li>
<li><code>--with-target-bits=&lt;bits&gt;</code> - Create a target binary suitable for running on a <code>&lt;bits&gt;</code> platform. Use this to create 32-bit output on a 64-bit build platform, instead of doing a full cross-compile. (This is known as a <em>reduced</em> build.)</li>
</ul>
<p>On Linux, BSD and AIX, it is possible to override where Java by default searches for runtime/JNI libraries. This can be useful in situations where there is a special shared directory for system JNI libraries. This setting can in turn be overriden at runtime by setting the <code>java.library.path</code> property.</p>
@@ -452,7 +536,7 @@
<li><code>dist-clean</code> - Remove all files, including configuration</li>
</ul>
<p>Run <code>make help</code> to get an up-to-date list of important make targets and make control variables.</p>
<p>It is possible to build just a single module, a single phase, or a single phase of a single module, by creating make targets according to these followin patterns. A phase can be either of <code>gensrc</code>, <code>gendata</code>, <code>copy</code>, <code>java</code>, <code>launchers</code>, or <code>libs</code>. See <a href="#using-fine-grained-make-targets">Using Fine-Grained Make Targets</a> for more details about this functionality.</p>
<p>It is possible to build just a single module, a single phase, or a single phase of a single module, by creating make targets according to these followin patterns. A phase can be either of <code>gensrc</code>, <code>gendata</code>, <code>copy</code>, <code>java</code>, <code>launchers</code>, <code>libs</code> or <code>rmic</code>. See <a href="#using-fine-grained-make-targets">Using Fine-Grained Make Targets</a> for more details about this functionality.</p>
<ul>
<li><code>&lt;phase&gt;</code> - Build the specified phase and everything it depends on</li>
<li><code>&lt;module&gt;</code> - Build the specified module and everything it depends on</li>
@@ -494,12 +578,7 @@
</ul>
<h2 id="running-tests">Running Tests</h2>
<p>Most of the JDK tests are using the <a href="http://openjdk.java.net/jtreg">JTReg</a> test framework. Make sure that your configuration knows where to find your installation of JTReg. If this is not picked up automatically, use the <code>--with-jtreg=&lt;path to jtreg home&gt;</code> option to point to the JTReg framework. Note that this option should point to the JTReg home, i.e. the top directory, containing <code>lib/jtreg.jar</code> etc.</p>
<p>The <a href="https://wiki.openjdk.java.net/display/Adoption">Adoption Group</a> provides recent builds of jtreg <a href="https://ci.adoptopenjdk.net/view/Dependencies/job/jtreg/lastSuccessfulBuild/artifact">here</a>. Download the latest <code>.tar.gz</code> file, unpack it, and point <code>--with-jtreg</code> to the <code>jtreg</code> directory that you just unpacked.</p>
<p>Building of Hotspot Gtest suite requires the source code of Google Test framework. The top directory, which contains both <code>googletest</code> and <code>googlemock</code> directories, should be specified via <code>--with-gtest</code>. The supported version of Google Test is 1.8.1, whose source code can be obtained:</p>
<ul>
<li>by downloading and unpacking the source bundle from <a href="https://github.com/google/googletest/releases/tag/release-1.8.1">here</a></li>
<li>or by checking out <code>release-1.8.1</code> tag of <code>googletest</code> project: <code>git clone -b release-1.8.1 https://github.com/google/googletest</code></li>
</ul>
<p>The <a href="https://wiki.openjdk.java.net/display/Adoption">Adoption Group</a> provides recent builds of jtreg <a href="https://adopt-openjdk.ci.cloudbees.com/job/jtreg/lastSuccessfulBuild/artifact">here</a>. Download the latest <code>.tar.gz</code> file, unpack it, and point <code>--with-jtreg</code> to the <code>jtreg</code> directory that you just unpacked.</p>
<p>To execute the most basic tests (tier 1), use:</p>
<pre><code>make run-test-tier1</code></pre>
<p>For more details on how to run tests, please see the <a href="testing.html">Testing the JDK</a> document.</p>
@@ -560,6 +639,11 @@ x86_64-linux-gnu-to-ppc64le-linux-gnu</code></pre>
<p>You will need two copies of your toolchain, one which generates output that can run on the target system (the normal, or <em>target</em>, toolchain), and one that generates output that can run on the build system (the <em>build</em> toolchain). Note that cross-compiling is only supported for gcc at the time being. The gcc standard is to prefix cross-compiling toolchains with the target denominator. If you follow this standard, <code>configure</code> is likely to pick up the toolchain correctly.</p>
<p>The <em>build</em> toolchain will be autodetected just the same way the normal <em>build</em>/<em>target</em> toolchain will be autodetected when not cross-compiling. If this is not what you want, or if the autodetection fails, you can specify a devkit containing the <em>build</em> toolchain using <code>--with-build-devkit</code> to <code>configure</code>, or by giving <code>BUILD_CC</code> and <code>BUILD_CXX</code> arguments.</p>
<p>It is often helpful to locate the cross-compilation tools, headers and libraries in a separate directory, outside the normal path, and point out that directory to <code>configure</code>. Do this by setting the sysroot (<code>--with-sysroot</code>) and appending the directory when searching for cross-compilations tools (<code>--with-toolchain-path</code>). As a compact form, you can also use <code>--with-devkit</code> to point to a single directory, if it is correctly setup. (See <code>basics.m4</code> for details.)</p>
<p>If you are unsure what toolchain and versions to use, these have been proved working at the time of writing:</p>
<ul>
<li><a href="https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-linux-gnu-4.8-2013.11_linux.tar.xz">aarch64</a></li>
<li><a href="https://launchpad.net/linaro-toolchain-unsupported/trunk/2012.09/+download/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux.tar.bz2">arm 32-bit hardware floating point</a></li>
</ul>
<h3 id="native-libraries">Native Libraries</h3>
<p>You will need copies of external native libraries for the <em>target</em> system, present on the <em>build</em> machine while building.</p>
<p>Take care not to replace the <em>build</em> system's version of these libraries by mistake, since that can render the <em>build</em> machine unusable.</p>
@@ -786,6 +870,9 @@ Clock skew detected. Your build may be incomplete.</code></pre>
<p>then the clock on your build machine is out of sync with the timestamps on the source files. Other errors, apparently unrelated but in fact caused by the clock skew, can occur along with the clock skew warnings. These secondary errors may tend to obscure the fact that the true root cause of the problem is an out-of-sync clock.</p>
<p>If you see these warnings, reset the clock on the build machine, run <code>make clean</code> and restart the build.</p>
<h4 id="out-of-memory-errors">Out of Memory Errors</h4>
<p>On Solaris, you might get an error message like this:</p>
<pre><code>Trouble writing out table to disk</code></pre>
<p>To solve this, increase the amount of swap space on your build machine.</p>
<p>On Windows, you might get error messages like this:</p>
<pre><code>fatal error - couldn&#39;t allocate heap
cannot create ... Permission denied
@@ -837,7 +924,7 @@ sudo mv /tmp/configure /usr/local/bin</code></pre>
<p>If you are prepared to take some risk of an incorrect build, and know enough of the system to understand how things build and interact, you can speed up the build process considerably by instructing make to only build a portion of the product.</p>
<h4 id="building-individual-modules">Building Individual Modules</h4>
<p>The safe way to use fine-grained make targets is to use the module specific make targets. All source code in the JDK is organized so it belongs to a module, e.g. <code>java.base</code> or <code>jdk.jdwp.agent</code>. You can build only a specific module, by giving it as make target: <code>make jdk.jdwp.agent</code>. If the specified module depends on other modules (e.g. <code>java.base</code>), those modules will be built first.</p>
<p>You can also specify a set of modules, just as you can always specify a set of make targets: <code>make jdk.crypto.cryptoki jdk.crypto.ec jdk.crypto.mscapi</code></p>
<p>You can also specify a set of modules, just as you can always specify a set of make targets: <code>make jdk.crypto.cryptoki jdk.crypto.ec jdk.crypto.mscapi jdk.crypto.ucrypto</code></p>
<h4 id="building-individual-module-phases">Building Individual Module Phases</h4>
<p>The build process for each module is divided into separate phases. Not all modules need all phases. Which are needed depends on what kind of source code and other artifact the module consists of. The phases are:</p>
<ul>
@@ -847,6 +934,7 @@ sudo mv /tmp/configure /usr/local/bin</code></pre>
<li><code>java</code> (Compile Java code)</li>
<li><code>launchers</code> (Compile native executables)</li>
<li><code>libs</code> (Compile native libraries)</li>
<li><code>rmic</code> (Run the <code>rmic</code> tool)</li>
</ul>
<p>You can build only a single phase for a module by using the notation <code>$MODULE-$PHASE</code>. For instance, to build the <code>gensrc</code> phase for <code>java.base</code>, use <code>make java.base-gensrc</code>.</p>
<p>Note that some phases may depend on others, e.g. <code>java</code> depends on <code>gensrc</code> (if present). Make will build all needed prerequisites before building the requested phase.</p>

View File

@@ -109,11 +109,19 @@ one of the limiting factors for build performance.
At a minimum, a machine with 2-4 cores is advisable, as well as 2-4 GB of RAM.
(The more cores to use, the more memory you need.) At least 6 GB of free disk
space is required.
space is required (8 GB minimum for building on Solaris).
Even for 32-bit builds, it is recommended to use a 64-bit build machine, and
instead create a 32-bit target using `--with-target-bits=32`.
### Building on sparc
At a minimum, a machine with 4 cores is advisable, as well as 4 GB of RAM. (The
more cores to use, the more memory you need.) At least 8 GB of free disk space
is required.
Note: The sparc port is deprecated.
### Building on aarch64
At a minimum, a machine with 8 cores is advisable, as well as 8 GB of RAM.
@@ -130,7 +138,7 @@ This is not recommended. Instead, see the section on [Cross-compiling](
## Operating System Requirements
The mainline JDK project supports Linux, macOS, AIX and Windows.
The mainline JDK project supports Linux, Solaris, macOS, AIX and Windows.
Support for other operating system, e.g. BSD, exists in separate "port"
projects.
@@ -145,10 +153,11 @@ time of writing.
Operating system Vendor/version used
----------------- -------------------------------------------------------
Linux Oracle Enterprise Linux 6.4 / 7.6
Solaris Solaris 11.3 SRU 20
macOS Mac OS X 10.13 (High Sierra)
Windows Windows Server 2012 R2
The double version numbers for Linux are due to the hybrid model
The double version numbers for Linux and Solaris are due to the hybrid model
used at Oracle, where header files and external libraries from an older version
are used when building on a more modern version of the OS.
@@ -238,6 +247,21 @@ options.
Note that while it's possible to build on WSL, testing is still not fully
supported.
### Solaris
See `make/devkit/solaris11.1-package-list.txt` for a list of recommended
packages to install when building on Solaris. The versions specified in this
list is the versions used by the daily builds at Oracle, and is likely to work
properly.
Older versions of Solaris shipped a broken version of `objcopy`. At least
version 2.21.1 is needed, which is provided by Solaris 11 Update 1. Objcopy is
needed if you want to have external debug symbols. Please make sure you are
using at least version 2.21.1 of objcopy, or that you disable external debug
symbols.
Note: The Solaris port is deprecated.
### macOS
Apple is using a quite aggressive scheme of pushing OS updates, and coupling
@@ -290,6 +314,7 @@ one-to-one correlation between target operating system and toolchain.
------------------ -------------------------
Linux gcc, clang
macOS Apple Xcode (using clang)
Solaris Oracle Solaris Studio
AIX IBM XL C/C++
Windows Microsoft Visual Studio
@@ -302,9 +327,10 @@ issues.
Operating system Toolchain version
------------------ -------------------------------------------------------
Linux gcc 9.2.0
Linux gcc 8.3.0
macOS Apple Xcode 10.1 (using clang 10.0.0)
Windows Microsoft Visual Studio 2019 update 16.5.3
Solaris Oracle Solaris Studio 12.6 (with compiler version 5.15)
Windows Microsoft Visual Studio 2017 update 15.9.16
All compilers are expected to be able to compile to the C99 language standard,
as some C99 features are used in the source code. Microsoft Visual Studio
@@ -313,10 +339,10 @@ features that it does support.
### gcc
The minimum accepted version of gcc is 5.0. Older versions will generate a warning
The minimum accepted version of gcc is 4.8. Older versions will generate a warning
by `configure` and are unlikely to work.
The JDK is currently known to be able to compile with at least version 9.2 of
The JDK is currently known to be able to compile with at least version 8.3 of
gcc.
In general, any version between these two should be usable.
@@ -353,6 +379,36 @@ Build Environment](#problems-with-the-build-environment), and [Getting
Help](#getting-help) to find out if there are any recent, non-merged patches
available for this update.
### Oracle Solaris Studio
The minimum accepted version of the Solaris Studio compilers is 5.13
(corresponding to Solaris Studio 12.4). Older versions will not be accepted by
configure.
The Solaris Studio installation should contain at least these packages:
Package Version
-------------------------------------------------- -------------
developer/solarisstudio-124/backend 12.4-1.0.6.0
developer/solarisstudio-124/c++ 12.4-1.0.10.0
developer/solarisstudio-124/cc 12.4-1.0.4.0
developer/solarisstudio-124/library/c++-libs 12.4-1.0.10.0
developer/solarisstudio-124/library/math-libs 12.4-1.0.0.1
developer/solarisstudio-124/library/studio-gccrt 12.4-1.0.0.1
developer/solarisstudio-124/studio-common 12.4-1.0.0.1
developer/solarisstudio-124/studio-ja 12.4-1.0.0.1
developer/solarisstudio-124/studio-legal 12.4-1.0.0.1
developer/solarisstudio-124/studio-zhCN 12.4-1.0.0.1
Compiling with Solaris Studio can sometimes be finicky. This is the exact
version used by Oracle, which worked correctly at the time of writing:
```
$ cc -V
cc: Sun C 5.13 SunOS_i386 2014/10/20
$ CC -V
CC: Sun C++ 5.13 SunOS_i386 151846-10 2015/10/30
```
### Microsoft Visual Studio
The minimum accepted version of Visual Studio is 2010. Older versions will not
@@ -438,6 +494,7 @@ rather than bundling the JDK's own copy.
libfreetype6-dev`.
* To install on an rpm-based Linux, try running `sudo yum install
freetype-devel`.
* To install on Solaris, try running `pkg install system/library/freetype-2`.
Use `--with-freetype-include=<path>` and `--with-freetype-lib=<path>`
if `configure` does not automatically locate the platform FreeType files.
@@ -452,6 +509,7 @@ your operating system.
libcups2-dev`.
* To install on an rpm-based Linux, try running `sudo yum install
cups-devel`.
* To install on Solaris, try running `pkg install print/cups`.
Use `--with-cups=<path>` if `configure` does not properly locate your CUPS
files.
@@ -459,12 +517,18 @@ files.
### X11
Certain [X11](http://www.x.org/) libraries and include files are required on
Linux.
Linux and Solaris.
* To install on an apt-based Linux, try running `sudo apt-get install
libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev`.
* To install on an rpm-based Linux, try running `sudo yum install
libXtst-devel libXt-devel libXrender-devel libXrandr-devel libXi-devel`.
* To install on Solaris, try running `pkg install x11/header/x11-protocols
x11/library/libice x11/library/libpthread-stubs x11/library/libsm
x11/library/libx11 x11/library/libxau x11/library/libxcb
x11/library/libxdmcp x11/library/libxevie x11/library/libxext
x11/library/libxrender x11/library/libxrandr x11/library/libxscrnsaver
x11/library/libxtst x11/library/toolkit/libxt`.
Use `--with-x=<path>` if `configure` does not properly locate your X11 files.
@@ -539,6 +603,8 @@ will present no issues, but if you have a very old `make`, or a non-GNU Make
If you want to override the default make found by `configure`, use the `MAKE`
configure variable, e.g. `configure MAKE=/opt/gnu/make`.
On Solaris, it is common to call the GNU version of make by using `gmake`.
### GNU Bash
The JDK requires [GNU Bash](http://www.gnu.org/software/bash). No other shells
@@ -618,14 +684,11 @@ features, use `bash configure --help=short` instead.)
(or variants) of Hotspot. Valid variants are: `server`, `client`,
`minimal`, `core`, `zero`, `custom`. Note that not all
variants are possible to combine in a single build.
* `--enable-jvm-feature-<feature>` or `--disable-jvm-feature-<feature>` -
Include (or exclude) `<feature>` as a JVM feature in Hotspot. You can also
specify a list of features to be enabled, separated by space or comma, as
`--with-jvm-features=<feature>[,<feature>...]`. If you prefix `<feature>`
with a `-`, it will be disabled. These options will modify the default list
of features for the JVM variant(s) you are building. For the `custom` JVM
variant, the default list is empty. A complete list of valid JVM features
can be found using `bash configure --help`.
* `--with-jvm-features=<feature>[,<feature>...]` - Use the specified JVM
features when building Hotspot. The list of features will be enabled on top
of the default list. For the `custom` JVM variant, this default list is
empty. A complete list of available JVM features can be found using `bash
configure --help`.
* `--with-target-bits=<bits>` - Create a target binary suitable for running
on a `<bits>` platform. Use this to create 32-bit output on a 64-bit build
platform, instead of doing a full cross-compile. (This is known as a
@@ -752,7 +815,7 @@ control variables.
It is possible to build just a single module, a single phase, or a single phase
of a single module, by creating make targets according to these followin
patterns. A phase can be either of `gensrc`, `gendata`, `copy`, `java`,
`launchers`, or `libs`. See [Using Fine-Grained Make Targets](
`launchers`, `libs` or `rmic`. See [Using Fine-Grained Make Targets](
#using-fine-grained-make-targets) for more details about this functionality.
* `<phase>` - Build the specified phase and everything it depends on
@@ -825,18 +888,10 @@ containing `lib/jtreg.jar` etc.
The [Adoption Group](https://wiki.openjdk.java.net/display/Adoption) provides
recent builds of jtreg [here](
https://ci.adoptopenjdk.net/view/Dependencies/job/jtreg/lastSuccessfulBuild/artifact).
https://adopt-openjdk.ci.cloudbees.com/job/jtreg/lastSuccessfulBuild/artifact).
Download the latest `.tar.gz` file, unpack it, and point `--with-jtreg` to the
`jtreg` directory that you just unpacked.
Building of Hotspot Gtest suite requires the source code of Google Test framework.
The top directory, which contains both `googletest` and `googlemock`
directories, should be specified via `--with-gtest`.
The supported version of Google Test is 1.8.1, whose source code can be obtained:
* by downloading and unpacking the source bundle from [here](https://github.com/google/googletest/releases/tag/release-1.8.1)
* or by checking out `release-1.8.1` tag of `googletest` project: `git clone -b release-1.8.1 https://github.com/google/googletest`
To execute the most basic tests (tier 1), use:
```
make run-test-tier1
@@ -983,6 +1038,14 @@ appending the directory when searching for cross-compilations tools
to point to a single directory, if it is correctly setup. (See `basics.m4` for
details.)
If you are unsure what toolchain and versions to use, these have been proved
working at the time of writing:
* [aarch64](
https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-linux-gnu-4.8-2013.11_linux.tar.xz)
* [arm 32-bit hardware floating point](
https://launchpad.net/linaro-toolchain-unsupported/trunk/2012.09/+download/gcc-linaro-arm-linux-gnueabihf-raspbian-2012.09-20120921_linux.tar.bz2)
### Native Libraries
You will need copies of external native libraries for the *target* system,
@@ -1402,6 +1465,12 @@ clean` and restart the build.
#### Out of Memory Errors
On Solaris, you might get an error message like this:
```
Trouble writing out table to disk
```
To solve this, increase the amount of swap space on your build machine.
On Windows, you might get error messages like this:
```
fatal error - couldn't allocate heap
@@ -1540,7 +1609,8 @@ module depends on other modules (e.g. `java.base`), those modules will be built
first.
You can also specify a set of modules, just as you can always specify a set of
make targets: `make jdk.crypto.cryptoki jdk.crypto.ec jdk.crypto.mscapi`
make targets: `make jdk.crypto.cryptoki jdk.crypto.ec jdk.crypto.mscapi
jdk.crypto.ucrypto`
#### Building Individual Module Phases
@@ -1554,6 +1624,7 @@ and other artifact the module consists of. The phases are:
* `java` (Compile Java code)
* `launchers` (Compile native executables)
* `libs` (Compile native libraries)
* `rmic` (Run the `rmic` tool)
You can build only a single phase for a module by using the notation
`$MODULE-$PHASE`. For instance, to build the `gensrc` phase for `java.base`,

View File

@@ -0,0 +1,631 @@
This document describes system properties that are used for internal
debugging and instrumentation purposes, along with the system loggers,
which are used for the same thing.
This document is intended as a developer resource, and it is not
needed as Nashorn documentation for normal usage. Flags and system
properties described herein are subject to change without notice.
=====================================
1. System properties used internally
=====================================
This documentation of the system property flags assume that the
default value of the flag is false, unless otherwise specified.
SYSTEM PROPERTY: -Dnashorn.args=<string>
This property takes as its value a space separated list of Nashorn
command line options that should be passed to Nashorn. This might be
useful in environments where it is hard to tell how a nashorn.jar is
launched.
Example:
> java -Dnashorn.args="--lazy-complation --log=compiler" large-java-app-with-nashorn.jar
> ant -Dnashorn.args="--log=codegen" antjob
SYSTEM PROPERTY: -Dnashorn.args.prepend=<string>
This property behaves like nashorn.args, but adds the given arguments
before the existing ones instead of after them. Later arguments will
overwrite earlier ones, so this is useful for setting default arguments
that can be overwritten.
SYSTEM PROPERTY: -Dnashorn.unstable.relink.threshold=x
NOTE: This property is deprecated in favor of the
"--unstable-relink-threshold" command line option. It controls how many
call site misses are allowed before a callsite is relinked with "apply"
semantics to never change again. In the case of megamorphic callsites,
this is necessary, or the program would spend all its time swapping out
callsite targets. When neither the system property nor the command line
option are specified, defaults to 8, or 16 with optimistic types turned
on.
SYSTEM PROPERTY: -Dnashorn.compiler.splitter.threshold=x
This will change the node weight that requires a subgraph of the IR to
be split into several classes in order not to run out of bytecode space.
The default value is 0x8000 (32768).
SYSTEM PROPERTY: -Dnashorn.serialize.compression=<x>
This property sets the compression level used when deflating serialized
AST structures of anonymous split functions. Valid values range from 0 to 9,
the default value is 4. Higher values will reduce memory size of serialized
AST but increase CPU usage required for compression.
SYSTEM PROPERTY: -Dnashorn.codegen.debug.trace=<x>
See the description of the codegen logger below.
SYSTEM PROPERTY: -Dnashorn.fields.objects, -Dnashorn.fields.dual
When the nashorn.fields.objects property is true, Nashorn will always
use object fields for AccessorProperties, requiring boxing for all
primitive property values. When nashorn.fields.dual is set, Nashorn
will always use dual long/object fields, which allows primitives to be
stored without boxing. When neither system property is set, Nashorn
chooses a setting depending on the optimistic types setting (dual
fields when optimistic types are enabled, object-only fields otherwise).
With dual fields, Nashorn uses long fields to store primitive values.
Ints are represented as the 32 low bits of the long fields. Doubles
are represented as the doubleToLongBits of their value. This way a
single field can be used for all primitive types. Packing and
unpacking doubles to their bit representation is intrinsified by
the JVM and extremely fast.
In the future, this might complement or be replaced by experimental
feature sun.misc.TaggedArray, which has been discussed on the mlvm
mailing list. TaggedArrays are basically a way to share data space
between primitives and references, and have the GC understand this.
SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[<x>[,*]],
-Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]
When this property is set, creation and manipulation of any symbol
named "x" will show information about when the compiler changes its
type assumption, bytecode local variable slot assignment and other
data. This is useful if, for example, a symbol shows up as an Object,
when you believe it should be a primitive. Usually there is an
explanation for this, for example that it exists in the global scope
and type analysis has to be more conservative.
Several symbols names to watch can be specified by comma separation.
If no variable name is specified (and no equals sign), all symbols
will be watched
By using "stacktrace" instead of or together with "trace", stack
traces will be displayed upon symbol changes according to the same
semantics.
SYSTEM PROPERTY: -Dnashorn.lexer.xmlliterals
If this property it set, it means that the Lexer should attempt to
parse XML literals, which would otherwise generate syntax
errors. Warning: there are currently no unit tests for this
functionality.
XML literals, when this is enabled, end up as standard LiteralNodes in
the IR.
SYSTEM_PROPERTY: -Dnashorn.debug
If this property is set to true, Nashorn runs in Debug mode. Debug
mode is slightly slower, as for example statistics counters are enabled
during the run. Debug mode makes available a NativeDebug instance
called "Debug" in the global space that can be used to print property
maps and layout for script objects, as well as a "dumpCounters" method
that will print the current values of the previously mentioned stats
counters.
These functions currently exists for Debug:
"map" - print(Debug.map(x)) will dump the PropertyMap for object x to
stdout (currently there also exist functions called "embedX", where X
is a value from 0 to 3, that will dump the contents of the embed pool
for the first spill properties in any script object and "spill", that
will dump the contents of the growing spill pool of spill properties
in any script object. This is of course subject to change without
notice, should we change the script object layout.
"methodHandle" - this method returns the method handle that is used
for invoking a particular script function.
"identical" - this method compares two script objects for reference
equality. It is a == Java comparison
"equals" - Returns true if two objects are either referentially
identical or equal as defined by java.lang.Object.equals.
"dumpCounters" - will dump the debug counters' current values to
stdout.
Currently we count number of ScriptObjects in the system, number of
Scope objects in the system, number of ScriptObject listeners added,
removed and dead (without references).
We also count number of ScriptFunctions, ScriptFunction invocations
and ScriptFunction allocations.
Furthermore we count PropertyMap statistics: how many property maps
exist, how many times were property maps cloned, how many times did
the property map history cache hit, prevent new allocations, how many
prototype invalidations were done, how many time the property map
proto cache hit.
Finally we count callsite misses on a per callsite bases, which occur
when a callsite has to be relinked, due to a previous assumption of
object layout being invalidated.
"getContext" - return the current Nashorn context.
"equalWithoutType" - Returns true if if the two objects are both
property maps, and they have identical properties in the same order,
but allows the properties to differ in their types.
"diffPropertyMaps" Returns a diagnostic string representing the difference
of two property maps.
"getClass" - Returns the Java class of an object, or undefined if null.
"toJavaString" - Returns the Java toString representation of an object.
"toIdentString" - Returns a string representation of an object consisting
of its java class name and hash code.
"getListenerCount" - Return the number of property listeners for a
script object.
"getEventQueueCapacity" - Get the capacity of the event queue.
"setEventQueueCapacity" - Set the event queue capacity.
"addRuntimeEvent" - Add a runtime event to the runtime event queue.
The queue has a fixed size (see -Dnashorn.runtime.event.queue.size)
and the oldest entry will be thrown out of the queue is about to overflow.
"expandEventQueueCapacity" - Expands the event queue capacity,
or truncates if capacity is lower than current capacity. Then only
the newest entries are kept.
"clearRuntimeEvents" - Clear the runtime event queue.
"removeRuntimeEvent" - Remove a specific runtime event from the event queue.
"getRuntimeEvents" - Return all runtime events in the queue as an array.
"getLastRuntimeEvent" - Return the last runtime event in the queue.
SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktrace
This enhances methodhandles logging (see below) to also dump the
stack trace for every instrumented method handle operation.
Warning: This is enormously verbose, but provides a pretty
decent "grep:able" picture of where the calls are coming from.
SYSTEM PROPERTY: -Dnashorn.cce
Setting this system property causes the Nashorn linker to rely on
ClassCastExceptions for triggering a callsite relink. If not set, the linker
will add an explicit instanceof guard.
SYSTEM PROPERTY: -Dnashorn.spill.threshold=<x>
This property sets the number of fields in an object from which to use
generic array based spill storage instead of Java fields. The default value
is 256.
SYSTEM PROPERTY: -Dnashorn.tcs.miss.samplePercent=<x>
When running with the trace callsite option (-tcs), Nashorn will count
and instrument any callsite misses that require relinking. As the
number of relinks is large and usually produces a lot of output, this
system property can be used to constrain the percentage of misses that
should be logged. Typically this is set to 1 or 5 (percent). 1% is the
default value.
SYSTEM PROPERTY: -Dnashorn.persistent.code.cache
This property can be used to set the directory where Nashorn stores
serialized script classes generated with the -pcc/--persistent-code-cache
option. The default directory name is "nashorn_code_cache".
SYSTEM PROPERTY: -Dnashorn.typeInfo.maxFiles
Maximum number of files to store in the type info cache. The type info cache
is used to cache type data of JavaScript functions when running with
optimistic types (-ot/--optimistic-types). There is one file per JavaScript
function in the cache.
The default value is 0 which means the feature is disabled. Setting this
to something like 20000 is probably good enough for most applications and
will usually cap the cache directory to about 80MB presuming a 4kB
filesystem allocation unit. Set this to "unlimited" to run without limit.
If the value is not 0 or "unlimited", Nashorn will spawn a cleanup thread
that makes sure the number of files in the cache does not exceed the given
value by deleting the least recently modified files.
SYSTEM PROPERTY: -Dnashorn.typeInfo.cacheDir
This property can be used to set the directory where Nashorn stores the
type info cache when -Dnashorn.typeInfo.maxFiles is set to a nonzero
value. The default location is platform specific. On Windows, it is
"${java.io.tmpdir}\com.oracle.java.NashornTypeInfo". On Linux and
Solaris it is "~/.cache/com.oracle.java.NashornTypeInfo". On Mac OS X,
it is "~/Library/Caches/com.oracle.java.NashornTypeInfo".
SYSTEM PROPERTY: -Dnashorn.typeInfo.cleanupDelaySeconds=<value>
This sets the delay between cleanups of the typeInfo cache, in seconds.
The default delay is 20 seconds.
SYSTEM PROPERTY: -Dnashorn.profilefile=<filename>
When running with the profile callsite options (-pcs), Nashorn will
dump profiling data for all callsites to stderr as a shutdown hook. To
instead redirect this to a file, specify the path to the file using
this system property.
SYSTEM_PROPERTY: -Dnashorn.regexp.impl=[jdk|joni]
This property defines the regular expression engine to be used by
Nashorn. Set this flag to "jdk" to get an implementation based on the
JDK's java.util.regex package. Set this property to "joni" to install
an implementation based on Joni, the regular expression engine used by
the JRuby project. The default value for this flag is "joni"
SYSTEM PROPERTY: -Dnashorn.runtime.event.queue.size=<value>
Nashorn provides a fixed sized runtime event queue for debugging purposes.
See -Dnashorn.debug for methods to access the event queue.
The default value is 1024.
SYSTEM PROPERTY: -Dnashorn.anonymous.classes.threshold=<value>
Nashorn can use anonymous classes for loading compiled scripts, depending
on the --anonymous-classes=[auto|true|false] option. Anonymous classes load
faster, but the loaded classes get less optimization applied to them and
therefore usually run slower. In the default "auto" setting, scripts are
loaded as anonymous classes if the script size does not exceed 512 bytes.
The above system property allows to set this threshold to a user defined
value.
===============
2. The loggers.
===============
It is very simple to create your own logger. Use the DebugLogger class
and give the subsystem name as a constructor argument.
The Nashorn loggers can be used to print per-module or per-subsystem
debug information with different levels of verbosity. The loggers for
a given subsystem are available are enabled by using
--log=<systemname>[:<level>]
on the command line.
Here <systemname> identifies the name of the subsystem to be logged
and the optional colon and level argument is a standard
java.util.logging.Level name (severe, warning, info, config, fine,
finer, finest). If the level is left out for a particular subsystem,
it defaults to "info". Any log message logged as the level or a level
that is more important will be output to stderr by the logger.
Several loggers can be enabled by a single command line option, by
putting a comma after each subsystem/level tuple (or each subsystem if
level is unspecified). The --log option can also be given multiple
times on the same command line, with the same effect.
For example: --log=codegen,fields:finest is equivalent to
--log=codegen:info --log=fields:finest
The following is an incomplete list of subsystems that currently
support logging. Look for classes implementing
jdk.nashorn.internal.runtime.logging.Loggable for more loggers.
* compiler
The compiler is in charge of turning source code and function nodes
into byte code, and installs the classes into a class loader
controlled from the Context. Log messages are, for example, about
things like new compile units being allocated. The compiler has global
settings that all the tiers of codegen (e.g. Lower and CodeGenerator)
use.s
* recompile
This logger shows information about recompilation of scripts and
functions at runtime. Recompilation may happen because a function
was called with different parameter types, or because an optimistic
assumption failed while executing a function with -ot/--optimistic-types.
* codegen
The code generator is the emitter stage of the code pipeline, and
turns the lowest tier of a FunctionNode into bytecode. Codegen logging
shows byte codes as they are being emitted, line number information
and jumps. It also shows the contents of the bytecode stack prior to
each instruction being emitted. This is a good debugging aid. For
example:
[codegen] #41 line:2 (f)_afc824e
[codegen] #42 load symbol x slot=2
[codegen] #43 {1:O} load int 0
[codegen] #44 {2:I O} dynamic_runtime_call GT:ZOI_I args=2 returnType=boolean
[codegen] #45 signature (Ljava/lang/Object;I)Z
[codegen] #46 {1:Z} ifeq ternary_false_5402fe28
[codegen] #47 load symbol x slot=2
[codegen] #48 {1:O} goto ternary_exit_107c1f2f
[codegen] #49 ternary_false_5402fe28
[codegen] #50 load symbol x slot=2
[codegen] #51 {1:O} convert object -> double
[codegen] #52 {1:D} neg
[codegen] #53 {1:D} convert double -> object
[codegen] #54 {1:O} ternary_exit_107c1f2f
[codegen] #55 {1:O} return object
shows a ternary node being generated for the sequence "return x > 0 ?
x : -x"
The first number on the log line is a unique monotonically increasing
emission id per bytecode. There is no guarantee this is the same id
between runs. depending on non deterministic code
execution/compilation, but for small applications it usually is. If
the system variable -Dnashorn.codegen.debug.trace=<x> is set, where x
is a bytecode emission id, a stack trace will be shown as the
particular bytecode is about to be emitted. This can be a quick way to
determine where it comes from without attaching the debugger. "Who
generated that neg?"
The --log=codegen option is equivalent to setting the system variable
"nashorn.codegen.debug" to true.
* fold
Shows constant folding taking place before lowering
* lower
This is the first lowering pass.
Lower is a code generation pass that turns high level IR nodes into
lower level one, for example substituting comparisons to RuntimeNodes
and inlining finally blocks.
Lower is also responsible for determining control flow information
like end points.
* symbols
The symbols logger tracks the assignment os symbols to identifiers.
* scopedepths
This logs the calculation of scope depths for non-local symbols.
* fields
The --log=fields option (at info level) is equivalent to setting the
system variable "nashorn.fields.debug" to true. At the info level it
will only show info about type assumptions that were invalidated. If
the level is set to finest, it will also trace every AccessorProperty
getter and setter in the program, show arguments, return values
etc. It will also show the internal representation of respective field
(Object in the normal case, unless running with the dual field
representation)
* time
This enables timers for various phases of script compilation. The timers
will be dumped when the Nashorn process exits. We see a percentage value
of how much time was spent not executing bytecode (i.e. compilation and
internal tasks) at the end of the report.
A finer level than "info" will show individual compilation timings as they
happen.
Here is an example:
[time] Accumulated complation phase Timings:
[time]
[time] 'JavaScript Parsing' 1076 ms
[time] 'Constant Folding' 159 ms
[time] 'Control Flow Lowering' 303 ms
[time] 'Program Point Calculation' 282 ms
[time] 'Builtin Replacement' 71 ms
[time] 'Code Splitting' 670 ms
[time] 'Symbol Assignment' 474 ms
[time] 'Scope Depth Computation' 249 ms
[time] 'Optimistic Type Assignment' 186 ms
[time] 'Local Variable Type Calculation' 526 ms
[time] 'Bytecode Generation' 5177 ms
[time] 'Class Installation' 1854 ms
[time]
[time] Total runtime: 11994 ms (Non-runtime: 11027 ms [91%])
* methodhandles
If this logger is enabled, each MethodHandle related call that uses
the java.lang.invoke package gets its MethodHandle intercepted and an
instrumentation printout of arguments and return value appended to
it. This shows exactly which method handles are executed and from
where. (Also MethodTypes and SwitchPoints).
* classcache
This logger shows information about reusing code classes using the
in-memory class cache. Nashorn will try to avoid compilation of
scripts by using existing classes. This can significantly improve
performance when repeatedly evaluating the same script.
=======================
3. Undocumented options
=======================
Here follows a short description of undocumented options for Nashorn.
To see a list of all undocumented options, use the (undocumented) flag
"-xhelp".
i.e. jjs -xhelp or java -jar nashorn.jar -xhelp
Undocumented options are not guaranteed to work, run correctly or be
bug free. They are experimental and for internal or debugging use.
They are also subject to change without notice.
In practice, though, all options below not explicitly documented as
EXPERIMENTAL can be relied upon, for example --dump-on-error is useful
for any JavaScript/Nashorn developer, but there is no guarantee.
A short summary follows:
-D (-Dname=value. Set a system property. This option can be repeated.)
-ccs, --class-cache-size (Size of the Class cache size per global scope.)
-cp, -classpath (-cp path. Specify where to find user class files.)
-co, --compile-only (Compile without running.)
param: [true|false] default: false
-d, --dump-debug-dir (specify a destination directory to dump class files.)
param: <path>
--debug-lines (Generate line number table in .class files.)
param: [true|false] default: true
--debug-locals (Generate local variable table in .class files.)
param: [true|false] default: false
-doe, -dump-on-error (Dump a stack trace on errors.)
param: [true|false] default: false
--early-lvalue-error (invalid lvalue expressions should be reported as early errors.)
param: [true|false] default: true
--empty-statements (Preserve empty statements in AST.)
param: [true|false] default: false
-fv, -fullversion (Print full version info of Nashorn.)
param: [true|false] default: false
--function-statement-error (Report an error when function declaration is used as a statement.)
param: [true|false] default: false
--function-statement-warning (Warn when function declaration is used as a statement.)
param: [true|false] default: false
-fx (Launch script as an fx application.)
param: [true|false] default: false
--global-per-engine (Use single Global instance per script engine instance.)
param: [true|false] default: false
-h, -help (Print help for command line flags.)
param: [true|false] default: false
--loader-per-compile (Create a new class loader per compile.)
param: [true|false] default: true
-l, --locale (Set Locale for script execution.)
param: <locale> default: en-US
--log (Enable logging of a given level for a given number of sub systems.
[for example: --log=fields:finest,codegen:info].)
param: <module:level>,*
-nj, --no-java (Disable Java support.)
param: [true|false] default: false
-nse, --no-syntax-extensions (Disallow non-standard syntax extensions.)
param: [true|false] default: false
-nta, --no-typed-arrays (Disable typed arrays support.)
param: [true|false] default: false
--parse-only (Parse without compiling.)
param: [true|false] default: false
--print-ast (Print abstract syntax tree.)
param: [true|false] default: false
-pc, --print-code (Print generated bytecode. If a directory is specified, nothing will
be dumped to stderr. Also, in that case, .dot files will be generated
for all functions or for the function with the specified name only.)
param: [dir:<output-dir>,function:<name>]
--print-lower-ast (Print lowered abstract syntax tree.)
param: [true|false] default: false
-plp, --print-lower-parse (Print the parse tree after lowering.)
param: [true|false] default: false
--print-no-newline (Print function will not print new line char.)
param: [true|false] default: false
-pp, --print-parse (Print the parse tree.)
param: [true|false] default: false
--print-symbols (Print the symbol table.)
param: [true|false] default: false
-pcs, --profile-callsites (Dump callsite profile data.)
param: [true|false] default: false
-scripting (Enable scripting features.)
param: [true|false] default: false
--stderr (Redirect stderr to a filename or to another tty, e.g. stdout.)
param: <output console>
--stdout (Redirect stdout to a filename or to another tty, e.g. stderr.)
param: <output console>
-strict (Run scripts in strict mode.)
param: [true|false] default: false
-t, -timezone (Set timezone for script execution.)
param: <timezone> default: Europe/Stockholm
-tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses]
enterexit [trace callsite enter/exit], objects [print object properties].)
param: [=[option,]*]
-urt, --unstable-relink-threshold (Number of times a dynamic call site has to be relinked before it
is considered unstable, when the runtime will try to link it as
if it is megamorphic.)
--verify-code (Verify byte code before running.)
param: [true|false] default: false
-v, -version (Print version info of Nashorn.)
param: [true|false] default: false
-xhelp (Print extended help for command line flags.)
param: [true|false] default: false

View File

@@ -0,0 +1,988 @@
<!--
Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License version 2 only, as
published by the Free Software Foundation. Oracle designates this
particular file as subject to the "Classpath" exception as provided
by Oracle in the LICENSE file that accompanied this code.
This code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
version 2 for more details (a copy is included in the LICENSE file that
accompanied this code).
You should have received a copy of the GNU General Public License version
2 along with this work; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
or visit www.oracle.com if you need additional information or have any
questions.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html class=" regenabled gecko radius jsenabled regloaded" xmlns="http://www.w3.org/1999/xhtml"><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Java Scripting Programmer's Guide</title>
<!-- ============ -->
<!-- MAIN CONTENT -->
<!-- ============ -->
<table summary="layout" border="0" width="100%">
<tbody><tr>
<td>
<div id="sharepage" class="smallpagetitle"><h1>Java Scripting Programmer's Guide</h1><div class="sharepage"> <div class="sharepagew1 share-mailto"> <table summary="" cellpadding="0" cellspacing="0"><tbody><tr> <td id="share-mailto"><a href="mailto:?subject=Java%20Documentation%20Page:%20Java%20Scripting%20Programmer%27s%20Guide&amp;body=Check%20out%20this%20page:%20%0A%0Ahttp%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink mailto" title="Email this page to a friend"></a></td> <td id="share-technorati"><a href="http://technorati.com/search/http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink technorati" title="See who links to this page on Technorati"></a></td> <td id="share-delicious"><a href="http://del.icio.us/post?v=4;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html;title=Java%20Scripting%20Programmer%27s%20Guide" class="sharelink delicious" title="Bookmark this page in del.icio.us"></a></td> <td id="share-digg"><a href="http://digg.com/submit?phase=2&amp;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html&amp;title=Java%20Scripting%20Programmer%27s%20Guide" class="sharelink digg" title="Submit this page to Digg"></a></td> <td id="share-slashdot"><a href="http://slashdot.org/bookmark.pl?title=Java%20Scripting%20Programmer%27s%20Guide&amp;url=http%3A%2F%2Fdocs.oracle.com%2Fjavase%2F6%2Fdocs%2Ftechnotes%2Fguides%2Fscripting%2Fprogrammer_guide%2Findex.html" class="sharelink slashdot" title="Submit this page to Slashdot"></a></td> <td id="share-blank"> </td></tr></tbody></table></div></div></div>
</td>
</tr>
</tbody></table>
<!-- Body text begins here -->
<ul>
<li><span><a href="#who">Who is the Java Scripting API
For?</a></span></li>
<li><span><a href="#package">Scripting Package</a></span></li>
<li><span><a href="#examples">Examples</a></span>
<ul>
<li><span><a href="#helloworld">"Hello, World"</a></span></li>
<li><span><a href="#evalfile">Evaluating a Script
File</a></span></li>
<li><span><a href="#scriptvars">Script Variables</a></span></li>
<li><span><a href="#invoke">Invoking Script Functions and
Methods</a></span></li>
<li><span><a href="#interfaces">Implementing Java Interfaces by
Scripts</a></span></li>
<li><span><a href="#scopes">Multiple Scopes for
Scripts</a></span></li>
</ul>
</li>
<li><span><a href="#jsengine">JavaScript Script
Engine</a></span></li>
<li><span><a href="#jstojava">JavaScript to Java
Communication</a></span>
<ul>
<li><span><a href="#jsjavaclass">Accessing Java
Classes</a></span></li>
<li><span><a href="#jsimport">Importing Java Packages,
Classes</a></span></li>
<li><span><a href="#jsarrays">Creating, Converting and Using Java
Arrays</a></span></li>
<li><span><a href="#jsimplement">Implementing Java
Interfaces</a></span></li>
<li><span><a href="#jsextendabstract">Extending Abstract Java Classes
</a></span></li>
<li><span><a href="#jsextendconcrete">Extending Concrete Java Classes
</a></span></li>
<li><span><a href="#jsimplementmultiple">Implementing Multiple Java Interfaces
</a></span></li>
<li><span><a href="#classBoundImplementations">Class-Bound Implementations
</a></span></li>
<li><span><a href="#jsoverload">Overload Resolution</a></span></li>
<li><span><a href="#dataTypeMapping">Mapping of Data Types Between Java
and JavaScript</a></span></li>
</ul>
</li>
<li><span><a href="#engineimpl">Implementing Your Own Script
Engine</a></span></li>
<li><span><a href="#refs">References</a></span></li>
</ul>
<span><a name="who" id="who"></a></span>
<h2><span>Who is the Java Scripting API For?</span></h2>
<span>Some useful characteristics of scripting languages
are:</span>
<ul>
<li><span><b>Convenience</b>: Most scripting languages are
dynamically typed. You can usually create new variables without
declaring the variable type, and you can reuse variables to store
objects of different types. Also, scripting languages tend to
perform many type conversions automatically, for example,
converting the number 10 to the text "10" as necessary.</span></li>
<li><span><b>Developing rapid prototypes</b>: You can avoid the
edit-compile-run cycle and just use edit-run!</span></li>
<li><span><b>Application extension/customization</b>: You can
"externalize" parts of your application - like configuration
scripts, business logic/rules and math expressions for financial
applications.</span></li>
<li><span><b>"Command line" shells for applications</b> -for
debugging, runtime/deploy time configuration etc. Most applications
have a web-based GUI configuaration tool these days. But
sysadmins/deployers frequently prefer command line tools. Instead
of inventing ad-hoc scripting language for that purpose, a
"standard" scripting language can be used.</span></li>
</ul>
<p><span>The Java<font size="-1"><sup>TM</sup></font> Scripting API
is a scripting language indepedent framework for using script
engines from Java code. With the Java Scripting API, it is possible
to write customizable/extendable applications in the Java language
and leave the customization scripting language choice to the end
user. The Java application developer need not choose the extension
language during development. If you write your application with
JSR-223 API, then your users can use any JSR-223 compliant
scripting language.</span></p>
<hr>
<span><a name="package" id="package"></a></span>
<h2><span>Scripting Package</span></h2>
<p><span>The Java Scripting functionality is in the <code><a href="http://docs.oracle.com/javase/9/docs/api/javax/script/package-summary.html">javax.script</a></code>
package. This is a relatively small, simple API. The starting point
of the scripting API is the <code>ScriptEngineManager</code> class.
A ScriptEngineManager object can discover script engines through
the jar file service discovery mechanism. It can also instantiate
ScriptEngine objects that interpret scripts written in a specific
scripting language. The simplest way to use the scripting API is as
follows:</span></p>
<ol>
<li><span>Create a <code>ScriptEngineManager</code>
object.</span></li>
<li><span>Get a <code>ScriptEngine</code> object from the
manager.</span></li>
<li><span>Evaluate script using the <code>ScriptEngine</code>'s
<code>eval</code> methods.</span></li>
</ol>
<p><span>Now, it is time to look at some sample code. While it is
not mandatory, it may be useful to know a bit of JavaScript to read
these examples.</span></p>
<hr>
<span><a name="examples" id="examples"></a></span>
<h2><span>Examples</span></h2>
<span><a name="helloworld" id="helloworld"></a></span>
<h3><span>"Hello, World"</span></h3>
<p><span>From the <code>ScriptEngineManager</code> instance, we
request a JavaScript engine instance using
<code>getEngineByName</code> method. On the script engine, the
<code>eval</code> method is called to execute a given String as
JavaScript code! For brevity, in this as well as in subsequent
examples, we have not shown exception handling. There are checked
and runtime exceptions thrown from <code>javax.script</code> API.
Needless to say, you have to handle the exceptions
appropriately.</span></p>
<pre>
<span><code>
// <a href="source/EvalScript.java">EvalScript.java</a>
import javax.script.*;
public class EvalScript {
public static void main(String[] args) throws Exception {
// create a script engine manager
<span class="classref">ScriptEngineManager</span> factory = new ScriptEngineManager();
// create a JavaScript engine
<span class="classref">ScriptEngine</span> engine = factory.<span class="methodref">getEngineByName</span>("nashorn");
// evaluate JavaScript code from String
engine.<span class="methodref">eval</span>("print('Hello, World')");
}
}
</code></span>
</pre>
<hr>
<a name="evalfile" id="evalfile"></a>
<h3>Evaluating a Script File</h3>
<p>In this example, we call the <code>eval</code> method that
accepts <code>java.io.Reader</code> for the input source. The
script read by the given reader is executed. This way it is
possible to execute scripts from files, URLs and resources by
wrapping the relevant input stream objects as readers.</p>
<pre>
<code>
// <a href="source/EvalFile.java">EvalFile.java</a>
import javax.script.*;
public class EvalFile {
public static void main(String[] args) throws Exception {
// create a script engine manager
<span class="classref">ScriptEngineManager</span> factory = new ScriptEngineManager();
// create JavaScript engine
<span class="classref">ScriptEngine</span> engine = factory.<span class="methodref">getEngineByName</span>("nashorn");
// evaluate JavaScript code from given file - specified by first argument
engine.<span class="methodref">eval</span>(new java.io.FileReader(args[0]));
}
}
</code>
</pre>
Let us assume that we have the file named <a href="source/test.js">test.js</a> with the
following text:
<pre><code>
print("This is hello from test.js");
</code>
</pre>
We can run the above Java as
<pre><code>
java EvalFile test.js
</code>
</pre>
<hr>
<a name="scriptvars" id="scriptvars"></a>
<h3>Script Variables</h3>
<p>When you embed script engines and scripts with your Java
application, you may want to expose your application objects as
global variables to scripts. This example demonstrates how you can
expose your application objects as global variables to a script. We
create a <code>java.io.File</code> in the application and expose
the same as a global variable with the name "file". The script can
access the variable - for example, it can call public methods on
it. Note that the syntax to access Java objects, methods and fields
is dependent on the scripting language. JavaScript supports the
most "natural" Java-like syntax.</p>
<p>
Nashorn script engine pre-defines two global variables named "context"
and "engine". The "context" variable is of type javax.script.ScriptContext
and refers to the current ScriptContext instance passed to script engine's
eval method. The "engine" variable is of type javax.script.ScriptEngine and
refers to the current nashorn script engine instance evaluating the script.
Both of these variables are non-writable, non-enumerable and non-configurable
- which implies script code can not write overwrite the value, for..loop iteration
on global object will not iterate these variables and these variables can not be
deleted by script.
<pre><code>
// <a href="source/ScriptVars.java">ScriptVars.java</a>
import javax.script.*;
import java.io.*;
public class ScriptVars {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
File f = new File("test.txt");
// expose File object as variable to script
engine.<span class="methodref">put</span>("file", f);
// evaluate a script string. The script accesses "file"
// variable and calls method on it
engine.eval("print(file.getAbsolutePath())");
}
}
</code>
</pre>
<hr>
<a name="invoke" id="invoke"></a>
<h3>Invoking Script Functions and Methods</h3>
<p>Sometimes you may want to call a specific scripting function
repeatedly - for example, your application menu functionality might
be implemented by a script. In your menu's action event handler you
may want to call a specific script function. The following example
demonstrates invoking a specific script function from Java
code.</p>
<pre><code>
// <a href="source/InvokeScriptFunction.java">InvokeScriptFunction.java</a>
import javax.script.*;
public class InvokeScriptFunction {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript code in a String
String script = "function hello(name) { print('Hello, ' + name); }";
// evaluate script
engine.eval(script);
// <code>javax.script.Invocable</code> is an optional interface.
// Check whether your script engine implements it or not!
// Note that the JavaScript engine implements Invocable interface.
<span class="classref">Invocable</span> inv = (Invocable) engine;
// invoke the global function named "hello"
inv.<span class="methodref">invokeFunction</span>("hello", "Scripting!!" );
}
}
</code>
</pre>
<p>If your scripting language is object based (like JavaScript) or
object-oriented, then you can invoke a script method on a script
object.</p>
<pre><code>
// <a href="source/InvokeScriptMethod.java">InvokeScriptMethod.java</a>
import javax.script.*;
public class InvokeScriptMethod {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript code in a String. This code defines a script object 'obj'
// with one method called 'hello'.
String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
// evaluate script
engine.eval(script);
// <code>javax.script.Invocable</code> is an optional interface.
// Check whether your script engine implements or not!
// Note that the JavaScript engine implements Invocable interface.
<span class="classref">Invocable</span> inv = (Invocable) engine;
// get script object on which we want to call the method
Object obj = engine.<span class="methodref">get</span>("obj");
// invoke the method named "hello" on the script object "obj"
inv.<span class="methodref">invokeMethod</span>(obj, "hello", "Script Method !!" );
}
}
</code>
</pre>
<hr>
<a name="interfaces" id="interfaces"></a>
<h3>Implementing Java Interfaces by Scripts</h3>
<p>Instead of calling specific script functions from Java,
sometimes it is convenient to implement a Java interface by script
functions or methods. Also, by using interfaces we can avoid having
to use the <code>javax.script</code> API in many places. We can get
an interface implementor object and pass it to various Java APIs.
The following example demonstrates implementing the
<code>java.lang.Runnable</code> interface with a script.</p>
<pre><code>
// <a href="source/RunnableImpl.java">RunnableImpl.java</a>
import javax.script.*;
public class RunnableImpl {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript code in a String
String script = "function run() { print('run called'); }";
// evaluate script
engine.eval(script);
<span class="classref">Invocable</span> inv = (Invocable) engine;
// get Runnable interface object from engine. This interface methods
// are implemented by script functions with the matching name.
Runnable r = inv.<span class="methodref">getInterface</span>(Runnable.class);
// start a new thread that runs the script implemented
// runnable interface
Thread th = new Thread(r);
th.start();
th.join();
}
}
</code>
</pre>
<p>If your scripting language is object-based or object-oriented,
it is possible to implement a Java interface by script methods on
script objects. This avoids having to call script global functions
for interface methods. The script object can store the "state"
associated with the interface implementor.</p>
<pre><code>
// <a href="source/RunnableImplObject.java">RunnableImplObject.java</a>
import javax.script.*;
public class RunnableImplObject {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript code in a String
String script = "var obj = new Object(); obj.run = function() { print('run method called'); }";
// evaluate script
engine.eval(script);
// get script object on which we want to implement the interface with
Object obj = engine.<span class="methodref">get</span>("obj");
<span class="classref">Invocable</span> inv = (Invocable) engine;
// get Runnable interface object from engine. This interface methods
// are implemented by script methods of object 'obj'
Runnable r = inv.<span class="methodref">getInterface</span>(obj, Runnable.class);
// start a new thread that runs the script implemented
// runnable interface
Thread th = new Thread(r);
th.start();
th.join();
}
}
</code>
</pre>
<hr>
<a name="scopes" id="scopes"></a>
<h3>Multiple Scopes for Scripts</h3>
<p>In the <a href="#scriptvars">script variables</a> example, we
saw how to expose application objects as script global variables.
It is possible to expose multiple global "scopes" for scripts. A
single scope is an instance of <code>javax.script.Bindings</code>.
This interface is derived from <code>java.util.Map&lt;String,
Object&gt;</code>. A scope a set of name-value pairs where name is
any non-empty, non-null String.
<code>javax.script.ScriptContext</code> interface supports multiple
scopes with associated Bindings for each
scope. By default, every script engine has a default script
context. The default script context has atleast one scope called
"ENGINE_SCOPE". Various scopes supported by a script context are
available through <code>getScopes</code> method.</p>
<pre><code>
// <a href="source/MultiScopes.java">MultiScopes.java</a>
import javax.script.*;
public class MultiScopes {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
engine.put("x", "hello");
// print global variable "x"
engine.eval("print(x);");
// the above line prints "hello"
// Now, pass a different script context
<span class="classref">ScriptContext</span> newContext = new <span class="classref">SimpleScriptContext</span>();
newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
<span class="classref">Bindings</span> engineScope = newContext.<span class="methodref">getBindings</span>(ScriptContext.ENGINE_SCOPE);
// add new variable "x" to the new engineScope
engineScope.<span class="methodref">put</span>("x", "world");
// execute the same script - but this time pass a different script context
engine.eval("print(x);", newContext);
// the above line prints "world"
}
}
</code>
</pre>
<hr>
<a name="jsengine" id="jsengine"></a>
<h2>JavaScript Script Engine</h2>
<p>Oracle's implementation of JDK 8 is co-bundled with the Nashorn ECMAScript
script engine.
<hr>
<a name="jstojava" id="jstojava"></a>
<h2>JavaScript to Java Communication</h2>
<p>For the most part, accessing Java classes, objects and methods
is straightforward. In particular field and method access from
JavaScript is the same as it is from Java. We highlight important
aspects of JavaScript Java access here.
The following examples are JavaScript snippets accessing Java. This
section requires knowledge of JavaScript. This section can be
skipped if you are planning to use some other JSR-223 scripting
language rather than JavaScript.</p>
<hr>
<a name="jsjavaclass" id=jsjavalass"></a>
<h3>Accessing Java Classes</h3>
<pre>
<code>
// <a href="source/javatypes.js">javatypes.js</a>
var arrayListType = Java.type("java.util.ArrayList")
var intType = Java.type("int")
var stringArrayType = Java.type("java.lang.String[]")
var int2DArrayType = Java.type("int[][]")
</code>
</pre>
Note that the name of the type is always a string for a fully qualified name. You can use any of these expressions to create new instances, e.g.:
<pre><code>
var anArrayList = new (Java.type("java.util.ArrayList"))
</code></pre>
or
<pre><code>
var ArrayList = Java.type("java.util.ArrayList")
var anArrayList = new ArrayList
var anArrayListWithSize = new ArrayList(16)
</code></pre>
In the special case of inner classes, you can either use the JVM fully qualified name, meaning using the dollar sign in the class name, or you can use the dot:
<pre><code>
var ftype = Java.type("java.awt.geom.Arc2D$Float")
</code></pre>
and
<pre><code>
var ftype = Java.type("java.awt.geom.Arc2D.Float")
</code></pre>
both work. Note however that using the dollar sign is faster, as Java.type first tries to resolve the class name as it is originally specified, and the internal JVM names for inner classes use the dollar sign. If you use the dot, Java.type will internally get a ClassNotFoundException and subsequently retry by changing the last dot to dollar sign. As a matter of fact, it'll keep replacing dots with dollar signs until it either successfully loads the class or runs out of all dots in the name. This way it can correctly resolve and load even multiply nested inner classes with the dot notation. Again, this will be slower than using the dollar signs in the name. An alternative way to access the inner class is as a property of the outer class:
<pre><code>
var arctype = Java.type("java.awt.geom.Arc2D")
var ftype = arctype.Float
</code></pre>
<p>
You can access both static and non-static inner classes. If you want to create an instance of a non-static inner class, remember to pass an instance of its outer class as the first argument to the constructor.
</p>
<p>
In addition to creating new instances, the type objects returned from <code>Java.type</code> calls can also be used to access the
static fields and methods of the classes:
<pre><code>
var File = Java.type("java.io.File")
File.createTempFile("nashorn", ".tmp")
</code></pre>
<p>
Methods with names of the form <code>isXxx()</code>, <code>getXxx()</code>, and <code>setXxx()</code> can also be used as properties, for both instances and statics.
</p>
<p>
A type object returned from <code>Java.type</code> is distinct from a <code>java.lang.Class</code> object. You can obtain one from the other using properties <code>class</code> and <code>static</code> on them.
<pre><code>
var ArrayList = Java.type("java.util.ArrayList")
var a = new ArrayList
// All of the following print true:
print("Type acts as target of instanceof: " + (a instanceof ArrayList))
print("Class doesn't act as target of instanceof: " + !(a instanceof a.getClass()))
print("Type is not same as instance's getClass(): " + (a.getClass() !== ArrayList))
print("Type's `class` property is same as instance getClass(): " + (a.getClass() === ArrayList.class))
print("Type is same as instance getClass()'s `static` property: " + (a.getClass().static === ArrayList))
</code></pre>
<p>
You can think of the type object as similar to the class names as used in Java source code: you use them as the
arguments to the <code>new</code> and <code>instanceof</code> operators and as the namespace for the static fields
and methods, but they are different than the runtime <code>Class</code> objects returned by <code>getClass()</code> calls.
Syntactically and semantically, this separation produces code that is most similar to Java code, where a distinction
between compile-time class expressions and runtime class objects also exists. (Also, Java can't have the equivalent of <code>static</code>
property on a <code>Class</code> object since compile-time class expressions are never reified as objects).
</p>
<hr>
<a name="jsimport" id="jsimport"></a>
<h3>Importing Java Packages, Classes</h3>
<p>The built-in functions <code>importPackage</code> (in compatibility script) and
<code>importClass</code> can be used to import Java packages and
classes.</p>
<pre><code>
// <a href="source/importpackageclass.js">importpackageclass.js</a>
// load compatibility script
load("nashorn:mozilla_compat.js");
// Import Java packages and classes
// like import package.*; in Java
<span class="functionref">importPackage</span>(java.awt);
// like import java.awt.Frame in Java
<span class="functionref">importClass</span>(java.awt.Frame);
// Create Java Objects by "new ClassName"
var frame = new java.awt.Frame("hello");
// Call Java public methods from script
frame.setVisible(true);
// Access "JavaBean" properties like "fields"
print(frame.title);
</code>
</pre>
<p>The <span class="objectref">Packages</span> global variable can
be used to access Java packages. Examples:
<code>Packages.java.util.Vector</code>,
<code>Packages.javax.swing.JFrame</code>. Please note that "java"
is a shortcut for "Packages.java". There are equivalent shortcuts
for javax, org, edu, com, net prefixes, so pratically all JDK
platform classes can be accessed without the "Packages" prefix.</p>
<p>Note that java.lang is not imported by default (unlike Java)
because that would result in conflicts with JavaScript's built-in
Object, Boolean, Math and so on.</p>
<p><code>importPackage</code> and <code>importClass</code>
functions "pollute" the global variable scope of JavaScript. To
avoid that, you may use <span class="functionref">JavaImporter</span>.</p>
<pre><code>
// <a href="source/javaimporter.js">javaimporter.js</a>
// create JavaImporter with specific packages and classes to import
var SwingGui = new <span class="functionref">JavaImporter</span>(javax.swing,
javax.swing.event,
javax.swing.border,
java.awt.event);
with (SwingGui) {
// within this 'with' statement, we can access Swing and AWT
// classes by unqualified (simple) names.
var mybutton = new JButton("test");
var myframe = new JFrame("test");
}
</code>
</pre>
<hr>
<a name="jsarrays" id="jsarrays"></a>
<h3>Creating, Converting and Using Java Arrays</h3>
<p>
Array element access or length access is the same as in Java.</p>
<pre><code>
// <a href="source/javaarray.js">javaarray.js</a>
// create Java String array of 5 elements
var StringArray = Java.type("java.lang.String[]");
var a = new StringArray(5);
// Accessing elements and length access is by usual Java syntax
a[0] = "scripting is great!";
print(a.length);
print(a[0]);
</code>
</pre>
<p>
It is also possible to convert between JavaScript and Java arrays.
Given a JavaScript array and a Java type, <code>Java.to</code> returns a Java array with the same initial contents, and with the specified array type.
</p>
<pre><code>
var anArray = [1, "13", false]
var javaIntArray = Java.to(anArray, "int[]")
print(javaIntArray[0]) // prints 1
print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
</code></pre>
<p>
You can use either a string or a type object returned from <code>Java.type()</code> to specify the type of the array.
You can also omit the array type, in which case a <code>Object[]</code> will be created.
</p>
<p>
Given a Java array or Collection, <code>Java.from</code> returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
</p>
<pre><code>
var File = Java.type("java.io.File");
var listCurDir = new File(".").listFiles();
var jsList = Java.from(listCurDir);
print(jsList);
</code></pre>
<hr>
<a name="jsimplement" id="jsimplement"></a>
<h3>Implementing Java interfaces</h3>
<p>A Java interface can be implemented in JavaScript by using a
Java anonymous class-like syntax:</p>
<pre><code>
// <a href="source/runnable.js">runnable.js</a>
var r = new java.lang.Runnable() {
run: function() {
print("running...\n");
}
};
// "r" can be passed to Java methods that expect java.lang.Runnable
var th = new java.lang.Thread(r);
th.start();
th.join();
</code>
</pre>
<p>When an interface with a single method is expected, you can pass
a script function directly.(auto conversion)</p>
<pre><code>
// <a href="source/samfunc.js">samfunc.js</a>
function func() {
print("I am func!");
}
// pass script function for java.lang.Runnable argument
var th = new java.lang.Thread(func);
th.start();
th.join();
</code>
</pre>
<hr>
<a name="jsextendabstract" id="jsextendabstract"></a>
<h3>Extending Abstract Java Classes</h3>
<p>
If a Java class is abstract, you can instantiate an anonymous subclass of it using an argument list that is applicable to any of its public or protected constructors, but inserting a JavaScript object with functions properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the JavaScript function will provide implementation for all overloads. E.g.:
</p>
<pre><code>
var TimerTask = Java.type("java.util.TimerTask")
var task = new TimerTask({ run: function() { print("Hello World!") } })
</code></pre>
Nashorn supports a syntactic extension where a "new" expression followed by an argument is identical to invoking the constructor and passing the argument to it, so you can write the above example also as:
<pre><code>
var task = new TimerTask {
run: function() {
print("Hello World!")
}
}
</code></pre>
which is very similar to Java anonymous inner class definition. On the other hand, if the type is an abstract type with a single abstract method (commonly referred to as a "SAM type") or all abstract methods it has share the same overloaded name), then instead of an object, you can just pass a function, so the above example can become even more simplified to:
<pre><code>
var task = new TimerTask(function() { print("Hello World!") })
</code></pre>
<p>
Note that in every one of these cases if you are trying to instantiate an abstract class that has constructors that take some arguments, you can invoke those simply by specifying the arguments after the initial implementation object or function.
</p>
<p>
The use of functions can be taken even further; if you are invoking a Java method that takes a SAM type, you can just pass in a function object, and Nashorn will know what you meant:
</p>
<code><pre>
Java.type("java.util.Timer")
timer.schedule(function() { print("Hello World!") })
</code></pre>
Here, <code>Timer.schedule()</code> expects a <code>TimerTask</code> as its argument, so Nashorn creates an instance of a TimerTask subclass and uses the passed function to implement its only abstract method, run(). In this usage though, you can't use non-default constructors; the type must be either an interface, or must have a protected or public no-arg constructor.
<hr>
<a name="jsextendconcrete" id="jsextendconcrete"></a>
<h3>Extending Concrete Java Classes</h3>
<p>
To extend a concrete Java class, you have to use <code>Java.extend</code> function.
<code>Java.extend</code> returns a type object for a subclass of the specified Java class (or implementation of the specified interface) that acts as a script-to-Java adapter for it.
</p>
<pre><code>
// <a href="source/javaextend.js">javaextend.js</a>
var ArrayList = Java.type("java.util.ArrayList")
var ArrayListExtender = Java.extend(ArrayList)
var printSizeInvokedArrayList = new ArrayListExtender() {
size: function() { print("size invoked!"); }
}
var printAddInvokedArrayList = new ArrayListExtender() {
add: function(x, y) {
if(typeof(y) === "undefined") {
print("add(e) invoked!");
} else {
print("add(i, e) invoked!");
}
}
};
printSizeInvokedArrayList.size();
printAddInvokedArrayList.add(33, 33);
</code></pre>
<p>
The reason you must use <code>Java.extend()</code> with concrete classes is that with concrete classes, there can be a
syntactic ambiguity if you just invoke their constructor. Consider this example:
</p>
<pre><code>
var t = new java.lang.Thread({ run: function() { print("Hello!") } })
</code></pre>
<p>
If we allowed subclassing of concrete classes with constructor syntax, Nashorn couldn't tell if you're creating a new
<code>Thread</code> and passing it a <code>Runnable</code> at this point, or you are subclassing <code>Thread</code> and
passing it a new implementation for its own <code>run()</code> method.
</p>
<hr>
<a name="jsimplementmultiple" id="jsimplementmultiple"></a>
<h3>Implementing Multiple Interfaces</h3>
<p>
<code>Java.extend</code> can in fact take a list of multiple types. At most one of the types can be a class, and the rest must
be interfaces (the class doesn't have to be the first in the list). You will get back an object that extends the class and
implements all the interfaces. (Obviously, if you only specify interfaces and no class, the object will extend <code>java.lang.Object</code>).
<hr>
<a name="classBoundImplementations" id="classBoundImplementations"></a>
<h3>Class-Bound Implementations</h3>
<p>
The methods shown so far for extending Java classes and implementing interfaces &ndash; passing an implementation JavaScript object
or function to a constructor, or using <code>Java.extend</code> with <code>new</code> &ndash; all produce classes that take an
extra JavaScript object parameter in their constructors that specifies the implementation. The implementation is therefore always bound
to the actual instance being created with <code>new</code>, and not to the whole class. This has some advantages, for example in the
memory footprint of the runtime, as Nashorn can just create a single "universal adapter" for every combination of types being implemented.
In reality, the below code shows that different instantiations of, say, <code>Runnable</code> have the same class regardless of them having
different JavaScript implementation objects:
</p>
<pre><code>
var Runnable = java.lang.Runnable;
var r1 = new Runnable(function() { print("I'm runnable 1!") })
var r2 = new Runnable(function() { print("I'm runnable 2!") })
r1.run()
r2.run()
print("We share the same class: " + (r1.class === r2.class))
</code></pre>
<p>
prints:
</p>
<pre><code>
I'm runnable 1!
I'm runnable 2!
We share the same class: true
</code></pre>
<p>
Sometimes, however, you'll want to extend a Java class or implement an interface with implementation bound to the class, not to
its instances. Such a need arises, for example, when you need to pass the class for instantiation to an external API; prime example
of this is the JavaFX framework where you need to pass an Application class to the FX API and let it instantiate it.
</p>
<p>
Fortunately, there's a solution for that: <code>Java.extend()</code> &ndash; aside from being able to take any number of type parameters
denoting a class to extend and interfaces to implement &ndash; can also take one last argument that has to be a JavaScript object
that serves as the implementation for the methods. In this case, <code>Java.extend()</code> will create a class that has the same
constructors as the original class had, as they don't need to take an an extra implementation object parameter. The example below
shows how you can create class-bound implementations, and shows that in this case, the implementation classes for different invocations
are indeed different:
</p>
<pre><code>
var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") })
var r1 = new RunnableImpl1()
var r2 = new RunnableImpl2()
r1.run()
r2.run()
print("We share the same class: " + (r1.class === r2.class))
</code></pre>
<p>
prints:
</p>
<pre><code>
I'm runnable 1!
I'm runnable 2!
We share the same class: false
</code></pre>
<p>
As you can see, the major difference here is that we moved the implementation object into the invocation of <code>Java.extend</code>
from the constructor invocations &ndash; indeed the constructor invocations now don't even need to take an extra parameter! Since
the implementations are bound to a class, the two classes obviously can't be the same, and we indeed see that the two runnables no
longer share the same class &ndash; every invocation of <code>Java.extend()</code> with a class-specific implementation object triggers
the creation of a new Java adapter class.
</p>
<p>
Finally, the adapter classes with class-bound implementations can <i>still</i> take an additional constructor parameter to further
override the behavior on a per-instance basis. Thus, you can even combine the two approaches: you can provide part of the implementation
in a class-based JavaScript implementation object passed to <code>Java.extend</code>, and part in another object passed to the constructor.
Whatever functions are provided by the constructor-passed object will override the functions in the class-bound object.
</p>
<pre><code>
var RunnableImpl = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
var r1 = new RunnableImpl()
var r2 = new RunnableImpl(function() { print("I'm runnable 2!") })
r1.run()
r2.run()
print("We share the same class: " + (r1.class === r2.class))
</code></pre>
<p>
prints:
</p>
<pre><code>
I'm runnable 1!
I'm runnable 2!
We share the same class: true
</code></pre>
<hr>
<a name="jsoverload" id="jsoverload"></a>
<h3>Overload Resolution</h3>
<p>Java methods can be overloaded by argument types. In Java,
overload resolution occurs at compile time (performed by javac).
When calling Java methods from Nashorn, the appropriate method will be
selected based on the argument types at invocation time. You do not need
to do anything special &ndash; the correct Java method overload variant
is selected based automatically. You still have the option of explicitly
specifying a particular overload variant. Reasons for this include
either running into a genuine ambiguity with actual argument types, or
rarely reasons of performance &ndash; if you specify the actual overload
then the engine doesn't have to perform resolution during invocation.
Individual overloads of a Java methods are exposed as special properties
with the name of the method followed with its signature in parentheses.
You can invoke them like this:</p>
<pre><code>
// <a href="source/overload.js">overload.js</a>
var out = java.lang.System.out;
// select a particular print function
out["println(Object)"]("hello");
</code>
</pre>
<p>
Note that you normally don't even have to use qualified class names in
the signatures as long as the unqualified name of the type is sufficient
for uniquely identifying the signature. In practice this means that only
in the extremely unlikely case that two overloads only differ in
parameter types that have identical unqualified names but come from
different packages would you need to use the fully qualified name of the
class.
</p>
<hr>
<a name="dataTypeMapping" id="dataTypeMapping"></a>
<h3>Mapping of Data Types Between Java and JavaScript</h3>
<p>
We have previously shown some of the data type mappings between Java and JavaScript.
We saw that arrays need to be explicitly converted. We have also shown that JavaScript functions
are automatically converted to SAM types when passed as parameters to Java methods. Most other
conversions work as you would expect.
</p>
<p>
Every JavaScript object is also a <code>java.util.Map</code> so APIs receiving maps will receive them directly.
</p>
<p>
When numbers are passed to a Java API, they will be converted to the expected target numeric type, either boxed or
primitive, but if the target type is less specific, say <code>Number</code> or <code>Object</code>, you can only
count on them being a <code>Number</code>, and have to test specifically for whether it's a boxed <code>Double</code>,
<code>Integer</code>, <code>Long</code>, etc. &ndash; it can be any of these due to internal optimizations. Also, you
can pass any JavaScript value to a Java API expecting either a boxed or primitive number; the JavaScript specification's
<code>ToNumber</code> conversion algorithm will be applied to the value.
</p>
<p>
In a similar vein, if a Java method expects a <code>String</code> or a <code>Boolean</code>, the values will be
converted using all conversions allowed by the JavaScript specification's <code>ToString</code> and <code>ToBoolean</code>
conversions.
</p>
<p>
Finally, a word of caution about strings. Due to internal performance optimizations of string operations, JavaScript strings are
not always necessarily of type <code>java.lang.String</code>, but they will always be of type <code>java.lang.CharSequence</code>.
If you pass them to a Java method that expects a <code>java.lang.String</code> parameter, then you will naturally receive a Java
String, but if the signature of your method is more generic, i.e. it receives a <code>java.lang.Object</code> parameter, you can
end up with an object of private engine implementation class that implements <code>CharSequence</code> but is not a Java String.
</p>
<hr>
<a name="engineimpl" id="engineimpl"></a>
<h2>Implementing Your Own Script Engine</h2>
<p>We will not cover implementation of JSR-223 compliant script
engines in detail. Minimally, you need to implement the
<code>javax.script.ScriptEngine</code> and
<code>javax.script.ScriptEngineFactory</code> interfaces. The
abstract class <code>javax.script.AbstractScriptEngine</code>
provides useful defaults for a few methods of the
<code>ScriptEngine</code> interface.</p>
<p>Before starting to implement a JSR-223 engine, you may want to
check <a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting</a>
project. This project maintains JSR-223 implementations for many
popular open source scripting languages.</p>
<hr>
<a name="refs" id="refs"></a>
<h2>References</h2>
<ul>
<li><a href="http://jcp.org/en/jsr/detail?id=223">JSR-223 Scripting
for the Java Platform</a></li>
<li><a href="http://java.net/projects/Scripting">http://java.net/projects/Scripting
</a></li>
</ul>
<div class="hr"><hr></div>
<table summary="layout" border="0" width="100%">
<tbody><tr valign="TOP">
<td width="30%"> <img src="Java%20Scripting%20Programmer%27s%20Guide_files/logo_oracle_footer.gif" alt="Oracle and/or its affiliates" border="0" height="29" width="100"><br>
<font size="+1"> <i>Java Technology</i></font> </td>
<td width="30%">
<p><font size="-2">
<a href="http://docs.oracle.com/javase/6/docs/legal/cpyr.html">Copyright <20></a> 2013, Oracle and/or its affiliates. All rights reserved.
</font></p>
</td>
<td width="30%">
<p align="right"><font size="-2"><a href="http://download.oracle.com/javase/feedback.html">Contact Us</a></font></p><font size="-2">
</font></td>
</tr>
</tbody></table>
<div class="hr"><hr></div>
</div>
<!-- Start SiteCatalyst code -->
<script language="JavaScript" src="Java%20Scripting%20Programmer%27s%20Guide_files/s_code_download.js"></script>
<script language="JavaScript" src="Java%20Scripting%20Programmer%27s%20Guide_files/s_code.js"></script>
<!-- ********** DO NOT ALTER ANYTHING BELOW THIS LINE ! *********** -->
<!-- Below code will send the info to Omniture server -->
<script language="javascript">var s_code=s.t();if(s_code)document.write(s_code)</script>
<!-- End SiteCatalyst code -->
</body></html>

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@SuppressWarnings("javadoc")
public class EvalFile {
public static void main(final String[] args) throws Exception {
// create a script engine manager
final ScriptEngineManager factory = new ScriptEngineManager();
// create JavaScript engine
final ScriptEngine engine = factory.getEngineByName("nashorn");
// evaluate JavaScript code from given file - specified by first argument
engine.eval(new java.io.FileReader(args[0]));
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@SuppressWarnings("javadoc")
public class EvalScript {
public static void main(final String[] args) throws Exception {
// create a script engine manager
final ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
final ScriptEngine engine = factory.getEngineByName("nashorn");
// evaluate JavaScript code from String
engine.eval("print('Hello, World')");
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@SuppressWarnings("javadoc")
public class InvokeScriptFunction {
public static void main(final String[] args) throws Exception {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript code in a String
final String script = "function hello(name) { print('Hello, ' + name); }";
// evaluate script
engine.eval(script);
// javax.script.Invocable is an optional interface.
// Check whether your script engine implements or not!
// Note that the JavaScript engine implements Invocable interface.
final Invocable inv = (Invocable) engine;
// invoke the global function named "hello"
inv.invokeFunction("hello", "Scripting!!" );
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@SuppressWarnings("javadoc")
public class InvokeScriptMethod {
public static void main(final String[] args) throws Exception {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript code in a String. This code defines a script object 'obj'
// with one method called 'hello'.
final String script = "var obj = new Object(); obj.hello = function(name) { print('Hello, ' + name); }";
// evaluate script
engine.eval(script);
// javax.script.Invocable is an optional interface.
// Check whether your script engine implements or not!
// Note that the JavaScript engine implements Invocable interface.
final Invocable inv = (Invocable) engine;
// get script object on which we want to call the method
final Object obj = engine.get("obj");
// invoke the method named "hello" on the script object "obj"
inv.invokeMethod(obj, "hello", "Script Method !!" );
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleScriptContext;
@SuppressWarnings("javadoc")
public class MultiScopes {
public static void main(final String[] args) throws Exception {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("nashorn");
engine.put("x", "hello");
// print global variable "x"
engine.eval("print(x);");
// the above line prints "hello"
// Now, pass a different script context
final ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
final Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
// add new variable "x" to the new engineScope
engineScope.put("x", "world");
// execute the same script - but this time pass a different script context
engine.eval("print(x);", newContext);
// the above line prints "world"
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@SuppressWarnings("javadoc")
public class RunnableImpl {
public static void main(final String[] args) throws Exception {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript code in a String
final String script = "function run() { print('run called'); }";
// evaluate script
engine.eval(script);
final Invocable inv = (Invocable) engine;
// get Runnable interface object from engine. This interface methods
// are implemented by script functions with the matching name.
final Runnable r = inv.getInterface(Runnable.class);
// start a new thread that runs the script implemented
// runnable interface
final Thread th = new Thread(r);
th.start();
th.join();
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@SuppressWarnings("javadoc")
public class RunnableImplObject {
public static void main(final String[] args) throws Exception {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("nashorn");
// JavaScript code in a String
final String script = "var obj = new Object(); obj.run = function() { print('run method called'); }";
// evaluate script
engine.eval(script);
// get script object on which we want to implement the interface with
final Object obj = engine.get("obj");
final Invocable inv = (Invocable) engine;
// get Runnable interface object from engine. This interface methods
// are implemented by script methods of object 'obj'
final Runnable r = inv.getInterface(obj, Runnable.class);
// start a new thread that runs the script implemented
// runnable interface
final Thread th = new Thread(r);
th.start();
th.join();
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.io.File;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
@SuppressWarnings("javadoc")
public class ScriptVars {
public static void main(final String[] args) throws Exception {
final ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByName("nashorn");
final File f = new File("test.txt");
// expose File object as variable to script
engine.put("file", f);
// evaluate a script string. The script accesses "file"
// variable and calls method on it
engine.eval("print(file.getAbsolutePath())");
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// load compatibility script
load("nashorn:mozilla_compat.js");
// Import Java packages and classes
// like import package.*; in Java
importPackage(java.awt);
// like import java.awt.Frame in Java
importClass(java.awt.Frame);
// Create Java Objects by "new ClassName"
var frame = new java.awt.Frame("hello");
// Call Java public methods from script
frame.setVisible(true);
// Access "JavaBean" properties like "fields"
print(frame.title);

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// create Java String array of 5 elements
var StringArray = Java.type("java.lang.String[]");
var a = new StringArray(5);
// Accessing elements and length access is by usual Java syntax
a[0] = "scripting is great!";
print(a.length);
print(a[0]);
// convert a script array to Java array
var anArray = [1, "13", false];
var javaIntArray = Java.to(anArray, "int[]");
print(javaIntArray[0]);// prints 1
print(javaIntArray[1]); // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
print(javaIntArray[2]);// prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
// convert a Java array to a JavaScript array
var File = Java.type("java.io.File");
var listCurDir = new File(".").listFiles();
var jsList = Java.from(listCurDir);
print(jsList);

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var ArrayList = Java.type("java.util.ArrayList")
var ArrayListExtender = Java.extend(ArrayList)
var printSizeInvokedArrayList = new ArrayListExtender() {
size: function() { print("size invoked!"); }
}
var printAddInvokedArrayList = new ArrayListExtender() {
add: function(x, y) {
if(typeof(y) === "undefined") {
print("add(e) invoked!");
} else {
print("add(i, e) invoked!");
}
}
};
printSizeInvokedArrayList.size();
printAddInvokedArrayList.add(33, 33);

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// create JavaImporter with specific packages and classes to import
var SwingGui = new JavaImporter(javax.swing,
javax.swing.event,
javax.swing.border,
java.awt.event);
with (SwingGui) {
// within this 'with' statement, we can access Swing and AWT
// classes by unqualified (simple) names.
var mybutton = new JButton("test");
print(mybutton);
var myframe = new JFrame("test");
print(myframe);
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// accessing java types
var arrayListType = Java.type("java.util.ArrayList")
var intType = Java.type("int")
var stringArrayType = Java.type("java.lang.String[]")
var int2DArrayType = Java.type("int[][]")
// Using java types
var ArrayList = Java.type("java.util.ArrayList")
var anArrayList = new ArrayList
var anArrayListWithSize = new ArrayList(16)
// fully qualified name
var ftype = Java.type("java.awt.geom.Arc2D$Float")
// inner class property
var arctype = Java.type("java.awt.geom.Arc2D")
var ftype = arctype.Float

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var out = java.lang.System.out;
// select a particular print function
out["println(java.lang.Object)"]("hello");

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var r = new java.lang.Runnable() {
run: function() {
print("running...\n");
}
};
// "r" can be passed to Java methods that expect java.lang.Runnable
var th = new java.lang.Thread(r);
th.start();
th.join();

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
function func() {
print("I am func!");
}
// pass script function for java.lang.Runnable argument
var th = new java.lang.Thread(func);
th.start();
th.join();

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
print("This is hello from test.js");

View File

@@ -5,7 +5,7 @@
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Testing the JDK</title>
<style type="text/css">
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
@@ -21,9 +21,9 @@
<header id="title-block-header">
<h1 class="title">Testing the JDK</h1>
</header>
<nav id="TOC">
<nav id="TOC" role="doc-toc">
<ul>
<li><a href="#using-make-test-the-run-test-framework">Using &quot;make test&quot; (the run-test framework)</a><ul>
<li><a href="#using-make-test-the-run-test-framework">Using "make test" (the run-test framework)</a><ul>
<li><a href="#configuration">Configuration</a></li>
</ul></li>
<li><a href="#test-selection">Test selection</a><ul>
@@ -47,7 +47,7 @@
</ul></li>
</ul>
</nav>
<h2 id="using-make-test-the-run-test-framework">Using &quot;make test&quot; (the run-test framework)</h2>
<h2 id="using-make-test-the-run-test-framework">Using "make test" (the run-test framework)</h2>
<p>This new way of running tests is developer-centric. It assumes that you have built a JDK locally and want to test it. Running common test targets is simple, and more complex ad-hoc combination of tests is possible. The user interface is forgiving, and clearly report errors it cannot resolve.</p>
<p>The main target <code>test</code> uses the jdk-image as the tested product. There is also an alternate target <code>exploded-test</code> that uses the exploded image instead. Not all tests will run successfully on the exploded image, but using this target can greatly improve rebuild times for certain workflows.</p>
<p>Previously, <code>make test</code> was used to invoke an old system for running tests, and <code>make run-test</code> was used for the new test framework. For backward compatibility with scripts and muscle memory, <code>run-test</code> (and variants like <code>exploded-run-test</code> or <code>run-test-tier1</code>) are kept as aliases.</p>
@@ -56,7 +56,7 @@
$ make test-jdk_lang JTREG=&quot;JOBS=8&quot;
$ make test TEST=jdk_lang
$ make test-only TEST=&quot;gtest:LogTagSet gtest:LogTagSetDescriptions&quot; GTEST=&quot;REPEAT=-1&quot;
$ make test TEST=&quot;hotspot:hotspot_gc&quot; JTREG=&quot;JOBS=1;TIMEOUT_FACTOR=8;JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug&quot;
$ make test TEST=&quot;hotspot:hotspot_gc&quot; JTREG=&quot;JOBS=1;TIMEOUT_FACTOR=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug&quot;
$ make test TEST=&quot;jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java&quot;
$ make test TEST=&quot;micro:java.lang.reflect&quot; MICRO=&quot;FORK=1;WARMUP_ITER=2&quot;
$ make exploded-test TEST=tier2</code></pre>
@@ -65,7 +65,7 @@ $ make exploded-test TEST=tier2</code></pre>
<p>To be able to run microbenchmarks, <code>configure</code> needs to know where to find the JMH dependency. Use <code>--with-jmh=&lt;path to JMH jars&gt;</code> to point to a directory containing the core JMH and transitive dependencies. The recommended dependencies can be retrieved by running <code>sh make/devkit/createJMHBundle.sh</code>, after which <code>--with-jmh=build/jmh/jars</code> should work.</p>
<h2 id="test-selection">Test selection</h2>
<p>All functionality is available using the <code>test</code> make target. In this use case, the test or tests to be executed is controlled using the <code>TEST</code> variable. To speed up subsequent test runs with no source code changes, <code>test-only</code> can be used instead, which do not depend on the source and test image build.</p>
<p>For some common top-level tests, direct make targets have been generated. This includes all JTReg test groups, the hotspot gtest, and custom tests (if present). This means that <code>make test-tier1</code> is equivalent to <code>make test TEST=&quot;tier1&quot;</code>, but the latter is more tab-completion friendly. For more complex test runs, the <code>test TEST=&quot;x&quot;</code> solution needs to be used.</p>
<p>For some common top-level tests, direct make targets have been generated. This includes all JTReg test groups, the hotspot gtest, and custom tests (if present). This means that <code>make test-tier1</code> is equivalent to <code>make test TEST="tier1"</code>, but the latter is more tab-completion friendly. For more complex test runs, the <code>test TEST="x"</code> solution needs to be used.</p>
<p>The test specifications given in <code>TEST</code> is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an example, <code>:tier1</code> will expand to <code>jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1</code>. You can always submit a list of fully qualified test descriptors in the <code>TEST</code> variable if you want to shortcut the parser.</p>
<h3 id="jtreg">JTReg</h3>
<p>JTReg tests can be selected either by picking a JTReg test group, or a selection of files or directories containing JTReg tests.</p>
@@ -105,9 +105,9 @@ TEST FAILURE</code></pre>
<p>Additional work data is stored in <code>build/$BUILD/test-support/$TEST_ID</code>. For some frameworks, this directory might contain information that is useful in determining the cause of a failed test.</p>
<h2 id="test-suite-control">Test suite control</h2>
<p>It is possible to control various aspects of the test suites using make control variables.</p>
<p>These variables use a keyword=value approach to allow multiple values to be set. So, for instance, <code>JTREG=&quot;JOBS=1;TIMEOUT_FACTOR=8&quot;</code> will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting <code>JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8</code>, but using the keyword format means that the <code>JTREG</code> variable is parsed and verified for correctness, so <code>JTREG=&quot;TMIEOUT_FACTOR=8&quot;</code> would give an error, while <code>JTREG_TMIEOUT_FACTOR=8</code> would just pass unnoticed.</p>
<p>To separate multiple keyword=value pairs, use <code>;</code> (semicolon). Since the shell normally eats <code>;</code>, the recommended usage is to write the assignment inside qoutes, e.g. <code>JTREG=&quot;...;...&quot;</code>. This will also make sure spaces are preserved, as in <code>JTREG=&quot;JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug&quot;</code>.</p>
<p>(Other ways are possible, e.g. using backslash: <code>JTREG=JOBS=1\;TIMEOUT_FACTOR=8</code>. Also, as a special technique, the string <code>%20</code> will be replaced with space for certain options, e.g. <code>JTREG=JAVA_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)</p>
<p>These variables use a keyword=value approach to allow multiple values to be set. So, for instance, <code>JTREG="JOBS=1;TIMEOUT_FACTOR=8"</code> will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting <code>JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8</code>, but using the keyword format means that the <code>JTREG</code> variable is parsed and verified for correctness, so <code>JTREG="TMIEOUT_FACTOR=8"</code> would give an error, while <code>JTREG_TMIEOUT_FACTOR=8</code> would just pass unnoticed.</p>
<p>To separate multiple keyword=value pairs, use <code>;</code> (semicolon). Since the shell normally eats <code>;</code>, the recommended usage is to write the assignment inside qoutes, e.g. <code>JTREG="...;..."</code>. This will also make sure spaces are preserved, as in <code>JTREG="VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"</code>.</p>
<p>(Other ways are possible, e.g. using backslash: <code>JTREG=JOBS=1\;TIMEOUT_FACTOR=8</code>. Also, as a special technique, the string <code>%20</code> will be replaced with space for certain options, e.g. <code>JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)</p>
<p>As far as possible, the names of the keywords have been standardized between test suites.</p>
<h3 id="general-keywords-test_opts">General keywords (TEST_OPTS)</h3>
<p>Some keywords are valid across different test suites. If you want to run tests from multiple test suites, or just don't want to care which test suite specific control variable to use, then you can use the general TEST_OPTS control variable.</p>
@@ -116,32 +116,27 @@ TEST FAILURE</code></pre>
<p>Currently only applies to JTReg.</p>
<h4 id="timeout_factor">TIMEOUT_FACTOR</h4>
<p>Currently only applies to JTReg.</p>
<h4 id="java_options">JAVA_OPTIONS</h4>
<p>Applies to JTReg, GTest and Micro.</p>
<h4 id="vm_options">VM_OPTIONS</h4>
<p>Applies to JTReg, GTest and Micro.</p>
<h4 id="java_options">JAVA_OPTIONS</h4>
<p>Applies to JTReg, GTest and Micro.</p>
<h4 id="aot_modules">AOT_MODULES</h4>
<p>Applies to JTReg and GTest.</p>
<h4 id="jcov">JCOV</h4>
<p>This keywords applies globally to the test runner system. If set to <code>true</code>, it enables JCov coverage reporting for all tests run. To be useful, the JDK under test must be run with a JDK built with JCov instrumentation (<code>configure --with-jcov=&lt;path to directory containing lib/jcov.jar&gt;</code>, <code>make jcov-image</code>).</p>
<p>The simplest way to run tests with JCov coverage report is to use the special target <code>jcov-test</code> instead of <code>test</code>, e.g. <code>make jcov-test TEST=jdk_lang</code>. This will make sure the JCov image is built, and that JCov reporting is enabled.</p>
<p>The JCov report is stored in <code>build/$BUILD/test-results/jcov-output/report</code>.</p>
<p>The JCov report is stored in <code>build/$BUILD/test-results/jcov-output</code>.</p>
<p>Please note that running with JCov reporting can be very memory intensive.</p>
<h4 id="jcov_diff_changeset">JCOV_DIFF_CHANGESET</h4>
<p>While collecting code coverage with JCov, it is also possible to find coverage for only recently changed code. JCOV_DIFF_CHANGESET specifies a source revision. A textual report will be generated showing coverage of the diff between the specified revision and the repository tip.</p>
<p>The report is stored in <code>build/$BUILD/test-results/jcov-output/diff_coverage_report</code> file.</p>
<h3 id="jtreg-keywords">JTReg keywords</h3>
<h4 id="jobs-1">JOBS</h4>
<p>The test concurrency (<code>-concurrency</code>).</p>
<p>Defaults to TEST_JOBS (if set by <code>--with-test-jobs=</code>), otherwise it defaults to JOBS, except for Hotspot, where the default is <em>number of CPU cores/2</em>, but never more than <em>memory size in GB/2</em>.</p>
<p>Defaults to TEST_JOBS (if set by <code>--with-test-jobs=</code>), otherwise it defaults to JOBS, except for Hotspot, where the default is <em>number of CPU cores/2</em> (for sparc, if more than 16 cpus, then <em>number of CPU cores/5</em>, otherwise <em>number of CPU cores/4</em>), but never more than <em>memory size in GB/2</em>.</p>
<h4 id="timeout_factor-1">TIMEOUT_FACTOR</h4>
<p>The timeout factor (<code>-timeoutFactor</code>).</p>
<p>Defaults to 4.</p>
<h4 id="failure_handler_timeout">FAILURE_HANDLER_TIMEOUT</h4>
<p>Sets the argument <code>-timeoutHandlerTimeout</code> for JTReg. The default value is 0. This is only valid if the failure handler is built.</p>
<h4 id="test_mode">TEST_MODE</h4>
<p>The test mode (<code>agentvm</code> or <code>othervm</code>).</p>
<p>Defaults to <code>agentvm</code>.</p>
<p>The test mode (<code>-agentvm</code>, <code>-samevm</code> or <code>-othervm</code>).</p>
<p>Defaults to <code>-agentvm</code>.</p>
<h4 id="assert">ASSERT</h4>
<p>Enable asserts (<code>-ea -esa</code>, or none).</p>
<p>Set to <code>true</code> or <code>false</code>. If true, adds <code>-ea -esa</code>. Defaults to true, except for hotspot.</p>
@@ -155,10 +150,8 @@ TEST FAILURE</code></pre>
<p>Limit memory consumption (<code>-Xmx</code> and <code>-vmoption:-Xmx</code>, or none).</p>
<p>Limit memory consumption for JTReg test framework and VM under test. Set to 0 to disable the limits.</p>
<p>Defaults to 512m, except for hotspot, where it defaults to 0 (no limit).</p>
<h4 id="max_output">MAX_OUTPUT</h4>
<p>Set the property <code>javatest.maxOutputSize</code> for the launcher, to change the default JTReg log limit.</p>
<h4 id="keywords">KEYWORDS</h4>
<p>JTReg keywords sent to JTReg using <code>-k</code>. Please be careful in making sure that spaces and special characters (like <code>!</code>) are properly quoted. To avoid some issues, the special value <code>%20</code> can be used instead of space.</p>
<p>JTReg kewords sent to JTReg using <code>-k</code>. Please be careful in making sure that spaces and special characters (like <code>!</code>) are properly quoted. To avoid some issues, the special value <code>%20</code> can be used instead of space.</p>
<h4 id="extra_problem_lists">EXTRA_PROBLEM_LISTS</h4>
<p>Use additional problem lists file or files, in addition to the default ProblemList.txt located at the JTReg test roots.</p>
<p>If multiple file names are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
@@ -168,14 +161,11 @@ TEST FAILURE</code></pre>
<p>Set to <code>true</code> or <code>false</code>. If <code>true</code>, JTReg will use <code>-match:</code> option, otherwise <code>-exclude:</code> will be used. Default is <code>false</code>.</p>
<h4 id="options">OPTIONS</h4>
<p>Additional options to the JTReg test framework.</p>
<p>Use <code>JTREG=&quot;OPTIONS=--help all&quot;</code> to see all available JTReg options.</p>
<p>Use <code>JTREG="OPTIONS=--help all"</code> to see all available JTReg options.</p>
<h4 id="java_options-1">JAVA_OPTIONS</h4>
<p>Additional Java options for running test classes (sent to JTReg as <code>-javaoption</code>).</p>
<p>Additional Java options to JTReg (<code>-javaoption</code>).</p>
<h4 id="vm_options-1">VM_OPTIONS</h4>
<p>Additional Java options to be used when compiling and running classes (sent to JTReg as <code>-vmoption</code>).</p>
<p>This option is only needed in special circumstances. To pass Java options to your test classes, use <code>JAVA_OPTIONS</code>.</p>
<h4 id="launcher_options">LAUNCHER_OPTIONS</h4>
<p>Additional Java options that are sent to the java launcher that starts the JTReg harness.</p>
<p>Additional VM options to JTReg (<code>-vmoption</code>).</p>
<h4 id="aot_modules-1">AOT_MODULES</h4>
<p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
<h4 id="retry_count">RETRY_COUNT</h4>
@@ -186,7 +176,7 @@ TEST FAILURE</code></pre>
<p>Default is 1. Set to -1 to repeat indefinitely. This can be especially useful combined with <code>OPTIONS=--gtest_break_on_failure</code> to reproduce an intermittent problem.</p>
<h4 id="options-1">OPTIONS</h4>
<p>Additional options to the Gtest test framework.</p>
<p>Use <code>GTEST=&quot;OPTIONS=--help&quot;</code> to see all available Gtest options.</p>
<p>Use <code>GTEST="OPTIONS=--help"</code> to see all available Gtest options.</p>
<h4 id="aot_modules-2">AOT_MODULES</h4>
<p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
<h3 id="microbenchmark-keywords">Microbenchmark keywords</h3>
@@ -211,29 +201,24 @@ TEST FAILURE</code></pre>
<p>Docker tests with default parameters may fail on systems with glibc versions not compatible with the one used in the default docker image (e.g., Oracle Linux 7.6 for x86). For example, they pass on Ubuntu 16.04 but fail on Ubuntu 18.04 if run like this on x86:</p>
<pre><code>$ make test TEST=&quot;jtreg:test/hotspot/jtreg/containers/docker&quot;</code></pre>
<p>To run these tests correctly, additional parameters for the correct docker image are required on Ubuntu 18.04 by using <code>JAVA_OPTIONS</code>.</p>
<pre><code>$ make test TEST=&quot;jtreg:test/hotspot/jtreg/containers/docker&quot; \
JTREG=&quot;JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu
-Djdk.test.docker.image.version=latest&quot;</code></pre>
<pre><code>$ make test TEST=&quot;jtreg:test/hotspot/jtreg/containers/docker&quot; JTREG=&quot;JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest&quot;</code></pre>
<h3 id="non-us-locale">Non-US locale</h3>
<p>If your locale is non-US, some tests are likely to fail. To work around this you can set the locale to US. On Unix platforms simply setting <code>LANG=&quot;en_US&quot;</code> in the environment before running tests should work. On Windows, setting <code>JTREG=&quot;VM_OPTIONS=-Duser.language=en -Duser.country=US&quot;</code> helps for most, but not all test cases.</p>
<p>For example:</p>
<p>If your locale is non-US, some tests are likely to fail. To work around this you can set the locale to US. On Unix platforms simply setting <code>LANG="en_US"</code> in the environment before running tests should work. On Windows, setting <code>JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"</code> helps for most, but not all test cases. For example:</p>
<pre><code>$ export LANG=&quot;en_US&quot; &amp;&amp; make test TEST=...
$ make test JTREG=&quot;VM_OPTIONS=-Duser.language=en -Duser.country=US&quot; TEST=...</code></pre>
<h3 id="pkcs11-tests">PKCS11 Tests</h3>
<p>It is highly recommended to use the latest NSS version when running PKCS11 tests. Improper NSS version may lead to unexpected failures which are hard to diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04 with the default NSS version in the system. To run these tests correctly, the system property <code>test.nss.lib.paths</code> is required on Ubuntu 18.04 to specify the alternative NSS lib directories.</p>
<p>For example:</p>
<pre><code>$ make test TEST=&quot;jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java&quot; \
JTREG=&quot;JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs&quot;</code></pre>
<p>It is highly recommended to use the latest NSS version when running PKCS11 tests. Improper NSS version may lead to unexpected failures which are hard to diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04 with the default NSS version in the system. To run these tests correctly, the system property <code>test.nss.lib.paths</code> is required on Ubuntu 18.04 to specify the alternative NSS lib directories. For example:</p>
<pre><code>$ make test TEST=&quot;jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java&quot; JTREG=&quot;JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs&quot;</code></pre>
<p>For more notes about the PKCS11 tests, please refer to test/jdk/sun/security/pkcs11/README.</p>
<h3 id="client-ui-tests">Client UI Tests</h3>
<p>Some Client UI tests use key sequences which may be reserved by the operating system. Usually that causes the test failure. So it is highly recommended to disable system key shortcuts prior testing. The steps to access and disable system key shortcuts for various platforms are provided below.</p>
<h4 id="macos">MacOS</h4>
<p>Choose Apple menu; System Preferences, click Keyboard, then click Shortcuts; select or deselect desired shortcut.</p>
<p>For example, test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java fails on MacOS because it uses <code>CTRL + F1</code> key sequence to show or hide tooltip message but the key combination is reserved by the operating system. To run the test correctly the default global key shortcut should be disabled using the steps described above, and then deselect &quot;Turn keyboard access on or off&quot; option which is responsible for <code>CTRL + F1</code> combination.</p>
<p>For example, test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java fails on MacOS because it uses <code>CTRL + F1</code> key sequence to show or hide tooltip message but the key combination is reserved by the operating system. To run the test correctly the default global key shortcut should be disabled using the steps described above, and then deselect "Turn keyboard access on or off" option which is responsible for <code>CTRL + F1</code> combination.</p>
<h4 id="linux">Linux</h4>
<p>Open the Activities overview and start typing Settings; Choose Settings, click Devices, then click Keyboard; set or override desired shortcut.</p>
<h4 id="windows">Windows</h4>
<p>Type <code>gpedit</code> in the Search and then click Edit group policy; navigate to User Configuration -&gt; Administrative Templates -&gt; Windows Components -&gt; File Explorer; in the right-side pane look for &quot;Turn off Windows key hotkeys&quot; and double click on it; enable or disable hotkeys.</p>
<p>Type <code>gpedit</code> in the Search and then click Edit group policy; navigate to User Configuration -&gt; Administrative Templates -&gt; Windows Components -&gt; File Explorer; in the right-side pane look for "Turn off Windows key hotkeys" and double click on it; enable or disable hotkeys.</p>
<p>Note: restart is required to make the settings take effect.</p>
</body>
</html>

View File

@@ -23,7 +23,7 @@ Some example command-lines:
$ make test-jdk_lang JTREG="JOBS=8"
$ make test TEST=jdk_lang
$ make test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1"
$ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT_FACTOR=8;JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
$ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT_FACTOR=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
$ make test TEST="jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java"
$ make test TEST="micro:java.lang.reflect" MICRO="FORK=1;WARMUP_ITER=2"
$ make exploded-test TEST=tier2
@@ -37,11 +37,11 @@ Note that this option should point to the JTReg home, i.e. the top directory,
containing `lib/jtreg.jar` etc. (An alternative is to set the `JT_HOME`
environment variable to point to the JTReg home before running `configure`.)
To be able to run microbenchmarks, `configure` needs to know where to find the
JMH dependency. Use `--with-jmh=<path to JMH jars>` to point to a directory
containing the core JMH and transitive dependencies. The recommended
dependencies can be retrieved by running `sh make/devkit/createJMHBundle.sh`,
after which `--with-jmh=build/jmh/jars` should work.
To be able to run microbenchmarks, `configure` needs to know where to find
the JMH dependency. Use `--with-jmh=<path to JMH jars>` to point to a directory
containing the core JMH and transitive dependencies. The recommended dependencies
can be retrieved by running `sh make/devkit/createJMHBundle.sh`, after which
`--with-jmh=build/jmh/jars` should work.
## Test selection
@@ -182,19 +182,19 @@ variables.
These variables use a keyword=value approach to allow multiple values to be
set. So, for instance, `JTREG="JOBS=1;TIMEOUT_FACTOR=8"` will set the JTReg
concurrency level to 1 and the timeout factor to 8. This is equivalent to
setting `JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8`, but using the keyword format
means that the `JTREG` variable is parsed and verified for correctness, so
`JTREG="TMIEOUT_FACTOR=8"` would give an error, while `JTREG_TMIEOUT_FACTOR=8`
would just pass unnoticed.
setting `JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8`, but using the keyword format means that
the `JTREG` variable is parsed and verified for correctness, so
`JTREG="TMIEOUT_FACTOR=8"` would give an error, while `JTREG_TMIEOUT_FACTOR=8` would just
pass unnoticed.
To separate multiple keyword=value pairs, use `;` (semicolon). Since the shell
normally eats `;`, the recommended usage is to write the assignment inside
qoutes, e.g. `JTREG="...;..."`. This will also make sure spaces are preserved,
as in `JTREG="JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"`.
as in `JTREG="VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"`.
(Other ways are possible, e.g. using backslash: `JTREG=JOBS=1\;TIMEOUT_FACTOR=8`.
Also, as a special technique, the string `%20` will be replaced with space for
certain options, e.g. `JTREG=JAVA_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug`.
certain options, e.g. `JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug`.
This can be useful if you have layers of scripts and have trouble getting
proper quoting of command line arguments through.)
@@ -203,10 +203,9 @@ test suites.
### General keywords (TEST_OPTS)
Some keywords are valid across different test suites. If you want to run tests
from multiple test suites, or just don't want to care which test suite specific
control variable to use, then you can use the general TEST_OPTS control
variable.
Some keywords are valid across different test suites. If you want to run
tests from multiple test suites, or just don't want to care which test suite specific
control variable to use, then you can use the general TEST_OPTS control variable.
There are also some keywords that applies globally to the test runner system,
not to any specific test suites. These are also available as TEST_OPTS keywords.
@@ -219,11 +218,11 @@ Currently only applies to JTReg.
Currently only applies to JTReg.
#### JAVA_OPTIONS
#### VM_OPTIONS
Applies to JTReg, GTest and Micro.
#### VM_OPTIONS
#### JAVA_OPTIONS
Applies to JTReg, GTest and Micro.
@@ -242,68 +241,47 @@ The simplest way to run tests with JCov coverage report is to use the special
target `jcov-test` instead of `test`, e.g. `make jcov-test TEST=jdk_lang`. This
will make sure the JCov image is built, and that JCov reporting is enabled.
The JCov report is stored in `build/$BUILD/test-results/jcov-output/report`.
The JCov report is stored in `build/$BUILD/test-results/jcov-output`.
Please note that running with JCov reporting can be very memory intensive.
#### JCOV_DIFF_CHANGESET
While collecting code coverage with JCov, it is also possible to find coverage
for only recently changed code. JCOV_DIFF_CHANGESET specifies a source
revision. A textual report will be generated showing coverage of the diff
between the specified revision and the repository tip.
The report is stored in
`build/$BUILD/test-results/jcov-output/diff_coverage_report` file.
### JTReg keywords
#### JOBS
The test concurrency (`-concurrency`).
Defaults to TEST_JOBS (if set by `--with-test-jobs=`), otherwise it defaults to
JOBS, except for Hotspot, where the default is *number of CPU cores/2*,
but never more than *memory size in GB/2*.
JOBS, except for Hotspot, where the default is *number of CPU cores/2* (for
sparc, if more than 16 cpus, then *number of CPU cores/5*, otherwise *number of
CPU cores/4*), but never more than *memory size in GB/2*.
#### TIMEOUT_FACTOR
The timeout factor (`-timeoutFactor`).
Defaults to 4.
#### FAILURE_HANDLER_TIMEOUT
Sets the argument `-timeoutHandlerTimeout` for JTReg. The default value is 0.
This is only valid if the failure handler is built.
#### TEST_MODE
The test mode (`-agentvm`, `-samevm` or `-othervm`).
The test mode (`agentvm` or `othervm`).
Defaults to `agentvm`.
Defaults to `-agentvm`.
#### ASSERT
Enable asserts (`-ea -esa`, or none).
Set to `true` or `false`. If true, adds `-ea -esa`. Defaults to true, except
for hotspot.
#### VERBOSE
The verbosity level (`-verbose`).
Defaults to `fail,error,summary`.
#### RETAIN
What test data to retain (`-retain`).
Defaults to `fail,error`.
#### MAX_MEM
Limit memory consumption (`-Xmx` and `-vmoption:-Xmx`, or none).
Limit memory consumption for JTReg test framework and VM under test. Set to 0
@@ -311,14 +289,9 @@ to disable the limits.
Defaults to 512m, except for hotspot, where it defaults to 0 (no limit).
#### MAX_OUTPUT
Set the property `javatest.maxOutputSize` for the launcher, to change the
default JTReg log limit.
#### KEYWORDS
JTReg keywords sent to JTReg using `-k`. Please be careful in making sure that
JTReg kewords sent to JTReg using `-k`. Please be careful in making sure that
spaces and special characters (like `!`) are properly quoted. To avoid some
issues, the special value `%20` can be used instead of space.
@@ -341,29 +314,17 @@ Set to `true` or `false`.
If `true`, JTReg will use `-match:` option, otherwise `-exclude:` will be used.
Default is `false`.
#### OPTIONS
#### OPTIONS
Additional options to the JTReg test framework.
Use `JTREG="OPTIONS=--help all"` to see all available JTReg options.
#### JAVA_OPTIONS
Additional Java options for running test classes (sent to JTReg as
`-javaoption`).
Additional Java options to JTReg (`-javaoption`).
#### VM_OPTIONS
Additional Java options to be used when compiling and running classes (sent to
JTReg as `-vmoption`).
This option is only needed in special circumstances. To pass Java options to
your test classes, use `JAVA_OPTIONS`.
#### LAUNCHER_OPTIONS
Additional Java options that are sent to the java launcher that starts the
JTReg harness.
Additional VM options to JTReg (`-vmoption`).
#### AOT_MODULES
@@ -378,7 +339,6 @@ Retry failed tests up to a set number of times. Defaults to 0.
### Gtest keywords
#### REPEAT
The number of times to repeat the tests (`--gtest_repeat`).
Default is 1. Set to -1 to repeat indefinitely. This can be especially useful
@@ -386,7 +346,6 @@ combined with `OPTIONS=--gtest_break_on_failure` to reproduce an intermittent
problem.
#### OPTIONS
Additional options to the Gtest test framework.
Use `GTEST="OPTIONS=--help"` to see all available Gtest options.
@@ -400,127 +359,98 @@ modules. If multiple modules are specified, they should be separated by space
### Microbenchmark keywords
#### FORK
Override the number of benchmark forks to spawn. Same as specifying `-f <num>`.
#### ITER
Number of measurement iterations per fork. Same as specifying `-i <num>`.
#### TIME
Amount of time to spend in each measurement iteration, in seconds. Same as
specifying `-r <num>`
#### WARMUP_ITER
Number of warmup iterations to run before the measurement phase in each fork.
Same as specifying `-wi <num>`.
#### WARMUP_TIME
Amount of time to spend in each warmup iteration. Same as specifying `-w <num>`.
#### RESULTS_FORMAT
Specify to have the test run save a log of the values. Accepts the same values
as `-rff`, i.e., `text`, `csv`, `scsv`, `json`, or `latex`.
#### VM_OPTIONS
Additional VM arguments to provide to forked off VMs. Same as `-jvmArgs <args>`
#### OPTIONS
Additional arguments to send to JMH.
## Notes for Specific Tests
### Docker Tests
Docker tests with default parameters may fail on systems with glibc versions
not compatible with the one used in the default docker image (e.g., Oracle
Linux 7.6 for x86). For example, they pass on Ubuntu 16.04 but fail on Ubuntu
18.04 if run like this on x86:
Docker tests with default parameters may fail on systems with glibc versions not
compatible with the one used in the default docker image (e.g., Oracle Linux 7.6 for x86).
For example, they pass on Ubuntu 16.04 but fail on Ubuntu 18.04 if run like this on x86:
```
$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker"
```
$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker"
To run these tests correctly, additional parameters for the correct docker
image are required on Ubuntu 18.04 by using `JAVA_OPTIONS`.
To run these tests correctly, additional parameters for the correct docker image are
required on Ubuntu 18.04 by using `JAVA_OPTIONS`.
```
$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker" \
JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu
-Djdk.test.docker.image.version=latest"
```
$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker" JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest"
### Non-US locale
If your locale is non-US, some tests are likely to fail. To work around this
you can set the locale to US. On Unix platforms simply setting `LANG="en_US"`
in the environment before running tests should work. On Windows, setting
`JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"` helps for most, but
not all test cases.
If your locale is non-US, some tests are likely to fail. To work around this you can
set the locale to US. On Unix platforms simply setting `LANG="en_US"` in the
environment before running tests should work. On Windows, setting
`JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"` helps for most, but not all test cases.
For example:
```
$ export LANG="en_US" && make test TEST=...
$ make test JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US" TEST=...
```
$ export LANG="en_US" && make test TEST=...
$ make test JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US" TEST=...
### PKCS11 Tests
It is highly recommended to use the latest NSS version when running PKCS11
tests. Improper NSS version may lead to unexpected failures which are hard to
diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail
on Ubuntu 18.04 with the default NSS version in the system. To run these tests
correctly, the system property `test.nss.lib.paths` is required on Ubuntu 18.04
to specify the alternative NSS lib directories.
It is highly recommended to use the latest NSS version when running PKCS11 tests.
Improper NSS version may lead to unexpected failures which are hard to diagnose.
For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu
18.04 with the default NSS version in the system.
To run these tests correctly, the system property `test.nss.lib.paths` is required
on Ubuntu 18.04 to specify the alternative NSS lib directories.
For example:
```
$ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" \
JTREG="JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs"
```
$ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" JTREG="JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs"
For more notes about the PKCS11 tests, please refer to
test/jdk/sun/security/pkcs11/README.
For more notes about the PKCS11 tests, please refer to test/jdk/sun/security/pkcs11/README.
### Client UI Tests
Some Client UI tests use key sequences which may be reserved by the operating
system. Usually that causes the test failure. So it is highly recommended to
disable system key shortcuts prior testing. The steps to access and disable
system key shortcuts for various platforms are provided below.
system. Usually that causes the test failure. So it is highly recommended to disable
system key shortcuts prior testing. The steps to access and disable system key shortcuts
for various platforms are provided below.
#### MacOS
Choose Apple menu; System Preferences, click Keyboard, then click Shortcuts;
select or deselect desired shortcut.
For example,
test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java
fails on MacOS because it uses `CTRL + F1` key sequence to show or hide tooltip
message but the key combination is reserved by the operating system. To run the
test correctly the default global key shortcut should be disabled using the
steps described above, and then deselect "Turn keyboard access on or off"
option which is responsible for `CTRL + F1` combination.
For example, test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java fails
on MacOS because it uses `CTRL + F1` key sequence to show or hide tooltip message
but the key combination is reserved by the operating system. To run the test correctly
the default global key shortcut should be disabled using the steps described above, and then deselect
"Turn keyboard access on or off" option which is responsible for `CTRL + F1` combination.
#### Linux
Open the Activities overview and start typing Settings; Choose Settings, click
Devices, then click Keyboard; set or override desired shortcut.
Open the Activities overview and start typing Settings; Choose Settings, click Devices,
then click Keyboard; set or override desired shortcut.
#### Windows
Type `gpedit` in the Search and then click Edit group policy; navigate to User
Configuration -> Administrative Templates -> Windows Components -> File
Explorer; in the right-side pane look for "Turn off Windows key hotkeys" and
double click on it; enable or disable hotkeys.
Type `gpedit` in the Search and then click Edit group policy; navigate to
User Configuration -> Administrative Templates -> Windows Components -> File Explorer;
in the right-side pane look for "Turn off Windows key hotkeys" and double click on it;
enable or disable hotkeys.
Note: restart is required to make the settings take effect.

View File

@@ -1,10 +1,13 @@
# jetbrains/runtime:jbr15env
# jetbrains/runtime:jbr14env
FROM centos:7
RUN yum -y install centos-release-scl
RUN yum -y install devtoolset-8
RUN yum -y install zip bzip2 unzip tar wget make autoconf automake libtool alsa-devel cups-devel xorg-x11-devel libjpeg62-devel giflib-devel freetype-devel file which libXtst-devel libXt-devel libXrender-devel alsa-lib-devel fontconfig-devel libXrandr-devel libXi-devel git
# Install Java 11
RUN wget https://download.java.net/java/GA/jdk14.0.1/664493ef4a6946b186ff29eb326336a2/7/GPL/openjdk-14.0.1_linux-x64_bin.tar.gz \
RUN yum -y install zip bzip2 unzip tar wget make autoconf automake libtool gcc gcc-c++ libstdc++-devel alsa-devel cups-devel xorg-x11-devel libjpeg62-devel giflib-devel freetype-devel file which libXtst-devel libXt-devel libXrender-devel alsa-lib-devel fontconfig-devel libXrandr-devel libXi-devel git
# Install Java 13
RUN wget https://download.java.net/java/GA/jdk13.0.1/cec27d702aa74d5a8630c65ae61e4305/9/GPL/openjdk-13.0.1_linux-x64_bin.tar.gz \
-O - | tar xz -C /
ENV JAVA_HOME /jbrsdk
ENV PATH $JAVA_HOME/bin:/opt/rh/devtoolset-8/root/usr/bin:$PATH
RUN mkdir .git
RUN git config user.email "builduser@jetbrains.com"
RUN git config user.name "builduser"

View File

@@ -0,0 +1,10 @@
FROM i386/ubuntu:xenial
RUN linux32 apt-get update && apt-get install -y --no-install-recommends apt-utils
RUN linux32 apt-get -y install file build-essential zip unzip tar wget curl libx11-dev libxext-dev \
libxrender-dev libxrandr-dev libxtst-dev libxt-dev libcups2-dev libasound2-data \
libpng12-0 libasound2 libfreetype6 libfontconfig1-dev libasound2-dev autoconf git
RUN wget https://cdn.azul.com/zulu/bin/zulu13.31.11-ca-jdk13.0.3-linux_i686.tar.gz \
-O - | tar xz -C /
ENV JAVA_HOME /zulu13.31.11-ca-jdk13.0.3-linux_i686
ENV PATH $JAVA_HOME/bin:$PATH

View File

@@ -0,0 +1,49 @@
VENDOR_NAME="JetBrains s.r.o."
VENDOR_VERSION_STRING="JBR-${JBSDK_VERSION_WITH_DOTS}.${JDK_BUILD_NUMBER}-${build_number}"
[ -z "$bundle_type" ] || VENDOR_VERSION_STRING="${VENDOR_VERSION_STRING}-${bundle_type}"
do_reset_changes=0
function do_exit() {
exit_code=$1
[ $do_reset_changes -eq 1 ] && git checkout HEAD modules.list src/java.desktop/share/classes/module-info.java
exit "$exit_code"
}
function update_jsdk_mods() {
__jsdk=$1
__jcef_mods=$2
__orig_jsdk_mods=$3
__updated_jsdk_mods=$4
# re-create java.desktop.jmod with updated module-info.class
tmp=.java.desktop.$$.tmp
mkdir "$tmp" || exit $?
"$__jsdk"/bin/jmod extract --dir "$tmp" "$__orig_jsdk_mods"/java.desktop.jmod || exit $?
"$__jsdk"/bin/javac \
--patch-module java.desktop="$__orig_jsdk_mods"/java.desktop.jmod \
--module-path "$__jcef_mods" -d "$tmp"/classes src/java.desktop/share/classes/module-info.java || exit $?
"$__jsdk"/bin/jmod \
create --class-path "$tmp"/classes --config "$tmp"/conf --header-files "$tmp"/include --legal-notice "$tmp"/legal --libs "$tmp"/lib \
java.desktop.jmod || exit $?
mv java.desktop.jmod "$__updated_jsdk_mods" || exit $?
rm -rf "$tmp"
# re-create java.base.jmod with updated hashes
tmp=.java.base.$$.tmp
mkdir "$tmp" || exit $?
hash_modules=$("$JSDK"/bin/jmod describe "$__orig_jsdk_mods"/java.base.jmod | grep hashes | awk '{print $2}' | tr '\n' '|' | sed s/\|$//) || exit $?
"$__jsdk"/bin/jmod extract --dir "$tmp" "$__orig_jsdk_mods"/java.base.jmod || exit $?
rm "$__updated_jsdk_mods"/java.base.jmod || exit $? # temp exclude from path
"$__jsdk"/bin/jmod \
create --module-path "$__updated_jsdk_mods" --hash-modules "$hash_modules" \
--class-path "$tmp"/classes --cmds "$tmp"/bin --config "$tmp"/conf --header-files "$tmp"/include --legal-notice "$tmp"/legal --libs "$tmp"/lib \
java.base.jmod || exit $?
mv java.base.jmod "$__updated_jsdk_mods" || exit $?
rm -rf "$tmp"
}
function get_mods_list() {
__mods=$1
return `ls "$__mods"` | sed s/\.jmod/,/g | sed s/,$//g | sed s/' '//g
}

View File

@@ -1,9 +0,0 @@
#!/bin/bash -x
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
script_dir=jb/project/tools/linux/scripts
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jcef" || exit $?
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx" || exit $?
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx_jcef" || exit $?

View File

@@ -4,9 +4,6 @@
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
@@ -21,22 +18,30 @@ JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
source jb/project/tools/common/scripts/common.sh
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
[ -z "$bundle_type" ] && (git apply -p0 < jb/project/tools/patches/exclude_jcef_module.patch || exit $?)
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-build=$JDK_BUILD_NUMBER \
--with-vendor-name="${VENDOR_NAME}" \
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
--with-version-pre= \
--with-version-opt=b$build_number \
--with-boot-jdk=amazon-corretto-11.0.5.10.1-linux-aarch64 \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-import-modules=./modular-sdk \
--with-boot-jdk=${BOOT_JDK} \
--enable-cds=yes || exit $?
make clean CONF=linux-aarch64-normal-server-release || exit $?
make images CONF=linux-aarch64-normal-server-release test-image || exit $?
make clean CONF=linux-aarch64-server-release || exit $?
make images CONF=linux-aarch64-server-release test-image || exit $?
JBSDK=${JBRSDK_BASE_NAME}-linux-aarch64-b${build_number}
BASE_DIR=build/linux-aarch64-normal-server-release/images
BASE_DIR=build/linux-aarch64-server-release/images
JSDK=${BASE_DIR}/jdk
JBRSDK_BUNDLE=jbrsdk
@@ -47,6 +52,9 @@ rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
echo Creating $JBSDK.tar.gz ...
sed 's/JBR/JBRSDK/g' ${BASE_DIR}/${JBRSDK_BUNDLE}/release > release
mv release ${BASE_DIR}/${JBRSDK_BUNDLE}/release
tar -pcf $JBSDK.tar \
--exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man \
-C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?

View File

@@ -1,12 +1,13 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# JBSDK_VERSION - specifies major version of OpenJDK e.g. 11_0_6 (instead of dots '.' underbars "_" are used)
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
# bundle_type - specifies bundle to be built; possible values:
# <empty> or nomod - the release bundles without any additional modules (jcef)
# jcef - the release bundles with jcef
# fd - the fastdebug bundles which also include the jcef module
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
@@ -16,124 +17,109 @@
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
# Environment variables:
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_linux_x64
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
JCEF_PATH=${JCEF_PATH:=./jcef_linux_x64}
function create_jbr {
source jb/project/tools/common/scripts/common.sh
case "$1" in
"${bundle_type}_lw")
JBR_BASE_NAME=jbr_${bundle_type}_lw-${JBSDK_VERSION}
grep -v "jdk.compiler\|jdk.hotspot.agent" modules.list > modules_tmp.list
;;
"jfx" | "jcef")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
"jfx_jcef")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
*)
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
esac
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
function create_image_bundle {
__bundle_name=$1
__arch_name=$2
__modules_path=$3
__modules=$4
JBR=$JBR_BASE_NAME-linux-x64-b$build_number
[ "$bundle_type" == "fd" ] && fastdebug_infix="fastdebug-"
JBR=${__bundle_name}-${JBSDK_VERSION}-linux-x64-${fastdebug_infix}b${build_number}
echo Running jlink....
[ -d "$IMAGES_DIR"/"$__arch_name" ] && rm -rf "${IMAGES_DIR:?}"/"$__arch_name"
$JSDK/bin/jlink \
--module-path $JSDK/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules_tmp.list | sed s/" "//g) --output $BASE_DIR/$JBR_BUNDLE
--module-path "$__modules_path" --no-man-pages --compress=2 \
--add-modules "$__modules" --output "$IMAGES_DIR"/"$__arch_name"
if [[ "$bundle_type" == *jcef* ]]; then
cp -R $BASE_DIR/$JBR_BUNDLE $BASE_DIR/jbr
cp -R jcef_linux_x64/* $BASE_DIR/$JBR_BUNDLE/lib || exit $?
fi
grep -v "^JAVA_VERSION" $JSDK/release | grep -v "^MODULES" >> $BASE_DIR/$JBR_BUNDLE/release
# jmod does not preserve file permissions (JDK-8173610)
[ -f "$IMAGES_DIR"/"$__arch_name"/lib/jcef_helper ] && chmod a+x "$IMAGES_DIR"/"$__arch_name"/lib/jcef_helper
echo Creating $JBR.tar.gz ...
if [ ! -z "$bundle_type" ]; then
rm -rf ${BASE_DIR}/jbr
cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
fi
tar -pcf $JBR.tar -C $BASE_DIR jbr || exit $?
gzip $JBR.tar || exit $?
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
echo Creating "$JBR".tar.gz ...
tar -pcf "$JBR".tar -C "$IMAGES_DIR" "$__arch_name" || do_exit $?
[ -f "$JBR".tar.gz ] && rm "$JBR.tar.gz"
gzip "$JBR".tar || do_exit $?
rm -rf "${IMAGES_DIR:?}"/"$__arch_name"
}
JBRSDK_BASE_NAME=jbrsdk-$JBSDK_VERSION
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=linux-x86_64-server-release
#git checkout -- modules.list src
case "$bundle_type" in
"jfx")
git apply -p0 < jb/project/tools/exclude_jcef_module.patch
;;
"jcef")
git apply -p0 < jb/project/tools/exclude_jfx_module.patch
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
;;
"fd")
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=linux-x86_64-server-fastdebug
;;
esac
if [ -z "$bundle_type" ]; then
JBR_BUNDLE=jbr
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-boot-jdk=$BOOT_JDK \
--enable-cds=yes || exit $?
else
JBR_BUNDLE=jbr_${bundle_type}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-import-modules=./modular-sdk \
--with-boot-jdk=$BOOT_JDK \
--enable-cds=yes || exit $?
fi
sh configure \
--disable-warnings-as-errors \
$WITH_DEBUG_LEVEL \
--with-vendor-name="$VENDOR_NAME" \
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
--with-version-pre= \
--with-version-build="$JDK_BUILD_NUMBER" \
--with-version-opt=b"$build_number" \
--with-boot-jdk="$BOOT_JDK" \
--enable-cds=yes || do_exit $?
make images CONF=linux-x86_64-server-release || exit $?
make clean CONF=$RELEASE_NAME || exit $?
make images CONF=$RELEASE_NAME || do_exit $?
JSDK=build/linux-x86_64-server-release/images/jdk
JBSDK=$JBRSDK_BASE_NAME-linux-x64-b$build_number
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk
JSDK_MODS_DIR=$IMAGES_DIR/jmods
JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
BASE_DIR=build/linux-x86_64-server-release/images
JBRSDK_BUNDLE=jbrsdk
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
update_jsdk_mods $JSDK $JCEF_PATH/jmods $JSDK/jmods $JSDK_MODS_DIR || do_exit $?
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
if [[ "$bundle_type" == *jcef* ]]; then
cp -R jcef_linux_x64/* $BASE_DIR/$JBRSDK_BUNDLE/lib || exit $?
fi
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
echo Creating $JBSDK.tar.gz ...
tar -pcf $JBSDK.tar --exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man \
-C $BASE_DIR $JBRSDK_BUNDLE || exit $?
gzip $JBSDK.tar || exit $?
jbr_name_postfix="_${bundle_type}"
fi
create_jbr ${bundle_type}
# create runtime image bundle
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" || do_exit $?
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
make test-image || exit $?
# create sdk image bundle
modules=$(cat $JSDK/release | grep MODULES | sed s/MODULES=//g | sed s/' '/,/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle $JBRSDK_BUNDLE $JBRSDK_BUNDLE $JSDK_MODS_DIR "$modules" || do_exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-x64-b$build_number
if [ -z "$bundle_type" ]; then
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-linux-test-x64-b${build_number}
echo Creating "$JBRSDK_TEST" ...
make test-image CONF=$RELEASE_NAME || do_exit $?
tar -pcf "$JBRSDK_TEST".tar -C $IMAGES_DIR --exclude='test/jdk/demos' test || do_exit $?
[ -f "$JBRSDK_TEST.tar.gz" ] && rm "$JBRSDK_TEST.tar.gz"
gzip "$JBRSDK_TEST".tar || do_exit $?
fi
echo Creating $JBSDK_TEST.tar.gz ...
tar -pcf $JBRSDK_TEST.tar -C $BASE_DIR --exclude='test/jdk/demos' test || exit $?
gzip $JBRSDK_TEST.tar || exit $?
fi
do_exit 0

View File

@@ -1,72 +0,0 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=fastdebug \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-pre= \
--with-version-opt=b$build_number \
--with-import-modules=./modular-sdk \
--enable-cds=yes || exit $?
make clean CONF=linux-x86_64-normal-server-fastdebug || exit $?
make images CONF=linux-x86_64-normal-server-fastdebug || exit $?
JBSDK=${JBRSDK_BASE_NAME}-linux-x64-fastdebug-b${build_number}
BASE_DIR=build/linux-x86_64-normal-server-fastdebug/images
JSDK=${BASE_DIR}/jdk
JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
cp -R jcef_linux_x64/* $BASE_DIR/$JBRSDK_BUNDLE/lib || exit $?
echo Creating $JBSDK.tar.gz ...
tar -pcf $JBSDK.tar \
--exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man \
-C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?
gzip $JBSDK.tar || exit $?
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-$JBSDK_VERSION
rm -rf $BASE_DIR/$JBR_BUNDLE
JBR=$JBR_BASE_NAME-linux-x64-fastdebug-b$build_number
echo Running jlink....
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list | sed s/" "//g | sed s/,$//g) \
--output ${BASE_DIR}/${JBR_BUNDLE} || exit $?
cp -R jcef_linux_x64/* $BASE_DIR/$JBR_BUNDLE/lib || exit $?
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${BASE_DIR}/${JBR_BUNDLE}/release
echo Creating $JBR.tar.gz ...
tar -czf $JBR.tar -C $BASE_DIR ${JBR_BUNDLE} || exit $?
gzip $JBR.tar || exit $?

View File

@@ -4,9 +4,6 @@
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
@@ -21,21 +18,29 @@ JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
source jb/project/tools/common/scripts/common.sh
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
[ -z "$bundle_type" ] && (git apply -p0 < jb/project/tools/patches/exclude_jcef_module.patch || exit $?)
linux32 bash configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-build=$JDK_BUILD_NUMBER \
--with-vendor-name="${VENDOR_NAME}" \
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
--with-version-pre= \
--with-version-opt=b$build_number \
--with-boot-jdk=/jbrsdk-11.0.5-b1 \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-opt=b${build_number} \
--with-boot-jdk=${BOOT_JDK} \
--enable-cds=yes || exit $?
make clean CONF=linux-x86-normal-server-release || exit $?
make images CONF=linux-x86-normal-server-release test-image || exit $?
make clean CONF=linux-x86-server-release || exit $?
make images CONF=linux-x86-server-release test-image || exit $?
JBSDK=${JBRSDK_BASE_NAME}-linux-x86-b${build_number}
BASE_DIR=build/linux-x86-normal-server-release/images
BASE_DIR=build/linux-x86-server-release/images
JSDK=${BASE_DIR}/jdk
JBRSDK_BUNDLE=jbrsdk
@@ -46,6 +51,9 @@ rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
echo Creating $JBSDK.tar.gz ...
sed 's/JBR/JBRSDK/g' ${BASE_DIR}/${JBRSDK_BUNDLE}/release > release
mv release ${BASE_DIR}/${JBRSDK_BUNDLE}/release
tar -pcf $JBSDK.tar --exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man -C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?
gzip $JBSDK.tar || exit $?

View File

@@ -1,9 +0,0 @@
#!/bin/bash -x
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
script_dir=jb/project/tools/mac/scripts
${script_dir}/mkimages.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jcef" || exit $?
${script_dir}/mkimages.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx" || exit $?
${script_dir}/mkimages.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx_jcef" || exit $?

View File

@@ -1,12 +1,13 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# JBSDK_VERSION - specifies major version of OpenJDK e.g. 11_0_6 (instead of dots '.' underbars "_" are used)
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
# bundle_type - specifies bundle to be built; possible values:
# <empty> or nomod - the release bundles without any additional modules (jcef)
# jcef - the release bundles with jcef
# fd - the fastdebug bundles which also include the jcef module
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
@@ -16,133 +17,110 @@
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
# Environment variables:
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_mac
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
JBSDK_VERSION_WITH_DOTS=$(echo "$JBSDK_VERSION" | sed 's/_/\./g')
JCEF_PATH=${JCEF_PATH:=./jcef_mac}
MAJOR_JBSDK_VERSION=$(echo "$JBSDK_VERSION_WITH_DOTS" | awk -F "." '{print $1}')
BOOT_JDK=${BOOT_JDK:=$(/usr/libexec/java_home -v 14)}
function create_jbr {
source jb/project/tools/common/scripts/common.sh
case "$1" in
"${bundle_type}_lw")
JBR_BASE_NAME=jbr_${bundle_type}_lw-${JBSDK_VERSION}
grep -v "jdk.compiler\|jdk.hotspot.agent" modules.list > modules_tmp.list
;;
"jfx" | "jcef")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
"jfx_jcef")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
*)
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
;;
esac
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
function create_image_bundle {
__bundle_name=$1
__modules_path=$2
__modules=$3
JRE_CONTENTS=${BASE_DIR}/${JBR_BUNDLE}/Contents
JRE_HOME=${JRE_CONTENTS}/Home
if [ -d "${JRE_CONTENTS}" ]; then
rm -rf ${JRE_CONTENTS}
fi
mkdir -p ${JRE_CONTENTS}
tmp=.bundle.$$.tmp
mkdir "$tmp" || do_exit $?
JBR=${JBR_BASE_NAME}-osx-x64-b${build_number}
[ "$bundle_type" == "fd" ] && fastdebug_infix="fastdebug-"
JBR=${__bundle_name}-${JBSDK_VERSION}-osx-x64-${fastdebug_infix}b${build_number}
${BASE_DIR}/$JBRSDK_BUNDLE/Contents/Home/bin/jlink \
--module-path ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Home/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules_tmp.list | sed s/" "//g) --output ${JRE_HOME} || exit $?
grep -v "^JAVA_VERSION" ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Home/release | grep -v "^MODULES" >> ${JRE_HOME}/release
cp -R ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/MacOS ${JRE_CONTENTS}
cp ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Info.plist ${JRE_CONTENTS}
JRE_CONTENTS=$tmp/$__bundle_name/Contents
mkdir -p "$JRE_CONTENTS" || do_exit $?
if [[ "${bundle_type}" == *jcef* ]]; then
rm -rf ${JRE_CONTENTS}/Frameworks || exit $?
rm -rf ${JRE_CONTENTS}/Helpers || exit $?
cp -a jcef_mac/Frameworks ${JRE_CONTENTS} || exit $?
cp -a jcef_mac/Helpers ${JRE_CONTENTS} || exit $?
fi
echo Running jlink...
"$JSDK"/bin/jlink \
--module-path "$__modules_path" --no-man-pages --compress=2 \
--add-modules "$__modules" --output "$JRE_CONTENTS/Home" || do_exit $?
echo Creating ${JBR}.tar.gz ...
if [ ! -z "$bundle_type" ]; then
rm -rf ${BASE_DIR}/jbr
cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
fi
COPYFILE_DISABLE=1 tar -pczf ${JBR}.tar.gz --exclude='*.dSYM' --exclude='man' -C ${BASE_DIR} jbr || exit $?
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
cp -R "$JSDK"/../MacOS "$JRE_CONTENTS"
cp "$JSDK"/../Info.plist "$JRE_CONTENTS"
[ -n "$bundle_type" ] && (cp -a $JCEF_PATH/Frameworks "$JRE_CONTENTS" || do_exit $?)
echo Creating "$JBR".tar.gz ...
COPYFILE_DISABLE=1 tar -pczf "$JBR".tar.gz --exclude='*.dSYM' --exclude='man' -C "$tmp" "$__bundle_name" || do_exit $?
rm -rf "$tmp"
}
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=macosx-x86_64-server-release
#git checkout -- modules.list src
case "$bundle_type" in
"jfx")
git apply -p0 < jb/project/tools/exclude_jcef_module.patch
;;
"jcef")
git apply -p0 < jb/project/tools/exclude_jfx_module.patch
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
;;
"fd")
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=macosx-x86_64-server-fastdebug
;;
esac
if [ -z "$bundle_type" ]; then
JBR_BUNDLE=jbr
sh configure \
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
$WITH_DEBUG_LEVEL \
--with-vendor-name="$VENDOR_NAME" \
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-boot-jdk=`/usr/libexec/java_home -v $BOOT_JDK` \
--enable-cds=yes || exit $?
else
JBR_BUNDLE=jbr_${bundle_type}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-import-modules=./modular-sdk \
--with-boot-jdk=`/usr/libexec/java_home -v $BOOT_JDK` \
--enable-cds=yes || exit $?
fi
make images CONF=macosx-x86_64-server-release || exit $?
--with-version-build="$JDK_BUILD_NUMBER" \
--with-version-opt=b"$build_number" \
--with-boot-jdk="$BOOT_JDK" \
--enable-cds=yes || do_exit $?
JSDK=build/macosx-x86_64-server-release/images/jdk-bundle
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-b${build_number}
make clean CONF=$RELEASE_NAME || do_exit $?
make images CONF=$RELEASE_NAME || do_exit $?
BASE_DIR=jre
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk-bundle/jdk-$MAJOR_JBSDK_VERSION.jdk/Contents/Home
JSDK_MODS_DIR=$IMAGES_DIR/jmods
JBRSDK_BUNDLE=jbrsdk
rm -rf $BASE_DIR
mkdir $BASE_DIR || exit $?
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
cp -a $JSDK/jdk-$JBSDK_VERSION_WITH_DOTS.jdk $BASE_DIR/$JBRSDK_BUNDLE || exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
update_jsdk_mods "$JSDK" "$JCEF_PATH"/jmods "$JSDK"/jmods "$JSDK_MODS_DIR" || do_exit $?
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
if [[ "$bundle_type" == *jcef* ]]; then
cp -a jcef_mac/Frameworks $BASE_DIR/$JBRSDK_BUNDLE/Contents/ || exit $?
cp -a jcef_mac/Helpers $BASE_DIR/$JBRSDK_BUNDLE/Contents/ || exit $?
fi
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
echo Creating $JBSDK.tar.gz ...
COPYFILE_DISABLE=1 tar -pczf $JBSDK.tar.gz -C $BASE_DIR \
--exclude='._*' --exclude='.DS_Store' --exclude='*~' \
--exclude='Home/demo' --exclude='Home/man' --exclude='Home/sample' \
$JBRSDK_BUNDLE || exit $?
jbr_name_postfix="_${bundle_type}"
fi
create_jbr "${bundle_type}" || exit $?
# create runtime image bundle
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
create_image_bundle "jbr${jbr_name_postfix}" $JSDK_MODS_DIR "$modules" || do_exit $?
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
make test-image || exit $?
# create sdk image bundle
modules=$(cat "$JSDK"/release | grep MODULES | sed s/MODULES=//g | sed s/' '/,/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle "$JBRSDK_BUNDLE" "$JSDK_MODS_DIR" "$modules" || do_exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-osx-test-x64-b$build_number
if [ -z "$bundle_type" ]; then
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-osx-test-x64-b${build_number}
echo Creating "$JBRSDK_TEST" ...
make test-image CONF=$RELEASE_NAME || do_exit $?
[ -f "$JBRSDK_TEST.tar.gz" ] && rm "$JBRSDK_TEST.tar.gz"
COPYFILE_DISABLE=1 tar -pczf "$JBRSDK_TEST".tar.gz -C $IMAGES_DIR --exclude='test/jdk/demos' test || do_exit $?
fi
echo Creating $JBRSDK_TEST.tar.gz ...
COPYFILE_DISABLE=1 tar -pczf $JBRSDK_TEST.tar.gz -C build/macosx-x86_64-server-release/images \
--exclude='test/jdk/demos' test || exit $?
fi
do_exit 0

View File

@@ -1,83 +0,0 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
#
# $ ./java --version
# openjdk 11.0.6 2020-01-14
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
sh configure \
--disable-warnings-as-errors \
--with-debug-level=fastdebug \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-pre= \
--with-version-opt=b$build_number \
--with-import-modules=./modular-sdk \
--with-boot-jdk=`/usr/libexec/java_home -v 11` \
--enable-cds=yes || exit $?
make clean CONF=macosx-x86_64-normal-server-fastdebug || exit $?
make images CONF=macosx-x86_64-normal-server-fastdebug || exit $?
JSDK=build/macosx-x86_64-normal-server-fastdebug/images/jdk-bundle
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-fastdebug-b${build_number}
BASE_DIR=jre
JBRSDK_BUNDLE=jbrsdk
rm -rf $BASE_DIR
mkdir $BASE_DIR || exit $?
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
cp -a $JSDK/jdk-$JBSDK_VERSION_WITH_DOTS.jdk $BASE_DIR/$JBRSDK_BUNDLE || exit $?
echo Creating $JBSDK.tar.gz ...
cp -a jcef_mac/Frameworks $BASE_DIR/$JBRSDK_BUNDLE/Contents/
cp -a jcef_mac/Helpers $BASE_DIR/$JBRSDK_BUNDLE/Contents
COPYFILE_DISABLE=1 \
tar -pczf ${JBSDK}.tar.gz -C ${BASE_DIR} \
--exclude='._*' --exclude='.DS_Store' --exclude='*~' \
--exclude='Home/demo' --exclude='Home/man' --exclude='Home/sample' \
${JBRSDK_BUNDLE} || exit $?
JBR_BUNDLE=jbr
JRE_CONTENTS=$BASE_DIR/$JBR_BUNDLE/Contents
JRE_HOME=$JRE_CONTENTS/Home
JBR_BASE_NAME=jbr-$JBSDK_VERSION
mkdir -p $JRE_CONTENTS
if [ -d "$JRE_HOME" ]; then
rm -rf $JRE_HOME
fi
JBR=${JBR_BASE_NAME}-osx-x64-fastdebug-b${build_number}
$BASE_DIR/$JBRSDK_BUNDLE/Contents/Home/bin/jlink \
--module-path $BASE_DIR/$JBRSDK_BUNDLE/Contents/Home/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list | sed s/" "//g) --output $JRE_HOME || exit $?
grep -v "^JAVA_VERSION" $BASE_DIR/$JBRSDK_BUNDLE/Contents/Home/release | grep -v "^MODULES" >> $JRE_HOME/release
cp -R $BASE_DIR/$JBRSDK_BUNDLE/Contents/MacOS $JRE_CONTENTS
cp $BASE_DIR/$JBRSDK_BUNDLE/Contents/Info.plist $JRE_CONTENTS
cp -a jcef_mac/Frameworks ${JRE_CONTENTS} || exit $?
cp -a jcef_mac/Helpers ${JRE_CONTENTS} || exit $?
echo Creating $JBR.tar.gz ...
COPYFILE_DISABLE=1 tar -pczf $JBR.tar.gz --exclude='*.dSYM' --exclude='man' -C $BASE_DIR $JBR_BUNDLE || exit $?

View File

@@ -26,7 +26,8 @@ log "Signing libraries and executables..."
# -perm +111 searches for executables
for f in \
"Contents/Home/bin" \
"Contents/Home/lib"; do
"Contents/Home/lib" \
"Contents/Frameworks"; do
if [ -d "$APP_DIRECTORY/$f" ]; then
find "$APP_DIRECTORY/$f" \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -perm +111 \) \

View File

@@ -37,14 +37,13 @@ BUILD_NAME="$(ls "$EXPLODED")"
if test -d $EXPLODED/$BUILD_NAME/Contents/Home/jmods; then
mv $EXPLODED/$BUILD_NAME/Contents/Home/jmods $BACKUP_JMODS
fi
if test -d $EXPLODED/$BUILD_NAME/Contents/Home/Frameworks; then
mv $EXPLODED/$BUILD_NAME/Contents/Home/Frameworks $BACKUP_JMODS
fi
if test -f $EXPLODED/$BUILD_NAME/Contents/MacOS/libjli.dylib; then
mv $EXPLODED/$BUILD_NAME/Contents/MacOS/libjli.dylib $BACKUP_JMODS
fi
if test -d $EXPLODED/$BUILD_NAME/Contents/Home/Frameworks; then
mv $EXPLODED/$BUILD_NAME/Contents/Home/Frameworks $BACKUP_JMODS
fi
#log "$INPUT_FILE unzipped and removed"
log "$INPUT_FILE extracted and removed"
APPLICATION_PATH="$EXPLODED/$BUILD_NAME"
@@ -128,15 +127,9 @@ log "Zipping $BUILD_NAME to $INPUT_FILE ..."
(
#cd "$EXPLODED"
#ditto -c -k --sequesterRsrc --keepParent "$BUILD_NAME" "../$INPUT_FILE"
if test ! -z $(ls $BACKUP_JMODS/libjli.dylib); then
mv $BACKUP_JMODS/libjli.dylib $EXPLODED/$BUILD_NAME/Contents/MacOS
fi
if test -d $BACKUP_JMODS/jmods; then
mv $BACKUP_JMODS/jmods $EXPLODED/$BUILD_NAME/Contents/Home
fi
if test -d $BACKUP_JMODS/Frameworks; then
mv $BACKUP_JMODS/Frameworks $EXPLODED/$BUILD_NAME/Contents/Home
fi
COPYFILE_DISABLE=1 tar -pczf $INPUT_FILE --exclude='*.dSYM' --exclude='man' -C $EXPLODED $BUILD_NAME
log "Finished zipping"

View File

@@ -0,0 +1,30 @@
diff --git modules.list modules.list
index 7c4b3e9cb6d..5ed60349ca7 100644
--- modules.list
+++ modules.list
@@ -53,4 +53,7 @@ jdk.security.jgss,
jdk.unsupported,
jdk.xml.dom,
jdk.zipfs,
-jdk.hotspot.agent
+jdk.hotspot.agent,
+jcef,
+gluegen.rt,
+jogl.all
diff --git src/java.desktop/share/classes/module-info.java src/java.desktop/share/classes/module-info.java
index b663b382f52..3e9acdc0c27 100644
--- src/java.desktop/share/classes/module-info.java
+++ src/java.desktop/share/classes/module-info.java
@@ -109,7 +109,11 @@ module java.desktop {
// see make/GensrcModuleInfo.gmk
exports sun.awt to
jdk.accessibility,
- jdk.unsupported.desktop;
+ jdk.unsupported.desktop,
+ jcef,
+ jogl.all;
+
+ exports java.awt.peer to jcef;
exports java.awt.dnd.peer to jdk.unsupported.desktop;
exports sun.awt.dnd to jdk.unsupported.desktop;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
From 095315ce3f66bcf14ae1d06d84bbeb24bb068ae8 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Wed, 14 Nov 2018 21:18:22 +0100
Subject: [PATCH 02/48] We need to set classRedefinitionCount on new class, not
old class.
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 83c0952de37..83cf0be090b 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1904,7 +1904,7 @@ void VM_EnhancedRedefineClasses::increment_class_counter(InstanceKlass *ik, TRAP
oop class_mirror = ik->java_mirror();
Klass* class_oop = java_lang_Class::as_Klass(class_mirror);
int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
- java_lang_Class::set_classRedefinedCount(class_mirror, new_count);
+ java_lang_Class::set_classRedefinedCount(ik->new_version()->java_mirror(), new_count);
if (class_oop != _the_class_oop) {
// _the_class_oop count is printed at end of redefine_single_class()
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,30 @@
From 9ddbbcdc73e653af7807ead68705c1c9267c9192 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Wed, 14 Nov 2018 21:22:01 +0100
Subject: [PATCH 03/48] Fix crashes in MetadataOnStackMark::~MetadataOnSta
MetadataOnStackMark shoukld not remove dcevm stuff. It was added
accidentaly in dcevm9,
and never was part of doit() in previous versions.
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 83cf0be090b..61af07d0f86 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -470,7 +470,9 @@ void VM_EnhancedRedefineClasses::doit() {
// Mark methods seen on stack and everywhere else so old methods are not
// cleaned up if they're on the stack.
- MetadataOnStackMark md_on_stack(true);
+
+ // FIXME: fails in enhanced redefinition
+ // MetadataOnStackMark md_on_stack(true);
HandleMark hm(thread); // make sure any handles created are deleted
// before the stack walk again.
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,25 @@
From bb3eb4931818c3ef43c48d0781d73b8e2eb6dea9 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Mon, 3 Dec 2018 19:34:53 +0100
Subject: [PATCH 04/48] Fix problem with nested members
Reported at : https://stackoverflow.com/questions/53370380/hotswapagent-incompatibleclasschangeerror-type-headerpanel1-is-not-a-nest-mem
---
src/hotspot/share/oops/instanceKlass.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 8a262bc3735..9b6ba7e9304 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -178,6 +178,7 @@ bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const {
}
Klass* k2 = _constants->klass_at(cp_index, CHECK_false);
+ k2 = k2->newest_version();
if (k2 == k) {
log_trace(class, nestmates)("- class is listed as a nest member");
return true;
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,26 @@
From 90746a0267b2de4063667f5423093115f814bf08 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Mon, 10 Dec 2018 20:12:07 +0100
Subject: [PATCH 05/48] Use init_mark_raw()
method changed since j8 - it used init_mark()
---
src/hotspot/share/gc/shared/space.inline.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/gc/shared/space.inline.hpp b/src/hotspot/share/gc/shared/space.inline.hpp
index 4394eff00c5..75d7e685edf 100644
--- a/src/hotspot/share/gc/shared/space.inline.hpp
+++ b/src/hotspot/share/gc/shared/space.inline.hpp
@@ -371,7 +371,7 @@ inline void CompactibleSpace::scan_and_compact(SpaceType* space, bool redefiniti
} else {
MarkSweep::update_fields(oop(cur_obj), oop(compaction_top));
}
- oop(compaction_top)->init_mark();
+ oop(compaction_top)->init_mark_raw();
assert(oop(compaction_top)->klass() != NULL, "should have a class");
debug_only(prev_obj = cur_obj);
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,25 @@
From 026346bfb72eaaae53e8998900d9f520da5ef74d Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Thu, 13 Dec 2018 20:51:09 +0100
Subject: [PATCH 06/48] Fix methodHandles
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 61af07d0f86..1c7595787a1 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -248,7 +248,7 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
if (MethodHandles::ref_kind_is_method(ref_kind)) {
Method* m = (Method*) java_lang_invoke_MemberName::vmtarget(obj);
- if (m != NULL && m->method_holder()->new_version() != NULL) {
+ if (m != NULL && m->method_holder()->is_redefining()) {
// Let's try to re-resolve method
InstanceKlass* newest = InstanceKlass::cast(m->method_holder()->newest_version());
Method* new_method = newest->find_method(m->name(), m->signature());
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,58 @@
From b99ebb71bce6119cd800d69848f84281f2fd2b16 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Sat, 15 Dec 2018 18:23:30 +0100
Subject: [PATCH 07/48] Fix field method
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 1c7595787a1..a3b65b273e5 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -264,21 +264,26 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
}
}
} else if (MethodHandles::ref_kind_is_field(ref_kind)) {
- Klass* k = (Klass*) java_lang_invoke_MemberName::vmtarget(obj);
+ oop clazz = java_lang_invoke_MemberName::clazz(obj);
+ if (clazz == NULL) {
+ return false;
+ }
+ Klass* k = java_lang_Class::as_Klass(clazz);
if (k == NULL) {
return false; // Was cleared before, this MemberName is invalid.
}
- if (k != NULL && k->new_version() != NULL) {
+ if (k->is_redefining()) {
// Let's try to re-resolve field
+ InstanceKlass* old = InstanceKlass::cast(k->old_version());
fieldDescriptor fd;
int offset = java_lang_invoke_MemberName::vmindex(obj);
bool is_static = MethodHandles::ref_kind_is_static(ref_kind);
- InstanceKlass* ik = InstanceKlass::cast(k);
- if (ik->find_local_field_from_offset(offset, is_static, &fd)) {
- InstanceKlass* newest = InstanceKlass::cast(k->newest_version());
+ InstanceKlass* ik_old = InstanceKlass::cast(old);
+ if (ik_old->find_local_field_from_offset(offset, is_static, &fd)) {
+ InstanceKlass* ik_new = InstanceKlass::cast(k->newest_version());
fieldDescriptor fd_new;
- if (newest->find_local_field(fd.name(), fd.signature(), &fd_new)) {
+ if (ik_new->find_local_field(fd.name(), fd.signature(), &fd_new)) {
Handle objHandle(Thread::current(), obj); // TODO : review thread
MethodHandles::init_field_MemberName(objHandle, fd_new, MethodHandles::ref_kind_is_setter(ref_kind));
} else {
@@ -288,7 +293,7 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
// Eventually, we probably want to replace them with something more meaningful,
// like instance throwing NoSuchFieldError or DMH that will resort to dynamic
// field resolution (with possibility of type conversion)
- java_lang_invoke_MemberName::set_method(obj, NULL);
+ java_lang_invoke_MemberName::set_clazz(obj, NULL);
java_lang_invoke_MemberName::set_vmindex(obj, 0);
return false;
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,43 @@
From dd57a1b40a83f7691c0fb9aa960f77c4428c0eec Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Sat, 15 Dec 2018 20:16:37 +0100
Subject: [PATCH 08/48] Fix nonstatic field handles
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index a3b65b273e5..c64d6bb1bb5 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -337,6 +337,7 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
if (obj == NULL) {
return;
}
+ bool oop_updated = false;
if (obj->is_instance() && InstanceKlass::cast(obj->klass())->is_mirror_instance_klass()) {
Klass* klass = java_lang_Class::as_Klass(obj);
if (klass != NULL && klass->is_instance_klass()) {
@@ -344,13 +345,17 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
if (klass->new_version() != NULL) {
obj = InstanceKlass::cast(klass->new_version())->java_mirror();
S::oop_store(p, obj);
+ oop_updated = true;
}
}
}
+
// JSR 292 support, uptade java.lang.invoke.MemberName instances
if (java_lang_invoke_MemberName::is_instance(obj)) {
- update_member_name(obj);
+ if (oop_updated) {
+ update_member_name(obj);
+ }
} else if (java_lang_invoke_DirectMethodHandle::is_instance(obj)) {
if (!update_direct_method_handle(obj)) {
// DMH is no longer valid, replace it with null reference.
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,488 @@
From 333c0c639e12296d05a547b015c948516c8c504e Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Wed, 12 Dec 2018 19:38:28 +0100
Subject: [PATCH 09/48] Support for Concurrent Mark Sweep (CMS) collector
---
.../share/gc/cms/compactibleFreeListSpace.cpp | 139 ++++++++++++------
.../share/gc/cms/compactibleFreeListSpace.hpp | 5 +-
.../gc/cms/concurrentMarkSweepThread.cpp | 10 +-
src/hotspot/share/gc/serial/markSweep.cpp | 2 +-
src/hotspot/share/gc/shared/gcConfig.cpp | 2 +-
src/hotspot/share/gc/shared/space.cpp | 16 +-
src/hotspot/share/gc/shared/space.hpp | 6 +-
src/hotspot/share/gc/shared/space.inline.hpp | 16 +-
.../prims/jvmtiEnhancedRedefineClasses.cpp | 12 +-
src/hotspot/share/runtime/arguments.cpp | 6 +-
10 files changed, 135 insertions(+), 79 deletions(-)
diff --git a/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp b/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp
index a93f764f1b9..efaa09473a9 100644
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.cpp
@@ -376,55 +376,58 @@ CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, M
_used_stable = 0;
}
+#define forward_compact_top_DEFN() \
+ assert(this == cp->space, "'this' should be current compaction space."); \
+ size_t compaction_max_size = pointer_delta(end(), compact_top); \
+ assert(adjustObjectSize(size) == cp->space->adjust_object_size_v(size), \
+ "virtual adjustObjectSize_v() method is not correct"); \
+ size_t adjusted_size = adjustObjectSize(size); \
+ assert(compaction_max_size >= MinChunkSize || compaction_max_size == 0, \
+ "no small fragments allowed"); \
+ assert(minimum_free_block_size() == MinChunkSize, \
+ "for de-virtualized reference below"); \
+ /* Can't leave a nonzero size, residual fragment smaller than MinChunkSize */ \
+ if (adjusted_size + MinChunkSize > compaction_max_size && \
+ adjusted_size != compaction_max_size) { \
+ do { \
+ /* switch to next compaction space*/ \
+ cp->space->set_compaction_top(compact_top); \
+ cp->space = cp->space->next_compaction_space(); \
+ if (cp->space == NULL) { \
+ cp->gen = CMSHeap::heap()->young_gen(); \
+ assert(cp->gen != NULL, "compaction must succeed"); \
+ cp->space = cp->gen->first_compaction_space(); \
+ assert(cp->space != NULL, "generation must have a first compaction space"); \
+ } \
+ compact_top = cp->space->bottom(); \
+ cp->space->set_compaction_top(compact_top); \
+ /* The correct adjusted_size may not be the same as that for this method */ \
+ /* (i.e., cp->space may no longer be "this" so adjust the size again. */ \
+ /* Use the virtual method which is not used above to save the virtual */ \
+ /* dispatch. */ \
+ adjusted_size = cp->space->adjust_object_size_v(size); \
+ compaction_max_size = pointer_delta(cp->space->end(), compact_top); \
+ assert(cp->space->minimum_free_block_size() == 0, "just checking"); \
+ } while (adjusted_size > compaction_max_size); \
+ }
+
+
HeapWord* CompactibleFreeListSpace::forward_compact_top(size_t size,
CompactPoint* cp, HeapWord* compact_top) {
- ShouldNotReachHere();
- return NULL;
+ forward_compact_top_DEFN()
+ return compact_top;
}
// Like CompactibleSpace forward() but always calls cross_threshold() to
// update the block offset table. Removed initialize_threshold call because
// CFLS does not use a block offset array for contiguous spaces.
HeapWord* CompactibleFreeListSpace::forward(oop q, size_t size,
- CompactPoint* cp, HeapWord* compact_top) {
- // q is alive
- // First check if we should switch compaction space
- assert(this == cp->space, "'this' should be current compaction space.");
- size_t compaction_max_size = pointer_delta(end(), compact_top);
- assert(adjustObjectSize(size) == cp->space->adjust_object_size_v(size),
- "virtual adjustObjectSize_v() method is not correct");
- size_t adjusted_size = adjustObjectSize(size);
- assert(compaction_max_size >= MinChunkSize || compaction_max_size == 0,
- "no small fragments allowed");
- assert(minimum_free_block_size() == MinChunkSize,
- "for de-virtualized reference below");
- // Can't leave a nonzero size, residual fragment smaller than MinChunkSize
- if (adjusted_size + MinChunkSize > compaction_max_size &&
- adjusted_size != compaction_max_size) {
- do {
- // switch to next compaction space
- cp->space->set_compaction_top(compact_top);
- cp->space = cp->space->next_compaction_space();
- if (cp->space == NULL) {
- cp->gen = CMSHeap::heap()->young_gen();
- assert(cp->gen != NULL, "compaction must succeed");
- cp->space = cp->gen->first_compaction_space();
- assert(cp->space != NULL, "generation must have a first compaction space");
- }
- compact_top = cp->space->bottom();
- cp->space->set_compaction_top(compact_top);
- // The correct adjusted_size may not be the same as that for this method
- // (i.e., cp->space may no longer be "this" so adjust the size again.
- // Use the virtual method which is not used above to save the virtual
- // dispatch.
- adjusted_size = cp->space->adjust_object_size_v(size);
- compaction_max_size = pointer_delta(cp->space->end(), compact_top);
- assert(cp->space->minimum_free_block_size() == 0, "just checking");
- } while (adjusted_size > compaction_max_size);
- }
+ CompactPoint* cp, HeapWord* compact_top, bool force_forward) {
+ forward_compact_top_DEFN()
// store the forwarding pointer into the mark word
- if ((HeapWord*)q != compact_top) {
+ // the size of object changed for: new_version() != NULL
+ if (force_forward || (HeapWord*)q != compact_top || q->klass()->new_version() != NULL) {
q->forward_to(oop(compact_top));
assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
} else {
@@ -2196,13 +2199,60 @@ CompactibleFreeListSpace::refillLinearAllocBlock(LinearAllocBlock* blk) {
// Support for compaction
void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) {
- scan_and_forward(this, cp, false);
- // of the free lists doesn't work after.
+ if (!Universe::is_redefining_gc_run()) {
+ scan_and_forward(this, cp, false);
+ } else {
+ // Redefinition run
+ scan_and_forward(this, cp, true);
+ }
// Prepare_for_compaction() uses the space between live objects
// so that later phase can skip dead space quickly. So verification
// of the free lists doesn't work after.
}
+bool CompactibleFreeListSpace::must_rescue(oop old_obj, oop new_obj) {
+ // Only redefined objects can have the need to be rescued.
+ if (oop(old_obj)->klass()->new_version() == NULL) return false;
+
+ int new_size = adjustObjectSize(old_obj->size_given_klass(oop(old_obj)->klass()->new_version()));
+ int original_size = adjustObjectSize(old_obj->size());
+
+ Generation* tenured_gen = CMSHeap::heap()->old_gen();
+ bool old_in_tenured = tenured_gen->is_in_reserved(old_obj);
+ bool new_in_tenured = tenured_gen->is_in_reserved(new_obj);
+ if (old_in_tenured == new_in_tenured) {
+ // Rescue if object may overlap with a higher memory address.
+ bool overlap = ((HeapWord*)old_obj + original_size < (HeapWord*)new_obj + new_size);
+ if (old_in_tenured) {
+ // Old and new address are in same space, so just compare the address.
+ // Must rescue if object moves towards the top of the space.
+ assert(space_index(old_obj) == space_index(new_obj), "old_obj and new_obj must be in same space");
+ } else {
+ // In the new generation, eden is located before the from space, so a
+ // simple pointer comparison is sufficient.
+ assert(CMSHeap::heap()->young_gen()->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration");
+ assert(CMSHeap::heap()->young_gen()->is_in_reserved(new_obj), "new_obj must be in DefNewGeneration");
+ assert(overlap == (space_index(old_obj) < space_index(new_obj)), "slow and fast computation must yield same result");
+ }
+ return overlap;
+
+ } else {
+ assert(space_index(old_obj) != space_index(new_obj), "old_obj and new_obj must be in different spaces");
+ if (new_in_tenured) {
+ // Must never rescue when moving from the new into the old generation.
+ assert(CMSHeap::heap()->young_gen()->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration");
+ assert(space_index(old_obj) > space_index(new_obj), "must be");
+ return false;
+
+ } else /* if (tenured_gen->is_in_reserved(old_obj)) */ {
+ // Must always rescue when moving from the old into the new generation.
+ assert(CMSHeap::heap()->young_gen()->is_in_reserved(new_obj), "new_obj must be in DefNewGeneration");
+ assert(space_index(old_obj) < space_index(new_obj), "must be");
+ return true;
+ }
+ }
+}
+
void CompactibleFreeListSpace::adjust_pointers() {
// In other versions of adjust_pointers(), a bail out
// based on the amount of live data in the generation
@@ -2215,7 +2265,12 @@ void CompactibleFreeListSpace::adjust_pointers() {
}
void CompactibleFreeListSpace::compact() {
- scan_and_compact(this, false);
+ if(!Universe::is_redefining_gc_run()) {
+ scan_and_compact(this, false);
+ } else {
+ // Redefinition run
+ scan_and_compact(this, true);
+ }
}
// Fragmentation metric = 1 - [sum of (fbs**2) / (sum of fbs)**2]
diff --git a/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp b/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp
index 9fd2ea58320..d29b81f6fca 100644
--- a/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp
+++ b/src/hotspot/share/gc/cms/compactibleFreeListSpace.hpp
@@ -201,7 +201,7 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// Support for compacting cms
HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
HeapWord* forward_compact_top(size_t size, CompactPoint* cp, HeapWord* compact_top);
- HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top);
+ HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top, bool force_forward);
// Initialization helpers.
void initializeIndexedFreeListArray();
@@ -576,6 +576,9 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// Support for compaction.
void prepare_for_compaction(CompactPoint* cp);
+
+ bool must_rescue(oop old_obj, oop new_obj);
+
void adjust_pointers();
void compact();
// Reset the space to reflect the fact that a compaction of the
diff --git a/src/hotspot/share/gc/cms/concurrentMarkSweepThread.cpp b/src/hotspot/share/gc/cms/concurrentMarkSweepThread.cpp
index 3ada5755875..b6e930922d7 100644
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepThread.cpp
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepThread.cpp
@@ -78,10 +78,12 @@ void ConcurrentMarkSweepThread::run_service() {
while (!should_terminate()) {
sleepBeforeNextCycle();
if (should_terminate()) break;
- GCIdMark gc_id_mark;
- GCCause::Cause cause = _collector->_full_gc_requested ?
- _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
- _collector->collect_in_background(cause);
+ if (!Universe::is_redefining_gc_run()) {
+ GCIdMark gc_id_mark;
+ GCCause::Cause cause = _collector->_full_gc_requested ?
+ _collector->_full_gc_cause : GCCause::_cms_concurrent_mark;
+ _collector->collect_in_background(cause);
+ }
}
// Check that the state of any protocol for synchronization
diff --git a/src/hotspot/share/gc/serial/markSweep.cpp b/src/hotspot/share/gc/serial/markSweep.cpp
index d0ff86c8215..b4ed59f020c 100644
--- a/src/hotspot/share/gc/serial/markSweep.cpp
+++ b/src/hotspot/share/gc/serial/markSweep.cpp
@@ -247,7 +247,7 @@ void MarkSweep::copy_rescued_objects_back() {
FREE_RESOURCE_ARRAY(HeapWord, rescued_ptr, size);
- new_obj->init_mark();
+ new_obj->init_mark_raw();
assert(oopDesc::is_oop(new_obj), "must be a valid oop");
}
_rescued_oops->clear();
diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp
index 8aac2b39e1e..39364a64cb2 100644
--- a/src/hotspot/share/gc/shared/gcConfig.cpp
+++ b/src/hotspot/share/gc/shared/gcConfig.cpp
@@ -101,7 +101,7 @@ void GCConfig::fail_if_unsupported_gc_is_selected() {
}
void GCConfig::select_gc_ergonomically() {
- if (AllowEnhancedClassRedefinition) {
+ if (AllowEnhancedClassRedefinition && !UseConcMarkSweepGC) {
// Enhanced class redefinition only supports serial GC at the moment
FLAG_SET_ERGO(bool, UseSerialGC, true);
} else if (os::is_server_class_machine()) {
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
index 763abc91a39..947dff8ae0c 100644
--- a/src/hotspot/share/gc/shared/space.cpp
+++ b/src/hotspot/share/gc/shared/space.cpp
@@ -388,11 +388,11 @@ HeapWord* CompactibleSpace::forward_compact_top(size_t size, CompactPoint* cp, H
}
HeapWord* CompactibleSpace::forward(oop q, size_t size,
- CompactPoint* cp, HeapWord* compact_top) {
+ CompactPoint* cp, HeapWord* compact_top, bool force_forward) {
compact_top = forward_compact_top(size, cp, compact_top);
// store the forwarding pointer into the mark word
- if ((HeapWord*)q != compact_top || (size_t)q->size() != size) {
+ if (force_forward || (HeapWord*)q != compact_top || (size_t)q->size() != size) {
q->forward_to(oop(compact_top));
assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
} else {
@@ -514,7 +514,7 @@ bool CompactibleSpace::must_rescue(oop old_obj, oop new_obj) {
} else {
assert(space_index(old_obj) != space_index(new_obj), "old_obj and new_obj must be in different spaces");
- if (tenured_gen->is_in_reserved(new_obj)) {
+ if (new_in_tenured) {
// Must never rescue when moving from the new into the old generation.
assert(GenCollectedHeap::heap()->young_gen()->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration");
assert(space_index(old_obj) > space_index(new_obj), "must be");
@@ -858,14 +858,14 @@ void OffsetTableContigSpace::verify() const {
// Compute the forward sizes and leave out objects whose position could
// possibly overlap other objects.
HeapWord* CompactibleSpace::forward_with_rescue(HeapWord* q, size_t size,
- CompactPoint* cp, HeapWord* compact_top) {
+ CompactPoint* cp, HeapWord* compact_top, bool force_forward) {
size_t forward_size = size;
// (DCEVM) There is a new version of the class of q => different size
if (oop(q)->klass()->new_version() != NULL && oop(q)->klass()->new_version()->update_information() != NULL) {
size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version());
- assert(size != new_size, "instances without changed size have to be updated prior to GC run");
+ // assert(size != new_size, "instances without changed size have to be updated prior to GC run");
forward_size = new_size;
}
@@ -879,7 +879,7 @@ HeapWord* CompactibleSpace::forward_with_rescue(HeapWord* q, size_t size,
return compact_top;
}
- return forward(oop(q), forward_size, cp, compact_top);
+ return forward(oop(q), forward_size, cp, compact_top, force_forward);
}
// Compute the forwarding addresses for the objects that need to be rescued.
@@ -895,11 +895,11 @@ HeapWord* CompactibleSpace::forward_rescued(CompactPoint* cp, HeapWord* compact_
// (DCEVM) There is a new version of the class of q => different size
if (oop(q)->klass()->new_version() != NULL) {
size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version());
- assert(size != new_size, "instances without changed size have to be updated prior to GC run");
+ // assert(size != new_size, "instances without changed size have to be updated prior to GC run");
size = new_size;
}
- compact_top = cp->space->forward(oop(q), size, cp, compact_top);
+ compact_top = cp->space->forward(oop(q), size, cp, compact_top, true);
assert(compact_top <= end(), "must not write over end of space!");
}
MarkSweep::_rescued_oops->clear();
diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp
index 8eb5669fb79..901c89d8a30 100644
--- a/src/hotspot/share/gc/shared/space.hpp
+++ b/src/hotspot/share/gc/shared/space.hpp
@@ -421,7 +421,7 @@ public:
virtual void prepare_for_compaction(CompactPoint* cp) = 0;
// MarkSweep support phase3
DEBUG_ONLY(int space_index(oop obj));
- bool must_rescue(oop old_obj, oop new_obj);
+ virtual bool must_rescue(oop old_obj, oop new_obj);
HeapWord* rescue(HeapWord* old_obj);
virtual void adjust_pointers();
// MarkSweep support phase4
@@ -452,11 +452,11 @@ public:
// function of the then-current compaction space, and updates "cp->threshold
// accordingly".
virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp,
- HeapWord* compact_top);
+ HeapWord* compact_top, bool force_forward);
// (DCEVM) same as forwad, but can rescue objects. Invoked only during
// redefinition runs
HeapWord* forward_with_rescue(HeapWord* q, size_t size, CompactPoint* cp,
- HeapWord* compact_top);
+ HeapWord* compact_top, bool force_forward);
HeapWord* forward_rescued(CompactPoint* cp, HeapWord* compact_top);
diff --git a/src/hotspot/share/gc/shared/space.inline.hpp b/src/hotspot/share/gc/shared/space.inline.hpp
index 75d7e685edf..26e56ae6f7e 100644
--- a/src/hotspot/share/gc/shared/space.inline.hpp
+++ b/src/hotspot/share/gc/shared/space.inline.hpp
@@ -163,6 +163,8 @@ inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* c
HeapWord* cur_obj = space->bottom();
HeapWord* scan_limit = space->scan_limit();
+ bool force_forward = false;
+
while (cur_obj < scan_limit) {
assert(!space->scanned_block_is_obj(cur_obj) ||
oop(cur_obj)->mark_raw()->is_marked() || oop(cur_obj)->mark_raw()->is_unlocked() ||
@@ -174,14 +176,15 @@ inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* c
size_t size = space->scanned_block_size(cur_obj);
if (redefinition_run) {
- compact_top = cp->space->forward_with_rescue(cur_obj, size, cp, compact_top);
+ compact_top = cp->space->forward_with_rescue(cur_obj, size, cp, compact_top, force_forward);
if (first_dead == NULL && oop(cur_obj)->is_gc_marked()) {
/* Was moved (otherwise, forward would reset mark),
set first_dead to here */
first_dead = cur_obj;
+ force_forward = true;
}
} else {
- compact_top = cp->space->forward(oop(cur_obj), size, cp, compact_top);
+ compact_top = cp->space->forward(oop(cur_obj), size, cp, compact_top, false);
}
cur_obj += size;
@@ -197,9 +200,9 @@ inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* c
// see if we might want to pretend this object is alive so that
// we don't have to compact quite as often.
- if (cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
+ if (!redefinition_run && cur_obj == compact_top && dead_spacer.insert_deadspace(cur_obj, end)) {
oop obj = oop(cur_obj);
- compact_top = cp->space->forward(obj, obj->size(), cp, compact_top);
+ compact_top = cp->space->forward(obj, obj->size(), cp, compact_top, force_forward);
end_of_live = end;
} else {
// otherwise, it really is a free region.
@@ -351,7 +354,7 @@ inline void CompactibleSpace::scan_and_compact(SpaceType* space, bool redefiniti
HeapWord* compaction_top = (HeapWord*)oop(cur_obj)->forwardee();
if (redefinition_run && space->must_rescue(oop(cur_obj), oop(cur_obj)->forwardee())) {
- space->rescue(cur_obj);
+ space->rescue(cur_obj);
debug_only(Copy::fill_to_words(cur_obj, size, 0));
cur_obj += size;
continue;
@@ -361,8 +364,7 @@ inline void CompactibleSpace::scan_and_compact(SpaceType* space, bool redefiniti
Prefetch::write(compaction_top, copy_interval);
// copy object and reinit its mark
- assert(cur_obj != compaction_top || oop(cur_obj)->klass()->new_version() != NULL,
- "everything in this pass should be moving");
+ assert(redefinition_run || cur_obj != compaction_top, "everything in this pass should be moving");
if (redefinition_run && oop(cur_obj)->klass()->new_version() != NULL) {
Klass* new_version = oop(cur_obj)->klass()->new_version();
if (new_version->update_information() == NULL) {
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index c64d6bb1bb5..9b8678a53fb 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -52,6 +52,7 @@
#include "prims/jvmtiThreadState.inline.hpp"
#include "utilities/events.hpp"
#include "oops/constantPool.inline.hpp"
+#include "gc/cms/cmsHeap.hpp"
Array<Method*>* VM_EnhancedRedefineClasses::_old_methods = NULL;
Array<Method*>* VM_EnhancedRedefineClasses::_new_methods = NULL;
@@ -420,13 +421,11 @@ public:
Klass* new_klass = obj->klass()->new_version();
if (new_klass->update_information() != NULL) {
- int size_diff = obj->size() - obj->size_given_klass(new_klass);
-
- // Either new size is bigger or gap is to small to be filled
- if (size_diff < 0 || (size_diff > 0 && (size_t) size_diff < CollectedHeap::min_fill_size())) {
+ if (obj->size() - obj->size_given_klass(new_klass) != 0) {
// We need an instance update => set back to old klass
_needs_instance_update = true;
} else {
+ // Either new size is bigger or gap is to small to be filled
oop src = obj;
if (new_klass->is_copying_backwards()) {
copy_to_tmp(obj);
@@ -436,11 +435,6 @@ public:
// FIXME: instance updates...
//guarantee(false, "instance updates!");
MarkSweep::update_fields(obj, src, new_klass->update_information());
-
- if (size_diff > 0) {
- HeapWord* dead_space = ((HeapWord *)obj) + obj->size();
- CollectedHeap::fill_with_object(dead_space, size_diff);
- }
}
} else {
obj->set_klass(obj->klass()->new_version());
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index ca57b524593..2ca6dde069d 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -2047,14 +2047,14 @@ bool Arguments::check_gc_consistency() {
if (AllowEnhancedClassRedefinition) {
// Must use serial GC. This limitation applies because the instance size changing GC modifications
// are only built into the mark and compact algorithm.
- if (!UseSerialGC && i >= 1) {
+ if ((!UseSerialGC && !UseConcMarkSweepGC) && i >= 1) {
jio_fprintf(defaultStream::error_stream(),
- "Must use the serial GC with enhanced class redefinition\n");
+ "Must use the serial or concurrent mark sweep GC with enhanced class redefinition.\n");
return false;
}
}
- if (i > 1) {
+ if (i > 2) {
jio_fprintf(defaultStream::error_stream(),
"Conflicting collector combinations in option list; "
"please refer to the release notes for the combinations "
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,257 @@
From b9ceda6f7c230750a87e8a686d833ce853d84712 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Sat, 29 Dec 2018 13:22:29 +0100
Subject: [PATCH 10/48] Code cleanup
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 125 ++++++------------
.../prims/jvmtiEnhancedRedefineClasses.hpp | 3 -
2 files changed, 40 insertions(+), 88 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 9b8678a53fb..0aa1ac4ff80 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -35,7 +35,7 @@
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "memory/iterator.inline.hpp"
-#include "gc/serial/markSweep.hpp" // FIXME: other GC?
+#include "gc/serial/markSweep.hpp"
#include "oops/fieldStreams.hpp"
#include "oops/klassVtable.hpp"
#include "oops/oop.inline.hpp"
@@ -485,7 +485,9 @@ void VM_EnhancedRedefineClasses::doit() {
}
// Deoptimize all compiled code that depends on this class (do only once, because it clears whole cache)
- flush_dependent_code(NULL, thread);
+ //if (_max_redefinition_flags > Klass::ModifyClass) {
+ flush_dependent_code(NULL, thread);
+ //}
// JSR-292 support
if (_any_class_has_resolved_methods) {
@@ -593,17 +595,28 @@ void VM_EnhancedRedefineClasses::doit() {
// See jvmtiExport.hpp for detailed explanation.
JvmtiExport::set_has_redefined_a_class();
- // check_class() is optionally called for product bits, but is
- // always called for non-product bits.
#ifdef PRODUCT
if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
#endif
- log_trace(redefine, class, obsolete, metadata)("calling check_class");
- CheckClass check_class(thread);
- ClassLoaderDataGraph::classes_do(&check_class);
+ for (int i=0; i<_affected_klasses->length(); i++) {
+ Klass* the_class = _affected_klasses->at(i);
+ assert(the_class->new_version() != NULL, "Must have been redefined");
+ Klass* new_version = the_class->new_version();
+ assert(new_version->new_version() == NULL, "Must be newest version");
+
+ if (!(new_version->super() == NULL || new_version->super()->new_version() == NULL)) {
+ new_version->print();
+ new_version->super()->print();
+ }
+ assert(new_version->super() == NULL || new_version->super()->new_version() == NULL, "Super class must be newest version");
+ }
+ log_trace(redefine, class, obsolete, metadata)("calling check_class");
+ CheckClass check_class(thread);
+ ClassLoaderDataGraph::classes_do(&check_class);
#ifdef PRODUCT
}
#endif
+
}
/**
@@ -1279,24 +1292,23 @@ void VM_EnhancedRedefineClasses::calculate_instance_update_information(Klass* ne
GrowableArray<int> result = cl.finish();
ik->store_update_information(result);
ik->set_copying_backwards(cl.does_copy_backwards());
-/* TODO logging
- if (RC_TRACE_ENABLED(0x00000001)) {
- RC_TRACE(0x00000001, ("Instance update information for %s:", new_version->name()->as_C_string()));
+ if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
+ log_trace(redefine, class, obsolete, metadata)("Instance update information for %s:", new_version->name()->as_C_string());
if (cl.does_copy_backwards()) {
- RC_TRACE(0x00000001, ("\tDoes copy backwards!"));
+ log_trace(redefine, class, obsolete, metadata)("\tDoes copy backwards!");
}
for (int i=0; i<result.length(); i++) {
int curNum = result.at(i);
if (curNum < 0) {
- RC_TRACE(0x00000001, ("\t%d CLEAN", curNum));
+ log_trace(redefine, class, obsolete, metadata)("\t%d CLEAN", curNum);
} else if (curNum > 0) {
- RC_TRACE(0x00000001, ("\t%d COPY from %d", curNum, result.at(i + 1)));
+ log_trace(redefine, class, obsolete, metadata)("\t%d COPY from %d", curNum, result.at(i + 1));
i++;
} else {
- RC_TRACE(0x00000001, ("\tEND"));
+ log_trace(redefine, class, obsolete, metadata)("\tEND");
}
}
- }*/
+ }
}
/**
@@ -1813,6 +1825,7 @@ void VM_EnhancedRedefineClasses::compute_added_deleted_matching_methods() {
/**
FIXME - swap_annotations is never called, check that annotations work
*/
+// TODO : delete it
void VM_EnhancedRedefineClasses::swap_annotations(InstanceKlass* the_class,
InstanceKlass* new_class) {
// FIXME - probably original implementation only
@@ -1822,7 +1835,6 @@ void VM_EnhancedRedefineClasses::swap_annotations(InstanceKlass* the_class,
new_class->set_annotations(old_annotations);
}
-
// Install the redefinition of a class:
// - house keeping (flushing breakpoints and caches, deoptimizing
// dependent compiled code)
@@ -1853,7 +1865,9 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
// DCEVM Deoptimization is always for whole java world, call only once after all classes are redefined
// Deoptimize all compiled code that depends on this class
- // flush_dependent_code(the_class, THREAD);
+ //if (_max_redefinition_flags <= Klass::ModifyClass) {
+ //flush_dependent_code(the_class, THREAD);
+ //}
_old_methods = the_class->methods();
_new_methods = new_class->methods();
@@ -1928,64 +1942,15 @@ void VM_EnhancedRedefineClasses::increment_class_counter(InstanceKlass *ik, TRAP
}
}
-// FIXME - class check is currently disabled
void VM_EnhancedRedefineClasses::CheckClass::do_klass(Klass* k) {
- return;
- bool no_old_methods = true; // be optimistic
-
- // Both array and instance classes have vtables.
- // a vtable should never contain old or obsolete methods
- ResourceMark rm(_thread);
- if (k->vtable_length() > 0 &&
- !k->vtable().check_no_old_or_obsolete_entries()) {
- if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
- log_trace(redefine, class, obsolete, metadata)
- ("klassVtable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
- k->signature_name());
- k->vtable().dump_vtable();
- }
- no_old_methods = false;
- }
-
- if (k->is_instance_klass()) {
- HandleMark hm(_thread);
- InstanceKlass *ik = InstanceKlass::cast(k);
+ HandleMark hm(_thread);
+ InstanceKlass *ik = (InstanceKlass *) k;
+ assert(ik->new_version() == NULL, "must be latest version in system dictionary");
- // an itable should never contain old or obsolete methods
- if (ik->itable_length() > 0 &&
- !ik->itable().check_no_old_or_obsolete_entries()) {
- if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
- log_trace(redefine, class, obsolete, metadata)
- ("klassItable::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
- ik->signature_name());
- ik->itable().dump_itable();
- }
- no_old_methods = false;
- }
-
- // the constant pool cache should never contain non-deleted old or obsolete methods
- if (ik->constants() != NULL &&
- ik->constants()->cache() != NULL &&
- !ik->constants()->cache()->check_no_old_or_obsolete_entries()) {
- if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
- log_trace(redefine, class, obsolete, metadata)
- ("cp-cache::check_no_old_or_obsolete_entries failure -- OLD or OBSOLETE method found -- class: %s",
- ik->signature_name());
- ik->constants()->cache()->dump_cache();
- }
- no_old_methods = false;
- }
- }
-
- // print and fail guarantee if old methods are found.
- if (!no_old_methods) {
- if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
- dump_methods();
- } else {
- log_trace(redefine, class)("Use the '-Xlog:redefine+class*:' option "
- "to see more info about the following guarantee() failure.");
- }
- guarantee(false, "OLD and/or OBSOLETE method(s) found");
+ if (ik->vtable_length() > 0) {
+ ResourceMark rm(_thread);
+ assert(ik->vtable().check_no_old_or_obsolete_entries(), "old method found");
+ ik->vtable().verify(tty, true);
}
}
@@ -2051,15 +2016,6 @@ void VM_EnhancedRedefineClasses::dump_methods() {
}
}
-// TODO - is it called anywhere?
-void VM_EnhancedRedefineClasses::print_on_error(outputStream* st) const {
- VM_Operation::print_on_error(st);
- if (_the_class_oop != NULL) {
- ResourceMark rm;
- st->print_cr(", redefining class %s", _the_class_oop->external_name());
- }
-}
-
/**
Helper class to traverse all loaded classes and figure out if the class is affected by redefinition.
*/
@@ -2093,7 +2049,7 @@ class AffectedKlassClosure : public KlassClosure {
log_trace(redefine, class, load)("found affected class: %s", klass->name()->as_C_string());
klass->set_redefinition_flag(Klass::MarkedAsAffected);
_affected_klasses->append(klass);
- return;
+ return;
}
}
@@ -2125,7 +2081,7 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
// Find classes not directly redefined, but affected by a redefinition (because one of its supertypes is redefined)
AffectedKlassClosure closure(_affected_klasses);
- // TODO: j10 - review chancge from SystemDictionary::classes_do(&closure);
+ // Updated in j10, from original SystemDictionary::classes_do
ClassLoaderDataGraph::dictionary_classes_do(&closure);
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());
@@ -2160,7 +2116,6 @@ static bool match_second(void* value, KlassPair elem) {
For each class to be redefined parse the bytecode and figure out the superclass and all interfaces.
First newly introduced classes (_class_defs) are scanned and then affected classed (_affected_klasses).
Affected flag is cleared (clear_redefinition_flag(Klass::MarkedAsAffected))
-
For each dependency create a KlassPair instance. Finnaly, affected classes (_affected_klasses) are sorted according to pairs.
TODO - the class file is potentionally parsed multiple times - introduce a cache?
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index b712d69a193..37e63a1810f 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -195,8 +195,5 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
// Modifiable test must be shared between IsModifiableClass query
// and redefine implementation
static bool is_modifiable_class(oop klass_mirror);
-
- // Error printing
- void print_on_error(outputStream* st) const;
};
#endif // SHARE_VM_PRIMS_JVMTIREDEFINECLASSES2_HPP
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,118 @@
From 1d147a5db94b531fa027d5e13e4dd5cbaef62952 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Sat, 29 Dec 2018 16:05:25 +0100
Subject: [PATCH 11/48] Fix check_class
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 39 +++++++------------
.../prims/jvmtiEnhancedRedefineClasses.hpp | 5 +--
2 files changed, 16 insertions(+), 28 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 0aa1ac4ff80..c08b3e82b2e 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1,4 +1,4 @@
-/*
+ /*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -28,6 +28,7 @@
#include "classfile/metadataOnStackMark.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/verifier.hpp"
+#include "classfile/dictionary.hpp"
#include "interpreter/oopMapCache.hpp"
#include "interpreter/rewriter.hpp"
#include "logging/logStream.hpp"
@@ -611,8 +612,7 @@ void VM_EnhancedRedefineClasses::doit() {
assert(new_version->super() == NULL || new_version->super()->new_version() == NULL, "Super class must be newest version");
}
log_trace(redefine, class, obsolete, metadata)("calling check_class");
- CheckClass check_class(thread);
- ClassLoaderDataGraph::classes_do(&check_class);
+ ClassLoaderData::the_null_class_loader_data()->dictionary()->classes_do(check_class, thread);
#ifdef PRODUCT
}
#endif
@@ -1822,19 +1822,6 @@ void VM_EnhancedRedefineClasses::compute_added_deleted_matching_methods() {
assert(_matching_methods_length + _added_methods_length == _new_methods->length(), "sanity");
}
-/**
- FIXME - swap_annotations is never called, check that annotations work
-*/
-// TODO : delete it
-void VM_EnhancedRedefineClasses::swap_annotations(InstanceKlass* the_class,
- InstanceKlass* new_class) {
- // FIXME - probably original implementation only
- // Swap annotation fields values
- Annotations* old_annotations = the_class->annotations();
- the_class->set_annotations(new_class->annotations());
- new_class->set_annotations(old_annotations);
-}
-
// Install the redefinition of a class:
// - house keeping (flushing breakpoints and caches, deoptimizing
// dependent compiled code)
@@ -1942,15 +1929,17 @@ void VM_EnhancedRedefineClasses::increment_class_counter(InstanceKlass *ik, TRAP
}
}
-void VM_EnhancedRedefineClasses::CheckClass::do_klass(Klass* k) {
- HandleMark hm(_thread);
- InstanceKlass *ik = (InstanceKlass *) k;
- assert(ik->new_version() == NULL, "must be latest version in system dictionary");
+void VM_EnhancedRedefineClasses::check_class(InstanceKlass* ik, TRAPS) {
+ if (ik->is_instance_klass() && ik->old_version() != NULL) {
+ HandleMark hm(THREAD);
+
+ assert(ik->new_version() == NULL, "must be latest version in system dictionary");
- if (ik->vtable_length() > 0) {
- ResourceMark rm(_thread);
- assert(ik->vtable().check_no_old_or_obsolete_entries(), "old method found");
- ik->vtable().verify(tty, true);
+ if (ik->vtable_length() > 0) {
+ ResourceMark rm(THREAD);
+ assert(ik->vtable().check_no_old_or_obsolete_entries(), "old method found");
+ ik->vtable().verify(tty, true);
+ }
}
}
@@ -2017,7 +2006,7 @@ void VM_EnhancedRedefineClasses::dump_methods() {
}
/**
- Helper class to traverse all loaded classes and figure out if the class is affected by redefinition.
+ Helper class to traverse all loaded classes and figure out if the class is affected by redefinition.
*/
class AffectedKlassClosure : public KlassClosure {
private:
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 37e63a1810f..5b3ebc13661 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -144,15 +144,14 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
// Install the redefinition of a class
void redefine_single_class(InstanceKlass* new_class_oop, TRAPS);
- void swap_annotations(InstanceKlass* new_class,
- InstanceKlass* scratch_class);
-
// Increment the classRedefinedCount field in the specific InstanceKlass
// and in all direct and indirect subclasses.
void increment_class_counter(InstanceKlass *ik, TRAPS);
void flush_dependent_code(InstanceKlass* k_h, TRAPS);
+ static void check_class(InstanceKlass* k_oop, TRAPS);
+
static void dump_methods();
// Check that there are no old or obsolete methods
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,24 @@
From 84777c09ddbbbbd6a90de5b1f17a4101c8f076b8 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Sat, 29 Dec 2018 17:58:39 +0100
Subject: [PATCH 12/48] Fix force_forward in dead space
---
src/hotspot/share/gc/shared/space.inline.hpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/hotspot/share/gc/shared/space.inline.hpp b/src/hotspot/share/gc/shared/space.inline.hpp
index 26e56ae6f7e..8c255d6d428 100644
--- a/src/hotspot/share/gc/shared/space.inline.hpp
+++ b/src/hotspot/share/gc/shared/space.inline.hpp
@@ -213,6 +213,7 @@ inline void CompactibleSpace::scan_and_forward(SpaceType* space, CompactPoint* c
// see if this is the first dead region.
if (first_dead == NULL) {
first_dead = cur_obj;
+ force_forward = true;
}
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,25 @@
From 4d973861fbcd13dc50bd603f731c75d2013034c6 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Fri, 1 Mar 2019 18:45:13 +0100
Subject: [PATCH 13/48] Cleanup
---
src/hotspot/share/gc/shared/space.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
index 947dff8ae0c..56b144b46f1 100644
--- a/src/hotspot/share/gc/shared/space.cpp
+++ b/src/hotspot/share/gc/shared/space.cpp
@@ -862,7 +862,7 @@ HeapWord* CompactibleSpace::forward_with_rescue(HeapWord* q, size_t size,
size_t forward_size = size;
// (DCEVM) There is a new version of the class of q => different size
- if (oop(q)->klass()->new_version() != NULL && oop(q)->klass()->new_version()->update_information() != NULL) {
+ if (oop(q)->klass()->new_version() != NULL) {
size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version());
// assert(size != new_size, "instances without changed size have to be updated prior to GC run");
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,61 @@
From 5f31460556d86fa0233e7998112a65483034fd45 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Sat, 29 Dec 2018 17:38:27 +0100
Subject: [PATCH 14/48] Add codecache flush optimization, but just flush all
cache.
Redefined class can define a new method that overrides
method in superclass which is already used in codecache for
optimized non-virtual calls, etc...
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index c08b3e82b2e..4ca638548dc 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -486,9 +486,9 @@ void VM_EnhancedRedefineClasses::doit() {
}
// Deoptimize all compiled code that depends on this class (do only once, because it clears whole cache)
- //if (_max_redefinition_flags > Klass::ModifyClass) {
+ // if (_max_redefinition_flags > Klass::ModifyClass) {
flush_dependent_code(NULL, thread);
- //}
+ // }
// JSR-292 support
if (_any_class_has_resolved_methods) {
@@ -1736,8 +1736,14 @@ void VM_EnhancedRedefineClasses::flush_dependent_code(InstanceKlass* k_h, TRAPS)
// All dependencies have been recorded from startup or this is a second or
// subsequent use of RedefineClasses
// FIXME: for now, deoptimize all!
- if (0 && JvmtiExport::all_dependencies_are_recorded()) {
+ if (0 && k_h != NULL && JvmtiExport::all_dependencies_are_recorded()) {
CodeCache::flush_evol_dependents_on(k_h);
+ Klass* superCl = k_h->super();
+ // Deoptimize super classes since redefined class can has a new method override
+ while (superCl != NULL && !superCl->is_redefining()) {
+ CodeCache::flush_evol_dependents_on(InstanceKlass::cast(superCl));
+ superCl = superCl->super();
+ }
} else {
CodeCache::mark_all_nmethods_for_deoptimization();
@@ -1852,9 +1858,9 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
// DCEVM Deoptimization is always for whole java world, call only once after all classes are redefined
// Deoptimize all compiled code that depends on this class
- //if (_max_redefinition_flags <= Klass::ModifyClass) {
- //flush_dependent_code(the_class, THREAD);
- //}
+// if (_max_redefinition_flags <= Klass::ModifyClass) {
+// flush_dependent_code(the_class, THREAD);
+// }
_old_methods = the_class->methods();
_new_methods = new_class->methods();
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,484 @@
From d457702275bc47f3f9ea416dc794be403bc6eb94 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Wed, 14 Nov 2018 21:20:08 +0100
Subject: [PATCH 15/48] HotswapAgent integration
It include:
- option to compile DCEVM only version with -DDCEVM_ONLY added
to CFLAGS (bash configure --with-extra-cflags="-DDCEVM_ONLY"), by
default compilation goes with HotswapAgent
Add --add-opens for necessary modules/packages
- java.base/java.lang - for reflection access to Proxy.proxyCache
- java.base/jdk.internal.loader - for access proxyCache class
- java.desktop/java.beans - for reflection access to Introspector
- be quiet if HotswapAgent is not found in lib/, it is compatible with
old DCEVM
- disable hotswapagent for -Xshare:dump
- disable HotswapAgent in jvm tools
---
make/launcher/Launcher-java.rmi.gmk | 2 +
make/launcher/Launcher-java.scripting.gmk | 3 +-
make/launcher/Launcher-java.security.jgss.gmk | 3 +
make/launcher/Launcher-jdk.aot.gmk | 2 +
make/launcher/Launcher-jdk.compiler.gmk | 5 +-
make/launcher/Launcher-jdk.hotspot.agent.gmk | 1 +
make/launcher/Launcher-jdk.jartool.gmk | 2 +
make/launcher/Launcher-jdk.javadoc.gmk | 3 +-
make/launcher/Launcher-jdk.jcmd.gmk | 13 +++-
make/launcher/Launcher-jdk.jconsole.gmk | 3 +-
make/launcher/Launcher-jdk.jdeps.gmk | 3 +
make/launcher/Launcher-jdk.jdi.gmk | 1 +
make/launcher/Launcher-jdk.jlink.gmk | 5 +-
make/launcher/Launcher-jdk.jshell.gmk | 1 +
make/launcher/Launcher-jdk.jstatd.gmk | 1 +
make/launcher/Launcher-jdk.pack.gmk | 1 +
make/launcher/Launcher-jdk.rmic.gmk | 1 +
.../Launcher-jdk.scripting.nashorn.shell.gmk | 3 +-
src/hotspot/share/runtime/arguments.cpp | 59 +++++++++++++++++++
src/hotspot/share/runtime/arguments.hpp | 3 +
src/hotspot/share/runtime/globals.hpp | 12 +++-
21 files changed, 117 insertions(+), 10 deletions(-)
diff --git a/make/launcher/Launcher-java.rmi.gmk b/make/launcher/Launcher-java.rmi.gmk
index a69a90bcc81..07046232275 100644
--- a/make/launcher/Launcher-java.rmi.gmk
+++ b/make/launcher/Launcher-java.rmi.gmk
@@ -27,8 +27,10 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, rmid, \
MAIN_CLASS := sun.rmi.server.Activation, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, rmiregistry, \
MAIN_CLASS := sun.rmi.registry.RegistryImpl, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
diff --git a/make/launcher/Launcher-java.scripting.gmk b/make/launcher/Launcher-java.scripting.gmk
index 057d2bf3aca..cf100e20789 100644
--- a/make/launcher/Launcher-java.scripting.gmk
+++ b/make/launcher/Launcher-java.scripting.gmk
@@ -27,5 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jrunscript, \
MAIN_CLASS := com.sun.tools.script.shell.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT \
+ -XX:+DisableHotswapAgent, \
))
diff --git a/make/launcher/Launcher-java.security.jgss.gmk b/make/launcher/Launcher-java.security.jgss.gmk
index 7411e1a21c4..2b856bfccb4 100644
--- a/make/launcher/Launcher-java.security.jgss.gmk
+++ b/make/launcher/Launcher-java.security.jgss.gmk
@@ -28,13 +28,16 @@ include LauncherCommon.gmk
ifeq ($(OPENJDK_TARGET_OS), windows)
$(eval $(call SetupBuildLauncher, kinit, \
MAIN_CLASS := sun.security.krb5.internal.tools.Kinit, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, klist, \
MAIN_CLASS := sun.security.krb5.internal.tools.Klist, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, ktab, \
MAIN_CLASS := sun.security.krb5.internal.tools.Ktab, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
endif
diff --git a/make/launcher/Launcher-jdk.aot.gmk b/make/launcher/Launcher-jdk.aot.gmk
index 10717a5e1c5..2c52c31a555 100644
--- a/make/launcher/Launcher-jdk.aot.gmk
+++ b/make/launcher/Launcher-jdk.aot.gmk
@@ -31,6 +31,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jaotc, \
MAIN_CLASS := jdk.tools.jaotc.Main, \
EXTRA_JAVA_ARGS := -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI \
+ -XX:+DisableHotswapAgent \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.aarch64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.amd64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.code=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
@@ -40,6 +41,7 @@ $(eval $(call SetupBuildLauncher, jaotc, \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
, \
JAVA_ARGS := --add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.aarch64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
+ -XX:+DisableHotswapAgent \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.amd64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.aarch64=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
--add-exports=jdk.internal.vm.ci/jdk.vm.ci.hotspot.sparc=$(call CommaList, jdk.internal.vm.compiler jdk.aot) \
diff --git a/make/launcher/Launcher-jdk.compiler.gmk b/make/launcher/Launcher-jdk.compiler.gmk
index f71c37adf74..744969546de 100644
--- a/make/launcher/Launcher-jdk.compiler.gmk
+++ b/make/launcher/Launcher-jdk.compiler.gmk
@@ -27,12 +27,14 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javac, \
MAIN_CLASS := com.sun.tools.javac.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT \
+ -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
$(eval $(call SetupBuildLauncher, serialver, \
MAIN_CLASS := sun.tools.serialver.SerialVer, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
@@ -41,6 +43,7 @@ ifeq ($(ENABLE_SJAVAC), yes)
# into any real images
$(eval $(call SetupBuildLauncher, sjavac, \
MAIN_CLASS := com.sun.tools.sjavac.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
OUTPUT_DIR := $(JDK_OUTPUTDIR)/bin, \
))
diff --git a/make/launcher/Launcher-jdk.hotspot.agent.gmk b/make/launcher/Launcher-jdk.hotspot.agent.gmk
index 76da3600368..9f12b05b172 100644
--- a/make/launcher/Launcher-jdk.hotspot.agent.gmk
+++ b/make/launcher/Launcher-jdk.hotspot.agent.gmk
@@ -27,5 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jhsdb, \
MAIN_CLASS := sun.jvm.hotspot.SALauncher, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
MACOSX_PRIVILEGED := true, \
))
diff --git a/make/launcher/Launcher-jdk.jartool.gmk b/make/launcher/Launcher-jdk.jartool.gmk
index f74e82bfdae..647d82b65b1 100644
--- a/make/launcher/Launcher-jdk.jartool.gmk
+++ b/make/launcher/Launcher-jdk.jartool.gmk
@@ -27,8 +27,10 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jar, \
MAIN_CLASS := sun.tools.jar.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, jarsigner, \
MAIN_CLASS := sun.security.tools.jarsigner.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
diff --git a/make/launcher/Launcher-jdk.javadoc.gmk b/make/launcher/Launcher-jdk.javadoc.gmk
index 889028a2b17..c3d2093be04 100644
--- a/make/launcher/Launcher-jdk.javadoc.gmk
+++ b/make/launcher/Launcher-jdk.javadoc.gmk
@@ -27,6 +27,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javadoc, \
MAIN_CLASS := jdk.javadoc.internal.tool.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT \
+ -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.jcmd.gmk b/make/launcher/Launcher-jdk.jcmd.gmk
index 7117fa78059..761a52d8466 100644
--- a/make/launcher/Launcher-jdk.jcmd.gmk
+++ b/make/launcher/Launcher-jdk.jcmd.gmk
@@ -30,6 +30,7 @@ $(eval $(call SetupBuildLauncher, jinfo, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
-Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
+ -XX:+DisableHotswapAgent, \
MACOSX_PRIVILEGED := true, \
))
@@ -37,28 +38,36 @@ $(eval $(call SetupBuildLauncher, jmap, \
MAIN_CLASS := sun.tools.jmap.JMap, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
- -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
+ -Dsun.jvm.hotspot.debugger.useWindbgDebugger \
+ -XX:+DisableHotswapAgent, \
MACOSX_PRIVILEGED := true, \
))
$(eval $(call SetupBuildLauncher, jps, \
MAIN_CLASS := sun.tools.jps.Jps, \
+ JAVA_ARGS := \
+ -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, jstack, \
MAIN_CLASS := sun.tools.jstack.JStack, \
JAVA_ARGS := \
-Dsun.jvm.hotspot.debugger.useProcDebugger \
- -Dsun.jvm.hotspot.debugger.useWindbgDebugger, \
+ -Dsun.jvm.hotspot.debugger.useWindbgDebugger \
+ -XX:+DisableHotswapAgent, \
MACOSX_PRIVILEGED := true, \
))
$(eval $(call SetupBuildLauncher, jstat, \
MAIN_CLASS := sun.tools.jstat.Jstat, \
+ JAVA_ARGS := \
+ -XX:+DisableHotswapAgent, \
))
$(eval $(call SetupBuildLauncher, jcmd, \
MAIN_CLASS := sun.tools.jcmd.JCmd, \
+ JAVA_ARGS := \
+ -XX:+DisableHotswapAgent, \
))
# Hook to include the corresponding custom file, if present.
diff --git a/make/launcher/Launcher-jdk.jconsole.gmk b/make/launcher/Launcher-jdk.jconsole.gmk
index 6205ae63d16..5ca6a0c123b 100644
--- a/make/launcher/Launcher-jdk.jconsole.gmk
+++ b/make/launcher/Launcher-jdk.jconsole.gmk
@@ -28,7 +28,8 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jconsole, \
MAIN_CLASS := sun.tools.jconsole.JConsole, \
JAVA_ARGS := --add-opens java.base/java.io=jdk.jconsole \
- -Djconsole.showOutputViewer, \
+ -Djconsole.showOutputViewer \
+ -XX:+DisableHotswapAgent, \
CFLAGS_windows := -DJAVAW, \
LIBS_windows := user32.lib, \
))
diff --git a/make/launcher/Launcher-jdk.jdeps.gmk b/make/launcher/Launcher-jdk.jdeps.gmk
index 217523c48cc..5448278dae7 100644
--- a/make/launcher/Launcher-jdk.jdeps.gmk
+++ b/make/launcher/Launcher-jdk.jdeps.gmk
@@ -27,15 +27,18 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, javap, \
MAIN_CLASS := com.sun.tools.javap.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
$(eval $(call SetupBuildLauncher, jdeps, \
MAIN_CLASS := com.sun.tools.jdeps.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
$(eval $(call SetupBuildLauncher, jdeprscan, \
MAIN_CLASS := com.sun.tools.jdeprscan.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.jdi.gmk b/make/launcher/Launcher-jdk.jdi.gmk
index fcce98cf430..27bd448e3ae 100644
--- a/make/launcher/Launcher-jdk.jdi.gmk
+++ b/make/launcher/Launcher-jdk.jdi.gmk
@@ -27,4 +27,5 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jdb, \
MAIN_CLASS := com.sun.tools.example.debug.tty.TTY, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
diff --git a/make/launcher/Launcher-jdk.jlink.gmk b/make/launcher/Launcher-jdk.jlink.gmk
index df2173996d7..9e61edeb2c8 100644
--- a/make/launcher/Launcher-jdk.jlink.gmk
+++ b/make/launcher/Launcher-jdk.jlink.gmk
@@ -27,18 +27,21 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jimage,\
MAIN_CLASS := jdk.tools.jimage.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DENABLE_ARG_FILES, \
))
$(eval $(call SetupBuildLauncher, jlink,\
MAIN_CLASS := jdk.tools.jlink.internal.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT \
+ -XX:+DisableHotswapAgent, \
CFLAGS := -DENABLE_ARG_FILES \
-DEXPAND_CLASSPATH_WILDCARDS, \
))
$(eval $(call SetupBuildLauncher, jmod,\
MAIN_CLASS := jdk.tools.jmod.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DENABLE_ARG_FILES \
-DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.jshell.gmk b/make/launcher/Launcher-jdk.jshell.gmk
index 349eb88e9eb..7287f8f998a 100644
--- a/make/launcher/Launcher-jdk.jshell.gmk
+++ b/make/launcher/Launcher-jdk.jshell.gmk
@@ -27,5 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jshell, \
MAIN_CLASS := jdk.internal.jshell.tool.JShellToolProvider, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.jstatd.gmk b/make/launcher/Launcher-jdk.jstatd.gmk
index e9286d63094..e1657910c67 100644
--- a/make/launcher/Launcher-jdk.jstatd.gmk
+++ b/make/launcher/Launcher-jdk.jstatd.gmk
@@ -27,6 +27,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jstatd, \
MAIN_CLASS := sun.tools.jstatd.Jstatd, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
# Hook to include the corresponding custom file, if present.
diff --git a/make/launcher/Launcher-jdk.pack.gmk b/make/launcher/Launcher-jdk.pack.gmk
index a93fd2a9017..64bbbb7c949 100644
--- a/make/launcher/Launcher-jdk.pack.gmk
+++ b/make/launcher/Launcher-jdk.pack.gmk
@@ -28,6 +28,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, pack200, \
MAIN_MODULE := java.base, \
MAIN_CLASS := com.sun.java.util.jar.pack.Driver, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
################################################################################
diff --git a/make/launcher/Launcher-jdk.rmic.gmk b/make/launcher/Launcher-jdk.rmic.gmk
index d60c3d9b60b..b8a55900b0e 100644
--- a/make/launcher/Launcher-jdk.rmic.gmk
+++ b/make/launcher/Launcher-jdk.rmic.gmk
@@ -27,5 +27,6 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, rmic, \
MAIN_CLASS := sun.rmi.rmic.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
CFLAGS := -DEXPAND_CLASSPATH_WILDCARDS, \
))
diff --git a/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk b/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk
index 82311e69fd6..bd39f8595b2 100644
--- a/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk
+++ b/make/launcher/Launcher-jdk.scripting.nashorn.shell.gmk
@@ -27,6 +27,7 @@ include LauncherCommon.gmk
$(eval $(call SetupBuildLauncher, jjs, \
MAIN_CLASS := jdk.nashorn.tools.jjs.Main, \
- JAVA_ARGS := --add-modules ALL-DEFAULT, \
+ JAVA_ARGS := --add-modules ALL-DEFAULT \
+ -XX:+DisableHotswapAgent, \
CFLAGS := -DENABLE_ARG_FILES, \
))
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 2ca6dde069d..c75bb5d8f49 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -3937,6 +3937,8 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
// Set object alignment values.
set_object_alignment();
+ setup_hotswap_agent();
+
#if !INCLUDE_CDS
if (DumpSharedSpaces || RequireSharedSpaces) {
jio_fprintf(defaultStream::error_stream(),
@@ -4270,3 +4272,60 @@ bool Arguments::copy_expand_pid(const char* src, size_t srclen,
*b = '\0';
return (p == src_end); // return false if not all of the source was copied
}
+
+void Arguments::setup_hotswap_agent() {
+
+ if (DumpSharedSpaces)
+ return;
+
+ if (!AllowEnhancedClassRedefinition)
+ return;
+
+ // Set HotswapAgent
+ if (!DisableHotswapAgent) {
+
+ char ext_path_str[JVM_MAXPATHLEN];
+
+ os::jvm_path(ext_path_str, sizeof(ext_path_str));
+ for (int i = 0; i < 3; i++) {
+ char *end = strrchr(ext_path_str, *os::file_separator());
+ if (end != NULL) *end = '\0';
+ }
+ size_t ext_path_length = strlen(ext_path_str);
+ if (ext_path_length >= 3) {
+ if (strcmp(ext_path_str + ext_path_length - 3, "lib") != 0) {
+ if (ext_path_length < JVM_MAXPATHLEN - 4) {
+ jio_snprintf(ext_path_str + ext_path_length, sizeof(ext_path_str) - ext_path_length, "%slib", os::file_separator());
+ ext_path_length += 4;
+ }
+ }
+ }
+ if (ext_path_length < JVM_MAXPATHLEN - 10) {
+ jio_snprintf(ext_path_str + ext_path_length, sizeof(ext_path_str) - ext_path_length,
+ "%shotswap%shotswap-agent.jar", os::file_separator(), os::file_separator());
+ }
+
+ int fd = ::open(ext_path_str, O_RDONLY);
+ if (fd >= 0) {
+ os::close(fd);
+ size_t length = strlen(ext_path_str) + 1;
+ char *options = NEW_C_HEAP_ARRAY(char, length, mtArguments);
+ jio_snprintf(options, length, "%s", ext_path_str);
+ add_init_agent("instrument", ext_path_str, false);
+ jio_fprintf(defaultStream::output_stream(), "Starting HotswapAgent '%s'\n", ext_path_str);
+ }
+// else
+// {
+// jio_fprintf(defaultStream::error_stream(), "HotswapAgent not found on path:'%s'\n", ext_path_str);
+// }
+ }
+
+ // TODO: open it only for org.hotswap.agent module
+ // Use to access java.lang.reflect.Proxy/proxyCache
+ create_numbered_property("jdk.module.addopens", "java.base/java.lang=ALL-UNNAMED", addopens_count++);
+ // Class of field java.lang.reflect.Proxy/proxyCache
+ create_numbered_property("jdk.module.addopens", "java.base/jdk.internal.loader=ALL-UNNAMED", addopens_count++);
+ // java.beans.Introspector access
+ create_numbered_property("jdk.module.addopens", "java.desktop/java.beans=ALL-UNNAMED", addopens_count++);
+
+}
diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp
index 46450cce5c9..3dc5b3d4bae 100644
--- a/src/hotspot/share/runtime/arguments.hpp
+++ b/src/hotspot/share/runtime/arguments.hpp
@@ -506,6 +506,9 @@ class Arguments : AllStatic {
static size_t conservative_max_heap_alignment() { return _conservative_max_heap_alignment; }
+ // Initialize HotswapAgent
+ static void setup_hotswap_agent();
+
// Return the maximum size a heap with compressed oops can take
static size_t max_heap_for_compressed_oops();
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index f3cf08fffb6..5f6c7b8e388 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -32,6 +32,12 @@
#include <float.h> // for DBL_MAX
+#ifdef DCEVM_ONLY
+#define DISABLED_HOTSWAP_AGENT true
+#else
+#define DISABLED_HOTSWAP_AGENT false
+#endif
+
// The larger HeapWordSize for 64bit requires larger heaps
// for the same application running in 64bit. See bug 4967770.
// The minimum alignment to a heap word size is done. Other
@@ -2675,8 +2681,10 @@ define_pd_global(uint64_t,MaxRAM, 1ULL*G);
\
product(bool, AllowEnhancedClassRedefinition, true, \
"Allow enhanced class redefinition beyond swapping method " \
- "bodies")
-
+ "bodies") \
+ \
+ product(bool, DisableHotswapAgent, DISABLED_HOTSWAP_AGENT, \
+ "Disable integrated Hotswap Agent (HotswapVM only)")
#define VM_FLAGS(develop, \
develop_pd, \
product, \
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,25 @@
From 603b446449aa715aa3f409fb49ed00169b89fd91 Mon Sep 17 00:00:00 2001
From: skybber <lada.dvorak7@gmail.com>
Date: Sun, 16 Dec 2018 09:55:31 +0100
Subject: [PATCH 16/48] Add dcevm distro name
---
make/autoconf/version-numbers | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/make/autoconf/version-numbers b/make/autoconf/version-numbers
index b5a23138213..5c0a3242c80 100644
--- a/make/autoconf/version-numbers
+++ b/make/autoconf/version-numbers
@@ -43,7 +43,7 @@ PRODUCT_NAME=OpenJDK
PRODUCT_SUFFIX="Runtime Environment"
JDK_RC_PLATFORM_NAME=Platform
COMPANY_NAME=N/A
-HOTSPOT_VM_DISTRO="OpenJDK"
+HOTSPOT_VM_DISTRO="Dynamic Code Evolution"
# Might need better names for these
MACOSX_BUNDLE_NAME_BASE="OpenJDK"
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,24 @@
From 6869b6f67f8c8db57d91ea0ef9f33aaf44def1db Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Tue, 19 Nov 2019 19:58:27 +0100
Subject: [PATCH 17/48] java.desktop/com.sun.beans=ALL-UNNAMED
---
src/hotspot/share/runtime/arguments.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index c75bb5d8f49..ba6e78d6daa 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -4327,5 +4327,7 @@ void Arguments::setup_hotswap_agent() {
create_numbered_property("jdk.module.addopens", "java.base/jdk.internal.loader=ALL-UNNAMED", addopens_count++);
// java.beans.Introspector access
create_numbered_property("jdk.module.addopens", "java.desktop/java.beans=ALL-UNNAMED", addopens_count++);
+ // java.beans.Introspector access
+ create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans=ALL-UNNAMED", addopens_count++);
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,113 @@
From bbcbaa9d5814017565b8f7f0d86844e9f64905c1 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Tue, 19 Nov 2019 21:07:59 +0100
Subject: [PATCH 18/48] increment_class_counter() using orig dcevm code
Probably it is cause of SISEGV on:
_
VM_EnhancedRedefineClasses::redefine_single_class->java_mirror()
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 39 ++++++-------------
1 file changed, 12 insertions(+), 27 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 4ca638548dc..efb9e806508 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1146,9 +1146,9 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
}
-/**
+/**
Searches for the class bytecode of the given class and returns it as a byte array.
-
+
@param the_class definition of a class, either existing class or new_class
@param class_bytes - if the class is redefined, it contains new class definition, otherwise just original class bytecode.
@param class_byte_count - size of class_bytes
@@ -1460,7 +1460,7 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
//
// ik->itable()->adjust_method_entries(the_class, &trace_name_printed);
// }
-
+
constantPoolHandle other_cp = constantPoolHandle(ik->constants());
// Update host klass of anonymous classes (for example, produced by lambdas) to newest version.
@@ -1764,7 +1764,7 @@ void VM_EnhancedRedefineClasses::flush_dependent_code(InstanceKlass* k_h, TRAPS)
/**
Compare _old_methods and _new_methods arrays and store the result into
_matching_old_methods, _matching_new_methods, _added_methods, _deleted_methods
-
+
Setup _old_methods and _new_methods before the call - it should be called for one class only!
*/
void VM_EnhancedRedefineClasses::compute_added_deleted_matching_methods() {
@@ -1898,13 +1898,13 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
ResourceMark rm(THREAD);
// increment the classRedefinedCount field in the_class and in any
// direct and indirect subclasses of the_class
- increment_class_counter(the_class, THREAD);
+ increment_class_counter(new_class, THREAD);
log_info(redefine, class, load)
("redefined name=%s, count=%d (avail_mem=" UINT64_FORMAT "K)",
- the_class->external_name(), java_lang_Class::classRedefinedCount(the_class->java_mirror()), os::available_memory() >> 10);
+ new_class->external_name(), java_lang_Class::classRedefinedCount(new_class->java_mirror()), os::available_memory() >> 10);
Events::log_redefinition(THREAD, "redefined class name=%s, count=%d",
- the_class->external_name(),
- java_lang_Class::classRedefinedCount(the_class->java_mirror()));
+ new_class->external_name(),
+ java_lang_Class::classRedefinedCount(new_class->java_mirror()));
}
_timer_rsc_phase2.stop();
@@ -1914,25 +1914,10 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
// Increment the classRedefinedCount field in the specific InstanceKlass
// and in all direct and indirect subclasses.
void VM_EnhancedRedefineClasses::increment_class_counter(InstanceKlass *ik, TRAPS) {
- oop class_mirror = ik->java_mirror();
+ oop class_mirror = ik->old_version()->java_mirror();
Klass* class_oop = java_lang_Class::as_Klass(class_mirror);
int new_count = java_lang_Class::classRedefinedCount(class_mirror) + 1;
- java_lang_Class::set_classRedefinedCount(ik->new_version()->java_mirror(), new_count);
-
- if (class_oop != _the_class_oop) {
- // _the_class_oop count is printed at end of redefine_single_class()
- log_debug(redefine, class, subclass)("updated count in subclass=%s to %d", ik->external_name(), new_count);
- }
-
- for (Klass *subk = ik->subklass(); subk != NULL;
- subk = subk->next_sibling()) {
- if (subk->is_instance_klass()) {
- // Only update instanceKlasses
- InstanceKlass *subik = InstanceKlass::cast(subk);
- // recursively do subclasses of the current subclass
- increment_class_counter(subik, THREAD);
- }
- }
+ java_lang_Class::set_classRedefinedCount(ik->java_mirror(), new_count);
}
void VM_EnhancedRedefineClasses::check_class(InstanceKlass* ik, TRAPS) {
@@ -2063,7 +2048,7 @@ class AffectedKlassClosure : public KlassClosure {
/**
Find all affected classes by current redefinition (either because of redefine, class hierarchy or interface change).
- Affected classes are stored in _affected_klasses and parent classes always precedes child class.
+ Affected classes are stored in _affected_klasses and parent classes always precedes child class.
*/
jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
for (int i = 0; i < _class_count; i++) {
@@ -2112,7 +2097,7 @@ static bool match_second(void* value, KlassPair elem) {
First newly introduced classes (_class_defs) are scanned and then affected classed (_affected_klasses).
Affected flag is cleared (clear_redefinition_flag(Klass::MarkedAsAffected))
For each dependency create a KlassPair instance. Finnaly, affected classes (_affected_klasses) are sorted according to pairs.
-
+
TODO - the class file is potentionally parsed multiple times - introduce a cache?
*/
jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,38 @@
From 62c65c226bbc4fadbc598db1a2ac7d05d17ae731 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Thu, 21 Nov 2019 19:30:07 +0100
Subject: [PATCH 19/48] Allow 11715ha class initializer calls
---
src/hotspot/share/classfile/vmSymbols.hpp | 1 +
src/hotspot/share/interpreter/linkResolver.cpp | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index e2bac31b27f..6eeda3b8f68 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -340,6 +340,7 @@
/* common method and field names */ \
template(object_initializer_name, "<init>") \
template(class_initializer_name, "<clinit>") \
+ template(ha_class_initializer_name, "$$ha$clinit") \
template(println_name, "println") \
template(printStackTrace_name, "printStackTrace") \
template(main_name, "main") \
diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp
index b9ccdee8cca..cb76d2ef50c 100644
--- a/src/hotspot/share/interpreter/linkResolver.cpp
+++ b/src/hotspot/share/interpreter/linkResolver.cpp
@@ -1009,7 +1009,7 @@ void LinkResolver::resolve_field(fieldDescriptor& fd,
assert(!m.is_null(), "information about the current method must be available for 'put' bytecodes");
bool is_initialized_static_final_update = (byte == Bytecodes::_putstatic &&
fd.is_static() &&
- !m()->is_static_initializer());
+ !(m()->is_static_initializer() || m()->name() == vmSymbols::ha_class_initializer_name()));
bool is_initialized_instance_final_update = ((byte == Bytecodes::_putfield || byte == Bytecodes::_nofast_putfield) &&
!fd.is_static() &&
!m->is_object_initializer());
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,24 @@
From 88b6f7a27e35d9ed3b82418b82c1cb1fe14f61e6 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Tue, 26 Nov 2019 22:13:07 +0100
Subject: [PATCH 20/48] Disable HA in keytool
---
make/launcher/Launcher-java.base.gmk | 1 +
1 file changed, 1 insertion(+)
diff --git a/make/launcher/Launcher-java.base.gmk b/make/launcher/Launcher-java.base.gmk
index 5ee4530004b..88c1a14b2aa 100644
--- a/make/launcher/Launcher-java.base.gmk
+++ b/make/launcher/Launcher-java.base.gmk
@@ -63,6 +63,7 @@ endif
$(eval $(call SetupBuildLauncher, keytool, \
MAIN_CLASS := sun.security.tools.keytool.Main, \
+ JAVA_ARGS := -XX:+DisableHotswapAgent, \
))
################################################################################
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,24 @@
From 7fb12fc40a76a37ce67b051276a7ef582de1b04a Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Thu, 28 Nov 2019 18:53:11 +0100
Subject: [PATCH 21/48] Open jdk module to access ClassInfo.CACHE
---
src/hotspot/share/runtime/arguments.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index ba6e78d6daa..0081f688120 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -4329,5 +4329,7 @@ void Arguments::setup_hotswap_agent() {
create_numbered_property("jdk.module.addopens", "java.desktop/java.beans=ALL-UNNAMED", addopens_count++);
// java.beans.Introspector access
create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans=ALL-UNNAMED", addopens_count++);
+ // com.sun.beans.introspect.ClassInfo access
+ create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans.introspect=ALL-UNNAMED", addopens_count++);
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,25 @@
From d3d53f242337bd3bc79917f922ff569c0a112f3b Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 8 Dec 2019 17:55:01 +0100
Subject: [PATCH 22/48] Open java.base/java.io module
---
src/hotspot/share/runtime/arguments.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 0081f688120..0cdd8c88315 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -4325,6 +4325,8 @@ void Arguments::setup_hotswap_agent() {
create_numbered_property("jdk.module.addopens", "java.base/java.lang=ALL-UNNAMED", addopens_count++);
// Class of field java.lang.reflect.Proxy/proxyCache
create_numbered_property("jdk.module.addopens", "java.base/jdk.internal.loader=ALL-UNNAMED", addopens_count++);
+ // Use to access java.io.Reader, java.io.InputStream, java.io.FileInputStream
+ create_numbered_property("jdk.module.addopens", "java.base/java.io=ALL-UNNAMED", addopens_count++);
// java.beans.Introspector access
create_numbered_property("jdk.module.addopens", "java.desktop/java.beans=ALL-UNNAMED", addopens_count++);
// java.beans.Introspector access
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,54 @@
From 833ef503677e066b3639e7418a22587992df1829 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@mailprofiler.com>
Date: Fri, 6 Mar 2020 09:28:24 +0100
Subject: [PATCH 23/48] Fix fieldDescriptor.inline.hpp
---
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index efb9e806508..a404fd3f016 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -49,6 +49,7 @@
#include "runtime/deoptimization.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/relocator.hpp"
+#include "runtime/fieldDescriptor.inline.hpp"
#include "utilities/bitMap.inline.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
#include "utilities/events.hpp"
@@ -490,6 +491,11 @@ void VM_EnhancedRedefineClasses::doit() {
flush_dependent_code(NULL, thread);
// }
+ // Adjust constantpool caches for all classes that reference methods of the evolved class.
+ ClearCpoolCacheAndUnpatch clear_cpool_cache(thread);
+ ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
+
+
// JSR-292 support
if (_any_class_has_resolved_methods) {
bool trace_name_printed = false;
@@ -1890,9 +1896,6 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
}
*/
- // Adjust constantpool caches for all classes that reference methods of the evolved class.
- ClearCpoolCacheAndUnpatch clear_cpool_cache(THREAD);
- ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
{
ResourceMark rm(THREAD);
@@ -1905,7 +1908,6 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
Events::log_redefinition(THREAD, "redefined class name=%s, count=%d",
new_class->external_name(),
java_lang_Class::classRedefinedCount(new_class->java_mirror()));
-
}
_timer_rsc_phase2.stop();
} // end redefine_single_class()
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,38 @@
From 1af8b1f3f891388a37cc71076c324d3905ab2a46 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@mailprofiler.com>
Date: Fri, 6 Mar 2020 15:46:51 +0100
Subject: [PATCH 24/48] Fix clear_cpool_cache
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index a404fd3f016..1f5a67f8866 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -491,11 +491,6 @@ void VM_EnhancedRedefineClasses::doit() {
flush_dependent_code(NULL, thread);
// }
- // Adjust constantpool caches for all classes that reference methods of the evolved class.
- ClearCpoolCacheAndUnpatch clear_cpool_cache(thread);
- ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
-
-
// JSR-292 support
if (_any_class_has_resolved_methods) {
bool trace_name_printed = false;
@@ -1896,6 +1891,9 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
}
*/
+ // Adjust constantpool caches for all classes that reference methods of the evolved class.
+ ClearCpoolCacheAndUnpatch clear_cpool_cache(THREAD);
+ ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
{
ResourceMark rm(THREAD);
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,163 @@
From def550828411b677ed2d7807e51cc5ffe70331fc Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@mailprofiler.com>
Date: Mon, 9 Mar 2020 09:54:04 +0100
Subject: [PATCH 25/48] Refactor ClearCpoolCacheAndUnpatch
Call it after redefinition of all classes
---
make/common/MakeBase.gmk | 4 +-
.../prims/jvmtiEnhancedRedefineClasses.cpp | 98 ++++---------------
2 files changed, 21 insertions(+), 81 deletions(-)
diff --git a/make/common/MakeBase.gmk b/make/common/MakeBase.gmk
index a040effe83a..c33a7d52ddb 100644
--- a/make/common/MakeBase.gmk
+++ b/make/common/MakeBase.gmk
@@ -1044,7 +1044,9 @@ DependOnVariableHelper = \
$(info NewVariable $1: >$(strip $($1))<) \
$(info OldVariable $1: >$(strip $($1_old))<)) \
$(call WriteFile, $1_old:=$(call DoubleDollar,$(call EscapeHash,$($1))), \
- $($1_filename))) \
+ $($1_filename)) \
+ $(eval $($1_filename): ) \
+ ) \
$($1_filename) \
)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 1f5a67f8866..24fb76b6de4 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -491,6 +491,11 @@ void VM_EnhancedRedefineClasses::doit() {
flush_dependent_code(NULL, thread);
// }
+ // Adjust constantpool caches for all classes that reference methods of the evolved class.
+ ClearCpoolCacheAndUnpatch clear_cpool_cache(thread);
+ ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
+
+
// JSR-292 support
if (_any_class_has_resolved_methods) {
bool trace_name_printed = false;
@@ -1383,86 +1388,23 @@ void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method) {
}
}
-// Unevolving classes may point to methods of the_class directly
+// Unevolving classes may point to old methods directly
// from their constant pool caches, itables, and/or vtables. We
-// use the ClassLoaderDataGraph::classes_do() facility and this helper
-// to fix up these pointers.
-// Adjust cpools and vtables closure
+// use the SystemDictionary::classes_do() facility and this helper
+// to fix up these pointers. Additional field offsets and vtable indices
+// in the constant pool cache entries are fixed.
+//
+// Note: We currently don't support updating the vtable in
+// arrayKlassOops. See Open Issues in jvmtiRedefineClasses.hpp.
void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
- // This is a very busy routine. We don't want too much tracing
- // printed out.
- bool trace_name_printed = false;
- InstanceKlass *the_class = InstanceKlass::cast(_the_class_oop);
-
- // If the class being redefined is java.lang.Object, we need to fix all
- // array class vtables also
- if (k->is_array_klass() && _the_class_oop == SystemDictionary::Object_klass()) {
- k->vtable().adjust_method_entries(the_class, &trace_name_printed);
- } else if (k->is_instance_klass()) {
- HandleMark hm(_thread);
- InstanceKlass *ik = InstanceKlass::cast(k);
+ if (!k->is_instance_klass()) {
+ return;
+ }
- // HotSpot specific optimization! HotSpot does not currently
- // support delegation from the bootstrap class loader to a
- // user-defined class loader. This means that if the bootstrap
- // class loader is the initiating class loader, then it will also
- // be the defining class loader. This also means that classes
- // loaded by the bootstrap class loader cannot refer to classes
- // loaded by a user-defined class loader. Note: a user-defined
- // class loader can delegate to the bootstrap class loader.
- //
- // If the current class being redefined has a user-defined class
- // loader as its defining class loader, then we can skip all
- // classes loaded by the bootstrap class loader.
- bool is_user_defined =
- InstanceKlass::cast(_the_class_oop)->class_loader() != NULL;
- if (is_user_defined && ik->class_loader() == NULL) {
- return;
- }
-
- // Fix the vtable embedded in the_class and subclasses of the_class,
- // if one exists. We discard scratch_class and we don't keep an
- // InstanceKlass around to hold obsolete methods so we don't have
- // any other InstanceKlass embedded vtables to update. The vtable
- // holds the Method*s for virtual (but not final) methods.
- // Default methods, or concrete methods in interfaces are stored
- // in the vtable, so if an interface changes we need to check
- // adjust_method_entries() for every InstanceKlass, which will also
- // adjust the default method vtable indices.
- // We also need to adjust any default method entries that are
- // not yet in the vtable, because the vtable setup is in progress.
- // This must be done after we adjust the default_methods and
- // default_vtable_indices for methods already in the vtable.
- // If redefining Unsafe, walk all the vtables looking for entries.
-// FIXME - code from standard redefine - if needed, it should switch to new_class
-// if (ik->vtable_length() > 0 && (_the_class_oop->is_interface()
-// || _the_class_oop == SystemDictionary::internal_Unsafe_klass()
-// || ik->is_subtype_of(_the_class_oop))) {
-// // ik->vtable() creates a wrapper object; rm cleans it up
-// ResourceMark rm(_thread);
-//
-// ik->vtable()->adjust_method_entries(the_class, &trace_name_printed);
-// ik->adjust_default_methods(the_class, &trace_name_printed);
-// }
-
- // If the current class has an itable and we are either redefining an
- // interface or if the current class is a subclass of the_class, then
- // we potentially have to fix the itable. If we are redefining an
- // interface, then we have to call adjust_method_entries() for
- // every InstanceKlass that has an itable since there isn't a
- // subclass relationship between an interface and an InstanceKlass.
- // If redefining Unsafe, walk all the itables looking for entries.
-// FIXME - code from standard redefine - if needed, it should switch to new_class
-// if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
-// || _the_class_oop == SystemDictionary::internal_Unsafe_klass()
-// || ik->is_subclass_of(_the_class_oop))) {
-// // ik->itable() creates a wrapper object; rm cleans it up
-// ResourceMark rm(_thread);
-//
-// ik->itable()->adjust_method_entries(the_class, &trace_name_printed);
-// }
+ HandleMark hm(_thread);
+ InstanceKlass *ik = InstanceKlass::cast(k);
- constantPoolHandle other_cp = constantPoolHandle(ik->constants());
+ constantPoolHandle other_cp = constantPoolHandle(ik->constants());
// Update host klass of anonymous classes (for example, produced by lambdas) to newest version.
if (ik->is_anonymous() && ik->host_klass()->new_version() != NULL) {
@@ -1491,7 +1433,6 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
if (RewriteBytecodes) {
ik->methods_do(unpatch_bytecode);
}
- }
}
// Clean method data for this class
@@ -1891,9 +1832,6 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
}
*/
- // Adjust constantpool caches for all classes that reference methods of the evolved class.
- ClearCpoolCacheAndUnpatch clear_cpool_cache(THREAD);
- ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
{
ResourceMark rm(THREAD);
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,29 @@
From 5f416d7a25bd23399b9189cc94ab5d5887e6b4d4 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@mailprofiler.com>
Date: Wed, 11 Mar 2020 14:19:34 +0100
Subject: [PATCH 26/48] Fix class cast exception on redefinition of class A,
that is superclass of B that has anonymous class C
---
src/hotspot/share/oops/instanceKlass.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 9b6ba7e9304..8cbd4b8edf2 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -788,7 +788,10 @@ bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) {
if (!is_linked()) {
if (!is_rewritten()) {
- {
+ // In cases, if class A is being redefined and class B->A (B is extended from A) and B is host class of anonymous class C
+ // then second redefinition fails with cannot cast klass exception. So we currently turn off bytecode verification
+ // on redefinition.
+ if (!newest_version()->is_redefining()) {
bool verify_ok = verify_code(throw_verifyerror, THREAD);
if (!verify_ok) {
return false;
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,60 @@
From 9a7abdf08bf207f5265a552500446c3178bf5794 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 10 Apr 2020 23:28:07 +0200
Subject: [PATCH 27/48] Update klass reference in Klass.implementor()
If interface X is removed from class Y then old reference to Y could be
stored in X.implementor()
---
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 12 ++++++++++++
.../share/prims/jvmtiEnhancedRedefineClasses.hpp | 11 -----------
2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 24fb76b6de4..f6d2d3a40fe 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1411,6 +1411,18 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
ik->set_host_klass(InstanceKlass::cast(ik->host_klass()->newest_version()));
}
+ // Update implementor if there is only one, in this case implementor() can reference old class
+ if (ik->is_interface()) {
+ Klass* implKlass = ik->implementor();
+ if (implKlass != NULL && implKlass != ik && implKlass->new_version() != NULL) {
+ InstanceKlass* newest_impl = InstanceKlass::cast(implKlass->newest_version());
+ ik->init_implementor();
+ if (newest_impl->implements_interface(ik)) {
+ ik->add_implementor(newest_impl);
+ }
+ }
+ }
+
for (int i = 0; i < other_cp->length(); i++) {
if (other_cp->tag_at(i).is_klass()) {
Klass* klass = other_cp->resolved_klass_at(i);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 5b3ebc13661..2d114635ee5 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -69,17 +69,6 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
// RetransformClasses. Indicate which.
JvmtiClassLoadKind _class_load_kind;
- // _index_map_count is just an optimization for knowing if
- // _index_map_p contains any entries.
- int _index_map_count;
- intArray * _index_map_p;
-
- // _operands_index_map_count is just an optimization for knowing if
- // _operands_index_map_p contains any entries.
- int _operands_cur_length;
- int _operands_index_map_count;
- intArray * _operands_index_map_p;
-
GrowableArray<InstanceKlass*>* _new_classes;
jvmtiError _res;
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,96 @@
From 8f13d3b4ba9aecd847b7da306055ba53ee2e29d0 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 10 Apr 2020 23:30:21 +0200
Subject: [PATCH 28/48] Fix DirectMethodHandle accessors klasses
---
src/hotspot/share/classfile/javaClasses.cpp | 28 +++++++++++++++------
src/hotspot/share/classfile/javaClasses.hpp | 4 +++
2 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index a89443d22ea..ea0588e5388 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -3641,14 +3641,20 @@ void java_lang_invoke_DirectMethodHandle_StaticAccessor::set_static_offset(oop d
dmh->long_field_put(_static_offset_offset, static_offset);
}
+#define DIRECTMETHODHANDLE_STATIC_ACCESSOR_FIELDS_DO(macro) \
+ macro(_static_offset_offset, k, vmSymbols::static_offset_name(), long_signature, false)
void java_lang_invoke_DirectMethodHandle_StaticAccessor::compute_offsets() {
- Klass* klass_oop = SystemDictionary::DirectMethodHandle_StaticAccessor_klass();
- if (klass_oop != NULL) {
- compute_offset(_static_offset_offset, InstanceKlass::cast(klass_oop), vmSymbols::static_offset_name(), vmSymbols::long_signature());
- }
+ InstanceKlass* k = SystemDictionary::DirectMethodHandle_StaticAccessor_klass();
+ DIRECTMETHODHANDLE_STATIC_ACCESSOR_FIELDS_DO(FIELD_COMPUTE_OFFSET);
}
+#if INCLUDE_CDS
+void java_lang_invoke_DirectMethodHandle_StaticAccessor::serialize_offsets(SerializeClosure* f) {
+ DIRECTMETHODHANDLE_STATIC_ACCESSOR_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
+}
+#endif
+
// Support for java_lang_invoke_DirectMethodHandle$Accessor
int java_lang_invoke_DirectMethodHandle_Accessor::_field_offset_offset;
@@ -3663,14 +3669,20 @@ void java_lang_invoke_DirectMethodHandle_Accessor::set_field_offset(oop dmh, int
dmh->int_field_put(_field_offset_offset, field_offset);
}
+#define DIRECTMETHODHANDLE_ACCESSOR_FIELDS_DO(macro) \
+ macro(_field_offset_offset, k, vmSymbols::field_offset_name(), int_signature, false)
void java_lang_invoke_DirectMethodHandle_Accessor::compute_offsets() {
- Klass* klass_oop = SystemDictionary::DirectMethodHandle_Accessor_klass();
- if (klass_oop != NULL) {
- compute_offset(_field_offset_offset, InstanceKlass::cast(klass_oop), vmSymbols::field_offset_name(), vmSymbols::int_signature());
- }
+ InstanceKlass* k = SystemDictionary::DirectMethodHandle_Accessor_klass();
+ DIRECTMETHODHANDLE_ACCESSOR_FIELDS_DO(FIELD_COMPUTE_OFFSET);
}
+#if INCLUDE_CDS
+void java_lang_invoke_DirectMethodHandle_Accessor::serialize_offsets(SerializeClosure* f) {
+ DIRECTMETHODHANDLE_ACCESSOR_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
+}
+#endif
+
// Support for java_lang_invoke_MethodHandle
int java_lang_invoke_MethodHandle::_type_offset;
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index ceb1670df5d..55f9fa62e2b 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -67,6 +67,8 @@
f(java_lang_invoke_LambdaForm) \
f(java_lang_invoke_MethodType) \
f(java_lang_invoke_CallSite) \
+ f(java_lang_invoke_DirectMethodHandle_StaticAccessor) \
+ f(java_lang_invoke_DirectMethodHandle_Accessor) \
f(java_lang_invoke_MethodHandleNatives_CallSiteContext) \
f(java_security_AccessControlContext) \
f(java_lang_reflect_AccessibleObject) \
@@ -1077,6 +1079,7 @@ class java_lang_invoke_DirectMethodHandle_StaticAccessor: AllStatic {
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
}
+ static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};
// Interface to java.lang.invoke.DirectMethodHandle$Accessor objects
@@ -1101,6 +1104,7 @@ class java_lang_invoke_DirectMethodHandle_Accessor: AllStatic {
static bool is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
}
+ static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,60 @@
From cbad9c34bf8920d772c646d041d4fc04fea203cc Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 11 Apr 2020 12:07:43 +0200
Subject: [PATCH 29/48] cleanup direct method handles code
---
src/hotspot/share/classfile/javaClasses.hpp | 10 ++++------
src/hotspot/share/classfile/javaClasses.inline.hpp | 8 ++++++++
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index 55f9fa62e2b..da004d1b307 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -1076,9 +1076,8 @@ class java_lang_invoke_DirectMethodHandle_StaticAccessor: AllStatic {
static bool is_subclass(Klass* klass) {
return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_StaticAccessor_klass());
}
- static bool is_instance(oop obj) {
- return obj != NULL && is_subclass(obj->klass());
- }
+ static bool is_instance(oop obj);
+
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};
@@ -1101,9 +1100,8 @@ class java_lang_invoke_DirectMethodHandle_Accessor: AllStatic {
static bool is_subclass(Klass* klass) {
return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_Accessor_klass());
}
- static bool is_instance(oop obj) {
- return obj != NULL && is_subclass(obj->klass());
- }
+ static bool is_instance(oop obj);
+
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
};
diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp
index 6c5787f4b70..ba9cffa8c62 100644
--- a/src/hotspot/share/classfile/javaClasses.inline.hpp
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp
@@ -175,6 +175,14 @@ inline bool java_lang_invoke_DirectMethodHandle::is_instance(oop obj) {
return obj != NULL && is_subclass(obj->klass());
}
+inline bool java_lang_invoke_DirectMethodHandle_StaticAccessor::is_instance(oop obj) {
+ return obj != NULL && is_subclass(obj->klass());
+}
+
+inline bool java_lang_invoke_DirectMethodHandle_Accessor::is_instance(oop obj) {
+ return obj != NULL && is_subclass(obj->klass());
+}
+
inline bool java_lang_Module::is_instance(oop obj) {
return obj != NULL && obj->klass() == SystemDictionary::Module_klass();
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,68 @@
From e3b94671ce5108a91e3a3e92b01eea07731c7639 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 11 Apr 2020 17:52:13 +0200
Subject: [PATCH 30/48] Add init_implementor_from_redefine, that skips compiler
lock assert
---
src/hotspot/share/oops/instanceKlass.cpp | 10 +++++++++-
src/hotspot/share/oops/instanceKlass.hpp | 1 +
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 2 +-
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 8cbd4b8edf2..c04bdf5abfc 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -789,7 +789,7 @@ bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) {
if (!is_linked()) {
if (!is_rewritten()) {
// In cases, if class A is being redefined and class B->A (B is extended from A) and B is host class of anonymous class C
- // then second redefinition fails with cannot cast klass exception. So we currently turn off bytecode verification
+ // then second redefinition fails with cannot cast klass exception. So we currently turn off bytecode verification
// on redefinition.
if (!newest_version()->is_redefining()) {
bool verify_ok = verify_code(throw_verifyerror, THREAD);
@@ -1139,6 +1139,14 @@ void InstanceKlass::init_implementor() {
}
}
+void InstanceKlass::init_implementor_from_redefine() {
+ assert(is_interface(), "not interface");
+ Klass** addr = adr_implementor();
+ assert(addr != NULL, "null addr");
+ if (addr != NULL) {
+ *addr = NULL;
+ }
+}
void InstanceKlass::process_interfaces(Thread *thread) {
// link this class into the implementors list of every interface it implements
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
index 2cc98b636f1..e8107a39813 100644
--- a/src/hotspot/share/oops/instanceKlass.hpp
+++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -1020,6 +1020,7 @@ public:
int nof_implementors() const;
void add_implementor(Klass* k); // k is a new class that implements this interface
void init_implementor(); // initialize
+ void init_implementor_from_redefine(); // initialize
// link this class into the implementors list of every interface it implements
void process_interfaces(Thread *thread);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index f6d2d3a40fe..aac9ba0911f 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1416,7 +1416,7 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
Klass* implKlass = ik->implementor();
if (implKlass != NULL && implKlass != ik && implKlass->new_version() != NULL) {
InstanceKlass* newest_impl = InstanceKlass::cast(implKlass->newest_version());
- ik->init_implementor();
+ ik->init_implementor_from_redefine();
if (newest_impl->implements_interface(ik)) {
ik->add_implementor(newest_impl);
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,73 @@
From a95c3daf0a1db23e2dcc977f427faa7be41007c9 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Mon, 13 Apr 2020 20:59:35 +0200
Subject: [PATCH 31/48] not nullable oop_store_not_null() method+handle NULL in
mem_name in dmh
---
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index aac9ba0911f..8d861ef43c9 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -225,13 +225,15 @@ void VM_EnhancedRedefineClasses::mark_as_scavengable(nmethod* nm) {
// TODO comment
struct StoreBarrier {
// TODO: j10 review change ::oop_store -> HeapAccess<>::oop_store
- template <class T> static void oop_store(T* p, oop v) { HeapAccess<>::oop_store(p, v); }
+ template <class T> static void oop_store_not_null(T* p, oop v) { HeapAccess<IS_NOT_NULL>::oop_store(p, v); }
+ template <class T> static void oop_store(T* p) { HeapAccess<>::oop_store(p, oop(NULL)); }
};
// TODO comment
struct StoreNoBarrier {
- template <class T> static void oop_store(T* p, oop v) { RawAccess<IS_NOT_NULL>::oop_store(p, v); }
+ template <class T> static void oop_store_not_null(T* p, oop v) { RawAccess<IS_NOT_NULL>::oop_store(p, v); }
+ template <class T> static void oop_store(T* p) { RawAccess<>::oop_store(p, oop(NULL)); }
};
/**
@@ -309,6 +311,9 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
bool update_direct_method_handle(oop obj) {
// Always update member name first.
oop mem_name = java_lang_invoke_DirectMethodHandle::member(obj);
+ if (mem_name == NULL) {
+ return true;
+ }
if (!update_member_name(mem_name)) {
return false;
}
@@ -347,7 +352,7 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
assert(obj == InstanceKlass::cast(klass)->java_mirror(), "just checking");
if (klass->new_version() != NULL) {
obj = InstanceKlass::cast(klass->new_version())->java_mirror();
- S::oop_store(p, obj);
+ S::oop_store_not_null(p, obj);
oop_updated = true;
}
}
@@ -363,7 +368,7 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
if (!update_direct_method_handle(obj)) {
// DMH is no longer valid, replace it with null reference.
// See note above. We probably want to replace this with something more meaningful.
- S::oop_store(p, NULL);
+ S::oop_store(p);
}
}
}
@@ -1430,8 +1435,7 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
// Constant pool entry points to redefined class -- update to the new version
other_cp->klass_at_put(i, klass->newest_version());
}
- klass = other_cp->resolved_klass_at(i);
- assert(klass->new_version() == NULL, "Must be new klass!");
+ assert(other_cp->resolved_klass_at(i)->new_version() == NULL, "Must be new klass!");
}
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,32 @@
From 15690197a276a86054e1ec9724c877d6d871ca01 Mon Sep 17 00:00:00 2001
From: Artem Khvastunov <artem.khvastunov@jetbrains.com>
Date: Tue, 14 Apr 2020 19:11:35 +0200
Subject: [PATCH 32/48] add jvmtiEnhancedRedefineClasses.* to CMakeLists.txt
---
jb/project/hotspot-cmake/CMakeLists.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/jb/project/hotspot-cmake/CMakeLists.txt b/jb/project/hotspot-cmake/CMakeLists.txt
index 8b552c27206..6516e39058f 100644
--- a/jb/project/hotspot-cmake/CMakeLists.txt
+++ b/jb/project/hotspot-cmake/CMakeLists.txt
@@ -1663,6 +1663,7 @@ set(SOURCE_FILES
../../../src/hotspot/share/prims/jvmtiGetLoadedClasses.hpp
../../../src/hotspot/share/prims/jvmtiAgentThread.hpp
../../../src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp
+../../../src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
../../../src/hotspot/share/prims/stackwalk.cpp
../../../src/hotspot/share/prims/privilegedStack.hpp
../../../src/hotspot/share/prims/jvmtiUtil.hpp
@@ -1684,6 +1685,7 @@ set(SOURCE_FILES
../../../src/hotspot/share/prims/stackwalk.hpp
../../../src/hotspot/share/prims/privilegedStack.cpp
../../../src/hotspot/share/prims/jvmtiCodeBlobEvents.hpp
+../../../src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
../../../src/hotspot/share/prims/jvmtiUtil.cpp
../../../src/hotspot/share/prims/jvmtiEnvBase.cpp
../../../src/hotspot/share/prims/methodHandles.cpp
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,25 @@
From dab6a53de4c25aae95667c78b8e1f1097ab47130 Mon Sep 17 00:00:00 2001
From: Artem Khvastunov <artem.khvastunov@jetbrains.com>
Date: Sun, 19 Apr 2020 11:36:12 +0200
Subject: [PATCH 33/48] migrate DCEVM to 11.0.7
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 2d114635ee5..6cabdca9c27 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -30,7 +30,7 @@
#include "memory/resourceArea.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
-#include "runtime/vm_operations.hpp"
+#include "runtime/vmOperations.hpp"
#include "gc/shared/vmGCOperations.hpp"
#include "../../../java.base/unix/native/include/jni_md.h"
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,33 @@
From 70d53ce28f9df75d9e50819d2b6654855da0d533 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 8 May 2020 21:07:50 +0200
Subject: [PATCH 34/48] Fix 11.0.7 compilation issues
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 6cabdca9c27..ed44f0e27ce 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -16,6 +16,8 @@
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
+ *
+ *
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
@@ -30,7 +32,6 @@
#include "memory/resourceArea.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
-#include "runtime/vmOperations.hpp"
#include "gc/shared/vmGCOperations.hpp"
#include "../../../java.base/unix/native/include/jni_md.h"
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,33 @@
From 805b588bc4bd45e61b81c90e23b71337072e9549 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 9 May 2020 10:08:17 +0200
Subject: [PATCH 35/48] Use INCLUDE_CDS condition on "UseSharedSpaces" block
from master
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 8d861ef43c9..660bf3a2e97 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -467,6 +467,7 @@ public:
void VM_EnhancedRedefineClasses::doit() {
Thread *thread = Thread::current();
+#if INCLUDE_CDS
if (UseSharedSpaces) {
// Sharing is enabled so we remap the shared readonly space to
// shared readwrite, private just in case we need to redefine
@@ -478,6 +479,7 @@ void VM_EnhancedRedefineClasses::doit() {
return;
}
}
+#endif
// Mark methods seen on stack and everywhere else so old methods are not
// cleaned up if they're on the stack.
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,141 @@
From 78619004206d224b319d68493672bee2c97f0946 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 16 May 2020 15:11:40 +0200
Subject: [PATCH 36/48] Access com.sun.beans.util - HotswapAgent patch
---
src/hotspot/share/runtime/arguments.cpp | 2 ++
.../sun/beans/introspect/package-info.java | 26 +++++++++++++++++++
.../classes/com/sun/beans/package-info.java | 26 +++++++++++++++++++
.../com/sun/beans/util/package-info.java | 26 +++++++++++++++++++
.../share/classes/module-info.java | 3 +++
5 files changed, 83 insertions(+)
create mode 100644 src/java.desktop/share/classes/com/sun/beans/introspect/package-info.java
create mode 100644 src/java.desktop/share/classes/com/sun/beans/package-info.java
create mode 100644 src/java.desktop/share/classes/com/sun/beans/util/package-info.java
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 0cdd8c88315..72580b384dd 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -4333,5 +4333,7 @@ void Arguments::setup_hotswap_agent() {
create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans=ALL-UNNAMED", addopens_count++);
// com.sun.beans.introspect.ClassInfo access
create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans.introspect=ALL-UNNAMED", addopens_count++);
+ // com.sun.beans.introspect.util.Cache access
+ create_numbered_property("jdk.module.addopens", "java.desktop/com.sun.beans.util=ALL-UNNAMED", addopens_count++);
}
diff --git a/src/java.desktop/share/classes/com/sun/beans/introspect/package-info.java b/src/java.desktop/share/classes/com/sun/beans/introspect/package-info.java
new file mode 100644
index 00000000000..6636e4dd62a
--- /dev/null
+++ b/src/java.desktop/share/classes/com/sun/beans/introspect/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.beans.introspect;
diff --git a/src/java.desktop/share/classes/com/sun/beans/package-info.java b/src/java.desktop/share/classes/com/sun/beans/package-info.java
new file mode 100644
index 00000000000..5c097eeaa53
--- /dev/null
+++ b/src/java.desktop/share/classes/com/sun/beans/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.beans;
diff --git a/src/java.desktop/share/classes/com/sun/beans/util/package-info.java b/src/java.desktop/share/classes/com/sun/beans/util/package-info.java
new file mode 100644
index 00000000000..2d5d735ffa8
--- /dev/null
+++ b/src/java.desktop/share/classes/com/sun/beans/util/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.beans.util;
diff --git a/src/java.desktop/share/classes/module-info.java b/src/java.desktop/share/classes/module-info.java
index f9cf021311f..e61ba7572cf 100644
--- a/src/java.desktop/share/classes/module-info.java
+++ b/src/java.desktop/share/classes/module-info.java
@@ -104,6 +104,9 @@ module java.desktop {
exports javax.swing.text.rtf;
exports javax.swing.tree;
exports javax.swing.undo;
+ exports com.sun.beans;
+ exports com.sun.beans.introspect;
+ exports com.sun.beans.util;
// qualified exports may be inserted at build time
// see make/GensrcModuleInfo.gmk
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,29 @@
From baf26456579eb0e560471d3bcb150005492f69f4 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 17 May 2020 12:19:18 +0200
Subject: [PATCH 37/48] Skip verifier only in AllowEnhancedClassRedefinition
---
src/hotspot/share/oops/instanceKlass.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index c04bdf5abfc..e14aaee21c4 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -788,10 +788,10 @@ bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) {
if (!is_linked()) {
if (!is_rewritten()) {
- // In cases, if class A is being redefined and class B->A (B is extended from A) and B is host class of anonymous class C
+ // (DCEVM): If class A is being redefined and class B->A (B is extended from A) and B is host class of anonymous class C
// then second redefinition fails with cannot cast klass exception. So we currently turn off bytecode verification
// on redefinition.
- if (!newest_version()->is_redefining()) {
+ if (!AllowEnhancedClassRedefinition || !newest_version()->is_redefining()) {
bool verify_ok = verify_code(throw_verifyerror, THREAD);
if (!verify_ok) {
return false;
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,98 @@
From 46dc38a58ac8afafab4e04ee47a1ed2b9e65c1e1 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 17 May 2020 18:18:52 +0200
Subject: [PATCH 38/48] Use original code for adjust_method_entries in standard
redefinition
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 2 +-
.../share/prims/resolvedMethodTable.cpp | 46 ++++++++++++++++++-
.../share/prims/resolvedMethodTable.hpp | 1 +
3 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 660bf3a2e97..0ca675e8ee6 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -506,7 +506,7 @@ void VM_EnhancedRedefineClasses::doit() {
// JSR-292 support
if (_any_class_has_resolved_methods) {
bool trace_name_printed = false;
- ResolvedMethodTable::adjust_method_entries(&trace_name_printed);
+ ResolvedMethodTable::adjust_method_entries_dcevm(&trace_name_printed);
}
ChangePointersOopClosure<StoreNoBarrier> oopClosureNoBarrier;
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
index a9057893368..af2ec48c2e1 100644
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
@@ -197,8 +197,52 @@ void ResolvedMethodTable::print() {
#endif // PRODUCT
#if INCLUDE_JVMTI
-// It is called at safepoint only for RedefineClasses
+
void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
+ assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
+ // For each entry in RMT, change to new method
+ for (int i = 0; i < _the_table->table_size(); ++i) {
+ for (ResolvedMethodEntry* entry = _the_table->bucket(i);
+ entry != NULL;
+ entry = entry->next()) {
+
+ oop mem_name = entry->object_no_keepalive();
+ // except ones removed
+ if (mem_name == NULL) {
+ continue;
+ }
+ Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
+
+ if (old_method->is_old()) {
+
+ Method* new_method;
+ if (old_method->is_deleted()) {
+ new_method = Universe::throw_no_such_method_error();
+ } else {
+ InstanceKlass* holder = old_method->method_holder();
+ new_method = holder->method_with_idnum(old_method->orig_method_idnum());
+ assert(holder == new_method->method_holder(), "call after swapping redefined guts");
+ assert(new_method != NULL, "method_with_idnum() should not be NULL");
+ assert(old_method != new_method, "sanity check");
+ }
+
+ java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, new_method);
+
+ ResourceMark rm;
+ if (!(*trace_name_printed)) {
+ log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
+ *trace_name_printed = true;
+ }
+ log_debug(redefine, class, update, constantpool)
+ ("ResolvedMethod method update: %s(%s)",
+ new_method->name()->as_C_string(), new_method->signature()->as_C_string());
+ }
+ }
+ }
+}
+
+// (DCEVM) It is called at safepoint only for RedefineClasses
+void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed) {
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
// For each entry in RMT, change to new method
GrowableArray<oop>* oops_to_add = new GrowableArray<oop>();
diff --git a/src/hotspot/share/prims/resolvedMethodTable.hpp b/src/hotspot/share/prims/resolvedMethodTable.hpp
index 841ae4ae585..543d4ffa485 100644
--- a/src/hotspot/share/prims/resolvedMethodTable.hpp
+++ b/src/hotspot/share/prims/resolvedMethodTable.hpp
@@ -93,6 +93,7 @@ public:
#if INCLUDE_JVMTI
// It is called at safepoint only for RedefineClasses
static void adjust_method_entries(bool * trace_name_printed);
+ static void adjust_method_entries_dcevm(bool * trace_name_printed);
#endif // INCLUDE_JVMTI
// Cleanup cleared entries
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,54 @@
From 6ac099d1b07fcc0d3c17ebd5d3335bcb6ceaedc9 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Tue, 19 May 2020 09:41:36 +0200
Subject: [PATCH 39/48] Revert code for !AllowEnhancedClassRedefinition
---
.../share/classfile/classLoaderData.cpp | 23 ++++++++++---------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index 25103fff2c0..f5b877b432b 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -1387,12 +1387,13 @@ bool ClassLoaderDataGraph::do_unloading(bool clean_previous_versions) {
// Klassesoto delete.
// FIXME: dcevm - block asserts in MetadataOnStackMark
- /*
- bool walk_all_metadata = clean_previous_versions &&
- JvmtiExport::has_redefined_a_class() &&
- InstanceKlass::has_previous_versions_and_reset();
- MetadataOnStackMark md_on_stack(walk_all_metadata);
- */
+ bool walk_all_metadata = false;
+ if (!AllowEnhancedClassRedefinition) {
+ walk_all_metadata = clean_previous_versions &&
+ JvmtiExport::has_redefined_a_class() &&
+ InstanceKlass::has_previous_versions_and_reset();
+ MetadataOnStackMark md_on_stack(walk_all_metadata);
+ }
// Save previous _unloading pointer for CMS which may add to unloading list before
// purging and we don't want to rewalk the previously unloaded class loader data.
@@ -1402,12 +1403,12 @@ bool ClassLoaderDataGraph::do_unloading(bool clean_previous_versions) {
while (data != NULL) {
if (data->is_alive()) {
// clean metaspace
- /*
- if (walk_all_metadata) {
- data->classes_do(InstanceKlass::purge_previous_versions);
+ if (!AllowEnhancedClassRedefinition) {
+ if (walk_all_metadata) {
+ data->classes_do(InstanceKlass::purge_previous_versions);
+ }
+ data->free_deallocate_list();
}
- data->free_deallocate_list();
- */
prev = data;
data = data->next();
loaders_processed++;
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,278 @@
From de04154ee21d33c1ac1b74b2740f2fda117c0430 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Tue, 19 May 2020 09:29:39 +0200
Subject: [PATCH 40/48] Code cleanup
---
src/hotspot/share/classfile/classFileParser.cpp | 4 +++-
src/hotspot/share/classfile/classFileParser.hpp | 2 +-
src/hotspot/share/classfile/classLoaderData.cpp | 2 ++
src/hotspot/share/classfile/dictionary.cpp | 4 ++++
src/hotspot/share/classfile/dictionary.hpp | 1 +
src/hotspot/share/classfile/loaderConstraints.cpp | 3 ++-
src/hotspot/share/classfile/systemDictionary.cpp | 8 +++++---
src/hotspot/share/interpreter/linkResolver.cpp | 1 +
src/hotspot/share/memory/universe.cpp | 4 ++--
src/hotspot/share/oops/instanceKlass.cpp | 13 ++++++++-----
10 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp
index ea150df9104..c2cd35da4e6 100644
--- a/src/hotspot/share/classfile/classFileParser.cpp
+++ b/src/hotspot/share/classfile/classFileParser.cpp
@@ -954,6 +954,7 @@ void ClassFileParser::parse_interfaces(const ClassFileStream* const stream,
CHECK);
}
+ // (DCEVM) pick newest
interf = (Klass *) maybe_newest(interf);
if (!interf->is_interface()) {
@@ -3749,6 +3750,7 @@ const InstanceKlass* ClassFileParser::parse_super_class(ConstantPool* const cp,
// However, make sure it is not an array type.
bool is_array = false;
if (cp->tag_at(super_class_index).is_klass()) {
+ // (DCEVM) pick newest
super_klass = InstanceKlass::cast(maybe_newest(cp->resolved_klass_at(super_class_index)));
if (need_verify)
is_array = super_klass->is_array_klass();
@@ -4417,7 +4419,7 @@ void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) {
if (!_has_empty_finalizer) {
if (_has_finalizer ||
(super != NULL && super->has_finalizer())) {
- // FIXME - condition from previous DCEVM version, however after reload new finelize() method is not active
+ // FIXME - (DCEVM) this is condition from previous DCEVM version, however after reload a new finalize() method is not active
if (ik->old_version() == NULL || ik->old_version()->has_finalizer()) {
ik->set_has_finalizer();
}
diff --git a/src/hotspot/share/classfile/classFileParser.hpp b/src/hotspot/share/classfile/classFileParser.hpp
index 3db14b678f3..93ed54d8f70 100644
--- a/src/hotspot/share/classfile/classFileParser.hpp
+++ b/src/hotspot/share/classfile/classFileParser.hpp
@@ -499,7 +499,7 @@ class ClassFileParser {
FieldLayoutInfo* info,
TRAPS);
- // Enhanced class redefinition
+ // (DCEVM) Enhanced class redefinition
inline const Klass* maybe_newest(const Klass* klass) const { return klass != NULL && _pick_newest ? klass->newest_version() : klass; }
public:
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index f5b877b432b..ab2615da0ed 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -1242,6 +1242,7 @@ void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*)) {
}
}
+// (DCEVM) - iterate over dict classes
void ClassLoaderDataGraph::dictionary_classes_do(KlassClosure* klass_closure) {
FOR_ALL_DICTIONARY(cld) {
cld->dictionary()->classes_do(klass_closure);
@@ -1257,6 +1258,7 @@ void ClassLoaderDataGraph::dictionary_classes_do(void f(InstanceKlass*, TRAPS),
}
}
+// (DCEVM) rollback redefined classes
void ClassLoaderDataGraph::rollback_redefinition() {
FOR_ALL_DICTIONARY(cld) {
cld->dictionary()->rollback_redefinition();
diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp
index 118730f1b83..dda5188c370 100644
--- a/src/hotspot/share/classfile/dictionary.cpp
+++ b/src/hotspot/share/classfile/dictionary.cpp
@@ -245,6 +245,8 @@ void Dictionary::classes_do(void f(InstanceKlass*)) {
}
}
+
+// (DCEVM) iterate over dict entry
void Dictionary::classes_do(KlassClosure* closure) {
for (int index = 0; index < table_size(); index++) {
for (DictionaryEntry* probe = bucket(index);
@@ -342,6 +344,7 @@ DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash,
return NULL;
}
+// (DCEVM) replace old_class by new class in dictionary
bool Dictionary::update_klass(unsigned int hash, Symbol* name, ClassLoaderData* loader_data, InstanceKlass* k, InstanceKlass* old_klass) {
// There are several entries for the same class in the dictionary: One extra entry for each parent classloader of the classloader of the class.
bool found = false;
@@ -356,6 +359,7 @@ bool Dictionary::update_klass(unsigned int hash, Symbol* name, ClassLoaderData*
return found;
}
+// (DCEVM) rollback redefinition
void Dictionary::rollback_redefinition() {
for (int index = 0; index < table_size(); index++) {
for (DictionaryEntry* entry = bucket(index);
diff --git a/src/hotspot/share/classfile/dictionary.hpp b/src/hotspot/share/classfile/dictionary.hpp
index fd4b134d7a7..5eaa741d500 100644
--- a/src/hotspot/share/classfile/dictionary.hpp
+++ b/src/hotspot/share/classfile/dictionary.hpp
@@ -119,6 +119,7 @@ public:
void rollback_redefinition();
+ // (DCEVM) return old class if redefining in AllowEnhancedClassRedefinition, otherwise return "k"
static InstanceKlass* old_if_redefined(InstanceKlass* k) {
return (k != NULL && k->is_redefining()) ? ((InstanceKlass* )k->old_version()) : k;
}
diff --git a/src/hotspot/share/classfile/loaderConstraints.cpp b/src/hotspot/share/classfile/loaderConstraints.cpp
index e4a23e8a27c..bca73b5e0dc 100644
--- a/src/hotspot/share/classfile/loaderConstraints.cpp
+++ b/src/hotspot/share/classfile/loaderConstraints.cpp
@@ -4,7 +4,7 @@
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
+ * published by the Free Software Foundation) replace old_class by new class in dictionary.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -87,6 +87,7 @@ LoaderConstraintEntry** LoaderConstraintTable::find_loader_constraint(
return pp;
}
+// (DCEVM) update constraint entries to new classes, called from dcevm redefinition code only
void LoaderConstraintTable::update_after_redefinition() {
for (int index = 0; index < table_size(); index++) {
LoaderConstraintEntry** p = bucket_addr(index);
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 9dbd6cc9c12..e70865109dd 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -876,7 +876,8 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
ClassLoaderData* loader_data = k->class_loader_data();
MutexLocker mu(SystemDictionary_lock, THREAD);
Klass* kk = find_class(name, loader_data);
- // FIXME: (kk == k() && !k->is_redefining()) || (k->is_redefining() && kk == k->old_version())
+ // FIXME: (DCEVM)
+ // assert(kk == k() && !k->is_redefining()) || (k->is_redefining() && kk == k->old_version())
assert(kk == k, "should be present in dictionary");
}
#endif
@@ -1083,7 +1084,7 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
InstanceKlass* k = NULL;
#if INCLUDE_CDS
- // FIXME: what to do during redefinition?
+ // FIXME: (DCEVM) what to do during redefinition?
if (!DumpSharedSpaces) {
k = SystemDictionaryShared::lookup_from_stream(class_name,
class_loader,
@@ -1836,7 +1837,7 @@ void SystemDictionary::add_to_hierarchy(InstanceKlass* k, TRAPS) {
CodeCache::flush_dependents_on(k);
}
-// Enhanced class redefinition
+// (DCEVM) - remove from klass hierarchy
void SystemDictionary::remove_from_hierarchy(InstanceKlass* k) {
assert(k != NULL, "just checking");
@@ -1844,6 +1845,7 @@ void SystemDictionary::remove_from_hierarchy(InstanceKlass* k) {
k->remove_from_sibling_list();
}
+// (DCEVM)
void SystemDictionary::update_constraints_after_redefinition() {
constraints()->update_after_redefinition();
}
diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp
index cb76d2ef50c..9dc184d02f5 100644
--- a/src/hotspot/share/interpreter/linkResolver.cpp
+++ b/src/hotspot/share/interpreter/linkResolver.cpp
@@ -1384,6 +1384,7 @@ void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
assert(resolved_method->can_be_statically_bound(), "cannot override this method");
selected_method = resolved_method;
} else {
+ // TODO: (DCEVM) explain
assert(recv_klass->is_subtype_of(resolved_method->method_holder()), "receiver and resolved method holder are inconsistent");
selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
}
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
index 7ecb950b231..d0a6d665aa0 100644
--- a/src/hotspot/share/memory/universe.cpp
+++ b/src/hotspot/share/memory/universe.cpp
@@ -176,7 +176,7 @@ void Universe::basic_type_classes_do(void f(Klass*)) {
f(doubleArrayKlassObj());
}
-// FIXME: This method should iterate all pointers that are not within heap objects.
+// FIXME: (DCEVM) This method should iterate all pointers that are not within heap objects.
void Universe::root_oops_do(OopClosure *oopClosure) {
class AlwaysTrueClosure: public BoolObjectClosure {
@@ -203,7 +203,7 @@ void Universe::root_oops_do(OopClosure *oopClosure) {
CodeBlobToOopClosure blobClosure(oopClosure, CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&blobClosure);
StringTable::oops_do(oopClosure);
-
+
// (DCEVM) TODO: Check if this is correct?
//CodeCache::scavenge_root_nmethods_oops_do(oopClosure);
//Management::oops_do(oopClosure);
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index e14aaee21c4..c860371d2fc 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -1139,6 +1139,7 @@ void InstanceKlass::init_implementor() {
}
}
+// (DCEVM) - init_implementor() for dcevm
void InstanceKlass::init_implementor_from_redefine() {
assert(is_interface(), "not interface");
Klass** addr = adr_implementor();
@@ -1209,6 +1210,8 @@ bool InstanceKlass::implements_interface(Klass* k) const {
return false;
}
+
+// (DCEVM)
bool InstanceKlass::implements_interface_any_version(Klass* k) const {
k = k->newest_version();
if (this->newest_version() == k) return true;
@@ -1491,10 +1494,8 @@ void InstanceKlass::methods_do(void f(Method* method)) {
}
}
-/**
- Update information contains mapping of fields from old class to the new class.
- Info is stored on HEAP, you need to call clear_update_information to free the space.
-*/
+// (DCEVM) Update information contains mapping of fields from old class to the new class.
+// Info is stored on HEAP, you need to call clear_update_information to free the space.
void InstanceKlass::store_update_information(GrowableArray<int> &values) {
int *arr = NEW_C_HEAP_ARRAY(int, values.length(), mtClass);
for (int i = 0; i < values.length(); i++) {
@@ -2162,6 +2163,7 @@ void InstanceKlass::add_dependent_nmethod(nmethod* nm) {
dependencies().add_dependent_nmethod(nm);
}
+// DCEVM - update jmethod ids
bool InstanceKlass::update_jmethod_id(Method* method, jmethodID newMethodID) {
size_t idnum = (size_t)method->method_idnum();
jmethodID* jmeths = methods_jmethod_ids_acquire();
@@ -2177,7 +2179,7 @@ bool InstanceKlass::update_jmethod_id(Method* method, jmethodID newMethodID) {
void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) {
dependencies().remove_dependent_nmethod(nm, delete_immediately);
- // (DCEVM) Hack as dependencies get wrong version of Klass*
+ // FIXME: (DCEVM) Hack as dependencies get wrong version of Klass*
// if (this->old_version() != NULL) {
// InstanceKlass::cast(this->old_version())->remove_dependent_nmethod(nm, true);
// return;
@@ -3594,6 +3596,7 @@ void InstanceKlass::verify_on(outputStream* st) {
}
guarantee(sib->is_klass(), "should be klass");
+ // TODO: (DCEVM) explain
guarantee(sib->super() == super || super->newest_version() == SystemDictionary::Object_klass(), "siblings should have same superklass");
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,36 @@
From ab8888737eaed76776b41b28af93a0c47826b8d6 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Tue, 19 May 2020 10:31:15 +0200
Subject: [PATCH 41/48] Activate cpCache definition asserts for !dcevm
---
src/hotspot/share/oops/cpCache.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp
index 47040d51f0c..4318df227d1 100644
--- a/src/hotspot/share/oops/cpCache.cpp
+++ b/src/hotspot/share/oops/cpCache.cpp
@@ -436,8 +436,7 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
if (has_appendix) {
const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset;
assert(appendix_index >= 0 && appendix_index < resolved_references->length(), "oob");
- // FIXME (DCEVM) relaxing for now...
- //assert(resolved_references->obj_at(appendix_index) == NULL, "init just once");
+ assert(AllowEnhancedClassRedefinition || resolved_references->obj_at(appendix_index) == NULL, "init just once");
resolved_references->obj_at_put(appendix_index, appendix());
}
@@ -445,8 +444,7 @@ void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle&
if (has_method_type) {
const int method_type_index = f2_as_index() + _indy_resolved_references_method_type_offset;
assert(method_type_index >= 0 && method_type_index < resolved_references->length(), "oob");
- // FIXME (DCEVM) relaxing for now...
- //assert(resolved_references->obj_at(method_type_index) == NULL, "init just once");
+ assert(AllowEnhancedClassRedefinition || resolved_references->obj_at(method_type_index) == NULL, "init just once");
resolved_references->obj_at_put(method_type_index, method_type());
}
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,29 @@
From 8596cf8b677eadcd18b527dd61c891475758bbaa Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Tue, 19 May 2020 10:54:38 +0200
Subject: [PATCH 42/48] iterate old method version only in dcevm
---
src/hotspot/share/prims/jvmtiImpl.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiImpl.cpp b/src/hotspot/share/prims/jvmtiImpl.cpp
index 2a92ece916e..d2044541d38 100644
--- a/src/hotspot/share/prims/jvmtiImpl.cpp
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp
@@ -294,8 +294,10 @@ void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
Symbol* m_signature = _method->signature();
// (DCEVM) Go through old versions of method
- for (Method* m = _method->old_version(); m != NULL; m = m->old_version()) {
- (m->*meth_act)(_bci);
+ if (AllowEnhancedClassRedefinition) {
+ for (Method* m = _method->old_version(); m != NULL; m = m->old_version()) {
+ (m->*meth_act)(_bci);
+ }
}
// search previous versions if they exist
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,258 @@
From f3c1667fc04abdd9aa556b2c00a23239eba14287 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 22 May 2020 21:23:01 +0200
Subject: [PATCH 43/48] Support for Lambda class redefinition
---
.../share/classfile/classLoaderData.cpp | 9 +++
.../share/classfile/classLoaderData.hpp | 1 +
.../share/classfile/systemDictionary.cpp | 12 +++-
.../share/classfile/systemDictionary.hpp | 2 +
.../prims/jvmtiEnhancedRedefineClasses.cpp | 65 +++++++++++++++++--
.../prims/jvmtiEnhancedRedefineClasses.hpp | 1 +
.../share/prims/resolvedMethodTable.cpp | 4 +-
src/hotspot/share/prims/unsafe.cpp | 1 +
8 files changed, 85 insertions(+), 10 deletions(-)
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index ab2615da0ed..1bc67adf5a7 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -663,6 +663,15 @@ Dictionary* ClassLoaderData::create_dictionary() {
return new Dictionary(this, size, resizable);
}
+void ClassLoaderData::exchange_holders(ClassLoaderData* cld) {
+ oop holder_oop = _holder.peek();
+ _holder.replace(cld->_holder.peek());
+ cld->_holder.replace(holder_oop);
+ WeakHandle<vm_class_loader_data> exchange = _holder;
+ _holder = cld->_holder;
+ cld->_holder = exchange;
+}
+
// Tell the GC to keep this klass alive while iterating ClassLoaderDataGraph
oop ClassLoaderData::holder_phantom() const {
// A klass that was previously considered dead can be looked up in the
diff --git a/src/hotspot/share/classfile/classLoaderData.hpp b/src/hotspot/share/classfile/classLoaderData.hpp
index 7e357929971..00a84610b43 100644
--- a/src/hotspot/share/classfile/classLoaderData.hpp
+++ b/src/hotspot/share/classfile/classLoaderData.hpp
@@ -292,6 +292,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
void accumulate_modified_oops() { if (has_modified_oops()) _accumulated_modified_oops = true; }
void clear_accumulated_modified_oops() { _accumulated_modified_oops = false; }
bool has_accumulated_modified_oops() { return _accumulated_modified_oops; }
+ void exchange_holders(ClassLoaderData* cld);
private:
void unload();
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index e70865109dd..cc9f1fa7831 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -971,12 +971,16 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
Handle protection_domain,
ClassFileStream* st,
const InstanceKlass* host_klass,
+ InstanceKlass* old_klass,
GrowableArray<Handle>* cp_patches,
TRAPS) {
EventClassLoad class_load_start_event;
ClassLoaderData* loader_data;
+
+ bool is_redefining = (old_klass != NULL);
+
if (host_klass != NULL) {
// Create a new CLD for anonymous class, that uses the same class loader
// as the host_klass
@@ -1000,8 +1004,12 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
protection_domain,
host_klass,
cp_patches,
- false, // pick_newest
+ is_redefining, // pick_newest
CHECK_NULL);
+ if (is_redefining && k != NULL) {
+ k->set_redefining(true);
+ k->set_old_version(old_klass);
+ }
if (host_klass != NULL && k != NULL) {
// Anonymous classes must update ClassLoaderData holder (was host_klass loader)
@@ -1845,7 +1853,7 @@ void SystemDictionary::remove_from_hierarchy(InstanceKlass* k) {
k->remove_from_sibling_list();
}
-// (DCEVM)
+// (DCEVM)
void SystemDictionary::update_constraints_after_redefinition() {
constraints()->update_after_redefinition();
}
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
index 717f34ce9a0..dc111846c12 100644
--- a/src/hotspot/share/classfile/systemDictionary.hpp
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -301,6 +301,7 @@ public:
protection_domain,
st,
NULL, // host klass
+ NULL, // old class
NULL, // cp_patches
THREAD);
}
@@ -309,6 +310,7 @@ public:
Handle protection_domain,
ClassFileStream* st,
const InstanceKlass* host_klass,
+ InstanceKlass* old_klass,
GrowableArray<Handle>* cp_patches,
TRAPS);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 0ca675e8ee6..08fe42d5c28 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -503,6 +503,8 @@ void VM_EnhancedRedefineClasses::doit() {
ClassLoaderDataGraph::classes_do(&clear_cpool_cache);
+ // SystemDictionary::methods_do(fix_invoke_method);
+
// JSR-292 support
if (_any_class_has_resolved_methods) {
bool trace_name_printed = false;
@@ -774,12 +776,34 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
// load hook event.
state->set_class_being_redefined(the_class, _class_load_kind);
- InstanceKlass* k = SystemDictionary::resolve_from_stream(the_class_sym,
- the_class_loader,
- protection_domain,
- &st,
- the_class,
- THREAD);
+ InstanceKlass* k;
+
+ if (InstanceKlass::cast(the_class)->is_anonymous()) {
+ const InstanceKlass* host_class = the_class->host_klass();
+
+ // Make sure it's the real host class, not another anonymous class.
+ while (host_class != NULL && host_class->is_anonymous()) {
+ host_class = host_class->host_klass();
+ }
+
+ k = SystemDictionary::parse_stream(the_class_sym,
+ the_class_loader,
+ protection_domain,
+ &st,
+ host_class,
+ the_class,
+ NULL,
+ THREAD);
+ k->class_loader_data()->exchange_holders(the_class->class_loader_data());
+ the_class->class_loader_data()->inc_keep_alive();
+ } else {
+ k = SystemDictionary::resolve_from_stream(the_class_sym,
+ the_class_loader,
+ protection_domain,
+ &st,
+ the_class,
+ THREAD);
+ }
// Clear class_being_redefined just to be sure.
state->clear_class_being_redefined();
@@ -1469,6 +1493,30 @@ void VM_EnhancedRedefineClasses::MethodDataCleaner::do_klass(Klass* k) {
}
}
+void VM_EnhancedRedefineClasses::fix_invoke_method(Method* method) {
+
+ constantPoolHandle other_cp = constantPoolHandle(method->constants());
+
+ for (int i = 0; i < other_cp->length(); i++) {
+ if (other_cp->tag_at(i).is_klass()) {
+ Klass* klass = other_cp->resolved_klass_at(i);
+ if (klass->new_version() != NULL) {
+ // Constant pool entry points to redefined class -- update to the new version
+ other_cp->klass_at_put(i, klass->newest_version());
+ }
+ assert(other_cp->resolved_klass_at(i)->new_version() == NULL, "Must be new klass!");
+ }
+ }
+
+ ConstantPoolCache* cp_cache = other_cp->cache();
+ if (cp_cache != NULL) {
+ cp_cache->clear_entries();
+ }
+
+}
+
+
+
void VM_EnhancedRedefineClasses::update_jmethod_ids() {
for (int j = 0; j < _matching_methods_length; ++j) {
Method* old_method = _matching_old_methods[j];
@@ -2018,7 +2066,10 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
// Find classes not directly redefined, but affected by a redefinition (because one of its supertypes is redefined)
AffectedKlassClosure closure(_affected_klasses);
// Updated in j10, from original SystemDictionary::classes_do
- ClassLoaderDataGraph::dictionary_classes_do(&closure);
+
+ ClassLoaderDataGraph::classes_do(&closure);
+ //ClassLoaderDataGraph::dictionary_classes_do(&closure);
+
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());
// Sort the affected klasses such that a supertype is always on a smaller array index than its subtype.
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index ed44f0e27ce..7e2afd49650 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -119,6 +119,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
void rollback();
static void mark_as_scavengable(nmethod* nm);
static void unpatch_bytecode(Method* method);
+ static void fix_invoke_method(Method* method);
// Figure out which new methods match old methods in name and signature,
// which methods have been added, and which are no longer present
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
index af2ec48c2e1..7741328979f 100644
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
@@ -200,7 +200,7 @@ void ResolvedMethodTable::print() {
void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
assert(SafepointSynchronize::is_at_safepoint(), "only called at safepoint");
- // For each entry in RMT, change to new method
+ // For each entry in RMT, change to new methodadjust_method_entries_dcevm
for (int i = 0; i < _the_table->table_size(); ++i) {
for (ResolvedMethodEntry* entry = _the_table->bucket(i);
entry != NULL;
@@ -271,6 +271,8 @@ void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed)
InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
Method* newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
+ log_info(redefine, class, load, exceptions)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
+
assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
assert(newer_method != NULL, "method_with_idnum() should not be NULL");
assert(old_method != newer_method, "sanity check");
diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp
index 2f14e01ce0d..d0e0367d8eb 100644
--- a/src/hotspot/share/prims/unsafe.cpp
+++ b/src/hotspot/share/prims/unsafe.cpp
@@ -818,6 +818,7 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
host_domain,
&st,
InstanceKlass::cast(host_klass),
+ NULL,
cp_patches,
CHECK_NULL);
if (anonk == NULL) {
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,34 @@
From b8a3d4249eb97613f796edc709e414900c9a0828 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Fri, 22 May 2020 21:43:22 +0200
Subject: [PATCH 44/48] Skip GC runs for redefinitions without instance size
change
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 08fe42d5c28..a785a43d352 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -578,14 +578,14 @@ void VM_EnhancedRedefineClasses::doit() {
}
}
-// if (objectClosure.needs_instance_update()) {
+ if (objectClosure.needs_instance_update()) {
// Do a full garbage collection to update the instance sizes accordingly
Universe::set_redefining_gc_run(true);
notify_gc_begin(true);
Universe::heap()->collect_as_vm_thread(GCCause::_heap_inspection);
notify_gc_end();
Universe::set_redefining_gc_run(false);
-// }
+ }
// Unmark Klass*s as "redefining"
for (int i = 0; i < _new_classes->length(); i++) {
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,135 @@
From 77bdf6253c457ed88436fb4da6a53c7c0c361a1c Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 23 May 2020 10:02:15 +0200
Subject: [PATCH 45/48] Fix "no original bytecode found" error if method with
bkp is missing
Sometimes IDE can deploy class with erroneous method, such method has
no bytecode, but breakpoint position can still exist.
---
src/hotspot/share/interpreter/bytecodes.cpp | 2 +-
.../share/interpreter/interpreterRuntime.cpp | 2 +-
src/hotspot/share/oops/method.cpp | 8 ++++----
src/hotspot/share/oops/method.hpp | 4 ++--
.../prims/jvmtiEnhancedRedefineClasses.cpp | 18 ++++++++++--------
5 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/src/hotspot/share/interpreter/bytecodes.cpp b/src/hotspot/share/interpreter/bytecodes.cpp
index e377e36b88c..262ecc021b2 100644
--- a/src/hotspot/share/interpreter/bytecodes.cpp
+++ b/src/hotspot/share/interpreter/bytecodes.cpp
@@ -84,7 +84,7 @@ Bytecodes::Code Bytecodes::code_at(Method* method, int bci) {
Bytecodes::Code Bytecodes::non_breakpoint_code_at(const Method* method, address bcp) {
assert(method != NULL, "must have the method for breakpoint conversion");
assert(method->contains(bcp), "must be valid bcp in method");
- return method->orig_bytecode_at(method->bci_from(bcp));
+ return method->orig_bytecode_at(method->bci_from(bcp), false);
}
int Bytecodes::special_length_at(Bytecodes::Code code, address bcp, address end) {
diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp
index f367e658879..71bbd15a4f5 100644
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp
@@ -834,7 +834,7 @@ IRT_END
// Invokes
IRT_ENTRY(Bytecodes::Code, InterpreterRuntime::get_original_bytecode_at(JavaThread* thread, Method* method, address bcp))
- return method->orig_bytecode_at(method->bci_from(bcp));
+ return method->orig_bytecode_at(method->bci_from(bcp), false);
IRT_END
IRT_ENTRY(void, InterpreterRuntime::set_original_bytecode_at(JavaThread* thread, Method* method, address bcp, Bytecodes::Code new_code))
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
index bee69f9cec6..f1e22db70d6 100644
--- a/src/hotspot/share/oops/method.cpp
+++ b/src/hotspot/share/oops/method.cpp
@@ -1747,14 +1747,14 @@ bool CompressedLineNumberReadStream::read_pair() {
#if INCLUDE_JVMTI
-Bytecodes::Code Method::orig_bytecode_at(int bci) const {
+Bytecodes::Code Method::orig_bytecode_at(int bci, bool no_fatal) const {
BreakpointInfo* bp = method_holder()->breakpoints();
for (; bp != NULL; bp = bp->next()) {
if (bp->match(this, bci)) {
return bp->orig_bytecode();
}
}
- {
+ if (!no_fatal) {
ResourceMark rm;
fatal("no original bytecode found in %s at bci %d", name_and_sig_as_C_string(), bci);
}
@@ -1900,7 +1900,7 @@ BreakpointInfo::BreakpointInfo(Method* m, int bci) {
_signature_index = m->signature_index();
_orig_bytecode = (Bytecodes::Code) *m->bcp_from(_bci);
if (_orig_bytecode == Bytecodes::_breakpoint)
- _orig_bytecode = m->orig_bytecode_at(_bci);
+ _orig_bytecode = m->orig_bytecode_at(_bci, false);
_next = NULL;
}
@@ -1909,7 +1909,7 @@ void BreakpointInfo::set(Method* method) {
{
Bytecodes::Code code = (Bytecodes::Code) *method->bcp_from(_bci);
if (code == Bytecodes::_breakpoint)
- code = method->orig_bytecode_at(_bci);
+ code = method->orig_bytecode_at(_bci, false);
assert(orig_bytecode() == code, "original bytecode must be the same");
}
#endif
diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp
index 4533476ff8f..193e1845b23 100644
--- a/src/hotspot/share/oops/method.hpp
+++ b/src/hotspot/share/oops/method.hpp
@@ -230,7 +230,7 @@ class Method : public Metadata {
// JVMTI breakpoints
#if !INCLUDE_JVMTI
- Bytecodes::Code orig_bytecode_at(int bci) const {
+ Bytecodes::Code orig_bytecode_at(int bci, bool no_fatal) const {
ShouldNotReachHere();
return Bytecodes::_shouldnotreachhere;
}
@@ -239,7 +239,7 @@ class Method : public Metadata {
};
u2 number_of_breakpoints() const {return 0;}
#else // !INCLUDE_JVMTI
- Bytecodes::Code orig_bytecode_at(int bci) const;
+ Bytecodes::Code orig_bytecode_at(int bci, bool no_fatal) const;
void set_orig_bytecode_at(int bci, Bytecodes::Code code);
void set_breakpoint(int bci);
void clear_breakpoint(int bci);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index a785a43d352..2321483dcbd 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1389,14 +1389,16 @@ void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method) {
if (code == Bytecodes::_breakpoint) {
int bci = method->bci_from(bcp);
- code = method->orig_bytecode_at(bci);
- java_code = Bytecodes::java_code(code);
- if (code != java_code &&
- (java_code == Bytecodes::_getfield ||
- java_code == Bytecodes::_putfield ||
- java_code == Bytecodes::_aload_0)) {
- // Let breakpoint table handling unpatch bytecode
- method->set_orig_bytecode_at(bci, java_code);
+ code = method->orig_bytecode_at(bci, true);
+ if (code != Bytecodes::_shouldnotreachhere) {
+ java_code = Bytecodes::java_code(code);
+ if (code != java_code &&
+ (java_code == Bytecodes::_getfield ||
+ java_code == Bytecodes::_putfield ||
+ java_code == Bytecodes::_aload_0)) {
+ // Let breakpoint table handling unpatch bytecode
+ method->set_orig_bytecode_at(bci, java_code);
+ }
}
} else {
java_code = Bytecodes::java_code(code);
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,421 @@
From d3371d7d52bd4dc66efd4f6a946d5045b8bc8b2b Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sat, 23 May 2020 10:17:56 +0200
Subject: [PATCH 46/48] Fix comments according hotspot formatting conventions
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 191 +++++++-----------
.../prims/jvmtiEnhancedRedefineClasses.hpp | 41 ++--
2 files changed, 90 insertions(+), 142 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 2321483dcbd..8d00203fd9a 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -67,21 +67,19 @@ int VM_EnhancedRedefineClasses::_deleted_methods_length = 0;
int VM_EnhancedRedefineClasses::_added_methods_length = 0;
Klass* VM_EnhancedRedefineClasses::_the_class_oop = NULL;
-/**
- * Create new instance of enhanced class redefiner.
- *
- * This class implements VM_GC_Operation - the usual usage should be:
- * VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
- * VMThread::execute(&op);
- * Which
- *
- * @param class_count size of class_defs
- * @param class_defs class definition - either new class or redefined class
- * note that this is not the final array of classes to be redefined
- * we need to scan for all affected classes (e.g. subclasses) and
- * caculcate redefinition for them as well.
- * @param class_load_kind always jvmti_class_load_kind_redefine
- */
+//
+// Create new instance of enhanced class redefiner.
+//
+// This class implements VM_GC_Operation - the usual usage should be:
+// VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
+// VMThread::execute(&op);
+// Which
+// - class_count size of class_defs
+// - class_defs class definition - either new class or redefined class
+// note that this is not the final array of classes to be redefined
+// we need to scan for all affected classes (e.g. subclasses) and
+// caculcate redefinition for them as well.
+// @param class_load_kind always jvmti_class_load_kind_redefine
VM_EnhancedRedefineClasses::VM_EnhancedRedefineClasses(jint class_count, const jvmtiClassDefinition *class_defs, JvmtiClassLoadKind class_load_kind) :
VM_GC_Operation(Universe::heap()->total_collections(), GCCause::_heap_inspection, Universe::heap()->total_full_collections(), true) {
_affected_klasses = NULL;
@@ -97,12 +95,10 @@ static inline InstanceKlass* get_ik(jclass def) {
return InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
}
-/**
- * Start the redefinition:
- * - Load new class definitions - @see load_new_class_versions
- * - Start mark&sweep GC.
- * @return true if success, otherwise all chnages are rollbacked.
- */
+// Start the redefinition:
+// - Load new class definitions - @see load_new_class_versions
+// - Start mark&sweep GC.
+// - true if success, otherwise all chnages are rollbacked.
bool VM_EnhancedRedefineClasses::doit_prologue() {
if (_class_count == 0) {
@@ -175,9 +171,7 @@ bool VM_EnhancedRedefineClasses::doit_prologue() {
return true;
}
-/**
- * Closer for static fields - copy value from old class to the new class.
- */
+// Closer for static fields - copy value from old class to the new class.
class FieldCopier : public FieldClosure {
public:
void do_field(fieldDescriptor* fd) {
@@ -236,9 +230,7 @@ struct StoreNoBarrier {
template <class T> static void oop_store(T* p) { RawAccess<>::oop_store(p, oop(NULL)); }
};
-/**
- Closure to scan all heap objects and update method handles
-*/
+// Closure to scan all heap objects and update method handles
template <class S>
class ChangePointersOopClosure : public BasicOopIterateClosure {
// import java_lang_invoke_MemberName.*
@@ -247,7 +239,6 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
};
-
bool update_member_name(oop obj) {
int flags = java_lang_invoke_MemberName::flags(obj);
int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
@@ -382,14 +373,12 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
}
};
-/**
- * Closure to scan all objects on heap for objects of changed classes
- * - if the fields are compatible, only update class definition reference
- * - otherwise if the new object size is smaller then old size, reshufle
- * the fields and fill the gap with "dead_space"
- * - otherwise set the _needs_instance_update flag, we need to do full GC
- * and reshuffle object positions durring mark&sweep
- */
+// Closure to scan all objects on heap for objects of changed classes
+// - if the fields are compatible, only update class definition reference
+// - otherwise if the new object size is smaller then old size, reshufle
+// the fields and fill the gap with "dead_space"
+// - otherwise set the _needs_instance_update flag, we need to do full GC
+// and reshuffle object positions durring mark&sweep
class ChangePointersObjectClosure : public ObjectClosure {
private:
@@ -451,19 +440,16 @@ public:
};
-/**
- Main transformation method - runs in VM thread.
-
- - UseSharedSpaces - TODO what does it mean?
- - for each sratch class call redefine_single_class
- - clear code cache (flush_dependent_code)
- - iterate the heap and update object defintions, check it old/new class fields
- are compatible. If new class size is smaller then old, it can be solved directly here.
- - iterate the heap and update method handles to new version
- - Swap marks to have same hashcodes
- - copy static fields
- - notify JVM of the modification
-*/
+// Main transformation method - runs in VM thread.
+// - UseSharedSpaces - TODO what does it mean?
+// - for each sratch class call redefine_single_class
+// - clear code cache (flush_dependent_code)
+// - iterate the heap and update object defintions, check it old/new class fields
+// are compatible. If new class size is smaller then old, it can be solved directly here.
+// - iterate the heap and update method handles to new version
+// - Swap marks to have same hashcodes
+// - copy static fields
+// - notify JVM of the modification
void VM_EnhancedRedefineClasses::doit() {
Thread *thread = Thread::current();
@@ -634,11 +620,9 @@ void VM_EnhancedRedefineClasses::doit() {
}
-/**
- * Cleanup - runs in JVM thread
- * - free used memory
- * - end GC
- */
+// Cleanup - runs in JVM thread
+// - free used memory
+// - end GC
void VM_EnhancedRedefineClasses::doit_epilogue() {
VM_GC_Operation::doit_epilogue();
@@ -670,11 +654,9 @@ void VM_EnhancedRedefineClasses::doit_epilogue() {
}
}
-/**
- * Exclude java primitives and arrays from redefinition
- * @param klass_mirror pointer to the klass
- * @return true if is modifiable
- */
+// Exclude java primitives and arrays from redefinition
+// - klass_mirror pointer to the klass
+// - true if is modifiable
bool VM_EnhancedRedefineClasses::is_modifiable_class(oop klass_mirror) {
// classes for primitives cannot be redefined
if (java_lang_Class::is_primitive(klass_mirror)) {
@@ -693,17 +675,12 @@ bool VM_EnhancedRedefineClasses::is_modifiable_class(oop klass_mirror) {
return true;
}
-/**
- Load and link new classes (either redefined or affected by redefinition - subclass, ...)
-
- - find sorted affected classes
- - resolve new class
- - calculate redefine flags (field change, method change, supertype change, ...)
- - calculate modified fields and mapping to old fields
- - link new classes
-
- The result is sotred in _affected_klasses(old definitions) and _new_classes(new definitions) arrays.
-*/
+// Load and link new classes (either redefined or affected by redefinition - subclass, ...)
+// - find sorted affected classes
+// - resolve new class
+// - calculate redefine flags (field change, method change, supertype change, ...)
+// - calculate modified fields and mapping to old fields
+// - link new classes
jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
_affected_klasses = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(_class_count, true);
@@ -898,9 +875,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
return JVMTI_ERROR_NONE;
}
-/**
- Calculated the difference between new and old class (field change, method change, supertype change, ...).
-*/
+ // Calculated the difference between new and old class (field change, method change, supertype change, ...).
int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_class) {
int result = Klass::NoRedefinition;
log_info(redefine, class, load)("Comparing different class versions of class %s",new_class->name()->as_C_string());
@@ -1183,14 +1158,11 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
}
-/**
- Searches for the class bytecode of the given class and returns it as a byte array.
-
- @param the_class definition of a class, either existing class or new_class
- @param class_bytes - if the class is redefined, it contains new class definition, otherwise just original class bytecode.
- @param class_byte_count - size of class_bytes
- @param not_changed - new_class not available or same as current class
-*/
+// Searches for the class bytecode of the given class and returns it as a byte array.
+// - the_class definition of a class, either existing class or new_class
+// - class_bytes - if the class is redefined, it contains new class definition, otherwise just original class bytecode.
+// - class_byte_count - size of class_bytes
+// - not_changed - new_class not available or same as current class
jvmtiError VM_EnhancedRedefineClasses::find_class_bytes(InstanceKlass* the_class, const unsigned char **class_bytes, jint *class_byte_count, jboolean *not_changed) {
*not_changed = false;
@@ -1233,11 +1205,9 @@ jvmtiError VM_EnhancedRedefineClasses::find_class_bytes(InstanceKlass* the_class
return JVMTI_ERROR_NONE;
}
-/**
- Calculate difference between non static fields of old and new class and store the info into new class:
- instanceKlass->store_update_information
- instanceKlass->copy_backwards
-*/
+// Calculate difference between non static fields of old and new class and store the info into new class:
+// instanceKlass->store_update_information
+// instanceKlass->copy_backwards
void VM_EnhancedRedefineClasses::calculate_instance_update_information(Klass* new_version) {
class CalculateFieldUpdates : public FieldClosure {
@@ -1348,9 +1318,7 @@ void VM_EnhancedRedefineClasses::calculate_instance_update_information(Klass* ne
}
}
-/**
- Rollback all changes - clear new classes from the system dictionary, return old classes to directory, free memory.
-*/
+// Rollback all changes - clear new classes from the system dictionary, return old classes to directory, free memory.
void VM_EnhancedRedefineClasses::rollback() {
log_info(redefine, class, load)("Rolling back redefinition, result=%d", _res);
ClassLoaderDataGraph::rollback_redefinition();
@@ -1547,9 +1515,7 @@ void VM_EnhancedRedefineClasses::update_jmethod_ids() {
}
}
-/**
- Set method as obsolete / old / deleted.
-*/
+// Set method as obsolete / old / deleted.
void VM_EnhancedRedefineClasses::check_methods_and_mark_as_obsolete() {
for (int j = 0; j < _matching_methods_length; ++j/*, ++old_index*/) {
Method* old_method = _matching_old_methods[j];
@@ -1771,12 +1737,9 @@ void VM_EnhancedRedefineClasses::flush_dependent_code(InstanceKlass* k_h, TRAPS)
}
}
-/**
- Compare _old_methods and _new_methods arrays and store the result into
- _matching_old_methods, _matching_new_methods, _added_methods, _deleted_methods
-
- Setup _old_methods and _new_methods before the call - it should be called for one class only!
-*/
+// Compare _old_methods and _new_methods arrays and store the result into
+// _matching_old_methods, _matching_new_methods, _added_methods, _deleted_methods
+// Setup _old_methods and _new_methods before the call - it should be called for one class only!
void VM_EnhancedRedefineClasses::compute_added_deleted_matching_methods() {
Method* old_method;
Method* new_method;
@@ -1900,7 +1863,6 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
}
*/
-
{
ResourceMark rm(THREAD);
// increment the classRedefinedCount field in the_class and in any
@@ -1940,9 +1902,7 @@ void VM_EnhancedRedefineClasses::check_class(InstanceKlass* ik, TRAPS) {
}
}
-/**
- * Logging of all methods (old, new, changed, ...)
- */
+// Logging of all methods (old, new, changed, ...)
void VM_EnhancedRedefineClasses::dump_methods() {
int j;
log_trace(redefine, class, dump)("_old_methods --");
@@ -2002,9 +1962,7 @@ void VM_EnhancedRedefineClasses::dump_methods() {
}
}
-/**
- Helper class to traverse all loaded classes and figure out if the class is affected by redefinition.
-*/
+// Helper class to traverse all loaded classes and figure out if the class is affected by redefinition.
class AffectedKlassClosure : public KlassClosure {
private:
GrowableArray<Klass*>* _affected_klasses;
@@ -2052,10 +2010,8 @@ class AffectedKlassClosure : public KlassClosure {
}
};
-/**
- Find all affected classes by current redefinition (either because of redefine, class hierarchy or interface change).
- Affected classes are stored in _affected_klasses and parent classes always precedes child class.
-*/
+// Find all affected classes by current redefinition (either because of redefine, class hierarchy or interface change).
+// Affected classes are stored in _affected_klasses and parent classes always precedes child class.
jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
for (int i = 0; i < _class_count; i++) {
InstanceKlass* klass_handle = get_ik(_class_defs[i].klass);
@@ -2086,9 +2042,7 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
return JVMTI_ERROR_NONE;
}
-/**
- Pairs of class dependencies (for topological sort)
-*/
+// Pairs of class dependencies (for topological sort)
struct KlassPair {
const Klass* _left;
const Klass* _right;
@@ -2101,14 +2055,11 @@ static bool match_second(void* value, KlassPair elem) {
return elem._right == value;
}
-/**
- For each class to be redefined parse the bytecode and figure out the superclass and all interfaces.
- First newly introduced classes (_class_defs) are scanned and then affected classed (_affected_klasses).
- Affected flag is cleared (clear_redefinition_flag(Klass::MarkedAsAffected))
- For each dependency create a KlassPair instance. Finnaly, affected classes (_affected_klasses) are sorted according to pairs.
-
- TODO - the class file is potentionally parsed multiple times - introduce a cache?
-*/
+// For each class to be redefined parse the bytecode and figure out the superclass and all interfaces.
+// First newly introduced classes (_class_defs) are scanned and then affected classed (_affected_klasses).
+// Affected flag is cleared (clear_redefinition_flag(Klass::MarkedAsAffected))
+// For each dependency create a KlassPair instance. Finnaly, affected classes (_affected_klasses) are sorted according to pairs.
+// TODO - the class file is potentionally parsed multiple times - introduce a cache?
jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
ResourceMark mark(THREAD);
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 7e2afd49650..d8a11b51fe9 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -35,17 +35,16 @@
#include "gc/shared/vmGCOperations.hpp"
#include "../../../java.base/unix/native/include/jni_md.h"
-/**
- * Enhanced class redefiner.
- *
- * This class implements VM_GC_Operation - the usual usage should be:
- * VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
- * VMThread::execute(&op);
- * Which in turn runs:
- * - doit_prologue() - calculate all affected classes (add subclasses etc) and load new class versions
- * - doit() - main redefition, adjust existing objects on the heap, clear caches
- * - doit_epilogue() - cleanup
-*/
+//
+// Enhanced class redefiner.
+//
+// This class implements VM_GC_Operation - the usual usage should be:
+// VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
+// VMThread::execute(&op);
+// Which in turn runs:
+// - doit_prologue() - calculate all affected classes (add subclasses etc) and load new class versions
+// - doit() - main redefition, adjust existing objects on the heap, clear caches
+// - doit_epilogue() - cleanup
class VM_EnhancedRedefineClasses: public VM_GC_Operation {
private:
// These static fields are needed by ClassLoaderDataGraph::classes_do()
@@ -93,17 +92,15 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
// These routines are roughly in call order unless otherwise noted.
- /**
- Load and link new classes (either redefined or affected by redefinition - subclass, ...)
-
- - find sorted affected classes
- - resolve new class
- - calculate redefine flags (field change, method change, supertype change, ...)
- - calculate modified fields and mapping to old fields
- - link new classes
-
- The result is sotred in _affected_klasses(old definitions) and _new_classes(new definitions) arrays.
- */
+ // Load and link new classes (either redefined or affected by redefinition - subclass, ...)
+ //
+ // - find sorted affected classes
+ // - resolve new class
+ // - calculate redefine flags (field change, method change, supertype change, ...)
+ // - calculate modified fields and mapping to old fields
+ // - link new classes
+ //
+ // The result is sotred in _affected_klasses(old definitions) and _new_classes(new definitions) arrays.
jvmtiError load_new_class_versions(TRAPS);
// Searches for all affected classes and performs a sorting such tha
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,47 @@
From 2ad306a4cce06cfccf95a1193daf5b968ec1fa87 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 24 May 2020 12:07:09 +0200
Subject: [PATCH 47/48] Review threads, cleanup
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 8d00203fd9a..1fbba406087 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -253,7 +253,7 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
// Note: we might set NULL at this point, which should force AbstractMethodError at runtime
Thread *thread = Thread::current();
CallInfo info(new_method, newest, thread);
- Handle objHandle(thread, obj); // TODO : review thread
+ Handle objHandle(thread, obj);
MethodHandles::init_method_MemberName(objHandle, info);
} else {
java_lang_invoke_MemberName::set_method(obj, NULL);
@@ -280,7 +280,7 @@ class ChangePointersOopClosure : public BasicOopIterateClosure {
InstanceKlass* ik_new = InstanceKlass::cast(k->newest_version());
fieldDescriptor fd_new;
if (ik_new->find_local_field(fd.name(), fd.signature(), &fd_new)) {
- Handle objHandle(Thread::current(), obj); // TODO : review thread
+ Handle objHandle(Thread::current(), obj);
MethodHandles::init_field_MemberName(objHandle, fd_new, MethodHandles::ref_kind_is_setter(ref_kind));
} else {
// Matching field is not found in new version, not much we can do here.
@@ -441,10 +441,9 @@ public:
// Main transformation method - runs in VM thread.
-// - UseSharedSpaces - TODO what does it mean?
-// - for each sratch class call redefine_single_class
+// - for each scratch class call redefine_single_class
// - clear code cache (flush_dependent_code)
-// - iterate the heap and update object defintions, check it old/new class fields
+// - iterate the heap and update object definitions, check it old/new class fields
// are compatible. If new class size is smaller then old, it can be solved directly here.
// - iterate the heap and update method handles to new version
// - Swap marks to have same hashcodes
--
2.24.3 (Apple Git-128)

View File

@@ -0,0 +1,57 @@
From a5586aff03fde654102e2c2e1fc19fdea406b31e Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <lada.dvorak7@gmail.com>
Date: Sun, 24 May 2020 12:07:42 +0200
Subject: [PATCH 48/48] Replace deleted method with
Universe::throw_no_such_method_error
---
.../share/prims/resolvedMethodTable.cpp | 28 +++++++++----------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
index 7741328979f..06581643c3b 100644
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
@@ -261,25 +261,25 @@ void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed)
if (old_method->is_old()) {
+ InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
+ Method* newer_method;
+
// Method* new_method;
if (old_method->is_deleted()) {
- // FIXME:(DCEVM) - check if exception can be thrown
- // new_method = Universe::throw_no_such_method_error();
- continue;
- }
-
- InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
- Method* newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
+ newer_method = Universe::throw_no_such_method_error();
+ } else {
+ newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
- log_info(redefine, class, load, exceptions)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
+ log_info(redefine, class, load, exceptions)("Adjusting method: '%s' of new class %s", newer_method->name_and_sig_as_C_string(), newer_klass->name()->as_C_string());
- assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
- assert(newer_method != NULL, "method_with_idnum() should not be NULL");
- assert(old_method != newer_method, "sanity check");
+ assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
+ assert(newer_method != NULL, "method_with_idnum() should not be NULL");
+ assert(old_method != newer_method, "sanity check");
- if (_the_table->lookup(newer_method) != NULL) {
- // old method was already adjusted if new method exists in _the_table
- continue;
+ if (_the_table->lookup(newer_method) != NULL) {
+ // old method was already adjusted if new method exists in _the_table
+ continue;
+ }
}
java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, newer_method);
--
2.24.3 (Apple Git-128)

View File

@@ -1,9 +0,0 @@
#!/bin/bash -x
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
script_dir=jb/project/tools/windows/scripts
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jcef" || exit $?
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx" || exit $?
${script_dir}/mkimages_x64.sh $JBSDK_VERSION $JDK_BUILD_NUMBER $build_number "jfx_jcef" || exit $?

View File

@@ -1,12 +1,13 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# JBSDK_VERSION - specifies major version of OpenJDK e.g. 11_0_6 (instead of dots '.' underbars "_" are used)
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
# bundle_type - specifies bundle to be built; possible values:
# <empty> or nomod - the release bundles without any additional modules (jcef)
# jcef - the release bundles with jcef
# fd - the fastdebug bundles which also include the jcef module
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
@@ -16,104 +17,91 @@
# OpenJDK Runtime Environment (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number})
# OpenJDK 64-Bit Server VM (build 11.0.6+${JDK_BUILD_NUMBER}-b${build_number}, mixed mode)
#
# Environment variables:
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_win_x64
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
WORK_DIR=$(pwd)
JCEF_PATH=${JCEF_PATH:=$WORK_DIR/jcef_win_x64}
function create_jbr {
source jb/project/tools/common/scripts/common.sh
case "$1" in
"${bundle_type}_lw")
grep -v "jdk.compiler\|jdk.hotspot.agent" modules.list > modules_tmp.list
;;
"jfx" | "jcef" | "jfx_jcef")
cat modules.list > modules_tmp.list
;;
*)
cat modules.list > modules_tmp.list
;;
esac
rm -rf ${JBR_BUNDLE}
function create_image_bundle {
__bundle_name=$1
__modules_path=$2
__modules=$3
[ -d $__bundle_name ] && rm -rf $__bundle_name
echo Running jlink ...
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules_tmp.list | sed s/" "//g) --output ${JBR_BUNDLE} || exit $?
if [[ "${bundle_type}" == *jcef* ]]
then
cp -R jcef_win_x64/* ${JBR_BUNDLE}/bin
fi
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${JBR_BUNDLE}/release
--module-path $__modules_path --no-man-pages --compress=2 \
--add-modules $__modules --output $__bundle_name || do_exit $?
}
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WORK_DIR=$(pwd)
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=windows-x86_64-server-release
#git checkout -- modules.list src
case "$bundle_type" in
"jfx")
echo "Excluding jcef modules"
git apply -p0 < jb/project/tools/exclude_jcef_module.patch
;;
"jcef")
echo "Excluding jfx modules"
git apply -p0 < jb/project/tools/exclude_jfx_module.patch
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
;;
"fd")
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=windows-x86_64-server-fastdebug
;;
esac
PATH="/usr/local/bin:/usr/bin:${PATH}"
sh ./configure \
--disable-warnings-as-errors \
$WITH_DEBUG_LEVEL \
--with-vendor-name="$VENDOR_NAME" \
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
--with-version-pre= \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-opt=b${build_number} \
--with-toolchain-version=$TOOLCHAIN_VERSION \
--with-boot-jdk=$BOOT_JDK \
--disable-ccache \
--enable-cds=yes || do_exit $?
if [ -z "$bundle_type" ]; then
bash ./configure \
--disable-warnings-as-errors \
--with-target-bits=64 \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-toolchain-version=${TOOLCHAIN_VERSION} \
--with-boot-jdk=${BOOT_JDK} \
--disable-ccache \
--enable-cds=yes || exit 1
make LOG=info CONF=$RELEASE_NAME clean images test-image || do_exit $?
else
bash ./configure \
--disable-warnings-as-errors \
--with-target-bits=64 \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-import-modules=${WORK_DIR}/modular-sdk \
--with-toolchain-version=${TOOLCHAIN_VERSION} \
--with-boot-jdk=${BOOT_JDK} \
--disable-ccache \
--enable-cds=yes || exit 1
make LOG=info CONF=$RELEASE_NAME clean images || do_exit $?
fi
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
make LOG=info images CONF=windows-x86_64-server-release test-image || exit 1
else
make LOG=info images CONF=windows-x86_64-server-release || exit 1
fi
JSDK=build/windows-x86_64-server-release/images/jdk
if [[ "$bundle_type" == "*jcef*" || -z "$bundle_type" ]]; then
JBSDK=${JBRSDK_BASE_NAME}-windows-x64-b${build_number}
fi
BASE_DIR=build/windows-x86_64-server-release/images
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk
JSDK_MODS_DIR=$IMAGES_DIR/jmods
JBRSDK_BUNDLE=jbrsdk
rm -rf ${BASE_DIR}/${JBRSDK_BUNDLE} && rsync -a --exclude demo --exclude sample ${JSDK}/ ${JBRSDK_BUNDLE} || exit 1
if [[ "$bundle_type" == "*jcef*" ]]; then
cp -R jcef_win_x64/* ${JBRSDK_BUNDLE}/bin
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
update_jsdk_mods "$JSDK" "$JCEF_PATH"/jmods "$JSDK"/jmods "$JSDK_MODS_DIR" || do_exit $?
cp $JCEF_PATH/jmods/* ${JSDK_MODS_DIR} # $JSDK/jmods is not unchanged
jbr_name_postfix="_${bundle_type}"
fi
if [ -z "$bundle_type" ]; then
JBR_BUNDLE=jbr
else
JBR_BUNDLE=jbr_${bundle_type}
fi
create_jbr ${bundle_type}
# create runtime image bundle
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
create_image_bundle "jbr${jbr_name_postfix}" $JSDK_MODS_DIR "$modules" || do_exit $?
#JBR_BUNDLE=jbr_${bundle_type}_lw
#create_jbr ${bundle_type}_lw
# create sdk image bundle
modules=$(cat ${JSDK}/release | grep MODULES | sed s/MODULES=//g | sed s/' '/,/g | sed s/\"//g | sed s/\\r//g | sed s/\\n//g)
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle "$JBRSDK_BUNDLE" "$JSDK_MODS_DIR" "$modules" || do_exit $?
do_exit 0

View File

@@ -4,9 +4,6 @@
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
@@ -21,30 +18,39 @@ JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
source jb/project/tools/common/scripts/common.sh
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WORK_DIR=$(pwd)
[ -z "$bundle_type" ] && (git apply -p0 < jb/project/tools/patches/exclude_jcef_module.patch || exit $?)
PATH="/usr/local/bin:/usr/bin:${PATH}"
./configure \
--disable-warnings-as-errors \
--disable-debug-symbols \
--with-target-bits=32 \
--with-vendor-name="${VENDOR_NAME}" \
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
--with-version-pre= \
--with-version-build=${JDK_BUILD_NUMBER} \
--with-version-opt=b${build_number} \
--with-toolchain-version=2015 \
--with-toolchain-version=${TOOLCHAIN_VERSION} \
--with-boot-jdk=${BOOT_JDK} \
--disable-ccache \
--enable-cds=yes || exit 1
make clean CONF=windows-x86-normal-server-release || exit 1
make LOG=info images CONF=windows-x86-normal-server-release test-image || exit 1
make clean CONF=windows-x86-server-release || exit 1
make LOG=info images CONF=windows-x86-server-release test-image || exit 1
JBSDK=${JBRSDK_BASE_NAME}-windows-x86-b${build_number}
BASE_DIR=build/windows-x86-normal-server-release/images
BASE_DIR=build/windows-x86-server-release/images
JSDK=${BASE_DIR}/jdk
JBRSDK_BUNDLE=jbrsdk
rm -rf ${BASE_DIR}/${JBRSDK_BUNDLE} && rsync -a --exclude demo --exclude sample ${JSDK}/ ${JBRSDK_BUNDLE} || exit 1
sed 's/JBR/JBRSDK/g' ${JSDK}/release > release
mv release ${JBRSDK_BUNDLE}/release
JBR_BUNDLE=jbr
rm -rf ${JBR_BUNDLE}
@@ -54,4 +60,4 @@ ${JSDK}/bin/jlink \
--add-modules $(xargs < modules.list.x86 | sed s/" "//g) --output ${JBR_BUNDLE} || exit $?
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${JBR_BUNDLE}/release
#grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${JBR_BUNDLE}/release

View File

@@ -1,12 +1,13 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# JBSDK_VERSION - specifies major version of OpenJDK e.g. 11_0_6 (instead of dots '.' underbars "_" are used)
# JDK_BUILD_NUMBER - specifies udate release of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
# bundle_type - specifies bundle to be built; possible values:
# <empty> or nomod - the bundles without any additional modules (jcef)
# jcef - the bundles with jcef
# fd - the fastdebug bundles which also include the jcef module
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
@@ -24,56 +25,51 @@ bundle_type=$4
function pack_jbr {
case "$1" in
"${bundle_type}_lw")
JBR_BASE_NAME=jbr_${bundle_type}_lw-${JBSDK_VERSION}
;;
"jfx" | "jcef")
JBR_BASE_NAME=jbr_${bundle_type}-${JBSDK_VERSION}
;;
"jfx_jcef" | "")
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
;;
*)
echo "***ERR*** bundle was not specified" && exit 1
;;
esac
if [ -z "${bundle_type}" ]; then
JBR_BUNDLE=jbr
else
JBR_BUNDLE=jbr_${bundle_type}
[ -d ${BASE_DIR}/jbr ] && rm -rf ${BASE_DIR}/jbr
cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
fi
JBR_BASE_NAME=${JBR_BUNDLE}-${JBSDK_VERSION}
JBR=$JBR_BASE_NAME-windows-x64-b$build_number
echo Creating $JBR.tar.gz ...
if [ ! -z "$bundle_type" ]; then
rm -rf ${BASE_DIR}/jbr
cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
fi
/usr/bin/tar -czf $JBR.tar.gz -C $BASE_DIR jbr || exit 1
#rm -rf ${BASE_DIR}/${JBR_BUNDLE}
/usr/bin/tar -czf $JBR.tar.gz -C $BASE_DIR jbr || do_exit $?
}
JBRSDK_BASE_NAME=jbrsdk-$JBSDK_VERSION
JBR_BASE_NAME=jbr-$JBSDK_VERSION
RELEASE_NAME=windows-x86_64-server-release
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-b${build_number}
case "$bundle_type" in
"nomod" | "")
bundle_type=""
;;
"fd")
RELEASE_NAME=macosx-x86_64-server-fastdebug
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-fastdebug-b${build_number}
;;
esac
IMAGES_DIR=build/windows-x86_64-server-release/images
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk
JBSDK=$JBRSDK_BASE_NAME-windows-x64-b$build_number
BASE_DIR=.
if [ -z "$bundle_type" ]; then
JBR_BUNDLE=jbr
else
JBR_BUNDLE=jbr_${bundle_type}
fi
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
JBRSDK_BUNDLE=jbrsdk
echo Creating $JBSDK.tar.gz ...
/usr/bin/tar -czf $JBSDK.tar.gz $JBRSDK_BUNDLE || exit 1
[ -f "$JBSDK.tar.gz" ] && rm "$JBSDK.tar.gz"
/usr/bin/tar -czf $JBSDK.tar.gz $JBRSDK_BUNDLE || do_exit $?
fi
JBR_BUNDLE=jbr_${bundle_type}
pack_jbr $bundle_type
if [[ "$bundle_type" == "jfx_jcef" || -z "$bundle_type" ]]; then
if [ "$bundle_type" == "jcef" ]; then
JBRSDK_TEST=$JBRSDK_BASE_NAME-windows-test-x64-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
/usr/bin/tar -czf $JBRSDK_TEST.tar.gz -C $IMAGES_DIR --exclude='test/jdk/demos' test || exit 1
/usr/bin/tar -czf $JBRSDK_TEST.tar.gz -C $IMAGES_DIR --exclude='test/jdk/demos' test || do_exit $?
fi

View File

@@ -4,9 +4,6 @@
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
# bundle_type - specifies bundle to bu built; possible values:
# jcef - the bundles 1) jbr with jcef+javafx, 2) jbrsdk and 3) test will be created
# jfx - the bundle 1) jbr with javafx only will be created
#
# jbrsdk-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
# jbr-${JBSDK_VERSION}-osx-x64-b${build_number}.tar.gz
@@ -24,7 +21,7 @@ build_number=$3
JBRSDK_BASE_NAME=jbrsdk-$JBSDK_VERSION
JBR_BASE_NAME=jbr-$JBSDK_VERSION
IMAGES_DIR=build/windows-x86-normal-server-release/images
IMAGES_DIR=build/windows-x86-server-release/images
JSDK=$IMAGES_DIR/jdk
JBSDK=$JBRSDK_BASE_NAME-windows-x86-b$build_number
BASE_DIR=.

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -101,7 +101,7 @@ define SetupBundleFileBody
# If no subdir is specified and only one BASE_DIR, tar.gz can be done
# directly from BASE_DIR.
$(CD) $$($1_BASE_DIRS) \
&& ( $(TAR) cf - \
&& ( $(TAR) cf - $(TAR_CREATE_EXTRA_PARAM) \
-$(TAR_INCLUDE_PARAM) $$($1_$$($1_BASE_DIRS)_LIST_FILE) \
$(TAR_IGNORE_EXIT_VALUE) ) \
| $(GZIP) > $$@
@@ -110,7 +110,7 @@ define SetupBundleFileBody
# If only one BASE_DIR, but with a SUBDIR set, tar.gz can use the
# transform option to create bundle directly from the BASE_DIR.
$(CD) $$($1_BASE_DIRS) \
&& ( $(TAR) cf - \
&& ( $(TAR) cf - $(TAR_CREATE_EXTRA_PARAM) \
-$(TAR_INCLUDE_PARAM) $$($1_$$($1_BASE_DIRS)_LIST_FILE) \
$$(if $$($1_SUBDIR), --transform 's|^|$$($1_SUBDIR)/|S') \
$(TAR_IGNORE_EXIT_VALUE) ) \
@@ -125,13 +125,6 @@ define SetupBundleFileBody
&& $(TAR) cf - -$(TAR_INCLUDE_PARAM) $$($1_$$d_LIST_FILE) \
$(TAR_IGNORE_EXIT_VALUE) ) \
| ( $(CD) $(SUPPORT_OUTPUTDIR)/bundles/$1/$$($1_SUBDIR) && $(TAR) xf - )$$(NEWLINE) )
# Rename stripped pdb files
ifeq ($(call isTargetOs, windows)+$(SHIP_DEBUG_SYMBOLS), true+public)
for f in `$(FIND) $(SUPPORT_OUTPUTDIR)/bundles/$1/$$($1_SUBDIR) -name "*.stripped.pdb"`; do \
$(ECHO) Renaming $$$${f} to $$$${f%stripped.pdb}pdb $(LOG_INFO); \
$(MV) $$$${f} $$$${f%stripped.pdb}pdb; \
done
endif
# Unzip any zipped debuginfo files
ifeq ($$($1_UNZIP_DEBUGINFO), true)
for f in `$(FIND) $(SUPPORT_OUTPUTDIR)/bundles/$1/$$($1_SUBDIR) -name "*.diz"`; do \
@@ -140,7 +133,7 @@ define SetupBundleFileBody
endif
ifeq ($$($1_TYPE), tar.gz)
$(CD) $(SUPPORT_OUTPUTDIR)/bundles/$1 && \
( $(TAR) cf - \
( $(TAR) cf - $(TAR_CREATE_EXTRA_PARAM) \
$$(if $$($1_SUBDIR), $$($1_SUBDIR), .) $(TAR_IGNORE_EXIT_VALUE) ) \
| $(GZIP) > $$@
else ifeq ($$($1_TYPE), zip)
@@ -190,7 +183,7 @@ endif
ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), )
SYMBOLS_EXCLUDE_PATTERN := %.debuginfo %.diz %.map
SYMBOLS_EXCLUDE_PATTERN := %.debuginfo %.diz %.pdb %.map
# There may be files with spaces in the names, so use ShellFindFiles
# explicitly.
@@ -216,21 +209,6 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), )
endif
endif
# Create special filter rules when dealing with debug symbols on windows
ifeq ($(call isTargetOs, windows), true)
ifeq ($(SHIP_DEBUG_SYMBOLS), )
JDK_SYMBOLS_EXCLUDE_PATTERN := %.pdb
else
ifeq ($(SHIP_DEBUG_SYMBOLS), public)
JDK_SYMBOLS_EXCLUDE_PATTERN := \
$(filter-out \
%.stripped.pdb, \
$(filter %.pdb, $(ALL_JDK_FILES)) \
)
endif
endif
endif
JDK_BUNDLE_FILES := \
$(filter-out \
$(JDK_SYMBOLS_EXCLUDE_PATTERN) \
@@ -240,14 +218,13 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), )
, \
$(ALL_JDK_FILES) \
)
JDK_SYMBOLS_BUNDLE_FILES := \
$(filter \
$(JDK_SYMBOLS_EXCLUDE_PATTERN) \
$(SYMBOLS_EXCLUDE_PATTERN) \
, \
$(filter-out \
$(JDK_IMAGE_HOMEDIR)/demo/% %.stripped.pdb \
$(JDK_IMAGE_HOMEDIR)/demo/% \
, \
$(ALL_JDK_SYMBOLS_FILES) \
) \
@@ -268,116 +245,29 @@ ifneq ($(filter product-bundles% legacy-bundles, $(MAKECMDGOALS)), )
endif
endif
# Create special filter rules when dealing with debug symbols on windows
ifeq ($(call isTargetOs, windows), true)
ifeq ($(SHIP_DEBUG_SYMBOLS), )
JRE_SYMBOLS_EXCLUDE_PATTERN := %.pdb
else
ifeq ($(SHIP_DEBUG_SYMBOLS), public)
JRE_SYMBOLS_EXCLUDE_PATTERN := \
$(filter-out \
%.stripped.pdb, \
$(filter %.pdb, $(ALL_JRE_FILES)) \
)
endif
endif
endif
JRE_BUNDLE_FILES := $(filter-out \
$(JRE_SYMBOLS_EXCLUDE_PATTERN) \
$(SYMBOLS_EXCLUDE_PATTERN), \
$(ALL_JRE_FILES))
# On Macosx release builds, when there is a code signing certificate available,
# the final bundle layout can be signed.
SIGN_BUNDLE := false
ifeq ($(call isTargetOs, macosx)+$(DEBUG_LEVEL), true+release)
ifneq ($(CODESIGN), )
SIGN_BUNDLE := true
endif
endif
$(eval $(call SetupBundleFile, BUILD_JDK_BUNDLE, \
BUNDLE_NAME := $(JDK_BUNDLE_NAME), \
FILES := $(JDK_BUNDLE_FILES), \
SPECIAL_INCLUDES := $(JDK_SPECIAL_INCLUDES), \
BASE_DIRS := $(JDK_IMAGE_DIR), \
SUBDIR := $(JDK_BUNDLE_SUBDIR), \
))
ifeq ($(SIGN_BUNDLE), true)
# Macosx release build and code signing available.
PRODUCT_TARGETS += $(BUILD_JDK_BUNDLE)
################################################################################
# JDK bundle
$(eval $(call SetupCopyFiles, CREATE_JDK_BUNDLE_DIR_SIGNED, \
SRC := $(JDK_IMAGE_DIR), \
FILES := $(JDK_BUNDLE_FILES), \
DEST := $(JDK_MACOSX_BUNDLE_DIR_SIGNED), \
))
$(eval $(call SetupBundleFile, BUILD_JRE_BUNDLE, \
BUNDLE_NAME := $(JRE_BUNDLE_NAME), \
FILES := $(JRE_BUNDLE_FILES), \
BASE_DIRS := $(JRE_IMAGE_DIR), \
SUBDIR := $(JRE_BUNDLE_SUBDIR), \
))
JDK_SIGNED_CODE_RESOURCES := \
$(JDK_MACOSX_BUNDLE_DIR_SIGNED)/$(JDK_MACOSX_CONTENTS_SUBDIR)/_CodeSignature/CodeResources
$(JDK_SIGNED_CODE_RESOURCES): $(CREATE_JDK_BUNDLE_DIR_SIGNED)
$(call LogWarn, Signing $(JDK_BUNDLE_NAME))
$(CODESIGN) -s "$(MACOSX_CODESIGN_IDENTITY)" \
--timestamp --options runtime --deep --force \
$(JDK_MACOSX_BUNDLE_DIR_SIGNED)/$(JDK_MACOSX_BUNDLE_TOP_DIR) $(LOG_DEBUG)
$(TOUCH) $@
$(eval $(call SetupBundleFile, BUILD_JDK_BUNDLE, \
BUNDLE_NAME := $(JDK_BUNDLE_NAME), \
FILES := \
$(CREATE_JDK_BUNDLE_DIR_SIGNED) \
$(JDK_SIGNED_CODE_RESOURCES), \
BASE_DIRS := $(JDK_MACOSX_BUNDLE_DIR_SIGNED), \
SUBDIR := $(JDK_BUNDLE_SUBDIR), \
))
PRODUCT_TARGETS += $(BUILD_JDK_BUNDLE)
################################################################################
# JRE bundle
$(eval $(call SetupCopyFiles, CREATE_JRE_BUNDLE_DIR_SIGNED, \
SRC := $(JRE_IMAGE_DIR), \
FILES := $(JRE_BUNDLE_FILES), \
DEST := $(JRE_MACOSX_BUNDLE_DIR_SIGNED), \
))
JRE_SIGNED_CODE_RESOURCES := \
$(JRE_MACOSX_BUNDLE_DIR_SIGNED)/$(JRE_MACOSX_CONTENTS_SUBDIR)/_CodeSignature/CodeResources
$(JRE_SIGNED_CODE_RESOURCES): $(CREATE_JRE_BUNDLE_DIR_SIGNED)
$(call LogWarn, Signing $(JRE_BUNDLE_NAME))
$(CODESIGN) -s "$(MACOSX_CODESIGN_IDENTITY)" \
--timestamp --options runtime --deep --force \
$(JRE_MACOSX_BUNDLE_DIR_SIGNED)/$(JRE_MACOSX_BUNDLE_TOP_DIR) $(LOG_DEBUG)
$(TOUCH) $@
$(eval $(call SetupBundleFile, BUILD_JRE_BUNDLE, \
BUNDLE_NAME := $(JRE_BUNDLE_NAME), \
FILES := \
$(CREATE_JRE_BUNDLE_DIR_SIGNED) \
$(JRE_SIGNED_CODE_RESOURCES), \
BASE_DIRS := $(JRE_MACOSX_BUNDLE_DIR_SIGNED), \
SUBDIR := $(JRE_BUNDLE_SUBDIR), \
))
LEGACY_TARGETS += $(BUILD_JRE_BUNDLE)
else
# Not a Macosx release build or code signing not available.
$(eval $(call SetupBundleFile, BUILD_JDK_BUNDLE, \
BUNDLE_NAME := $(JDK_BUNDLE_NAME), \
FILES := $(JDK_BUNDLE_FILES), \
SPECIAL_INCLUDES := $(JDK_SPECIAL_INCLUDES), \
BASE_DIRS := $(JDK_IMAGE_DIR), \
SUBDIR := $(JDK_BUNDLE_SUBDIR), \
))
PRODUCT_TARGETS += $(BUILD_JDK_BUNDLE)
$(eval $(call SetupBundleFile, BUILD_JRE_BUNDLE, \
BUNDLE_NAME := $(JRE_BUNDLE_NAME), \
FILES := $(JRE_BUNDLE_FILES), \
BASE_DIRS := $(JRE_IMAGE_DIR), \
SUBDIR := $(JRE_BUNDLE_SUBDIR), \
))
LEGACY_TARGETS += $(BUILD_JRE_BUNDLE)
endif
LEGACY_TARGETS += $(BUILD_JRE_BUNDLE)
ifeq ($(COPY_DEBUG_SYMBOLS), true)
$(eval $(call SetupBundleFile, BUILD_JDK_SYMBOLS_BUNDLE, \

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@ include $(SPEC)
include MakeBase.gmk
include JavaCompilation.gmk
include NativeCompilation.gmk
include SetupJavaCompilers.gmk
include TextFileProcessing.gmk
include ZipArchive.gmk
@@ -52,6 +53,7 @@ TARGETS =
# READMEs and other files.
DEMO_SHARE_SRC := $(TOPDIR)/src/demo/share
GLOBAL_VERSION_INFO_RESOURCE := $(TOPDIR)/src/java.base/windows/native/common/version.rc
DEMO_MANIFEST := $(SUPPORT_OUTPUTDIR)/demos/java-main-manifest.mf
@@ -91,7 +93,7 @@ COPY_TO_IMAGE := *.html *.txt *.png *.xml README*
# EXTRA_COPY_TO_IMAGE Additional files to copy to images (as wildcards)
# EXTRA_MANIFEST_ATTR Extra manifest attribute
# SKIP_COMPILATION Skip Java compilation iff true
# DISABLED_WARNINGS Additional disabled warnings
# DISABLE_SJAVAC Passed to SetupJavaCompilation
SetupBuildDemo = $(NamedParamsMacroTemplate)
define SetupBuildDemoBody
ifeq ($$($1_SRC_DIR), )
@@ -123,7 +125,7 @@ define SetupBuildDemoBody
ifneq ($$($1_SKIP_COMPILATION), true)
$$(eval $$(call SetupJavaCompilation, BUILD_DEMO_$1, \
TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \
SETUP := GENERATE_USINGJDKBYTECODE, \
SRC := $$($1_MAIN_SRC) $$($1_EXTRA_SRC_DIR), \
BIN := $(SUPPORT_OUTPUTDIR)/demos/classes/$$($1_DEMO_SUBDIR)/$1, \
COPY := $(COPY_TO_JAR) $$($1_EXTRA_COPY_TO_JAR), \
@@ -133,7 +135,7 @@ define SetupBuildDemoBody
EXTRA_MANIFEST_ATTR := $$($1_EXTRA_MANIFEST_ATTR), \
SRCZIP := $(SUPPORT_OUTPUTDIR)/demos/image/$$($1_DEMO_SUBDIR)/$1/src.zip, \
EXCLUDE_FILES := $$($1_EXCLUDE_FILES), \
DISABLED_WARNINGS := $$($1_DISABLED_WARNINGS), \
DISABLE_SJAVAC := $$($1_DISABLE_SJAVAC), \
))
$1 += $$(BUILD_DEMO_$1)
@@ -171,41 +173,35 @@ $(BUILD_DEMO_CodePointIM_JAR): $(CODEPOINT_METAINF_SERVICE_FILE)
$(eval $(call SetupBuildDemo, FileChooserDemo, \
DEMO_SUBDIR := jfc, \
DISABLED_WARNINGS := rawtypes deprecation unchecked, \
))
$(eval $(call SetupBuildDemo, SwingSet2, \
DEMO_SUBDIR := jfc, \
EXTRA_COPY_TO_JAR := .java, \
EXTRA_MANIFEST_ATTR := SplashScreen-Image: resources/images/splash.png, \
DISABLED_WARNINGS := rawtypes deprecation unchecked static serial cast, \
DISABLE_SJAVAC := true, \
))
$(eval $(call SetupBuildDemo, Font2DTest, \
DISABLED_WARNINGS := rawtypes deprecation unchecked serial cast, \
DEMO_SUBDIR := jfc, \
))
$(eval $(call SetupBuildDemo, J2Ddemo, \
DEMO_SUBDIR := jfc, \
MAIN_CLASS := java2d.J2Ddemo, \
DISABLED_WARNINGS := rawtypes deprecation unchecked cast, \
JAR_NAME := J2Ddemo, \
))
$(eval $(call SetupBuildDemo, Metalworks, \
DISABLED_WARNINGS := rawtypes unchecked, \
DEMO_SUBDIR := jfc, \
))
$(eval $(call SetupBuildDemo, Notepad, \
DISABLED_WARNINGS := rawtypes, \
DEMO_SUBDIR := jfc, \
))
$(eval $(call SetupBuildDemo, Stylepad, \
DEMO_SUBDIR := jfc, \
DISABLED_WARNINGS := rawtypes unchecked, \
EXTRA_SRC_DIR := $(DEMO_SHARE_SRC)/jfc/Notepad, \
EXCLUDE_FILES := $(DEMO_SHARE_SRC)/jfc/Notepad/README.txt, \
))
@@ -215,7 +211,6 @@ $(eval $(call SetupBuildDemo, SampleTree, \
))
$(eval $(call SetupBuildDemo, TableExample, \
DISABLED_WARNINGS := rawtypes unchecked deprecation, \
DEMO_SUBDIR := jfc, \
))
@@ -239,9 +234,15 @@ $(SUPPORT_OUTPUTDIR)/demos/image/nbproject/%: $(DEMO_SHARE_SRC)/nbproject/%
$(call install-file)
$(CHMOD) -f ug+w $@
TARGETS += $(patsubst $(DEMO_SHARE_SRC)/nbproject/%, \
$(SUPPORT_OUTPUTDIR)/demos/image/nbproject/%, \
$(call FindFiles, $(DEMO_SHARE_SRC)/nbproject))
ifeq ($(call isTargetOs, solaris), true)
TARGETS += $(patsubst $(DEMO_SHARE_SRC)/nbproject/%, \
$(SUPPORT_OUTPUTDIR)/demos/image/nbproject/%, \
$(call FindFiles, $(DEMO_SHARE_SRC)/nbproject))
else
TARGETS += $(patsubst $(DEMO_SHARE_SRC)/nbproject/%, \
$(SUPPORT_OUTPUTDIR)/demos/image/nbproject/%, \
$(call FindFiles, $(DEMO_SHARE_SRC)/nbproject))
endif
################################################################################

Some files were not shown because too many files have changed in this diff Show More