Compare commits

...

97 Commits

Author SHA1 Message Date
Vitaly Provodin
12fa314276 JBR-2787 fix copying jcef files into jbr/jbrsdk binaries 2020-10-16 05:10:58 +07: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
130 changed files with 13739 additions and 384 deletions

0
configure vendored Normal file → Executable file
View File

View File

@@ -0,0 +1,13 @@
# 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 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,10 @@
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
}

View File

@@ -0,0 +1,85 @@
#!/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
#
# 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
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
source jb/project/tools/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-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-import-modules=./modular-sdk \
--with-boot-jdk=${BOOT_JDK} \
--enable-cds=yes || 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-server-release/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 $?
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 $?
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-$JBSDK_VERSION
rm -rf $BASE_DIR/$JBR_BUNDLE
JBR=$JBR_BASE_NAME-linux-aarch64-b$build_number
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.aarch64
echo Running jlink....
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list.aarch64 | sed s/" "//g | sed s/,$//g) \
--output ${BASE_DIR}/${JBR_BUNDLE} || 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 -pcf $JBR.tar -C $BASE_DIR ${JBR_BUNDLE} || exit $?
gzip $JBR.tar || exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-aarch64-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
tar -pcf $JBRSDK_TEST.tar -C $BASE_DIR --exclude='test/jdk/demos' test || exit $?
gzip $JBRSDK_TEST.tar || exit $?

View File

@@ -0,0 +1,141 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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 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
#
# $ ./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)
#
# Environment variables:
# MODULAR_SDK_PATH - specifies the path to the directory where imported modules are located.
# By default imported modules should be located in ./modular-sdk
# 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')
WITH_IMPORT_MODULES="--with-import-modules=${MODULAR_SDK_PATH:=./modular-sdk}"
JCEF_PATH=${JCEF_PATH:=./jcef_linux_x64}
source jb/project/tools/common.sh
function create_jbr {
if [ -z "${bundle_type}" ]; then
JBR_BUNDLE=jbr
else
JBR_BUNDLE=jbr_${bundle_type}
fi
JBR_BASE_NAME=${JBR_BUNDLE}-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
rm -rf ${BASE_DIR}/jbr
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
JBR=$JBR_BASE_NAME-linux-x64-b$build_number
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 $BASE_DIR/$JBR_BUNDLE
if [ ! -z "${bundle_type}" ]; then
cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
rsync -av ${JCEF_PATH}/ $BASE_DIR/$JBR_BUNDLE/lib --exclude="modular-sdk" || do_exit $?
fi
grep -v "^JAVA_VERSION" $JSDK/release | grep -v "^MODULES" >> $BASE_DIR/$JBR_BUNDLE/release
echo Creating $JBR.tar.gz ...
tar -pcf $JBR.tar -C $BASE_DIR jbr || do_exit $?
[ -f "$JBR.tar.gz" ] && rm "$JBR.tar.gz"
gzip $JBR.tar || do_exit $?
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
}
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=linux-x86_64-server-release
JBSDK=${JBRSDK_BASE_NAME}-linux-x64-b${build_number}
case "$bundle_type" in
"jcef")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
WITH_IMPORT_MODULES=""
;;
"fd")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=linux-x86_64-server-fastdebug
JBSDK=${JBRSDK_BASE_NAME}-linux-x64-fastdebug-b${build_number}
;;
esac
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_IMPORT_MODULES \
--with-boot-jdk=${BOOT_JDK} \
--enable-cds=yes || do_exit $?
make clean CONF=$RELEASE_NAME || exit $?
make images CONF=$RELEASE_NAME || do_exit $?
JSDK=build/$RELEASE_NAME/images/jdk
echo Fixing permissions
chmod -R a+r $JSDK
BASE_DIR=build/$RELEASE_NAME/images
JBRSDK_BUNDLE=jbrsdk
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
rsync -av ${JCEF_PATH}/ $BASE_DIR/$JBRSDK_BUNDLE/lib --exclude="modular-sdk" || do_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 || do_exit $?
[ -f "$JBSDK.tar.gz" ] && rm "$JBSDK.tar.gz"
gzip $JBSDK.tar || do_exit $?
fi
create_jbr || do_exit $?
if [ "$bundle_type" == "jcef" ]; then
make test-image CONF=$RELEASE_NAME || do_exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-x64-b$build_number
echo Creating $JBSDK_TEST.tar.gz ...
tar -pcf $JBRSDK_TEST.tar -C $BASE_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
do_exit 0

View File

@@ -0,0 +1,81 @@
#!/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
#
# 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
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
source jb/project/tools/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-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 || 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-server-release/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 $?
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 $?
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-$JBSDK_VERSION
rm -rf $BASE_DIR/$JBR_BUNDLE
JBR=$JBR_BASE_NAME-linux-x86-b$build_number
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.x86
echo Running jlink....
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--add-modules $(xargs < modules.list.x86 | sed s/" "//g | sed s/,$//g) --output ${BASE_DIR}/${JBR_BUNDLE} || 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 -pcf $JBR.tar -C $BASE_DIR $JBR_BUNDLE || exit $?
gzip $JBR.tar || exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-linux-test-x86-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
tar -pcf $JBRSDK_TEST.tar -C $BASE_DIR --exclude='test/jdk/demos' --exclude='test/hotspot/gtest' test || exit $?
gzip $JBRSDK_TEST.tar || exit $?

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,146 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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 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
#
# $ ./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)
#
# Environment variables:
# MODULAR_SDK_PATH - specifies the path to the directory where imported modules are located.
# By default imported modules should be located in ./modular-sdk
# 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')
WITH_IMPORT_MODULES="--with-import-modules=${MODULAR_SDK_PATH:=./modular-sdk}"
JCEF_PATH=${JCEF_PATH:=./jcef_mac}
MAJOR_JBSDK_VERSION=$(echo $JBSDK_VERSION_WITH_DOTS | awk -F "." '{print $1}')
source jb/project/tools/common.sh
function create_jbr {
if [ -z "${bundle_type}" ]; then
JBR_BUNDLE=jbr
else
JBR_BUNDLE=jbr_${bundle_type}
fi
JBR_BASE_NAME=${JBR_BUNDLE}-${JBSDK_VERSION}
cat modules.list > modules_tmp.list
rm -rf ${BASE_DIR}/jbr
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
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}
JBR=${JBR_BASE_NAME}-osx-x64-b${build_number}
echo Running jlink....
${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} || do_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}
rm -rf ${JRE_CONTENTS}/Frameworks || do_exit $?
[ ! -z "${bundle_type}" ] && (cp -a ${JCEF_PATH}/Frameworks ${JRE_CONTENTS} || do_exit $?)
echo Creating ${JBR}.tar.gz ...
[ ! -z "${bundle_type}" ] && cp -R ${BASE_DIR}/${JBR_BUNDLE} ${BASE_DIR}/jbr
COPYFILE_DISABLE=1 tar -pczf ${JBR}.tar.gz --exclude='*.dSYM' --exclude='man' -C ${BASE_DIR} jbr || do_exit $?
rm -rf ${BASE_DIR}/${JBR_BUNDLE}
}
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=macosx-x86_64-server-release
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-b${build_number}
case "$bundle_type" in
"jcef")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
WITH_IMPORT_MODULES=""
;;
"fd")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=macosx-x86_64-server-fastdebug
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-fastdebug-b${build_number}
;;
esac
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_IMPORT_MODULES \
--with-boot-jdk=`/usr/libexec/java_home -v 14` \
--enable-cds=yes || do_exit $?
make clean CONF=$RELEASE_NAME || do_exit $?
make images CONF=$RELEASE_NAME || do_exit $?
JSDK=build/$RELEASE_NAME/images/jdk-bundle
BASE_DIR=jre
JBRSDK_BUNDLE=jbrsdk
rm -rf $BASE_DIR
mkdir $BASE_DIR || do_exit $?
cp -a $JSDK/jdk-$MAJOR_JBSDK_VERSION.jdk $BASE_DIR/$JBRSDK_BUNDLE || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
cp -a ${JCEF_PATH}/Frameworks $BASE_DIR/$JBRSDK_BUNDLE/Contents/
echo Creating $JBSDK.tar.gz ...
sed 's/JBR/JBRSDK/g' ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Home/release > release
mv release ${BASE_DIR}/${JBRSDK_BUNDLE}/Contents/Home/release
[ -f "$JBSDK.tar.gz" ] && rm "$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 || do_exit $?
fi
create_jbr || do_exit $?
if [ "$bundle_type" == "jcef" ]; then
make test-image CONF=$RELEASE_NAME || do_exit $?
JBRSDK_TEST=$JBRSDK_BASE_NAME-osx-test-x64-b$build_number
echo Creating $JBRSDK_TEST.tar.gz ...
[ -f "$JBRSDK_TEST.tar.gz" ] && rm "$JBRSDK_TEST.tar.gz"
COPYFILE_DISABLE=1 tar -pczf $JBRSDK_TEST.tar.gz -C build/${RELEASE_NAME}/images \
--exclude='test/jdk/demos' test || do_exit $?
fi
do_exit 0

View File

@@ -0,0 +1,120 @@
#!/bin/bash
APP_DIRECTORY=$1
APPL_USER=$2
APPL_PASSWORD=$3
APP_NAME=$4
BUNDLE_ID=$5
FAKE_ROOT="${6:-fake-root}"
if [[ -z "$APP_DIRECTORY" ]] || [[ -z "$APPL_USER" ]] || [[ -z "$APPL_PASSWORD" ]]; then
echo "Usage: $0 AppDirectory Username Password"
exit 1
fi
if [[ ! -d "$APP_DIRECTORY" ]]; then
echo "AppDirectory '$APP_DIRECTORY' does not exist or not a directory"
exit 1
fi
function log() {
echo "$(date '+[%H:%M:%S]') $*"
}
function publish-log() {
id=$1
file=$2
curl -T "$file" "$ARTIFACTORY_URL/$id" || true
}
function altool-upload() {
# Since altool uses same file for upload token we have to trick it into using different folders for token file location
# Also it copies zip into TMPDIR so we override it too, to simplify cleanup
OLD_HOME="$HOME"
export HOME="$FAKE_ROOT/home"
export TMPDIR="$FAKE_ROOT/tmp"
mkdir -p "$HOME"
mkdir -p "$TMPDIR"
export _JAVA_OPTIONS="-Duser.home=$HOME -Djava.io.tmpdir=$TMPDIR"
# Reduce amount of downloads, cache transporter libraries
shared_itmstransporter="$OLD_HOME/shared-itmstransporter"
if [[ -f "$shared_itmstransporter" ]]; then
cp -r "$shared_itmstransporter" "$HOME/.itmstransporter"
fi
# For some reason altool prints everything to stderr, not stdout
set +e
xcrun altool --notarize-app \
--username "$APPL_USER" --password "$APPL_PASSWORD" \
--primary-bundle-id "$BUNDLE_ID" \
--asc-provider JetBrainssro --file "$1" 2>&1 | tee "altool.init.out"
unset TMPDIR
export HOME="$OLD_HOME"
set -e
}
#immediately exit script with an error if a command fails
set -euo pipefail
file="$APP_NAME.zip"
log "Zipping $file..."
rm -rf "$file"
ditto -c -k --sequesterRsrc --keepParent "$APP_DIRECTORY/Contents" "$file"
log "Notarizing $file..."
rm -rf "altool.init.out" "altool.check.out"
altool-upload "$file"
rm -rf "$file"
notarization_info="$(grep -e "RequestUUID" "altool.init.out" | grep -oE '([0-9a-f-]{36})')"
if [ -z "$notarization_info" ]; then
log "Faile to read RequestUUID from altool.init.out"
exit 10
fi
PATH="$PATH:/usr/local/bin/"
log "Notarization request sent, awaiting response"
spent=0
while true; do
# For some reason altool prints everything to stderr, not stdout
xcrun altool --username "$APPL_USER" --notarization-info "$notarization_info" --password "$APPL_PASSWORD" >"altool.check.out" 2>&1 || true
status="$(grep -oe 'Status: .*' "altool.check.out" | cut -c 9- || true)"
log "Current status: $status"
if [ "$status" = "invalid" ]; then
log "Notarization failed"
ec=1
elif [ "$status" = "success" ]; then
log "Notarization succeeded"
ec=0
else
if [ "$status" != "in progress" ]; then
log "Unknown notarization status, waiting more, altool output:"
cat "altool.check.out"
fi
if [[ $spent -gt 60 ]]; then
log "Waiting time out (apx 60 minutes)"
ec=2
break
fi
sleep 60
((spent += 1))
continue
fi
developer_log="developer_log.json"
log "Fetching $developer_log"
# TODO: Replace cut with trim or something better
url="$(grep -oe 'LogFileURL: .*' "altool.check.out" | cut -c 13-)"
wget "$url" -O "$developer_log" && cat "$developer_log" || true
if [ $ec != 0 ]; then
log "Publishing $developer_log"
publish-log "$notarization_info" "$developer_log"
fi
break
done
cat "altool.check.out"
rm -rf "altool.init.out" "altool.check.out"
exit $ec

View File

@@ -0,0 +1,94 @@
#!/bin/bash
APP_DIRECTORY=$1
JB_CERT=$2
if [[ -z "$APP_DIRECTORY" ]] || [[ -z "$JB_CERT" ]]; then
echo "Usage: $0 AppDirectory CertificateID"
exit 1
fi
if [[ ! -d "$APP_DIRECTORY" ]]; then
echo "AppDirectory '$APP_DIRECTORY' does not exist or not a directory"
exit 1
fi
function log() {
echo "$(date '+[%H:%M:%S]') $*"
}
#immediately exit script with an error if a command fails
set -euo pipefail
# Cleanup files left from previous sign attempt (if any)
find "$APP_DIRECTORY" -name '*.cstemp' -exec rm '{}' \;
log "Signing libraries and executables..."
# -perm +111 searches for executables
for f in \
"Contents/Home/bin" \
"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 \) \
-exec codesign --timestamp \
-v -s "$JB_CERT" --options=runtime \
--entitlements entitlements.xml {} \;
fi
done
log "Signing libraries in jars in $PWD"
# todo: add set -euo pipefail; into the inner sh -c
# `-e` prevents `grep -q && printf` loginc
# with `-o pipefail` there's no input for 'while' loop
find "$APP_DIRECTORY" -name '*.jar' \
-exec sh -c "set -u; unzip -l \"\$0\" | grep -q -e '\.dylib\$' -e '\.jnilib\$' -e '\.so\$' -e '^jattach\$' && printf \"\$0\0\" " {} \; |
while IFS= read -r -d $'\0' file; do
log "Processing libraries in $file"
rm -rf jarfolder jar.jar
mkdir jarfolder
filename="${file##*/}"
log "Filename: $filename"
cp "$file" jarfolder && (cd jarfolder && jar xf "$filename" && rm "$filename")
find jarfolder \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -name "jattach" \) \
-exec codesign --timestamp \
-v -s "$JB_CERT" --options=runtime \
--entitlements entitlements.xml {} \;
(cd jarfolder; zip -q -r -o ../jar.jar .)
mv jar.jar "$file"
done
rm -rf jarfolder jar.jar
log "Signing other files..."
for f in \
"Contents/MacOS"; do
if [ -d "$APP_DIRECTORY/$f" ]; then
find "$APP_DIRECTORY/$f" \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -perm +111 \) \
-exec codesign --timestamp \
-v -s "$JB_CERT" --options=runtime \
--entitlements entitlements.xml {} \;
fi
done
#log "Signing executable..."
#codesign --timestamp \
# -v -s "$JB_CERT" --options=runtime \
# --force \
# --entitlements entitlements.xml "$APP_DIRECTORY/Contents/MacOS/idea"
log "Signing whole app..."
codesign --timestamp \
-v -s "$JB_CERT" --options=runtime \
--force \
--entitlements entitlements.xml "$APP_DIRECTORY"
log "Verifying java is not broken"
find "$APP_DIRECTORY" \
-type f -name 'java' -perm +111 -exec {} -version \;

View File

@@ -0,0 +1,138 @@
#!/bin/bash
#immediately exit script with an error if a command fails
set -euo pipefail
export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
export COPYFILE_DISABLE=true
INPUT_FILE=$1
EXPLODED=$2.exploded
BACKUP_JMODS=$2.backup
USERNAME=$3
PASSWORD=$4
CODESIGN_STRING=$5
NOTARIZE=$6
BUNDLE_ID=$7
cd "$(dirname "$0")"
function log() {
echo "$(date '+[%H:%M:%S]') $*"
}
log "Deleting $EXPLODED ..."
if test -d "$EXPLODED"; then
find "$EXPLODED" -mindepth 1 -maxdepth 1 -exec chmod -R u+wx '{}' \;
fi
rm -rf "$EXPLODED"
mkdir "$EXPLODED"
rm -rf "$BACKUP_JMODS"
mkdir "$BACKUP_JMODS"
log "Unzipping $INPUT_FILE to $EXPLODED ..."
tar -xzvf "$INPUT_FILE" --directory $EXPLODED
rm "$INPUT_FILE"
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 -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 extracted and removed"
APPLICATION_PATH="$EXPLODED/$BUILD_NAME"
find "$APPLICATION_PATH/Contents/Home/bin" \
-maxdepth 1 -type f -name '*.jnilib' -print0 |
while IFS= read -r -d $'\0' file; do
if [ -f "$file" ]; then
log "Linking $file"
b="$(basename "$file" .jnilib)"
ln -sf "$b.jnilib" "$(dirname "$file")/$b.dylib"
fi
done
find "$APPLICATION_PATH/Contents/" \
-maxdepth 1 -type f -name '*.txt' -print0 |
while IFS= read -r -d $'\0' file; do
if [ -f "$file" ]; then
log "Moving $file"
mv "$file" "$APPLICATION_PATH/Contents/Resources"
fi
done
non_plist=$(find "$APPLICATION_PATH/Contents/" -maxdepth 1 -type f -and -not -name 'Info.plist' | wc -l)
if [[ $non_plist -gt 0 ]]; then
log "Only Info.plist file is allowed in Contents directory but found $non_plist file(s):"
log "$(find "$APPLICATION_PATH/Contents/" -maxdepth 1 -type f -and -not -name 'Info.plist')"
exit 1
fi
log "Unlocking keychain..."
# Make sure *.p12 is imported into local KeyChain
security unlock-keychain -p "$PASSWORD" "/Users/$USERNAME/Library/Keychains/login.keychain"
attempt=1
limit=3
set +e
while [[ $attempt -le $limit ]]; do
log "Signing (attempt $attempt) $APPLICATION_PATH ..."
./sign.sh "$APPLICATION_PATH" "$CODESIGN_STRING"
ec=$?
if [[ $ec -ne 0 ]]; then
((attempt += 1))
if [ $attempt -eq $limit ]; then
set -e
fi
log "Signing failed, wait for 30 sec and try to sign again"
sleep 30
else
log "Signing done"
codesign -v "$APPLICATION_PATH" -vvvvv
log "Check sign done"
((attempt += limit))
fi
done
set -e
if [ "$NOTARIZE" = "yes" ]; then
log "Notarizing..."
# shellcheck disable=SC1090
source "$HOME/.notarize_token"
APP_NAME=$(echo ${INPUT_FILE} | awk -F"." '{ print $1 }')
# Since notarization tool uses same file for upload token we have to trick it into using different folders, hence fake root
# Also it leaves copy of zip file in TMPDIR, so notarize.sh overrides it and uses FAKE_ROOT as location for temp TMPDIR
FAKE_ROOT="$(pwd)/fake-root"
mkdir -p "$FAKE_ROOT"
echo "Notarization will use fake root: $FAKE_ROOT"
./notarize.sh "$APPLICATION_PATH" "$APPLE_USERNAME" "$APPLE_PASSWORD" "$APP_NAME" "$BUNDLE_ID" "$FAKE_ROOT"
rm -rf "$FAKE_ROOT"
set +e
log "Stapling..."
xcrun stapler staple "$APPLICATION_PATH"
else
log "Notarization disabled"
log "Stapling disabled"
fi
log "Zipping $BUILD_NAME to $INPUT_FILE ..."
(
#cd "$EXPLODED"
#ditto -c -k --sequesterRsrc --keepParent "$BUILD_NAME" "../$INPUT_FILE"
if test -d $BACKUP_JMODS/jmods; then
mv $BACKUP_JMODS/jmods $EXPLODED/$BUILD_NAME/Contents/Home
fi
COPYFILE_DISABLE=1 tar -pczf $INPUT_FILE --exclude='*.dSYM' --exclude='man' -C $EXPLODED $BUILD_NAME
log "Finished zipping"
)
rm -rf "$EXPLODED"
log "Done"

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

@@ -0,0 +1,112 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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 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
#
# $ ./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)
#
# Environment variables:
# MODULAR_SDK_PATH - specifies the path to the directory where imported modules are located.
# By default imported modules should be located in ./modular-sdk
# 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)
WITH_IMPORT_MODULES="--with-import-modules=${MODULAR_SDK_PATH:=$WORK_DIR/modular-sdk}"
JCEF_PATH=${JCEF_PATH:=$WORK_DIR/jcef_win_x64}
source jb/project/tools/common.sh
function create_jbr {
if [ -z "${bundle_type}" ]; then
JBR_BUNDLE=jbr
else
JBR_BUNDLE=jbr_${bundle_type}
fi
cat modules.list > modules_tmp.list
rm -rf ${JBR_BUNDLE}
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} || do_exit $?
[ ! -z "${bundle_type}" ] && (rsync -av ${JCEF_PATH}/ ${JBR_BUNDLE}/bin --exclude="modular-sdk" || do_exit $?)
echo Modifying release info ...
cat ${JSDK}/release | tr -d '\r' | grep -v 'JAVA_VERSION' | grep -v 'MODULES' >> ${JBR_BUNDLE}/release
}
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=windows-x86_64-server-release
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-b${build_number}
case "$bundle_type" in
"jcef")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
WITH_IMPORT_MODULES=""
;;
"fd")
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=windows-x86_64-server-fastdebug
JBSDK=${JBRSDK_BASE_NAME}-osx-x64-fastdebug-b${build_number}
;;
esac
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_IMPORT_MODULES \
--with-toolchain-version=${TOOLCHAIN_VERSION} \
--with-boot-jdk=${BOOT_JDK} \
--disable-ccache \
--enable-cds=yes || do_exit $?
if [ "$bundle_type" == "jcef" ]; then
make LOG=info CONF=$RELEASE_NAME clean images test-image || do_exit $?
else
make LOG=info CONF=$RELEASE_NAME clean images || do_exit $?
fi
JSDK=build/$RELEASE_NAME/images/jdk
BASE_DIR=build/$RELEASE_NAME/images
JBRSDK_BUNDLE=jbrsdk
rm -rf ${BASE_DIR}/${JBRSDK_BUNDLE} && rsync -a --exclude demo --exclude sample ${JSDK}/ ${JBRSDK_BUNDLE} || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
rsync -av ${JCEF_PATH}/ ${JBRSDK_BUNDLE}/bin --exclude='modular-sdk' || do_exit $?
sed 's/JBR/JBRSDK/g' ${JSDK}/release > release
mv release ${JBRSDK_BUNDLE}/release
fi
create_jbr || do_exit $?
do_exit 0

View File

@@ -0,0 +1,63 @@
#!/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
#
# 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
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
source jb/project/tools/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 \
--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=${TOOLCHAIN_VERSION} \
--with-boot-jdk=${BOOT_JDK} \
--disable-ccache \
--enable-cds=yes || 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-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}
grep -v javafx modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.x86
${JSDK}/bin/jlink \
--module-path ${JSDK}/jmods --no-man-pages --compress=2 \
--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

View File

@@ -0,0 +1,75 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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 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
#
# $ ./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
bundle_type=$4
function pack_jbr {
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 ...
/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/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk
JBSDK=$JBRSDK_BASE_NAME-windows-x64-b$build_number
BASE_DIR=.
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
JBRSDK_BUNDLE=jbrsdk
echo Creating $JBSDK.tar.gz ...
[ -f "$JBSDK.tar.gz" ] && rm "$JBSDK.tar.gz"
/usr/bin/tar -czf $JBSDK.tar.gz $JBRSDK_BUNDLE || do_exit $?
fi
pack_jbr $bundle_type
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 || do_exit $?
fi

View File

@@ -0,0 +1,42 @@
#!/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
#
# 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
JBR_BASE_NAME=jbr-$JBSDK_VERSION
IMAGES_DIR=build/windows-x86-server-release/images
JSDK=$IMAGES_DIR/jdk
JBSDK=$JBRSDK_BASE_NAME-windows-x86-b$build_number
BASE_DIR=.
JBRSDK_BUNDLE=jbrsdk
echo Creating $JBSDK.tar.gz ...
/usr/bin/tar -czf $JBSDK.tar.gz $JBRSDK_BUNDLE || exit 1
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-${JBSDK_VERSION}
JBR=$JBR_BASE_NAME-windows-x86-b$build_number
echo Creating $JBR.tar.gz ...
/usr/bin/tar -czf $JBR.tar.gz -C $BASE_DIR ${JBR_BUNDLE} || exit 1
JBRSDK_TEST=$JBRSDK_BASE_NAME-windows-test-x86-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

View File

@@ -556,7 +556,8 @@ AC_DEFUN_ONCE([BASIC_COMPILE_FIXPATH],
$RM -rf $FIXPATH_BIN $FIXPATH_DIR
$MKDIR -p $FIXPATH_DIR $CONFIGURESUPPORT_OUTPUTDIR/bin
cd $FIXPATH_DIR
$CC $FIXPATH_SRC_W -Fe$FIXPATH_BIN_W > $FIXPATH_DIR/fixpath1.log 2>&1
$CC $FIXPATH_SRC_W > $FIXPATH_DIR/fixpath1.log 2>&1
mv fixpath.exe $FIXPATH_BIN
cd $CONFIGURE_START_DIR
if test ! -x $FIXPATH_BIN; then

View File

@@ -525,15 +525,16 @@ DependOnVariableFileName = \
# Param 2 - (optional) name of file to store value in
DependOnVariableHelper = \
$(strip \
$(eval -include $(call DependOnVariableFileName, $1, $2)) \
$(eval $1_filename := $(call DependOnVariableFileName, $1, $2)) \
$(if $(wildcard $($1_filename)), $(eval include $($1_filename))) \
$(if $(call equals, $(strip $($1)), $(strip $($1_old))),,\
$(call MakeDir, $(dir $(call DependOnVariableFileName, $1, $2))) \
$(call MakeDir, $(dir $($1_filename))) \
$(if $(findstring $(LOG_LEVEL), trace), \
$(info NewVariable $1: >$(strip $($1))<) \
$(info OldVariable $1: >$(strip $($1_old))<)) \
$(call WriteFile, $1_old:=$(call DoubleDollar,$(call EscapeHash,$($1))), \
$(call DependOnVariableFileName, $1, $2))) \
$(call DependOnVariableFileName, $1, $2) \
$($1_filename))) \
$($1_filename) \
)
# Main macro

View File

@@ -272,12 +272,14 @@ XEvent.xclient 0
XEvent.xcolormap 0
XEvent.xconfigure 0
XEvent.xconfigurerequest 0
XEvent.xcookie 0
XEvent.xcreatewindow 0
XEvent.xcrossing 0
XEvent.xdestroywindow 0
XEvent.xerror 0
XEvent.xexpose 0
XEvent.xfocus 0
XEvent.xgeneric 0
XEvent.xgraphicsexpose 0
XEvent.xgravity 0
XEvent.xkey 0
@@ -370,6 +372,22 @@ XGCValues.subwindow_mode 64
XGCValues.tile 44
XGCValues.ts_x_origin 52
XGCValues.ts_y_origin 56
XGenericEvent 24
XGenericEventCookie 32
XGenericEventCookie.cookie 24
XGenericEventCookie.data 28
XGenericEventCookie.display 12
XGenericEventCookie.evtype 20
XGenericEventCookie.extension 16
XGenericEventCookie.send_event 8
XGenericEventCookie.serial 4
XGenericEventCookie.type 0
XGenericEvent.display 12
XGenericEvent.evtype 20
XGenericEvent.extension 16
XGenericEvent.send_event 8
XGenericEvent.serial 4
XGenericEvent.type 0
XGraphicsExposeEvent 48
XGraphicsExposeEvent.count 36
XGraphicsExposeEvent.display 12
@@ -396,6 +414,9 @@ XHostAddress 12
XHostAddress.address 8
XHostAddress.family 0
XHostAddress.length 4
XIButtonState 8
XIButtonState.mask 4
XIButtonState.mask_len 0
XIconSize 24
XIconSize.height_inc 20
XIconSize.max_height 12
@@ -403,6 +424,29 @@ XIconSize.max_width 8
XIconSize.min_height 4
XIconSize.min_width 0
XIconSize.width_inc 16
XIDeviceEvent 140
XIDeviceEvent.buttons 88
XIDeviceEvent.child 48
XIDeviceEvent.detail 36
XIDeviceEvent.deviceid 28
XIDeviceEvent.display 12
XIDeviceEvent.event 44
XIDeviceEvent.event_x 68
XIDeviceEvent.event_y 76
XIDeviceEvent.evtype 20
XIDeviceEvent.extension 16
XIDeviceEvent.flags 84
XIDeviceEvent.group 124
XIDeviceEvent.mods 108
XIDeviceEvent.root 40
XIDeviceEvent.root_x 52
XIDeviceEvent.root_y 60
XIDeviceEvent.send_event 8
XIDeviceEvent.serial 4
XIDeviceEvent.sourceid 32
XIDeviceEvent.time 24
XIDeviceEvent.type 0
XIDeviceEvent.valuators 96
XImage 88
XImage.bitmap_bit_order 28
XImage.bitmap_pad 32
@@ -436,6 +480,11 @@ XIMHotKeyTrigger.modifier_mask 8
XIMHotKeyTriggers 8
XIMHotKeyTriggers.key 4
XIMHotKeyTriggers.num_hot_key 0
XIModifierState 16
XIModifierState.base 0
XIModifierState.effective 12
XIModifierState.latched 4
XIModifierState.locked 8
XIMPreeditCaretCallbackStruct 12
XIMPreeditCaretCallbackStruct.direction 4
XIMPreeditCaretCallbackStruct.position 0
@@ -472,6 +521,10 @@ XIMText.string 12
XIMValuesList 8
XIMValuesList.count_values 0
XIMValuesList.supported_values 4
XIValuatorState 12
XIValuatorState.mask 4
XIValuatorState.mask_len 0
XIValuatorState.values 8
XkbAccessXNotifyEvent 44
XkbAccessXNotifyEvent.debounce_delay 40
XkbAccessXNotifyEvent.detail 28

View File

@@ -272,12 +272,14 @@ XEvent.xclient 0
XEvent.xcolormap 0
XEvent.xconfigure 0
XEvent.xconfigurerequest 0
XEvent.xcookie 0
XEvent.xcreatewindow 0
XEvent.xcrossing 0
XEvent.xdestroywindow 0
XEvent.xerror 0
XEvent.xexpose 0
XEvent.xfocus 0
XEvent.xgeneric 0
XEvent.xgraphicsexpose 0
XEvent.xgravity 0
XEvent.xkey 0
@@ -370,6 +372,22 @@ XGCValues.subwindow_mode 96
XGCValues.tile 64
XGCValues.ts_x_origin 80
XGCValues.ts_y_origin 84
XGenericEvent 40
XGenericEventCookie 56
XGenericEventCookie.cookie 40
XGenericEventCookie.data 48
XGenericEventCookie.display 24
XGenericEventCookie.evtype 36
XGenericEventCookie.extension 32
XGenericEventCookie.send_event 16
XGenericEventCookie.serial 8
XGenericEventCookie.type 0
XGenericEvent.display 24
XGenericEvent.evtype 36
XGenericEvent.extension 32
XGenericEvent.send_event 16
XGenericEvent.serial 8
XGenericEvent.type 0
XGraphicsExposeEvent 72
XGraphicsExposeEvent.count 56
XGraphicsExposeEvent.display 24
@@ -396,6 +414,9 @@ XHostAddress 16
XHostAddress.address 8
XHostAddress.family 0
XHostAddress.length 4
XIButtonState 16
XIButtonState.mask 8
XIButtonState.mask_len 0
XIconSize 24
XIconSize.height_inc 20
XIconSize.max_height 12
@@ -403,6 +424,29 @@ XIconSize.max_width 8
XIconSize.min_height 4
XIconSize.min_width 0
XIconSize.width_inc 16
XIDeviceEvent 200
XIDeviceEvent.buttons 128
XIDeviceEvent.child 80
XIDeviceEvent.detail 56
XIDeviceEvent.deviceid 48
XIDeviceEvent.display 24
XIDeviceEvent.event 72
XIDeviceEvent.event_x 104
XIDeviceEvent.event_y 112
XIDeviceEvent.evtype 36
XIDeviceEvent.extension 32
XIDeviceEvent.flags 120
XIDeviceEvent.group 184
XIDeviceEvent.mods 168
XIDeviceEvent.root 64
XIDeviceEvent.root_x 88
XIDeviceEvent.root_y 96
XIDeviceEvent.send_event 16
XIDeviceEvent.serial 8
XIDeviceEvent.sourceid 52
XIDeviceEvent.time 40
XIDeviceEvent.type 0
XIDeviceEvent.valuators 144
XImage 136
XImage.bitmap_bit_order 32
XImage.bitmap_pad 36
@@ -436,6 +480,11 @@ XIMHotKeyTrigger.modifier_mask 12
XIMHotKeyTriggers 16
XIMHotKeyTriggers.key 8
XIMHotKeyTriggers.num_hot_key 0
XIModifierState 16
XIModifierState.base 0
XIModifierState.effective 12
XIModifierState.latched 4
XIModifierState.locked 8
XIMPreeditCaretCallbackStruct 12
XIMPreeditCaretCallbackStruct.direction 4
XIMPreeditCaretCallbackStruct.position 0
@@ -472,6 +521,10 @@ XIMText.string 24
XIMValuesList 16
XIMValuesList.count_values 0
XIMValuesList.supported_values 8
XIValuatorState 24
XIValuatorState.mask 8
XIValuatorState.mask_len 0
XIValuatorState.values 16
XkbAccessXNotifyEvent 64
XkbAccessXNotifyEvent.debounce_delay 60
XkbAccessXNotifyEvent.detail 48

View File

@@ -127,6 +127,22 @@ XKeymapEvent
display long
window long
key_vector array byte 32
XGenericEvent
type int
serial long
send_event Bool
display long
extension int
evtype int
XGenericEventCookie
type int
serial long
send_event Bool
display long
extension int
evtype int
cookie int
data pointer
XDestroyWindowEvent
type int
serial long
@@ -814,6 +830,8 @@ XEvent
xmapping struct XMappingEvent
xerror struct XErrorEvent
xkeymap struct XKeymapEvent
xgeneric struct XGenericEvent
xcookie struct XGenericEventCookie
pad array long 24
XkbAnyEvent
@@ -1039,3 +1057,42 @@ XkbEvent
accessx struct XkbAccessXNotifyEvent
device struct XkbExtensionDeviceNotifyEvent
core struct XEvent
XIButtonState
mask_len int
mask pointer byte
XIValuatorState
mask_len int
mask pointer byte
values pointer double
XIModifierState
base int
latched int
locked int
effective int
XIDeviceEvent
type int
serial long
send_event Bool
display long
extension int
evtype int
time ulong
deviceid int
sourceid int
detail int
root long
event long
child long
root_x double
root_y double
event_x double
event_y double
flags int
buttons struct XIButtonState
valuators struct XIValuatorState
mods struct XIModifierState
group struct XIModifierState

View File

@@ -1142,6 +1142,8 @@ public class WrapperGenerator {
pw.println("/* This file is an automatically generated file, please do not edit this file, modify the XlibParser.java file instead !*/\n" );
pw.println("#include <X11/Xlib.h>\n#include <X11/Xutil.h>\n#include <X11/Xos.h>\n#include <X11/Xatom.h>\n#include <stdio.h>\n");
pw.println("#include <X11/extensions/Xdbe.h>");
pw.println("#include <X11/extensions/XI2.h>");
pw.println("#include <X11/extensions/XInput2.h>");
pw.println("#include <X11/XKBlib.h>");
pw.println("#include \"awt_p.h\"");
pw.println("#include \"color.h\"");

56
modules.list Normal file
View File

@@ -0,0 +1,56 @@
java.base,
java.compiler,
java.datatransfer,
java.desktop,
java.instrument,
java.logging,
java.management,
java.management.rmi,
java.naming,
java.net.http,
java.prefs,
java.rmi,
java.scripting,
java.se,
java.security.jgss,
java.security.sasl,
java.smartcardio,
java.sql,
java.sql.rowset,
java.transaction.xa,
java.xml,
java.xml.crypto,
jdk.accessibility,
jdk.aot,
jdk.attach,
jdk.charsets,
jdk.compiler,
jdk.crypto.cryptoki,
jdk.crypto.ec,
jdk.dynalink,
jdk.httpserver,
jdk.internal.ed,
jdk.internal.le,
jdk.internal.vm.ci,
jdk.internal.vm.compiler,
jdk.internal.vm.compiler.management,
jdk.jdi,
jdk.jdwp.agent,
jdk.jfr,
jdk.jsobject,
jdk.localedata,
jdk.management,
jdk.management.agent,
jdk.management.jfr,
jdk.naming.dns,
jdk.naming.rmi,
jdk.net,
jdk.scripting.nashorn,
jdk.scripting.nashorn.shell,
jdk.sctp,
jdk.security.auth,
jdk.security.jgss,
jdk.unsupported,
jdk.xml.dom,
jdk.zipfs,
jdk.hotspot.agent

View File

@@ -371,7 +371,11 @@ Klass* ClassListParser::load_current_class(TRAPS) {
if (!HAS_PENDING_EXCEPTION && (obj != NULL)) {
klass = java_lang_Class::as_Klass(obj);
} else { // load classes in bootclasspath/a
tty->print_cr("Class %s was not loaded from the system classloader", this->current_class_name());
if (HAS_PENDING_EXCEPTION) {
oop throwable = PENDING_EXCEPTION;
java_lang_Throwable::print(throwable, tty);
tty->cr();
CLEAR_PENDING_EXCEPTION;
}
@@ -380,6 +384,7 @@ Klass* ClassListParser::load_current_class(TRAPS) {
if (k != NULL) {
klass = k;
} else {
tty->print_cr("Class %s is not found from SystemDictionary::resolve_or_null(..) == null", this->current_class_name());
if (!HAS_PENDING_EXCEPTION) {
THROW_NULL(vmSymbols::java_lang_ClassNotFoundException());
}

View File

@@ -265,6 +265,7 @@ InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS)
ClassFileStream* stream = NULL;
ClassPathEntry* e = find_classpath_entry_from_cache(path, CHECK_NULL);
if (e == NULL) {
log_warning(cds)("Preload Warning: ClassPathEntry is not found for class %s and path %s", class_name, path);
return NULL;
}
{
@@ -329,12 +330,14 @@ ClassPathEntry* ClassLoaderExt::find_classpath_entry_from_cache(const char* path
struct stat st;
if (os::stat(path, &st) != 0) {
// File or directory not found
log_warning(cds)("Preload Warning: Source path %s is not found", path);
return NULL;
}
ClassPathEntry* new_entry = NULL;
new_entry = create_class_path_entry(path, &st, false, false, false, CHECK_NULL);
if (new_entry == NULL) {
log_warning(cds)("Preload Warning: The create_class_path_entry() call for path %s returned NULL", path);
return NULL;
}
ccpe._path = strdup(path);

View File

@@ -1856,10 +1856,16 @@ int MetaspaceShared::preload_classes(const char* class_list_path, TRAPS) {
while (parser.parse_one_line()) {
Klass* klass = parser.load_current_class(THREAD);
if (HAS_PENDING_EXCEPTION) {
if (klass == NULL &&
(PENDING_EXCEPTION->klass()->name() == vmSymbols::java_lang_ClassNotFoundException())) {
// print a warning only when the pending exception is class not found
log_warning(cds)("Preload Warning: Cannot find %s", parser.current_class_name());
if (klass == NULL) {
if (PENDING_EXCEPTION->klass()->name() == vmSymbols::java_lang_ClassNotFoundException()) {
// print a warning only when the pending exception is class not found
log_warning(cds)("Preload Warning: Cannot find %s", parser.current_class_name());
} else {
log_warning(cds)("Preload Warning: Exception loading class %s", parser.current_class_name());
oop throwable = PENDING_EXCEPTION;
java_lang_Throwable::print(throwable, tty);
tty->cr();
}
}
CLEAR_PENDING_EXCEPTION;
}
@@ -1907,6 +1913,11 @@ bool MetaspaceShared::try_link_class(InstanceKlass* ik, TRAPS) {
ResourceMark rm(THREAD);
log_warning(cds)("Preload Warning: Verification failed for %s",
ik->external_name());
oop throwable = PENDING_EXCEPTION;
java_lang_Throwable::print(throwable, tty);
tty->cr();
CLEAR_PENDING_EXCEPTION;
ik->set_in_error_state();
_has_error_classes = true;

View File

@@ -40,6 +40,7 @@ import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection;
import sun.awt.image.SunWritableRaster;
import sun.swing.ImageCache;
import sun.awt.X11GraphicsDevice;
/**
* GTKEngine delegates all painting job to native GTK libraries.
@@ -94,6 +95,7 @@ class GTKEngine {
static enum Settings {
GTK_FONT_NAME,
GTK_ICON_SIZES,
GTK_XFT_DPI,
GTK_CURSOR_BLINK,
GTK_CURSOR_BLINK_TIME
}
@@ -270,6 +272,18 @@ class GTKEngine {
regionToWidgetTypeMap.put(Region.TREE, WidgetType.TREE);
regionToWidgetTypeMap.put(Region.TREE_CELL, WidgetType.TREE_CELL);
regionToWidgetTypeMap.put(Region.VIEWPORT, WidgetType.VIEWPORT);
Object value = INSTANCE.getSetting(Settings.GTK_XFT_DPI);
if (value instanceof Integer) {
int dpi = ((Integer)value).intValue() / 1024;
if (dpi == -1) {
dpi = 96;
}
if (dpi < 50) {
dpi = 50;
}
X11GraphicsDevice.setGlobalScale(Math.round(dpi / 96f));
}
}
/** Translate Region and JComponent into WidgetType ordinals */

View File

@@ -45,6 +45,7 @@ import java.util.Map;
import sun.awt.SunToolkit;
import sun.awt.UNIXToolkit;
import sun.awt.OSInfo;
import sun.awt.X11GraphicsDevice;
import sun.security.action.GetPropertyAction;
import sun.swing.DefaultLayoutStyle;
import sun.swing.SwingAccessor;
@@ -1447,6 +1448,18 @@ public class GTKLookAndFeel extends SynthLookAndFeel {
gtkAAFontSettingsCond = SwingUtilities2.isLocalDisplay();
aaTextInfo = new HashMap<>(2);
SwingUtilities2.putAATextInfo(gtkAAFontSettingsCond, aaTextInfo);
Object value = GTKEngine.INSTANCE.getSetting(GTKEngine.Settings.GTK_XFT_DPI);
if (value instanceof Integer) {
int dpi = ((Integer)value).intValue() / 1024;
if (dpi == -1) {
dpi = 96;
}
if (dpi < 50) {
dpi = 50;
}
X11GraphicsDevice.setGlobalScale(Math.round(dpi / 96f));
}
}
static ReferenceQueue<GTKLookAndFeel> queue = new ReferenceQueue<GTKLookAndFeel>();

View File

@@ -30,8 +30,10 @@ import java.awt.geom.AffineTransform;
import javax.swing.plaf.FontUIResource;
import java.util.StringTokenizer;
import sun.awt.AWTAccessor;
import sun.font.FontConfigManager;
import sun.font.FontUtilities;
import sun.java2d.SunGraphicsEnvironment;
/**
* @author Shannon Hickey
@@ -161,11 +163,15 @@ class PangoFonts {
*/
double dsize = size;
int dpi = 96;
Object value =
Toolkit.getDefaultToolkit().getDesktopProperty("gnome.Xft/DPI");
Object xftDPI = Toolkit.getDefaultToolkit().getDesktopProperty("gnome.Xft/DPI");
Object value = xftDPI;
if (!(value instanceof Integer)) {
value = GTKEngine.INSTANCE.getSetting(GTKEngine.Settings.GTK_XFT_DPI);
}
if (value instanceof Integer) {
dpi = ((Integer)value).intValue() / 1024;
if (dpi == -1) {
if (dpi == -1 || SunGraphicsEnvironment.isUIScaleEnabled()) {
dpi = 96;
}
if (dpi < 50) { /* 50 dpi is the minimum value gnome allows */
@@ -175,6 +181,12 @@ class PangoFonts {
* 72 dpi, so we need to adjust for that.
*/
dsize = ((double)(dpi * size)/ 72.0);
if (xftDPI == null) {
// [tav] used to indicate the 96/72 scale correction to the client app
AWTAccessor.getToolkitAccessor().setDesktopProperty(
Toolkit.getDefaultToolkit(), "gnome.Xft/DPI", value);
}
} else {
/* If there's no property, GTK scales for the resolution
* reported by the Xserver using the formula listed above.

View File

@@ -1392,6 +1392,11 @@ public abstract class Toolkit {
public void setPlatformResources(ResourceBundle bundle) {
Toolkit.setPlatformResources(bundle);
}
@Override
public void setDesktopProperty(Toolkit tk, String prop, Object value) {
tk.setDesktopProperty(prop, value);
}
});
java.security.AccessController.doPrivileged(

View File

@@ -563,7 +563,8 @@ public class Window extends Container implements Accessible {
*/
public Window(Frame owner) {
this(owner == null ? (GraphicsConfiguration)null :
owner.getGraphicsConfiguration());
// until peer is not created, the device should match default to correctly handle bounds settings
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration());
ownedInit(owner);
}
@@ -593,7 +594,8 @@ public class Window extends Container implements Accessible {
*/
public Window(Window owner) {
this(owner == null ? (GraphicsConfiguration)null :
owner.getGraphicsConfiguration());
// until peer is not created, the device should match default to correctly handle bounds settings
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration());
ownedInit(owner);
}

View File

@@ -29,6 +29,7 @@ import java.awt.*;
import sun.awt.ModalExclude;
import sun.awt.SunToolkit;
import sun.swing.SwingUtilities2;
/**
* Popups are used to display a <code>Component</code> to the user, typically
@@ -158,7 +159,9 @@ public class Popup {
if (c instanceof JWindow) {
JWindow component = (JWindow)getComponent();
component.setLocation(ownerX, ownerY);
Point ownerPt = SwingUtilities2.scalePoint(owner, new Point(ownerX, ownerY), component);
component.setLocation(ownerPt.x, ownerPt.y);
component.getContentPane().add(contents, BorderLayout.CENTER);
component.invalidate();
component.validate();

View File

@@ -1211,8 +1211,15 @@ public class RepaintManager
GraphicsConfiguration gc = gd.getDefaultConfiguration();
virtualBounds = virtualBounds.union(gc.getBounds());
}
doubleBufferMaxSize = new Dimension(virtualBounds.width,
virtualBounds.height);
doubleBufferMaxSize =
// Sometimes underlying desktop environment reports
// incorrect gc bounds (w=0,h=0). Replace them with
// maximum values (as we do for headless mode)
new Dimension(
virtualBounds.width == 0 ?
Integer.MAX_VALUE : virtualBounds.width,
virtualBounds.height == 0 ?
Integer.MAX_VALUE : virtualBounds.height);
} catch (HeadlessException e) {
doubleBufferMaxSize = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}

View File

@@ -771,6 +771,7 @@ public final class AWTAccessor {
*/
public interface ToolkitAccessor {
void setPlatformResources(ResourceBundle bundle);
void setDesktopProperty(Toolkit tk, String prop, Object value);
}
/*

View File

@@ -25,6 +25,8 @@
package sun.awt;
import sun.swing.SwingUtilities2;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.InvocationEvent;
@@ -188,7 +190,8 @@ public abstract class GlobalCursorManager {
}
if (p != null) {
queryPos = new Point();
getCursorPos(queryPos);
getCursorPos(queryPos); // gets the pos in 1x scale
queryPos.setLocation(SwingUtilities2.scalePoint(null, queryPos, comp));
Component c = AWTAccessor.getContainerAccessor().
findComponentAt((Container) comp,
queryPos.x - p.x, queryPos.y - p.y, false);

View File

@@ -0,0 +1,21 @@
package sun.awt.event;
import java.lang.annotation.Native;
public class TouchEvent {
@Native public static final int TOUCH_BEGIN = 2;
@Native public static final int TOUCH_UPDATE = 3;
@Native public static final int TOUCH_END = 4;
/**
* The allowable difference between coordinates of touch update events
* in pixels
*/
@Native public static final int CLICK_RADIUS = 10;
/**
* Stop owning touch processing after timeout
* in ms
*/
public static final long NO_UPDATE_TIMEOUT = 1000L;
}

View File

@@ -2351,4 +2351,29 @@ public class SwingUtilities2 {
var oldTx = oldGC != null ? oldGC.getDefaultTransform() : null;
return !Objects.equals(newTx, oldTx);
}
/**
* Scales a point, given in a scale of the source source component's graphics device,
* into the destination component's graphics device scale.
*
* @param source the source component
* @param p the point to scale
* @param dest the destination component
* @return the scaled point
*/
public static Point scalePoint(Component source, Point p, Component dest) {
double fromScaleX = 1.0f;
double fromScaleY = 1.0f;
double toScaleX = 1.0f;
double toScaleY = 1.0f;
if (source != null) {
fromScaleX = source.getGraphicsConfiguration().getDefaultTransform().getScaleX();
fromScaleY = source.getGraphicsConfiguration().getDefaultTransform().getScaleY();
}
if (dest != null) {
toScaleX = dest.getGraphicsConfiguration().getDefaultTransform().getScaleX();
toScaleY = dest.getGraphicsConfiguration().getDefaultTransform().getScaleY();
}
return new Point((int)(p.x * fromScaleX / toScaleX), (int)(p.y * fromScaleY / toScaleY));
}
}

View File

@@ -374,6 +374,20 @@ class Native {
return res;
}
/**
* Access to C double data(eight bytes)
*/
static final int DOUBLE_SIZE = 8;
static double getDouble(long ptr) { return unsafe.getDouble(ptr); }
static double getDouble(long ptr, int index) { return getDouble(ptr + DOUBLE_SIZE * index); }
/**
* Stores to C double data(eight bytes)
*/
static void putDouble(long ptr, double data) { unsafe.putDouble(ptr, data); }
static void putDouble(long ptr, int index, double data) {
putDouble(ptr + index * DOUBLE_SIZE, data);
}
/**
* Access to C "unsigned long" date type, which is XID in X

View File

@@ -55,7 +55,9 @@ public class XBaseWindow {
VISIBLE = "visible", // whether it is visible by default
SAVE_UNDER = "save under", // save content under this window
BACKING_STORE = "backing store", // enables double buffering
BIT_GRAVITY = "bit gravity"; // copy old content on geometry change
BIT_GRAVITY = "bit gravity", // copy old content on geometry change
XI_EVENT_MASK = "xi event mask", // xi event mask, Long
XI_DEVICE_ID = "xi device id"; // xi device id, Integer
private XCreateWindowParams delayedParams;
Set<Long> children = new HashSet<Long>();
@@ -394,6 +396,19 @@ public class XBaseWindow {
throw new IllegalStateException("Couldn't create window because of wrong parameters. Run with NOISY_AWT to see details");
}
XToolkit.addToWinMap(window, this);
Long xiEventMask = (Long) params.get(XI_EVENT_MASK);
if (xiEventMask != null && XToolkit.isXInputEnabled()) {
Integer xiDeviceId = (Integer) params.get(XI_DEVICE_ID);
if (xiDeviceId == null) {
xiDeviceId = XConstants.XIAllDevices;
}
int status = XToolkit.XISelectEvents(XToolkit.getDisplay(), window, xiEventMask, xiDeviceId);
if (status != XConstants.Success) {
throw new IllegalStateException("Couldn't select XI events. Status: " + status);
}
}
} finally {
xattr.dispose();
}
@@ -1073,6 +1088,10 @@ public class XBaseWindow {
width = scaleDown(xe.get_width());
height = scaleDown(xe.get_height());
}
public void handleTouchEvent(XEvent xev) {
}
/**
* Checks ButtonRelease released all Mouse buttons
*/
@@ -1112,6 +1131,12 @@ public class XBaseWindow {
if (target == null || !isGrabbedEvent(ev, target)) {
target = XToolkit.windowToXWindow(ev.get_xany().get_window());
}
if (target == null && ev.get_type() == XConstants.GenericEvent &&
XlibWrapper.XGetEventData(ev.get_xgeneric().get_display(), ev.pData)) {
target = XToolkit.windowToXWindow(XToolkit.GetXIDeviceEvent(ev.get_xcookie()).get_event());
}
if (target != null && target.checkInitialised()) {
target.dispatchEvent(ev);
}
@@ -1178,6 +1203,17 @@ public class XBaseWindow {
case XConstants.CreateNotify:
handleCreateNotify(xev);
break;
case XConstants.GenericEvent:
switch (xev.get_xgeneric().get_evtype()) {
case XConstants.XI_TouchBegin:
case XConstants.XI_TouchUpdate:
case XConstants.XI_TouchEnd:
handleTouchEvent(xev);
break;
default:
break;
}
break;
}
}
protected boolean isEventDisabled(XEvent e) {

View File

@@ -170,7 +170,8 @@ public final class XConstants {
public static final int ColormapNotify = 32 ;
public static final int ClientMessage = 33 ;
public static final int MappingNotify = 34 ;
public static final int LASTEvent = 35 ; /* must be bigger than any event # */
public static final int GenericEvent = 35 ;
public static final int LASTEvent = 36 ; /* must be bigger than any event # */
/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer,
@@ -679,4 +680,70 @@ public final class XConstants {
public static final long XkbModifierMapMask = (1L<<2);
public static final long XkbVirtualModsMask = (1L<<6); //server map
/* Fake device ID's for event selection */
public static final int XIAllDevices = 0;
public static final int XIAllMasterDevices = 1;
/* XI Event types */
public static final int XI_DeviceChanged = 1;
public static final int XI_KeyPress = 2;
public static final int XI_KeyRelease = 3;
public static final int XI_ButtonPress = 4;
public static final int XI_ButtonRelease = 5;
public static final int XI_Motion = 6;
public static final int XI_Enter = 7;
public static final int XI_Leave = 8;
public static final int XI_FocusIn = 9;
public static final int XI_FocusOut = 10;
public static final int XI_HierarchyChanged = 11;
public static final int XI_PropertyEvent = 12;
public static final int XI_RawKeyPress = 13;
public static final int XI_RawKeyRelease = 14;
public static final int XI_RawButtonPress = 15;
public static final int XI_RawButtonRelease = 16;
public static final int XI_RawMotion = 17;
public static final int XI_TouchBegin = 18;/* XI 2.2 */
public static final int XI_TouchUpdate = 19;
public static final int XI_TouchEnd = 20;
public static final int XI_TouchOwnership = 21;
public static final int XI_RawTouchBegin = 22;
public static final int XI_RawTouchUpdate = 23;
public static final int XI_RawTouchEnd = 24;
public static final int XI_BarrierHit = 25;/* XI 2.3 */
public static final int XI_BarrierLeave = 26;
public static final int XI_LASTEVENT = XI_BarrierLeave;
/* NOTE: XI2LASTEVENT in xserver/include/inputstr.h must be the same value
* as XI_LASTEVENT if the server is supposed to handle masks etc. for this
* type of event. */
/* Event masks.
* Note: the protocol spec defines a mask to be of (1 << type). Clients are
* free to create masks by bitshifting instead of using these defines.
*/
public static final long XI_DeviceChangedMask = 1L << XI_DeviceChanged;
public static final long XI_KeyPressMask = 1L << XI_KeyPress;
public static final long XI_KeyReleaseMask = 1L << XI_KeyRelease;
public static final long XI_ButtonPressMask = 1L << XI_ButtonPress;
public static final long XI_ButtonReleaseMask = 1L << XI_ButtonRelease;
public static final long XI_MotionMask = 1L << XI_Motion;
public static final long XI_EnterMask = 1L << XI_Enter;
public static final long XI_LeaveMask = 1L << XI_Leave;
public static final long XI_FocusInMask = 1L << XI_FocusIn;
public static final long XI_FocusOutMask = 1L << XI_FocusOut;
public static final long XI_HierarchyChangedMask = 1L << XI_HierarchyChanged;
public static final long XI_PropertyEventMask = 1L << XI_PropertyEvent;
public static final long XI_RawKeyPressMask = 1L << XI_RawKeyPress;
public static final long XI_RawKeyReleaseMask = 1L << XI_RawKeyRelease;
public static final long XI_RawButtonPressMask = 1L << XI_RawButtonPress;
public static final long XI_RawButtonReleaseMask = 1L << XI_RawButtonRelease;
public static final long XI_RawMotionMask = 1L << XI_RawMotion;
public static final long XI_TouchBeginMask = 1L << XI_TouchBegin;
public static final long XI_TouchEndMask = 1L << XI_TouchEnd;
public static final long XI_TouchOwnershipChangedMask = 1L << XI_TouchOwnership;
public static final long XI_TouchUpdateMask = 1L << XI_TouchUpdate;
public static final long XI_RawTouchBeginMask = 1L << XI_RawTouchBegin;
public static final long XI_RawTouchEndMask = 1L << XI_RawTouchEnd;
public static final long XI_RawTouchUpdateMask = 1L << XI_RawTouchUpdate;
public static final long XI_BarrierHitMask = 1L << XI_BarrierHit;
public static final long XI_BarrierLeaveMask = 1L << XI_BarrierLeave;
}

View File

@@ -340,6 +340,7 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
log.finer("X locale modifiers are not supported, using default");
}
tryXKB();
checkXInput();
AwtScreenData defaultScreen = new AwtScreenData(XToolkit.getDefaultScreenData());
awt_defaultFg = defaultScreen.get_blackpixel();
@@ -738,12 +739,17 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
}
dispatchEvent(ev);
// free event data if XGetEventData was called
XlibWrapper.XFreeEventData(getDisplay(), ev.pData);
} catch (ThreadDeath td) {
XBaseWindow.ungrabInput();
return;
processException(td);
throw td;
} catch (Throwable thr) {
XBaseWindow.ungrabInput();
processException(thr);
// In case of ThreadDeath thread is still alive in finally block so we have to duplicate freeing
XlibWrapper.XFreeEventData(getDisplay(), ev.pData);
} finally {
awtUnlock();
}
@@ -2579,6 +2585,58 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
}
}
private static volatile boolean hasXInputExtension = false;
public static boolean isXInputEnabled() {
return hasXInputExtension;
}
public static void checkXInput() {
awtLock();
try {
String extensionName = "XInputExtension";
boolean hasExtension = XlibWrapper.XQueryExtension(XToolkit.getDisplay(), extensionName,
XlibWrapper.iarg1, XlibWrapper.iarg2, XlibWrapper.iarg3);
if (!hasExtension) {
log.warning("X Input extension isn't available, error: {0}", Native.getInt(XlibWrapper.iarg1));
return;
}
final int requiredMajor = 2;
final int requiredMinor = 2;
Native.putInt(XlibWrapper.iarg1, requiredMajor);
Native.putInt(XlibWrapper.iarg2, requiredMinor);
int status = XlibWrapper.XIQueryVersion(XToolkit.getDisplay(), XlibWrapper.iarg1, XlibWrapper.iarg2);
if (status == XConstants.BadRequest) {
log.warning("X Input2 not supported in the server");
return;
}
int major = Native.getInt(XlibWrapper.iarg1);
int minor = Native.getInt(XlibWrapper.iarg2);
if (major >= requiredMajor && minor >= requiredMinor) {
hasXInputExtension = true;
} else {
log.warning("Desired version is 2.2, server version is {0}.{1}", major, minor);
}
} finally {
awtUnlock();
}
}
public static XIDeviceEvent GetXIDeviceEvent(XGenericEventCookie cookie) {
return new XIDeviceEvent(cookie.get_data());
}
public static int XISelectEvents(long display, long window, long mask, int deviceid) {
if (isXInputEnabled()) {
return XlibWrapper.XISelectEvents(display, window, mask, deviceid);
} else {
log.warning("Attempting to select xi events while xinput isn't available");
return XConstants.BadRequest;
}
}
private static long eventNumber;
public static long getEventNumber() {
awtLock();

View File

@@ -105,7 +105,10 @@ final class XWM
LG3D_WM = 13,
CWM_WM = 14,
MUTTER_WM = 15,
UNITY_COMPIZ_WM = 16;
UNITY_COMPIZ_WM = 16,
XMONAD_WM = 17,
AWESOME_WM = 18;
public String toString() {
switch (WMID) {
case NO_WM:
@@ -138,6 +141,10 @@ final class XWM
return "CWM";
case MUTTER_WM:
return "Mutter";
case XMONAD_WM:
return "XMonad";
case AWESOME_WM:
return "Awesome";
case UNDETERMINED_WM:
default:
return "Undetermined WM";
@@ -602,13 +609,23 @@ final class XWM
return isNetWMName("Mutter") || isNetWMName("GNOME Shell");
}
static boolean isXmonad() {
return isNetWMName("xmonad");
}
static boolean isAwesome() {
return isNetWMName("awesome");
}
static int awtWMNonReparenting = -1;
static boolean isNonReparentingWM() {
if (awtWMNonReparenting == -1) {
awtWMNonReparenting = (XToolkit.getEnv("_JAVA_AWT_WM_NONREPARENTING") != null) ? 1 : 0;
}
return (awtWMNonReparenting == 1 || XWM.getWMID() == XWM.COMPIZ_WM
|| XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM);
|| XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM ||
XWM.getWMID() == XWM.XMONAD_WM
);
}
/*
@@ -799,6 +816,10 @@ final class XWM
awt_wmgr = XWM.ICE_WM;
} else if (isUnityCompiz()) {
awt_wmgr = XWM.UNITY_COMPIZ_WM;
} else if (isXmonad()) {
awt_wmgr = XWM.XMONAD_WM;
} else if (isAwesome()) {
awt_wmgr = XWM.AWESOME_WM;
}
/*
* We don't check for legacy WM when we already know that WM
@@ -1123,6 +1144,8 @@ final class XWM
case XWM.SAWFISH_WM:
case XWM.ICE_WM:
case XWM.METACITY_WM:
case XWM.XMONAD_WM:
case XWM.AWESOME_WM:
return true;
case XWM.OPENLOOK_WM:
case XWM.MOTIF_WM:
@@ -1364,6 +1387,8 @@ final class XWM
break;
case NO_WM:
case LG3D_WM:
case XMONAD_WM:
case AWESOME_WM:
res = zeroInsets;
break;
case UNITY_COMPIZ_WM:
@@ -1641,7 +1666,9 @@ final class XWM
break;
}
case XWM.SAWFISH_WM:
case XWM.OPENLOOK_WM: {
case XWM.OPENLOOK_WM:
case XWM.AWESOME_WM:
{
/* single reparenting */
syncTopLevelPos(window, lwinAttr);
correctWM.top = lwinAttr.get_y();

View File

@@ -36,8 +36,7 @@ import sun.awt.AWTAccessor.ComponentAccessor;
import sun.util.logging.PlatformLogger;
import sun.awt.*;
import sun.awt.image.PixelConverter;
import sun.awt.event.TouchEvent;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
@@ -48,6 +47,7 @@ class XWindow extends XBaseWindow implements X11ComponentPeer {
private static PlatformLogger eventLog = PlatformLogger.getLogger("sun.awt.X11.event.XWindow");
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XWindow");
private static PlatformLogger keyEventLog = PlatformLogger.getLogger("sun.awt.X11.kye.XWindow");
private static PlatformLogger touchEventLog = PlatformLogger.getLogger("sun.awt.event.TouchEvent");
/* If a motion comes in while a multi-click is pending,
* allow a smudge factor so that moving the mouse by a small
* amount does not wipe out the multi-click state variables.
@@ -60,6 +60,12 @@ class XWindow extends XBaseWindow implements X11ComponentPeer {
static WeakReference<XWindow> lastWindowRef = null;
static int clickCount = 0;
// all touch scrolls are measured in pixels
private static int touchBeginX = 0, touchBeginY = 0;
private static int trackingId = 0;
private static long lastTouchUpdateTime = 0;
private static boolean isTouchScroll = false;
// used to check if we need to re-create surfaceData.
int oldWidth = -1;
int oldHeight = -1;
@@ -223,6 +229,11 @@ class XWindow extends XBaseWindow implements X11ComponentPeer {
params.putIfNull(BACKING_STORE, XToolkit.getBackingStoreType());
params.putIfNull(XI_EVENT_MASK, XConstants.XI_TouchBeginMask |
XConstants.XI_TouchUpdateMask |
XConstants.XI_TouchEndMask);
params.putIfNull(XI_DEVICE_ID, XConstants.XIAllMasterDevices);
XToolkit.awtLock();
try {
if (wm_protocols == null) {
@@ -765,6 +776,143 @@ class XWindow extends XBaseWindow implements X11ComponentPeer {
}
}
public void handleTouchEvent(XEvent xev) {
super.handleTouchEvent(xev);
XIDeviceEvent dev = XToolkit.GetXIDeviceEvent(xev.get_xcookie());
// TODO remove this after TouchEvents support
// own touch processing by tracking id
if (isTouchReleased()) {
trackingId = dev.get_detail();
} else if (!isOwningTouch(dev.get_detail())) {
return;
}
int x = scaleDown((int) dev.get_event_x());
int y = scaleDown((int) dev.get_event_y());
if (dev.get_event() != window) {
Point localXY = toLocal(x, y);
x = localXY.x;
y = localXY.y;
}
int modifiers = getModifiers(dev.get_mods().get_effective(), MouseEvent.BUTTON1, 0);
int scrollModifiers = modifiers & ~InputEvent.SHIFT_DOWN_MASK;
long jWhen = XToolkit.nowMillisUTC_offset(dev.get_time());
switch (dev.get_evtype()) {
case XConstants.XI_TouchBegin:
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
touchEventLog.finest("Touch Begin at: " + x + ", " + y);
}
isTouchScroll = false;
touchBeginX = x;
touchBeginY = y;
lastTouchUpdateTime = jWhen;
sendWheelEventFromTouch(dev, jWhen, scrollModifiers, touchBeginX, touchBeginY, TouchEvent.TOUCH_BEGIN, 1);
break;
case XConstants.XI_TouchUpdate:
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
touchEventLog.finest("Touch Update at: " + x + ", " + y);
}
lastTouchUpdateTime = jWhen;
if (!isTouchScroll && isInsideTouchClickBoundaries(x, y)) {
return;
}
isTouchScroll = true;
int deltaY = lastY - y;
if (deltaY != 0) {
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
touchEventLog.finest("Vertical touch scroll, delta: " + deltaY);
}
sendWheelEventFromTouch(dev, jWhen, scrollModifiers, x, y, TouchEvent.TOUCH_UPDATE, deltaY);
}
int deltaX = lastX - x;
if (deltaX != 0) {
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
touchEventLog.finest("Horizontal touch scroll, delta: " + deltaX);
}
int horizontalScrollMods = scrollModifiers | InputEvent.SHIFT_DOWN_MASK;
sendWheelEventFromTouch(dev, jWhen, horizontalScrollMods, x, y, TouchEvent.TOUCH_UPDATE, deltaX);
}
break;
case XConstants.XI_TouchEnd:
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
touchEventLog.finest("Touch End at: " + x + ", " + y);
}
sendWheelEventFromTouch(dev, jWhen, scrollModifiers, x, y, TouchEvent.TOUCH_END, 1);
if (!isTouchScroll) {
if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {
touchEventLog.finest("Touch Press at: " + x + ", " + y);
}
sendButtonPressFromTouch(dev, jWhen, modifiers, touchBeginX, touchBeginY);
}
// release touch processing
trackingId = 0;
break;
}
lastX = x;
lastY = y;
}
private boolean isInsideTouchClickBoundaries(int x, int y) {
return Math.abs(touchBeginX - x) <= TouchEvent.CLICK_RADIUS &&
Math.abs(touchBeginY - y) <= TouchEvent.CLICK_RADIUS;
}
private static boolean isOwningTouch(int fingerId) {
return trackingId == fingerId;
}
private static boolean isTouchReleased() {
if (trackingId == 0) {
return true;
}
// recovery from situation when TOUCH_END event didn't occurred
long msFromLastUpdate = Math.abs(System.currentTimeMillis() - lastTouchUpdateTime);
if (msFromLastUpdate >= TouchEvent.NO_UPDATE_TIMEOUT) {
touchEventLog.warning("Release touch processing, milliseconds from last update: " + msFromLastUpdate);
}
return msFromLastUpdate >= TouchEvent.NO_UPDATE_TIMEOUT;
}
private void sendButtonPressFromTouch(XIDeviceEvent dev, long jWhen, int modifiers, int x, int y) {
sendMouseEventFromTouch(dev, MouseEvent.MOUSE_MOVED, jWhen, modifiers, x, y, MouseEvent.NOBUTTON, 0);
sendMouseEventFromTouch(dev, MouseEvent.MOUSE_DRAGGED, jWhen, modifiers, x, y, MouseEvent.BUTTON1, 0);
sendMouseEventFromTouch(dev, MouseEvent.MOUSE_PRESSED, jWhen, modifiers, x, y, MouseEvent.BUTTON1, 1);
sendMouseEventFromTouch(dev, MouseEvent.MOUSE_RELEASED, jWhen, modifiers, x, y, MouseEvent.BUTTON1, 1);
sendMouseEventFromTouch(dev, MouseEvent.MOUSE_CLICKED, jWhen, modifiers, x, y, MouseEvent.BUTTON1, 1);
}
private void sendWheelEventFromTouch(XIDeviceEvent dev, long jWhen, int modifiers, int x, int y, int type, int delta) {
postEventToEventQueue(
new MouseWheelEvent(getEventSource(), MouseEvent.MOUSE_WHEEL, jWhen,
modifiers,
x, y,
scaleDown((int) dev.get_root_x()),
scaleDown((int) dev.get_root_y()),
0, false, type,
1, delta));
}
private void sendMouseEventFromTouch(XIDeviceEvent dev, int type, long jWhen, int modifiers, int x, int y, int button, int clickCount) {
boolean popupTrigger = button == MouseEvent.BUTTON3;
postEventToEventQueue(
new MouseEvent(getEventSource(), type, jWhen,
modifiers, x, y,
scaleDown((int) dev.get_root_x()),
scaleDown((int) dev.get_root_y()),
clickCount, popupTrigger, button));
}
public void handleMotionNotify(XEvent xev) {
super.handleMotionNotify(xev);
XMotionEvent xme = xev.get_xmotion();

View File

@@ -777,6 +777,7 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
case XWM.MUTTER_WM:
case XWM.SAWFISH_WM:
case XWM.UNITY_COMPIZ_WM:
case XWM.AWESOME_WM:
{
Point xlocation = queryXLocation();
if (log.isLoggable(PlatformLogger.Level.FINE)) {

View File

@@ -564,6 +564,12 @@ static native String XSetLocaleModifiers(String modifier_list);
static native void SetZOrder(long display, long window, long above);
static native int XIQueryVersion(long display, long major_version_iptr, long minor_version_iptr);
static native int XISelectEvents(long display, long window, long mask, int deviceid);
static native boolean XGetEventData(long display, long ptr);
static native void XFreeEventData(long display, long ptr);
/* Global memory area used for X lib parameter passing */
static final long lbuffer = unsafe.allocateMemory(64); // array to hold 8 longs

View File

@@ -63,6 +63,8 @@ public final class X11GraphicsDevice extends GraphicsDevice
private DisplayMode origDisplayMode;
private boolean shutdownHookRegistered;
private int scale;
private volatile boolean isNativeScaleDefault;
private static int globalScale; // derived from Xft.dpi
public X11GraphicsDevice(int screennum) {
this.screen = screennum;
@@ -510,11 +512,22 @@ public final class X11GraphicsDevice extends GraphicsDevice
return scale;
}
public int getNativeScale() {
private int getNativeScale() {
isXrandrExtensionSupported();
return (int)Math.round(getNativeScaleFactor(screen));
}
public static void setGlobalScale(int scale) {
globalScale = scale;
for (GraphicsDevice gd : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
X11GraphicsDevice x11gd = (X11GraphicsDevice)gd;
if (x11gd.isNativeScaleDefault) {
x11gd.scale = globalScale;
x11gd.isNativeScaleDefault = false;
}
}
}
private int initScaleFactor() {
if (SunGraphicsEnvironment.isUIScaleEnabled()) {
@@ -525,7 +538,10 @@ public final class X11GraphicsDevice extends GraphicsDevice
return (int) debugScale;
}
int nativeScale = getNativeScale();
return nativeScale >= 1 ? nativeScale : 1;
if (nativeScale > 0) return nativeScale;
if (globalScale > 0) return globalScale;
isNativeScaleDefault = true;
return 1;
}
return 1;

View File

@@ -26,6 +26,7 @@
package sun.font;
import sun.awt.*;
import sun.java2d.InvalidPipeException;
import sun.java2d.SunGraphics2D;
import sun.java2d.pipe.GlyphListPipe;
import sun.java2d.xr.*;
@@ -61,8 +62,12 @@ public class XRTextRenderer extends GlyphListPipe {
try {
SunToolkit.awtLock();
XRSurfaceData x11sd = (XRSurfaceData) sg2d.surfaceData;
XRSurfaceData x11sd;
try {
x11sd = (XRSurfaceData) sg2d.surfaceData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
}
x11sd.validateAsDestination(null, sg2d.getCompClip());
x11sd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform, sg2d.paint, sg2d);

View File

@@ -99,7 +99,12 @@ public class XRMaskFill extends MaskFill {
try {
SunToolkit.awtLock();
XRSurfaceData x11sd = (XRSurfaceData) sData;
XRSurfaceData x11sd;
try {
x11sd = (XRSurfaceData) sData;
} catch (ClassCastException e) {
throw new InvalidPipeException("wrong surface data type: " + sData);
}
x11sd.validateAsDestination(null, sg2d.getCompClip());
XRCompositeManager maskBuffer = x11sd.maskBuffer;

View File

@@ -45,6 +45,7 @@ typedef void* g_variant_get_child_value(void *, unsigned long);
typedef void g_variant_unref(void *);
typedef char* g_variant_get_string(void *, unsigned long *);
typedef int g_variant_get_int32(void *);
typedef unsigned g_variant_get_uint32(void *);
typedef double g_variant_get_double(void *);
static g_settings_schema_has_key* fp_g_settings_schema_has_key;
@@ -55,6 +56,7 @@ static g_variant_n_children* fp_g_variant_n_children;
static g_variant_get_child_value* fp_g_variant_get_child_value;
static g_variant_get_string* fp_g_variant_get_string;
static g_variant_get_int32* fp_g_variant_get_int32;
static g_variant_get_uint32* fp_g_variant_get_uint32;
static g_variant_get_double* fp_g_variant_get_double;
static g_variant_unref* fp_g_variant_unref;
@@ -96,6 +98,9 @@ static void* get_schema_value(char *name, char *key) {
CHECK_NULL_RETURN(fp_g_variant_get_int32 =
(g_variant_get_int32*)
dlsym(lib_handle, "g_variant_get_int32"), NULL);
CHECK_NULL_RETURN(fp_g_variant_get_uint32 =
(g_variant_get_uint32*)
dlsym(lib_handle, "g_variant_get_uint32"), NULL);
CHECK_NULL_RETURN(fp_g_variant_get_double =
(g_variant_get_double*)
dlsym(lib_handle, "g_variant_get_double"), NULL);
@@ -165,6 +170,7 @@ static double getDesktopScale(char *output_name) {
}
fp_g_variant_unref(value);
}
/* [tav]
if (result > 0) {
value = get_schema_value("com.canonical.Unity.Interface",
"text-scale-factor");
@@ -172,9 +178,19 @@ static double getDesktopScale(char *output_name) {
result *= fp_g_variant_get_double(value);
fp_g_variant_unref(value);
}
}*/
}
if (result <= 0) {
void *value = get_schema_value("org.gnome.desktop.interface",
"scaling-factor");
if (value && fp_g_variant_is_of_type(value, "u")) {
result = fp_g_variant_get_uint32(value);
fp_g_variant_unref(value);
}
}
/* [tav]
if (result <= 0) {
void *value = get_schema_value("org.gnome.desktop.interface",
"text-scaling-factor");
@@ -182,7 +198,7 @@ static double getDesktopScale(char *output_name) {
result = fp_g_variant_get_double(value);
fp_g_variant_unref(value);
}
}
}*/
return result;
@@ -200,7 +216,7 @@ static int getScale(const char *name) {
return -1;
}
double getNativeScaleFactor(char *output_name) {
double getNativeScaleFactor(char *output_name, double default_value) {
static int scale = -2.0;
double native_scale = 0;
int gdk_scale = 0;
@@ -216,10 +232,10 @@ double getNativeScaleFactor(char *output_name) {
native_scale = getDesktopScale(output_name);
if (native_scale <= 0) {
native_scale = 1;
native_scale = default_value;
}
gdk_scale = getScale("GDK_SCALE");
return gdk_scale > 0 ? native_scale * gdk_scale : native_scale;
return gdk_scale > 0 ? (native_scale <= 0 ? 1 : native_scale) * gdk_scale : native_scale;
}

View File

@@ -28,7 +28,7 @@
#include <signal.h>
#include <stdlib.h>
double getNativeScaleFactor(char *output_name);
double getNativeScaleFactor(char *output_name, double default_value);
#endif

View File

@@ -34,6 +34,8 @@
#ifndef HEADLESS
#include <X11/extensions/Xdbe.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#ifndef NO_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
@@ -2178,7 +2180,27 @@ Java_sun_awt_X11GraphicsDevice_getNativeScaleFactor
(JNIEnv *env, jobject this, jint screen) {
// in case of Xinerama individual screen scales are not supported
char *name = get_output_screen_name(env, usingXinerama ? 0 : screen);
double scale = getNativeScaleFactor(name);
double scale = getNativeScaleFactor(name, -1);
#ifndef HEADLESS
// Ubuntu 18.04 introduced a new settings for a scale factor: Settings > Devices > Displays > Scale.
// It is propagated to Xresource (and is read fine with 'xrdb' util) but is not propagated to GSettings
// (gtk3 doesn't see it in 'gtk-xft-dpi'). So, retrieve "Xft.dpi" from Xresource via X11 API call.
if (scale <= 0 && awt_display) {
char *resource_manager = XResourceManagerString(awt_display);
if (resource_manager) {
XrmDatabase db = XrmGetStringDatabase(resource_manager);
if (db) {
XrmValue value;
char *type;
if (XrmGetResource(db, "Xft.dpi", "Xft.dpi", &type, &value)) {
scale = (double)atoi(value.addr) / 96;
}
}
}
}
#endif
if (name) {
free(name);
}

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