Compare commits

..

10 Commits

Author SHA1 Message Date
Sebastian Stenzel
0de6abd4b4 8260966: (fs) Consolidate Linux and macOS implementations of UserDefinedFileAttributeView
8260691: (fs) LinuxNativeDispatcher should link to xattr functions

Reviewed-by: alanb
2021-03-02 14:40:45 +00:00
Daniel Fuchs
5f4bc0aca6 8253100: Fix "no comment" warnings in java.base/java.net
Reviewed-by: ryadav, chegar, naoto, alanb
2021-03-02 12:54:54 +00:00
Attila Szegedi
d185a6c53e 8261483: jdk/dynalink/TypeConverterFactoryMemoryLeakTest.java failed with "AssertionError: Should have GCd a method handle by now"
Reviewed-by: shade, plevart
2021-03-02 12:25:25 +00:00
Jan Lahoda
85a5ae8cb7 8261606: Surprising behavior of step over in String switch
Reviewed-by: vromero
2021-03-02 12:02:26 +00:00
Nick Gasson
be67aaabe6 8262726: AArch64: C1 StubAssembler::call_RT can corrupt stack
Reviewed-by: aph
2021-03-02 09:56:05 +00:00
Jie Fu
0f6122b92f 8262819: gc/shenandoah/compiler/TestLinkToNativeRBP.java fails with release VMs
Reviewed-by: roland, shade
2021-03-02 09:30:06 +00:00
Matthias Baesken
dd33a8eaaa 8262461: handle wcstombsdmp return value correctly in unix awt_InputMethod.c
Reviewed-by: psadhukhan, azvegint, aivanov
2021-03-02 08:00:23 +00:00
Yasumasa Suenaga
3b350ad87f 8261710: SA DSO objects have sizes that are too large
Reviewed-by: sspitsyn, cjplummer
2021-03-02 06:56:40 +00:00
Thomas Stuefe
fdd109327c 8261552: s390: MacroAssembler::encode_klass_not_null() may produce wrong results for non-zero values of narrow klass base
Co-authored-by: Lutz Schmidt <lucy@openjdk.org>
Reviewed-by: mdoerr, lucy
2021-03-02 04:30:26 +00:00
Thomas Stuefe
f5ab7f688c 8262472: Buffer overflow in UNICODE::as_utf8 for zero length output buffer
Reviewed-by: dholmes, iklam
2021-03-02 04:28:48 +00:00
107 changed files with 1085 additions and 27486 deletions

0
configure vendored Executable file → Normal file
View File

View File

@@ -1,13 +0,0 @@
# jetbrains/runtime:jbr15env
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 15
RUN wget https://cdn.azul.com/zulu/bin/zulu15.27.17-ca-jdk15.0.0-linux_x64.tar.gz \
-O - | tar xz -C /
RUN mv /zulu15.27.17-ca-jdk15.0.0-linux_x64 /jdk15.0.0
ENV PATH /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

@@ -1,54 +0,0 @@
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
do_reset_dcevm=0
HEAD_REVISION=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
if [ $do_reset_dcevm -eq 1 ]; then
[ ! -z $HEAD_REVISION ] && git reset --hard $HEAD_REVISION
fi
exit "$exit_code"
}
function update_jsdk_mods() {
__jsdk=$1
__jcef_mods=$2
__orig_jsdk_mods=$3
__updated_jsdk_mods=$4
# re-create java.desktop.jmod with updated module-info.class
tmp=.java.desktop.$$.tmp
mkdir "$tmp" || exit $?
"$__jsdk"/bin/jmod extract --dir "$tmp" "$__orig_jsdk_mods"/java.desktop.jmod || exit $?
"$__jsdk"/bin/javac \
--patch-module java.desktop="$__orig_jsdk_mods"/java.desktop.jmod \
--module-path "$__jcef_mods" -d "$tmp"/classes src/java.desktop/share/classes/module-info.java || exit $?
"$__jsdk"/bin/jmod \
create --class-path "$tmp"/classes --config "$tmp"/conf --header-files "$tmp"/include --legal-notice "$tmp"/legal --libs "$tmp"/lib \
java.desktop.jmod || exit $?
mv java.desktop.jmod "$__updated_jsdk_mods" || exit $?
rm -rf "$tmp"
# re-create java.base.jmod with updated hashes
tmp=.java.base.$$.tmp
mkdir "$tmp" || exit $?
hash_modules=$("$JSDK"/bin/jmod describe "$__orig_jsdk_mods"/java.base.jmod | grep hashes | awk '{print $2}' | tr '\n' '|' | sed s/\|$//) || exit $?
"$__jsdk"/bin/jmod extract --dir "$tmp" "$__orig_jsdk_mods"/java.base.jmod || exit $?
rm "$__updated_jsdk_mods"/java.base.jmod || exit $? # temp exclude from path
"$__jsdk"/bin/jmod \
create --module-path "$__updated_jsdk_mods" --hash-modules "$hash_modules" \
--class-path "$tmp"/classes --cmds "$tmp"/bin --config "$tmp"/conf --header-files "$tmp"/include --legal-notice "$tmp"/legal --libs "$tmp"/lib \
java.base.jmod || exit $?
mv java.base.jmod "$__updated_jsdk_mods" || exit $?
rm -rf "$tmp"
}
function get_mods_list() {
__mods=$1
echo $(ls $__mods) | sed s/\.jmod/,/g | sed s/,$//g | sed s/' '//g
}

View File

@@ -1,84 +0,0 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
#
# 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/scripts/common.sh
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
[ -z "$bundle_type" ] && (git apply -p0 < jb/project/tools/patches/exclude_jcef_module.patch || exit $?)
sh configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-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-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

@@ -1,137 +0,0 @@
#!/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:
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_linux_x64
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
JCEF_PATH=${JCEF_PATH:=./jcef_linux_x64}
source jb/project/tools/common/scripts/common.sh
function create_image_bundle {
__bundle_name=$1
__arch_name=$2
__modules_path=$3
__modules=$4
[ "$bundle_type" == "fd" ] && fastdebug_infix="fastdebug-"
JBR=${__bundle_name}-${JBSDK_VERSION}-linux-x64-${fastdebug_infix}b${build_number}
echo Running jlink....
[ -d "$IMAGES_DIR"/"$__arch_name" ] && rm -rf "${IMAGES_DIR:?}"/"$__arch_name"
$JSDK/bin/jlink \
--module-path "$__modules_path" --no-man-pages --compress=2 \
--add-modules "$__modules" --output "$IMAGES_DIR"/"$__arch_name"
grep -v "^JAVA_VERSION" "$JSDK"/release | grep -v "^MODULES" >> "$IMAGES_DIR"/"$__arch_name"/release
if [ "$__bundle_name" == "$JBRSDK_BUNDLE" ]; then
sed 's/JBR/JBRSDK/g' "$IMAGES_DIR"/"$__arch_name"/release > release
mv release "$IMAGES_DIR"/"$__arch_name"/release
fi
# jmod does not preserve file permissions (JDK-8173610)
[ -f "$IMAGES_DIR"/"$__arch_name"/lib/jcef_helper ] && chmod a+x "$IMAGES_DIR"/"$__arch_name"/lib/jcef_helper
echo Creating "$JBR".tar.gz ...
tar -pcf "$JBR".tar -C "$IMAGES_DIR" "$__arch_name" || do_exit $?
[ -f "$JBR".tar.gz ] && rm "$JBR.tar.gz"
gzip "$JBR".tar || do_exit $?
rm -rf "${IMAGES_DIR:?}"/"$__arch_name"
}
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=linux-x86_64-server-release
case "$bundle_type" in
"jcef")
do_reset_changes=1
;;
"dcevm")
HEAD_REVISION=$(git rev-parse HEAD)
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?
do_reset_dcevm=1
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
;;
"fd")
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=linux-x86_64-server-fastdebug
;;
esac
sh configure \
--disable-warnings-as-errors \
$WITH_DEBUG_LEVEL \
--with-vendor-name="$VENDOR_NAME" \
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
--with-version-pre= \
--with-version-build="$JDK_BUILD_NUMBER" \
--with-version-opt=b"$build_number" \
--with-boot-jdk="$BOOT_JDK" \
--enable-cds=yes || do_exit $?
make clean CONF=$RELEASE_NAME || exit $?
make images CONF=$RELEASE_NAME || do_exit $?
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk
JSDK_MODS_DIR=$IMAGES_DIR/jmods
JBRSDK_BUNDLE=jbrsdk
echo Fixing permissions
chmod -R a+r $JSDK
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
update_jsdk_mods $JSDK $JCEF_PATH/jmods $JSDK/jmods $JSDK_MODS_DIR || do_exit $?
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
jbr_name_postfix="_${bundle_type}"
fi
# create runtime image bundle
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" || do_exit $?
# create sdk image bundle
modules=$(cat $JSDK/release | grep MODULES | sed s/MODULES=//g | sed s/' '/,/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle $JBRSDK_BUNDLE $JBRSDK_BUNDLE $JSDK_MODS_DIR "$modules" || do_exit $?
if [ -z "$bundle_type" ]; then
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-linux-test-x64-b${build_number}
echo Creating "$JBRSDK_TEST" ...
make test-image CONF=$RELEASE_NAME || do_exit $?
tar -pcf "$JBRSDK_TEST".tar -C $IMAGES_DIR --exclude='test/jdk/demos' test || do_exit $?
[ -f "$JBRSDK_TEST.tar.gz" ] && rm "$JBRSDK_TEST.tar.gz"
gzip "$JBRSDK_TEST".tar || do_exit $?
fi
do_exit 0

View File

@@ -1,81 +0,0 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
#
# 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/scripts/common.sh
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
[ -z "$bundle_type" ] && (git apply -p0 < jb/project/tools/patches/exclude_jcef_module.patch || exit $?)
linux32 bash configure \
--disable-warnings-as-errors \
--with-debug-level=release \
--with-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

@@ -1,16 +0,0 @@
<?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

@@ -1,139 +0,0 @@
#!/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:
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_mac
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
JBSDK_VERSION_WITH_DOTS=$(echo "$JBSDK_VERSION" | sed 's/_/\./g')
JCEF_PATH=${JCEF_PATH:=./jcef_mac}
MAJOR_JBSDK_VERSION=$(echo "$JBSDK_VERSION_WITH_DOTS" | awk -F "." '{print $1}')
BOOT_JDK=${BOOT_JDK:=$(/usr/libexec/java_home -v 14)}
source jb/project/tools/common/scripts/common.sh
function create_image_bundle {
__bundle_name=$1
__arch_name=$2
__modules_path=$3
__modules=$4
tmp=.bundle.$$.tmp
mkdir "$tmp" || do_exit $?
[ "$bundle_type" == "fd" ] && fastdebug_infix="fastdebug-"
JBR=${__bundle_name}-${JBSDK_VERSION}-osx-x64-${fastdebug_infix}b${build_number}
JRE_CONTENTS=$tmp/$__arch_name/Contents
mkdir -p "$JRE_CONTENTS" || do_exit $?
echo Running jlink...
"$JSDK"/bin/jlink \
--module-path "$__modules_path" --no-man-pages --compress=2 \
--add-modules "$__modules" --output "$JRE_CONTENTS/Home" || do_exit $?
grep -v "^JAVA_VERSION" "$JSDK"/release | grep -v "^MODULES" >> "$JRE_CONTENTS/Home/release"
if [ "$__bundle_name" == "$JBRSDK_BUNDLE" ]; then
sed 's/JBR/JBRSDK/g' $JRE_CONTENTS/Home/release > release
mv release $JRE_CONTENTS/Home/release
fi
cp -R "$JSDK"/../MacOS "$JRE_CONTENTS"
cp "$JSDK"/../Info.plist "$JRE_CONTENTS"
[ -n "$bundle_type" ] && (cp -a $JCEF_PATH/Frameworks "$JRE_CONTENTS" || do_exit $?)
echo Creating "$JBR".tar.gz ...
COPYFILE_DISABLE=1 tar -pczf "$JBR".tar.gz --exclude='*.dSYM' --exclude='man' -C "$tmp" "$__arch_name" || do_exit $?
rm -rf "$tmp"
}
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=macosx-x86_64-server-release
case "$bundle_type" in
"jcef")
do_reset_changes=1
;;
"dcevm")
HEAD_REVISION=$(git rev-parse HEAD)
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?
do_reset_dcevm=1
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
;;
"fd")
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=macosx-x86_64-server-fastdebug
;;
esac
sh configure \
--disable-warnings-as-errors \
$WITH_DEBUG_LEVEL \
--with-vendor-name="$VENDOR_NAME" \
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
--with-version-pre= \
--with-version-build="$JDK_BUILD_NUMBER" \
--with-version-opt=b"$build_number" \
--with-boot-jdk="$BOOT_JDK" \
--enable-cds=yes || do_exit $?
make clean CONF=$RELEASE_NAME || do_exit $?
make images CONF=$RELEASE_NAME || do_exit $?
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk-bundle/jdk-$MAJOR_JBSDK_VERSION.jdk/Contents/Home
JSDK_MODS_DIR=$IMAGES_DIR/jmods
JBRSDK_BUNDLE=jbrsdk
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
update_jsdk_mods "$JSDK" "$JCEF_PATH"/jmods "$JSDK"/jmods "$JSDK_MODS_DIR" || do_exit $?
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
jbr_name_postfix="_${bundle_type}"
fi
# create runtime image bundle
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" || do_exit $?
# create sdk image bundle
modules=$(cat "$JSDK"/release | grep MODULES | sed s/MODULES=//g | sed s/' '/,/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle "$JBRSDK_BUNDLE" "$JBRSDK_BUNDLE" "$JSDK_MODS_DIR" "$modules" || do_exit $?
if [ -z "$bundle_type" ]; then
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-osx-test-x64-b${build_number}
echo Creating "$JBRSDK_TEST" ...
make test-image CONF=$RELEASE_NAME || do_exit $?
[ -f "$JBRSDK_TEST.tar.gz" ] && rm "$JBRSDK_TEST.tar.gz"
COPYFILE_DISABLE=1 tar -pczf "$JBRSDK_TEST".tar.gz -C $IMAGES_DIR --exclude='test/jdk/demos' test || do_exit $?
fi
do_exit 0

View File

@@ -1,120 +0,0 @@
#!/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

@@ -1,94 +0,0 @@
#!/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

@@ -1,138 +0,0 @@
#!/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

@@ -1,30 +0,0 @@
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

@@ -1,29 +0,0 @@
From 960dafbeeba190911955c208b611fecc15d66738 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Wed, 11 Mar 2020 14:19:34 +0100
Subject: [PATCH 03/34] 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 994fc8a3bc8..3be3a09ef8f 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -953,7 +953,10 @@ bool InstanceKlass::link_class_impl(TRAPS) {
if (!is_linked()) {
if (!is_rewritten()) {
- {
+ // (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 (!AllowEnhancedClassRedefinition || !newest_version()->is_redefining()) {
bool verify_ok = verify_code(THREAD);
if (!verify_ok) {
return false;
--
2.23.0

View File

@@ -1,240 +0,0 @@
From 39df5f163d4a0f1fd6b92313a5570808f19d5e20 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 4 Oct 2020 21:12:12 +0200
Subject: [PATCH 05/34] Support for Lambda class redefinition
---
.../share/classfile/classLoaderData.cpp | 9 +++
.../share/classfile/classLoaderData.hpp | 2 +-
.../share/classfile/systemDictionary.cpp | 12 +++-
.../share/classfile/systemDictionary.hpp | 1 +
.../prims/jvmtiEnhancedRedefineClasses.cpp | 65 +++++++++++++++++--
.../prims/jvmtiEnhancedRedefineClasses.hpp | 1 +
.../share/prims/resolvedMethodTable.cpp | 2 +
src/hotspot/share/prims/unsafe.cpp | 1 +
8 files changed, 83 insertions(+), 10 deletions(-)
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index 0cd90bb8c27..4d64c6b454a 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -593,6 +593,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 ba2393f8dd0..e2ae0a77351 100644
--- a/src/hotspot/share/classfile/classLoaderData.hpp
+++ b/src/hotspot/share/classfile/classLoaderData.hpp
@@ -181,7 +181,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
bool has_accumulated_modified_oops() { return _accumulated_modified_oops; }
oop holder_no_keepalive() const;
oop holder_phantom() const;
-
+ void exchange_holders(ClassLoaderData* cld);
private:
void unload();
bool keep_alive() const { return _keep_alive > 0; }
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index bd0cae7cb9b..8f2b46add4d 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -1062,10 +1062,14 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
Handle class_loader,
ClassFileStream* st,
const ClassLoadInfo& cl_info,
+ InstanceKlass* old_klass,
TRAPS) {
EventClassLoad class_load_start_event;
ClassLoaderData* loader_data;
+
+ bool is_redefining = (old_klass != NULL);
+
bool is_unsafe_anon_class = cl_info.unsafe_anonymous_host() != NULL;
// - for unsafe anonymous class: create a new CLD whith a class holder that uses
@@ -1094,8 +1098,12 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
class_name,
loader_data,
cl_info,
- 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 ((cl_info.is_hidden() || is_unsafe_anon_class) && k != NULL) {
// Hidden classes that are not strong and unsafe anonymous classes must update
@@ -1998,7 +2006,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 4547449dbec..931e655d631 100644
--- a/src/hotspot/share/classfile/systemDictionary.hpp
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -329,6 +329,7 @@ public:
Handle class_loader,
ClassFileStream* st,
const ClassLoadInfo& cl_info,
+ InstanceKlass* old_klass,
TRAPS);
// Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 92ce6c27b8a..8b765623dcd 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -494,6 +494,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;
@@ -756,12 +758,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();
@@ -1442,6 +1466,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];
@@ -1979,7 +2027,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 60b62c3170a..d8a11b51fe9 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -116,6 +116,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 122bb8c186b..81b3aa96564 100644
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
@@ -414,6 +414,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 72d81ec9d6c..027afa3fabd 100644
--- a/src/hotspot/share/prims/unsafe.cpp
+++ b/src/hotspot/share/prims/unsafe.cpp
@@ -865,6 +865,7 @@ Unsafe_DefineAnonymousClass_impl(JNIEnv *env,
host_loader,
&st,
cl_info,
+ NULL,
CHECK_NULL);
if (anonk == NULL) {
return NULL;
--
2.23.0

View File

@@ -1,135 +0,0 @@
From 5af1daedc86b5fec0f222cbdda3afbdf518985ea Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sat, 23 May 2020 10:02:15 +0200
Subject: [PATCH 06/34] Fix "no original bytecode found" error if method with
bkp is missing
Sometimes IDE can deploy class with erroneous method, such method has
n 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 ed3cc3eb6a2..504e59caf51 100644
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp
@@ -814,7 +814,7 @@ JRT_END
// Invokes
JRT_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);
JRT_END
JRT_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 516f2bb8f2f..1c88511a5fc 100644
--- a/src/hotspot/share/oops/method.cpp
+++ b/src/hotspot/share/oops/method.cpp
@@ -1853,14 +1853,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);
}
@@ -2006,7 +2006,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;
}
@@ -2015,7 +2015,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 83ed2d9c3c1..4d4cc6dc012 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 8b765623dcd..a859b8e1162 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1362,14 +1362,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.23.0

View File

@@ -1,57 +0,0 @@
From 19d2274a5dff6e6b31474252b45e5e7484f0180b Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 24 May 2020 12:07:42 +0200
Subject: [PATCH 07/34] 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 81b3aa96564..caf03ffe56d 100644
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
@@ -404,25 +404,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.23.0

File diff suppressed because it is too large Load Diff

View File

@@ -1,50 +0,0 @@
From ca47ab5a0a6ce8e2644736f323a335a957311af9 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sat, 13 Jun 2020 18:50:59 +0200
Subject: [PATCH 09/34] Change log level in advanced redefinition
- Change log level for "Comparing different class ver.." to debug
- Fix adjust_method_entries_dcevm logging levels and severity
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 2 +-
src/hotspot/share/prims/resolvedMethodTable.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 6c9eb40ecf5..b09ba554e07 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -916,7 +916,7 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
// 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());
+ log_debug(redefine, class, load)("Comparing different class versions of class %s",new_class->name()->as_C_string());
assert(new_class->old_version() != NULL, "must have old version");
InstanceKlass* the_class = InstanceKlass::cast(new_class->old_version());
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
index caf03ffe56d..eb9fcda44f3 100644
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
@@ -413,7 +413,7 @@ void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed)
} 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_debug(redefine, class, update)("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");
@@ -433,7 +433,7 @@ void ResolvedMethodTable::adjust_method_entries_dcevm(bool * trace_name_printed)
ResourceMark rm;
if (!(*trace_name_printed)) {
- log_info(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
+ log_debug(redefine, class, update)("adjust: name=%s", old_method->method_holder()->external_name());
*trace_name_printed = true;
}
log_debug(redefine, class, update, constantpool)
--
2.23.0

View File

@@ -1,26 +0,0 @@
From 7e236beee0375656d1955fc1168143c1639fb7f1 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Tue, 6 Oct 2020 22:15:31 +0200
Subject: [PATCH 10/34] AllowEnhancedClassRedefinition is false (disabled) by
default
---
src/hotspot/share/runtime/globals.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index 5b367704800..2710c6ea0e5 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -2466,7 +2466,7 @@ const size_t minimumSymbolTableSize = 1024;
diagnostic(bool, DeoptimizeNMethodBarriersALot, false, \
"Make nmethod barriers deoptimise a lot.") \
\
- product(bool, AllowEnhancedClassRedefinition, true, \
+ product(bool, AllowEnhancedClassRedefinition, false, \
"Allow enhanced class redefinition beyond swapping method " \
"bodies") \
\
--
2.23.0

View File

@@ -1,25 +0,0 @@
From d56e73885111b386771f564ec6beb305338993df Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Mon, 19 Oct 2020 20:00:04 +0200
Subject: [PATCH 12/34] Set HOTSPOT_VM_DISTRO=Dynamic Code Evolution
---
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 aabdc5bed20..df8025a2e84 100644
--- a/make/autoconf/version-numbers
+++ b/make/autoconf/version-numbers
@@ -45,7 +45,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"
VENDOR_URL=https://openjdk.java.net/
VENDOR_URL_BUG=https://bugreport.java.com/bugreport/
VENDOR_URL_VM_BUG=https://bugreport.java.com/bugreport/crash.jsp
--
2.23.0

View File

@@ -1,71 +0,0 @@
From 7ebad43ed45805b0a3736c510f708ff17697ba7e Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 11 Oct 2020 10:43:28 +0200
Subject: [PATCH 13/34] Fix G1 nmethod registration
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 19 ++++++++++++++++---
.../prims/jvmtiEnhancedRedefineClasses.hpp | 3 ++-
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index b09ba554e07..718426f2819 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -216,7 +216,14 @@ void VM_EnhancedRedefineClasses::mark_as_scavengable(nmethod* nm) {
}
}
-void VM_EnhancedRedefineClasses::mark_as_scavengable_g1(nmethod* nm) {
+void VM_EnhancedRedefineClasses::unregister_nmethod_g1(nmethod* nm) {
+ // It should work not only for G1 but also for another GCs, but this way is safer now
+ if (!nm->is_zombie() && !nm->is_unloaded()) {
+ Universe::heap()->unregister_nmethod(nm);
+ }
+}
+
+void VM_EnhancedRedefineClasses::register_nmethod_g1(nmethod* nm) {
// It should work not only for G1 but also for another GCs, but this way is safer now
if (!nm->is_zombie() && !nm->is_unloaded()) {
Universe::heap()->register_nmethod(nm);
@@ -521,8 +528,9 @@ void VM_EnhancedRedefineClasses::doit() {
// For now, mark all nmethod's as scavengable that are not scavengable already
if (ScavengeRootsInCode) {
if (UseG1GC) {
- // this should work also for other GCs
- CodeCache::nmethods_do(mark_as_scavengable_g1);
+ // G1 holds references to nmethods in regions based on oops values. Since oops in nmethod can be changed in ChangePointers* closures
+ // we unregister nmethods from G1 heap, then closures are processed (oops are changed) and finally we register nmethod to G1 again
+ CodeCache::nmethods_do(unregister_nmethod_g1);
} else {
CodeCache::nmethods_do(mark_as_scavengable);
}
@@ -545,6 +553,11 @@ void VM_EnhancedRedefineClasses::doit() {
Universe::root_oops_do(&oopClosureNoBarrier);
+ if (UseG1GC) {
+ // this should work also for other GCs
+ CodeCache::nmethods_do(register_nmethod_g1);
+ }
+
}
log_trace(redefine, class, obsolete, metadata)("After updating instances");
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 9755944d70b..4c0412d343d 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -116,7 +116,8 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
void rollback();
static void mark_as_scavengable(nmethod* nm);
- static void mark_as_scavengable_g1(nmethod* nm);
+ static void unregister_nmethod_g1(nmethod* nm);
+ static void register_nmethod_g1(nmethod* nm);
static void unpatch_bytecode(Method* method);
static void fix_invoke_method(Method* method);
--
2.23.0

View File

@@ -1,26 +0,0 @@
From 5c7e5f245f79d7e8575461dab0c356ed74c8e9a3 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Thu, 22 Oct 2020 20:15:20 +0200
Subject: [PATCH 14/34] Initialize method's _new_version/_old_version to NULL
---
src/hotspot/share/oops/method.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
index 1c88511a5fc..ce940cf10a9 100644
--- a/src/hotspot/share/oops/method.cpp
+++ b/src/hotspot/share/oops/method.cpp
@@ -91,7 +91,8 @@ Method* Method::allocate(ClassLoaderData* loader_data,
return new (loader_data, size, MetaspaceObj::MethodType, THREAD) Method(cm, access_flags);
}
-Method::Method(ConstMethod* xconst, AccessFlags access_flags) {
+Method::Method(ConstMethod* xconst, AccessFlags access_flags) : _new_version(NULL),
+ _old_version(NULL) {
NoSafepointVerifier no_safepoint;
set_constMethod(xconst);
set_access_flags(access_flags);
--
2.23.0

View File

@@ -1,193 +0,0 @@
From 6ffac6e5064ec6633fdbeb8520333dca00bc6a62 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Fri, 23 Oct 2020 10:20:26 +0200
Subject: [PATCH 15/34] Clear dcevm code separation
---
src/hotspot/share/classfile/systemDictionary.cpp | 4 ++--
src/hotspot/share/gc/serial/genMarkSweep.cpp | 8 +++++---
src/hotspot/share/interpreter/linkResolver.cpp | 16 +++++++++++-----
.../instrumentation/jfrEventClassTransformer.cpp | 2 +-
src/hotspot/share/oops/instanceKlass.cpp | 10 ++++++----
src/hotspot/share/oops/method.cpp | 2 +-
.../share/prims/jvmtiGetLoadedClasses.cpp | 2 +-
src/hotspot/share/runtime/reflection.cpp | 2 +-
8 files changed, 28 insertions(+), 18 deletions(-)
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 8f2b46add4d..9ac6ec96cb5 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -1241,7 +1241,7 @@ InstanceKlass* SystemDictionary::resolve_from_stream(Symbol* class_name,
MutexLocker mu(THREAD, SystemDictionary_lock);
Klass* check = find_class(h_name, k->class_loader_data());
- assert((check == k && !k->is_redefining()) || (k->is_redefining() && check == k->old_version()), "should be present in the dictionary");
+ assert(check == k && !k->is_redefining() || k->is_redefining() && check == k->old_version(), "should be present in the dictionary");
} );
return k;
@@ -2290,7 +2290,7 @@ void SystemDictionary::check_constraints(unsigned int d_hash,
// also hold array classes.
assert(check->is_instance_klass(), "noninstance in systemdictionary");
- if ((defining == true) || ((k != check) && k->old_version() != check)) {
+ if ((defining == true) || (k != check && (!AllowEnhancedClassRedefinition || k->old_version() != check))) {
throwException = true;
ss.print("loader %s", loader_data->loader_name_and_id());
ss.print(" attempted duplicate %s definition for %s. (%s)",
diff --git a/src/hotspot/share/gc/serial/genMarkSweep.cpp b/src/hotspot/share/gc/serial/genMarkSweep.cpp
index 1d13c647452..548df01e557 100644
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp
@@ -334,7 +334,9 @@ void GenMarkSweep::mark_sweep_phase4() {
GenCompactClosure blk;
gch->generation_iterate(&blk, true);
- DcevmSharedGC::copy_rescued_objects_back(MarkSweep::_rescued_oops, true);
- DcevmSharedGC::clear_rescued_objects_resource(MarkSweep::_rescued_oops);
- MarkSweep::_rescued_oops = NULL;
+ if (AllowEnhancedClassRedefinition) {
+ DcevmSharedGC::copy_rescued_objects_back(MarkSweep::_rescued_oops, true);
+ DcevmSharedGC::clear_rescued_objects_resource(MarkSweep::_rescued_oops);
+ MarkSweep::_rescued_oops = NULL;
+ }
}
diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp
index b6e9e0a308d..b2f24ddbeda 100644
--- a/src/hotspot/share/interpreter/linkResolver.cpp
+++ b/src/hotspot/share/interpreter/linkResolver.cpp
@@ -282,9 +282,14 @@ void LinkResolver::check_klass_accessibility(Klass* ref_klass, Klass* sel_klass,
if (!base_klass->is_instance_klass()) {
return; // no relevant check to do
}
-
- Reflection::VerifyClassAccessResults vca_result =
- Reflection::verify_class_access(ref_klass->newest_version(), InstanceKlass::cast(base_klass->newest_version()), true);
+ Klass* refKlassNewest = ref_klass;
+ Klass* baseKlassNewest = base_klass;
+ if (AllowEnhancedClassRedefinition) {
+ refKlassNewest = ref_klass->newest_version();
+ baseKlassNewest = base_klass->newest_version();
+ }
+ Reflection::VerifyClassAccessResults vca_result =
+ Reflection::verify_class_access(refKlassNewest, InstanceKlass::cast(baseKlassNewest), true);
if (vca_result != Reflection::ACCESS_OK) {
ResourceMark rm(THREAD);
char* msg = Reflection::verify_class_access_msg(ref_klass,
@@ -566,7 +571,8 @@ void LinkResolver::check_method_accessability(Klass* ref_klass,
// We'll check for the method name first, as that's most likely
// to be false (so we'll short-circuit out of these tests).
if (sel_method->name() == vmSymbols::clone_name() &&
- sel_klass->newest_version() == SystemDictionary::Object_klass()->newest_version() &&
+ ( !AllowEnhancedClassRedefinition && sel_klass == SystemDictionary::Object_klass() ||
+ AllowEnhancedClassRedefinition && sel_klass->newest_version() == SystemDictionary::Object_klass()->newest_version()) &&
resolved_klass->is_array_klass()) {
// We need to change "protected" to "public".
assert(flags.is_protected(), "clone not protected?");
@@ -1011,7 +1017,7 @@ void LinkResolver::resolve_field(fieldDescriptor& fd,
// or by the <init> method (in case of an instance field).
if (is_put && fd.access_flags().is_final()) {
- if (sel_klass != current_klass && sel_klass != current_klass->active_version()) {
+ if (sel_klass != current_klass && (!AllowEnhancedClassRedefinition || sel_klass != current_klass->active_version())) {
ResourceMark rm(THREAD);
stringStream ss;
ss.print("Update to %s final field %s.%s attempted from a different class (%s) than the field's declaring class",
diff --git a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
index 96fc139bea3..f7284197c5a 100644
--- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
+++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp
@@ -1471,7 +1471,7 @@ static InstanceKlass* create_new_instance_klass(InstanceKlass* ik, ClassFileStre
cld,
&cl_info,
ClassFileParser::INTERNAL, // internal visibility
- false,
+ false,
THREAD);
if (HAS_PENDING_EXCEPTION) {
log_pending_exception(PENDING_EXCEPTION);
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 3be3a09ef8f..f8e60941046 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -199,7 +199,9 @@ bool InstanceKlass::has_nest_member(InstanceKlass* k, TRAPS) const {
// able to perform that loading but we can't exclude the compiler threads from
// executing this logic. But it should actually be impossible to trigger loading here.
Klass* k2 = _constants->klass_at(cp_index, THREAD);
- k2 = k2->newest_version();
+ if (AllowEnhancedClassRedefinition) {
+ k2 = k2->newest_version();
+ }
assert(!HAS_PENDING_EXCEPTION || PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass()),
"Exceptions should not be possible here");
if (k2 == k) {
@@ -1003,7 +1005,7 @@ bool InstanceKlass::link_class_impl(TRAPS) {
#endif
set_init_state(linked);
// (DCEVM) Must check for old version in order to prevent infinite loops.
- if (JvmtiExport::should_post_class_prepare() && old_version() == NULL /* JVMTI deadlock otherwise */) {
+ if (JvmtiExport::should_post_class_prepare() && (!AllowEnhancedClassRedefinition || old_version() == NULL) /* JVMTI deadlock otherwise */) {
Thread *thread = THREAD;
assert(thread->is_Java_thread(), "thread->is_Java_thread()");
JvmtiExport::post_class_prepare((JavaThread *) thread, this);
@@ -1084,7 +1086,7 @@ void InstanceKlass::initialize_impl(TRAPS) {
// we might end up throwing IE from link/symbol resolution sites
// that aren't expected to throw. This would wreak havoc. See 6320309.
while ((is_being_initialized() && !is_reentrant_initialization(jt))
- || (old_version() != NULL && InstanceKlass::cast(old_version())->is_being_initialized())) {
+ || (AllowEnhancedClassRedefinition && old_version() != NULL && InstanceKlass::cast(old_version())->is_being_initialized())) {
wait = true;
jt->set_class_to_be_initialized(this);
ol.wait_uninterruptibly(jt);
@@ -3782,7 +3784,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");
+ guarantee(sib->super() == super || AllowEnhancedClassRedefinition && super->newest_version() == SystemDictionary::Object_klass(), "siblings should have same superklass");
}
// Verify local interfaces
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
index ce940cf10a9..2d8e5b0256b 100644
--- a/src/hotspot/share/oops/method.cpp
+++ b/src/hotspot/share/oops/method.cpp
@@ -2208,7 +2208,7 @@ void Method::ensure_jmethod_ids(ClassLoaderData* loader_data, int capacity) {
// Add a method id to the jmethod_ids
jmethodID Method::make_jmethod_id(ClassLoaderData* loader_data, Method* m) {
// FIXME: (DCEVM) ???
- if (m != m->newest_version()) {
+ if (AllowEnhancedClassRedefinition && m != m->newest_version()) {
m = m->newest_version();
}
ClassLoaderData* cld = loader_data;
diff --git a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
index 1c7677f270f..6c12ee64a6e 100644
--- a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
@@ -75,7 +75,7 @@ public:
// the new version (SystemDictionary stores only new versions). But the LoadedClassesClosure's functionality was
// changed in java8 where jvmtiLoadedClasses collects all classes from all classloaders, therefore we
// must use new versions only.
- if (k->new_version()==NULL) {
+ if (AllowEnhancedClassRedefinition && k->new_version()==NULL) {
_classStack.push((jclass) _env->jni_reference(Handle(_cur_thread, k->java_mirror())));
if (_dictionary_walk) {
// Collect array classes this way when walking the dictionary (because array classes are
diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp
index 0e7722dba7d..d67457f02ac 100644
--- a/src/hotspot/share/runtime/reflection.cpp
+++ b/src/hotspot/share/runtime/reflection.cpp
@@ -628,7 +628,7 @@ bool Reflection::verify_member_access(const Klass* current_class,
TRAPS) {
// (DCEVM) Decide accessibility based on active version
- if (current_class != NULL) {
+ if (AllowEnhancedClassRedefinition && current_class != NULL) {
current_class = current_class->active_version();
}
--
2.23.0

View File

@@ -1,26 +0,0 @@
From dc675de6ac42819b8536827ea450fcad13a97448 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Wed, 11 Nov 2020 18:45:15 +0100
Subject: [PATCH 16/34] Fix LoadedClassesClosure - fixes problems with remote
debugging
---
src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
index 6c12ee64a6e..2a469555dbd 100644
--- a/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiGetLoadedClasses.cpp
@@ -75,7 +75,7 @@ public:
// the new version (SystemDictionary stores only new versions). But the LoadedClassesClosure's functionality was
// changed in java8 where jvmtiLoadedClasses collects all classes from all classloaders, therefore we
// must use new versions only.
- if (AllowEnhancedClassRedefinition && k->new_version()==NULL) {
+ if (!AllowEnhancedClassRedefinition || k->new_version()==NULL) {
_classStack.push((jclass) _env->jni_reference(Handle(_cur_thread, k->java_mirror())));
if (_dictionary_walk) {
// Collect array classes this way when walking the dictionary (because array classes are
--
2.23.0

View File

@@ -1,183 +0,0 @@
From 1d682efa88c716e1849163d5abff3a3367581d16 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Mon, 16 Nov 2020 21:11:19 +0100
Subject: [PATCH 18/34] pre dcevm15 - fix GC spaces originally in removed CMS
patch
---
src/hotspot/share/gc/shared/space.cpp | 16 ++++++++--------
src/hotspot/share/gc/shared/space.hpp | 6 +++---
src/hotspot/share/gc/shared/space.inline.hpp | 14 ++++++++------
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 6 ++----
4 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
index 875a6dc854f..9772c32c42e 100644
--- a/src/hotspot/share/gc/shared/space.cpp
+++ b/src/hotspot/share/gc/shared/space.cpp
@@ -375,11 +375,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 (cast_from_oop<HeapWord*>(q) != compact_top || (size_t)q->size() != size) {
+ if (force_forward || cast_from_oop<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 {
@@ -501,7 +501,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");
@@ -824,14 +824,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) {
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;
}
@@ -845,7 +845,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.
@@ -861,11 +861,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 c9bfc365f0f..f7648995454 100644
--- a/src/hotspot/share/gc/shared/space.hpp
+++ b/src/hotspot/share/gc/shared/space.hpp
@@ -405,7 +405,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
@@ -436,11 +436,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 5a93e93471b..fa645423685 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.
@@ -362,8 +365,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 718426f2819..1da6661dd3e 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -431,13 +431,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);
--
2.23.0

View File

@@ -1,942 +0,0 @@
From 297f564f6af79fb824f5b4e9119f1d3d0c827fb0 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Mon, 16 Nov 2020 20:20:12 +0100
Subject: [PATCH 19/34] dcevm15 - fix java15 patch compilation issues
---
.../share/classfile/classFileParser.hpp | 8 +-
.../share/classfile/classLoaderData.cpp | 2 +-
src/hotspot/share/classfile/dictionary.hpp | 10 +-
src/hotspot/share/classfile/javaClasses.hpp | 2 +
.../share/gc/g1/g1FullGCCompactTask.cpp | 4 +-
.../share/gc/g1/g1FullGCCompactionPoint.cpp | 8 +-
.../share/gc/g1/g1FullGCPrepareTask.cpp | 4 +-
src/hotspot/share/gc/shared/dcevmSharedGC.cpp | 14 +-
src/hotspot/share/gc/shared/dcevmSharedGC.hpp | 2 +-
src/hotspot/share/gc/shared/gcConfig.cpp | 2 +-
src/hotspot/share/gc/shared/space.cpp | 4 +-
.../share/interpreter/linkResolver.cpp | 2 +-
src/hotspot/share/oops/instanceKlass.cpp | 17 ++-
src/hotspot/share/oops/instanceKlass.hpp | 1 +
src/hotspot/share/oops/klass.cpp | 8 +-
src/hotspot/share/prims/jvm.cpp | 2 +
.../prims/jvmtiEnhancedRedefineClasses.cpp | 129 +++++++++---------
.../prims/jvmtiEnhancedRedefineClasses.hpp | 14 +-
src/hotspot/share/prims/jvmtiEnv.cpp | 11 +-
.../share/prims/jvmtiRedefineClasses.cpp | 1 +
src/hotspot/share/prims/methodHandles.hpp | 3 +
src/hotspot/share/runtime/arguments.cpp | 22 +--
src/hotspot/share/runtime/mutexLocker.cpp | 2 +-
23 files changed, 159 insertions(+), 113 deletions(-)
diff --git a/src/hotspot/share/classfile/classFileParser.hpp b/src/hotspot/share/classfile/classFileParser.hpp
index e5761e61767..0d266b9047e 100644
--- a/src/hotspot/share/classfile/classFileParser.hpp
+++ b/src/hotspot/share/classfile/classFileParser.hpp
@@ -150,9 +150,6 @@ class ClassFileParser {
const intArray* _method_ordering;
GrowableArray<Method*>* _all_mirandas;
- // Enhanced class redefinition
- const bool _pick_newest;
-
enum { fixed_buffer_size = 128 };
u_char _linenumbertable_buffer[fixed_buffer_size];
@@ -206,6 +203,9 @@ class ClassFileParser {
bool _has_vanilla_constructor;
int _max_bootstrap_specifier_index; // detects BSS values
+ // (DCEVM) Enhanced class redefinition
+ const bool _pick_newest;
+
void parse_stream(const ClassFileStream* const stream, TRAPS);
void mangle_hidden_class_name(InstanceKlass* const ik);
@@ -582,7 +582,7 @@ class ClassFileParser {
ClassLoaderData* loader_data() const { return _loader_data; }
const Symbol* class_name() const { return _class_name; }
const InstanceKlass* super_klass() const { return _super_klass; }
- Array<Klass*>* local_interfaces() const { return _local_interfaces; }
+ Array<InstanceKlass*>* local_interfaces() const { return _local_interfaces; }
ReferenceType reference_type() const { return _rt; }
AccessFlags access_flags() const { return _access_flags; }
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index 4d64c6b454a..aadcd50ef4a 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -597,7 +597,7 @@ 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;
+ WeakHandle<vm_weak_data> exchange = _holder;
_holder = cld->_holder;
cld->_holder = exchange;
}
diff --git a/src/hotspot/share/classfile/dictionary.hpp b/src/hotspot/share/classfile/dictionary.hpp
index 114a983e783..a50f4ff84d2 100644
--- a/src/hotspot/share/classfile/dictionary.hpp
+++ b/src/hotspot/share/classfile/dictionary.hpp
@@ -84,6 +84,11 @@ public:
void print_on(outputStream* st) const;
void verify();
+ // (DCEVM) Enhanced class redefinition
+ bool update_klass(unsigned int hash, Symbol* name, ClassLoaderData* loader_data, InstanceKlass* k, InstanceKlass* old_klass);
+
+ void rollback_redefinition();
+
private:
DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass);
@@ -106,11 +111,6 @@ public:
void free_entry(DictionaryEntry* entry);
- // Enhanced class redefinition
- bool update_klass(unsigned int hash, Symbol* name, ClassLoaderData* loader_data, InstanceKlass* k, InstanceKlass* old_klass);
-
- 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/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index a68c5139151..9abf2e1d105 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -255,7 +255,9 @@ class java_lang_Class : AllStatic {
static void set_init_lock(oop java_class, oop init_lock);
static void set_protection_domain(oop java_class, oop protection_domain);
static void set_class_loader(oop java_class, oop class_loader);
+ public: // DCEVM
static void set_component_mirror(oop java_class, oop comp_mirror);
+ private:
static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain,
Handle classData, TRAPS);
static void initialize_mirror_fields(Klass* k, Handle mirror, Handle protection_domain, TRAPS);
diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp
index f70f4606dc8..a22ed48560d 100644
--- a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp
@@ -157,14 +157,14 @@ void G1FullGCCompactTask::serial_compaction_dcevm() {
size_t G1FullGCCompactTask::G1CompactRegionClosureDcevm::apply(oop obj) {
size_t size = obj->size();
- HeapWord* destination = (HeapWord*)obj->forwardee();
+ HeapWord* destination = cast_from_oop<HeapWord*>(obj->forwardee());
if (destination == NULL) {
// Object not moving
return size;
}
// copy object and reinit its mark
- HeapWord* obj_addr = (HeapWord*) obj;
+ HeapWord* obj_addr = cast_from_oop<HeapWord*>(obj);
if (!_rescue_oops_it->at_end() && **_rescue_oops_it == obj_addr) {
++(*_rescue_oops_it);
diff --git a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp
index 1e49571c999..755935a2c91 100644
--- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp
@@ -174,7 +174,7 @@ void G1FullGCCompactionPoint::forward_dcevm(oop object, size_t size, bool force_
assert(_current_region != NULL, "Must have been initialized");
// Store a forwarding pointer if the object should be moved.
- if ((HeapWord*)object != _compaction_top || force_forward) {
+ if (cast_from_oop<HeapWord*>(object) != _compaction_top || force_forward) {
object->forward_to(oop(_compaction_top));
} else {
if (object->forwardee() != NULL) {
@@ -188,11 +188,11 @@ void G1FullGCCompactionPoint::forward_dcevm(oop object, size_t size, bool force_
} else {
// Make sure object has the correct mark-word set or that it will be
// fixed when restoring the preserved marks.
- assert(object->mark_raw() == markOopDesc::prototype_for_object(object) || // Correct mark
- object->mark_raw()->must_be_preserved(object) || // Will be restored by PreservedMarksSet
+ assert(object->mark_raw() == markWord::prototype_for_klass(object->klass()) || // Correct mark
+ object->mark_must_be_preserved() || // Will be restored by PreservedMarksSet
(UseBiasedLocking && object->has_bias_pattern_raw()), // Will be restored by BiasedLocking
"should have correct prototype obj: " PTR_FORMAT " mark: " PTR_FORMAT " prototype: " PTR_FORMAT,
- p2i(object), p2i(object->mark_raw()), p2i(markOopDesc::prototype_for_object(object)));
+ p2i(object), object->mark_raw().value(), markWord::prototype_for_klass(object->klass()).value());
}
assert(object->forwardee() == NULL, "should be forwarded to NULL");
}
diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
index a45681b60cf..2f06b9617e4 100644
--- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
@@ -269,7 +269,7 @@ size_t G1FullGCPrepareTask::G1PrepareCompactLiveClosureDcevm::apply(oop object)
HeapWord* compact_top = _cp->forward_compact_top(forward_size);
if (compact_top == NULL || must_rescue(object, oop(compact_top))) {
- _cp->rescued_oops()->append((HeapWord*)object);
+ _cp->rescued_oops()->append(cast_from_oop<HeapWord*>(object));
} else {
_cp->forward_dcevm(object, forward_size, (size != forward_size));
}
@@ -295,7 +295,7 @@ bool G1FullGCPrepareTask::G1PrepareCompactLiveClosureDcevm::must_rescue(oop old_
int new_size = old_obj->size_given_klass(oop(old_obj)->klass()->new_version());
int original_size = old_obj->size();
- bool overlap = ((HeapWord*)old_obj + original_size < (HeapWord*)new_obj + new_size);
+ bool overlap = (cast_from_oop<HeapWord*>(old_obj) + original_size < cast_from_oop<HeapWord*>(new_obj) + new_size);
return overlap;
}
diff --git a/src/hotspot/share/gc/shared/dcevmSharedGC.cpp b/src/hotspot/share/gc/shared/dcevmSharedGC.cpp
index 803e645f843..3dee097f1d3 100644
--- a/src/hotspot/share/gc/shared/dcevmSharedGC.cpp
+++ b/src/hotspot/share/gc/shared/dcevmSharedGC.cpp
@@ -58,10 +58,10 @@ void DcevmSharedGC::copy_rescued_objects_back(GrowableArray<HeapWord*>* rescued_
DcevmSharedGC::update_fields(rescued_obj, new_obj);
} else {
rescued_obj->set_klass(new_klass);
- Copy::aligned_disjoint_words((HeapWord*)rescued_obj, (HeapWord*)new_obj, size);
+ Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(rescued_obj), cast_from_oop<HeapWord*>(new_obj), size);
}
} else {
- Copy::aligned_disjoint_words((HeapWord*)rescued_obj, (HeapWord*)new_obj, size);
+ Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(rescued_obj), cast_from_oop<HeapWord*>(new_obj), size);
}
new_obj->init_mark_raw();
@@ -111,11 +111,11 @@ void DcevmSharedGC::update_fields(oop q, oop new_location) {
// Save object somewhere, there is an overlap in fields
if (new_klass_oop->is_copying_backwards()) {
- if (((HeapWord *)q >= (HeapWord *)new_location && (HeapWord *)q < (HeapWord *)new_location + new_size) ||
- ((HeapWord *)new_location >= (HeapWord *)q && (HeapWord *)new_location < (HeapWord *)q + size)) {
+ if ((cast_from_oop<HeapWord*>(q) >= cast_from_oop<HeapWord*>(new_location) && cast_from_oop<HeapWord*>(q) < cast_from_oop<HeapWord*>(new_location) + new_size) ||
+ (cast_from_oop<HeapWord*>(new_location) >= cast_from_oop<HeapWord*>(q) && cast_from_oop<HeapWord*>(new_location) < cast_from_oop<HeapWord*>(q) + size)) {
tmp = NEW_RESOURCE_ARRAY(HeapWord, size);
q = (oop) tmp;
- Copy::aligned_disjoint_words((HeapWord*)tmp_obj, (HeapWord*)q, size);
+ Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(tmp_obj), cast_from_oop<HeapWord*>(q), size);
}
}
@@ -131,13 +131,13 @@ void DcevmSharedGC::update_fields(oop q, oop new_location) {
void DcevmSharedGC::update_fields(oop new_location, oop tmp_obj, int *cur) {
assert(cur != NULL, "just checking");
- char* to = (char*)(HeapWord*)new_location;
+ char* to = (char*)cast_from_oop<HeapWord*>(new_location);
while (*cur != 0) {
int size = *cur;
if (size > 0) {
cur++;
int offset = *cur;
- HeapWord* from = (HeapWord*)(((char *)(HeapWord*)tmp_obj) + offset);
+ HeapWord* from = (HeapWord*)(((char *)cast_from_oop<HeapWord*>(tmp_obj)) + offset);
if (size == HeapWordSize) {
*((HeapWord*)to) = *from;
} else if (size == HeapWordSize * 2) {
diff --git a/src/hotspot/share/gc/shared/dcevmSharedGC.hpp b/src/hotspot/share/gc/shared/dcevmSharedGC.hpp
index e2ef0171fb2..a4e27e00280 100644
--- a/src/hotspot/share/gc/shared/dcevmSharedGC.hpp
+++ b/src/hotspot/share/gc/shared/dcevmSharedGC.hpp
@@ -29,7 +29,7 @@
#include "gc/shared/genOopClosures.hpp"
#include "gc/shared/taskqueue.hpp"
#include "memory/iterator.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
#include "oops/oop.hpp"
#include "runtime/timer.hpp"
#include "utilities/growableArray.hpp"
diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp
index f01d64d1434..5c1a09390f1 100644
--- a/src/hotspot/share/gc/shared/gcConfig.cpp
+++ b/src/hotspot/share/gc/shared/gcConfig.cpp
@@ -100,7 +100,7 @@ void GCConfig::fail_if_non_included_gc_is_selected() {
void GCConfig::select_gc_ergonomically() {
if (AllowEnhancedClassRedefinition && !UseG1GC) {
// Enhanced class redefinition only supports serial GC at the moment
- FLAG_SET_ERGO(bool, UseSerialGC, true);
+ FLAG_SET_ERGO(UseSerialGC, true);
} else if (os::is_server_class_machine()) {
#if INCLUDE_G1GC
FLAG_SET_ERGO_IF_DEFAULT(UseG1GC, true);
diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp
index 9772c32c42e..e8e3d7884c2 100644
--- a/src/hotspot/share/gc/shared/space.cpp
+++ b/src/hotspot/share/gc/shared/space.cpp
@@ -440,7 +440,7 @@ int CompactibleSpace::space_index(oop obj) {
index++;
}
- tty->print_cr("could not compute space_index for %08xh", (HeapWord*)obj);
+ tty->print_cr("could not compute space_index for %08xh", cast_from_oop<HeapWord*>(obj));
index = 0;
Generation* gen = heap->old_gen();
@@ -485,7 +485,7 @@ bool CompactibleSpace::must_rescue(oop old_obj, oop new_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);
+ bool overlap = (cast_from_oop<HeapWord*>(old_obj) + original_size < cast_from_oop<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.
diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp
index b2f24ddbeda..9daeeb70b34 100644
--- a/src/hotspot/share/interpreter/linkResolver.cpp
+++ b/src/hotspot/share/interpreter/linkResolver.cpp
@@ -1031,7 +1031,7 @@ void LinkResolver::resolve_field(fieldDescriptor& fd,
assert(m != 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()->name() == vmSymbols::ha_class_initializer_name()));
+ !(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());
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index f8e60941046..5e40d78a87e 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -1316,7 +1316,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();
+ Klass* volatile* addr = adr_implementor();
assert(addr != NULL, "null addr");
if (addr != NULL) {
*addr = NULL;
@@ -1659,6 +1659,21 @@ void InstanceKlass::methods_do(void f(Method* method)) {
}
}
+void InstanceKlass::methods_do(void f(Method* method, TRAPS), TRAPS) {
+ // Methods aren't stable until they are loaded. This can be read outside
+ // a lock through the ClassLoaderData for profiling
+ if (!is_loaded()) {
+ return;
+ }
+
+ int len = methods()->length();
+ for (int index = 0; index < len; index++) {
+ Method* m = methods()->at(index);
+ assert(m->is_method(), "must be method");
+ f(m, CHECK);
+ }
+}
+
// (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) {
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
index 6ead9426728..b56d42cb177 100644
--- a/src/hotspot/share/oops/instanceKlass.hpp
+++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -1069,6 +1069,7 @@ public:
void clear_update_information();
void methods_do(void f(Method* method));
+ void methods_do(void f(Method* method, TRAPS), TRAPS);
void array_klasses_do(void f(Klass* k));
void array_klasses_do(void f(Klass* k, TRAPS), TRAPS);
diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp
index 352d8f84631..88f5ec9ba4a 100644
--- a/src/hotspot/share/oops/klass.cpp
+++ b/src/hotspot/share/oops/klass.cpp
@@ -200,13 +200,13 @@ void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word
Klass::Klass(KlassID id) : _id(id),
_java_mirror(NULL),
_prototype_header(markWord::prototype()),
- _shared_class_path_index(-1),
- _new_version(NULL),
_old_version(NULL),
+ _new_version(NULL),
+ _redefinition_flags(Klass::NoRedefinition),
_is_redefining(false),
+ _update_information(NULL),
_is_copying_backwards(false),
- _redefinition_flags(Klass::NoRedefinition),
- _update_information(NULL) {
+ _shared_class_path_index(-1) {
CDS_ONLY(_shared_class_flags = 0;)
CDS_JAVA_HEAP_ONLY(_archived_mirror = 0;)
_primary_supers[0] = this;
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index 333b65ccfc1..13bcac352fb 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -1054,6 +1054,7 @@ static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *na
class_loader,
protection_domain,
&st,
+ NULL,
CHECK_NULL);
if (log_is_enabled(Debug, class, resolve) && defined_k != NULL) {
@@ -1074,6 +1075,7 @@ static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *na
class_loader,
&st,
cl_info,
+ NULL,
CHECK_NULL);
if (defined_k == NULL) {
THROW_MSG_0(vmSymbols::java_lang_Error(), "Failure to define a hidden class");
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 1da6661dd3e..619e3988e3a 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -24,11 +24,14 @@
#include "precompiled.hpp"
#include "aot/aotLoader.hpp"
+#include "classfile/classFileParser.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/metadataOnStackMark.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/verifier.hpp"
#include "classfile/dictionary.hpp"
+#include "classfile/classLoaderDataGraph.hpp"
+#include "interpreter/linkResolver.hpp"
#include "interpreter/oopMapCache.hpp"
#include "interpreter/rewriter.hpp"
#include "logging/logStream.hpp"
@@ -37,17 +40,22 @@
#include "memory/resourceArea.hpp"
#include "memory/iterator.inline.hpp"
#include "oops/fieldStreams.hpp"
+#include "oops/fieldStreams.inline.hpp"
#include "oops/klassVtable.hpp"
#include "oops/oop.inline.hpp"
#include "oops/constantPool.inline.hpp"
+#include "oops/metadata.hpp"
+#include "oops/methodData.hpp"
#include "prims/jvmtiImpl.hpp"
#include "prims/jvmtiClassFileReconstituter.hpp"
#include "prims/jvmtiEnhancedRedefineClasses.hpp"
#include "prims/methodComparator.hpp"
#include "prims/resolvedMethodTable.hpp"
+#include "prims/methodHandles.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/relocator.hpp"
+#include "runtime/fieldDescriptor.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "utilities/bitMap.inline.hpp"
#include "prims/jvmtiThreadState.inline.hpp"
@@ -55,6 +63,8 @@
#include "oops/constantPool.inline.hpp"
#include "gc/g1/g1CollectedHeap.hpp"
#include "gc/shared/dcevmSharedGC.hpp"
+#include "gc/shared/scavengableNMethods.hpp"
+#include "ci/ciObjectFactory.hpp"
Array<Method*>* VM_EnhancedRedefineClasses::_old_methods = NULL;
Array<Method*>* VM_EnhancedRedefineClasses::_new_methods = NULL;
@@ -66,6 +76,7 @@ int VM_EnhancedRedefineClasses::_matching_methods_length = 0;
int VM_EnhancedRedefineClasses::_deleted_methods_length = 0;
int VM_EnhancedRedefineClasses::_added_methods_length = 0;
Klass* VM_EnhancedRedefineClasses::_the_class_oop = NULL;
+u8 VM_EnhancedRedefineClasses::_id_counter = 0;
//
// Create new instance of enhanced class redefiner.
@@ -88,6 +99,7 @@ VM_EnhancedRedefineClasses::VM_EnhancedRedefineClasses(jint class_count, const j
_class_load_kind = class_load_kind;
_res = JVMTI_ERROR_NONE;
_any_class_has_resolved_methods = false;
+ _id = next_id();
}
static inline InstanceKlass* get_ik(jclass def) {
@@ -211,9 +223,7 @@ class FieldCopier : public FieldClosure {
// TODO: review...
void VM_EnhancedRedefineClasses::mark_as_scavengable(nmethod* nm) {
- if (!nm->on_scavenge_root_list()) {
- CodeCache::add_scavenge_root_nmethod(nm);
- }
+ ScavengableNMethods::register_nmethod(nm);
}
void VM_EnhancedRedefineClasses::unregister_nmethod_g1(nmethod* nm) {
@@ -414,7 +424,7 @@ public:
_tmp_obj_size = size;
_tmp_obj = (oop)resource_allocate_bytes(size * HeapWordSize);
}
- Copy::aligned_disjoint_words((HeapWord*)o, (HeapWord*)_tmp_obj, size);
+ Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(o), cast_from_oop<HeapWord*>(_tmp_obj), size);
}
virtual void do_object(oop obj) {
@@ -505,9 +515,6 @@ void VM_EnhancedRedefineClasses::doit() {
ClearCpoolCacheAndUnpatch clear_cpool_cache(thread);
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;
@@ -564,8 +571,8 @@ void VM_EnhancedRedefineClasses::doit() {
InstanceKlass* old = InstanceKlass::cast(cur->old_version());
// Swap marks to have same hashcodes
- markOop cur_mark = cur->prototype_header();
- markOop old_mark = old->prototype_header();
+ markWord cur_mark = cur->prototype_header();
+ markWord old_mark = old->prototype_header();
cur->set_prototype_header(old_mark);
old->set_prototype_header(cur_mark);
@@ -579,14 +586,14 @@ void VM_EnhancedRedefineClasses::doit() {
// Revert pool holder for old version of klass (it was updated by one of ours closure!)
old->constants()->set_pool_holder(old);
- Klass* array_klasses = old->array_klasses();
+ ObjArrayKlass* array_klasses = old->array_klasses();
if (array_klasses != NULL) {
assert(cur->array_klasses() == NULL, "just checking");
// Transfer the array classes, otherwise we might get cast exceptions when casting array types.
// Also, set array klasses element klass.
cur->set_array_klasses(array_klasses);
- ObjArrayKlass::cast(array_klasses)->set_element_klass(cur);
+ array_klasses->set_element_klass(cur);
java_lang_Class::release_set_array_klass(cur->java_mirror(), array_klasses);
java_lang_Class::set_component_mirror(array_klasses->java_mirror(), cur->java_mirror());
}
@@ -641,11 +648,15 @@ void VM_EnhancedRedefineClasses::doit() {
//ClassLoaderDataGraph::classes_do(&clean_weak_method_links);
// Disable any dependent concurrent compilations
- SystemDictionary::notice_modification();
+ // SystemDictionary::notice_modification();
+
+ JvmtiExport::increment_redefinition_count();
// Set flag indicating that some invariants are no longer true.
// See jvmtiExport.hpp for detailed explanation.
- JvmtiExport::set_has_redefined_a_class();
+
+ // dcevm15: handled by _redefinition_count
+ // JvmtiExport::set_has_redefined_a_class();
#ifdef PRODUCT
if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
@@ -718,7 +729,7 @@ bool VM_EnhancedRedefineClasses::is_modifiable_class(oop klass_mirror) {
}
// Cannot redefine or retransform an anonymous class.
- if (InstanceKlass::cast(k)->is_anonymous()) {
+ if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {
return false;
}
return true;
@@ -804,22 +815,30 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
InstanceKlass* k;
- if (InstanceKlass::cast(the_class)->is_anonymous()) {
- const InstanceKlass* host_class = the_class->host_klass();
+ if (InstanceKlass::cast(the_class)->is_unsafe_anonymous()) {
+ const InstanceKlass* host_class = the_class->unsafe_anonymous_host();
// 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();
+ while (host_class != NULL && host_class->is_unsafe_anonymous()) {
+ host_class = host_class->unsafe_anonymous_host();
}
+ ClassLoadInfo cl_info(protection_domain,
+ host_class,
+ NULL, // dynamic_nest_host
+ NULL, // cp_patches
+ Handle(), // classData
+ false, // is_hidden
+ false, // is_strong_hidden
+ true); // FIXME: check if correct. can_access_vm_annotations
+
k = SystemDictionary::parse_stream(the_class_sym,
the_class_loader,
- protection_domain,
&st,
- host_class,
+ cl_info,
the_class,
- NULL,
THREAD);
+
k->class_loader_data()->exchange_holders(the_class->class_loader_data());
the_class->class_loader_data()->inc_keep_alive();
} else {
@@ -966,7 +985,7 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
// Check interfaces
// Interfaces removed?
- Array<Klass*>* old_interfaces = the_class->transitive_interfaces();
+ Array<InstanceKlass*>* old_interfaces = the_class->transitive_interfaces();
for (i = 0; i < old_interfaces->length(); i++) {
InstanceKlass* old_interface = InstanceKlass::cast(old_interfaces->at(i));
if (!new_class->implements_interface_any_version(old_interface)) {
@@ -976,7 +995,7 @@ int VM_EnhancedRedefineClasses::calculate_redefinition_flags(InstanceKlass* new_
}
// Interfaces added?
- Array<Klass*>* new_interfaces = new_class->transitive_interfaces();
+ Array<InstanceKlass*>* new_interfaces = new_class->transitive_interfaces();
for (i = 0; i<new_interfaces->length(); i++) {
if (!the_class->implements_interface_any_version(new_interfaces->at(i))) {
result = result | Klass::ModifyClass;
@@ -1389,8 +1408,8 @@ void VM_EnhancedRedefineClasses::rollback() {
// Rewrite faster byte-codes back to their slower equivalent. Undoes rewriting happening in templateTable_xxx.cpp
// The reason is that once we zero cpool caches, we need to re-resolve all entries again. Faster bytecodes do not
// do that, they assume that cache entry is resolved already.
-void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method) {
- RawBytecodeStream bcs(method);
+void VM_EnhancedRedefineClasses::unpatch_bytecode(Method* method, TRAPS) {
+ RawBytecodeStream bcs(methodHandle(THREAD, method));
Bytecodes::Code code;
Bytecodes::Code java_code;
while (!bcs.is_last_bytecode()) {
@@ -1454,11 +1473,11 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
HandleMark hm(_thread);
InstanceKlass *ik = InstanceKlass::cast(k);
- constantPoolHandle other_cp = constantPoolHandle(ik->constants());
+ constantPoolHandle other_cp = constantPoolHandle(_thread, 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) {
- ik->set_host_klass(InstanceKlass::cast(ik->host_klass()->newest_version()));
+ if (ik->is_unsafe_anonymous() && ik->unsafe_anonymous_host()->new_version() != NULL) {
+ ik->set_unsafe_anonymous_host(InstanceKlass::cast(ik->unsafe_anonymous_host()->newest_version()));
}
// Update implementor if there is only one, in this case implementor() can reference old class
@@ -1492,7 +1511,18 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
// If bytecode rewriting is enabled, we also need to unpatch bytecode to force resolution of zeroed entries
if (RewriteBytecodes) {
- ik->methods_do(unpatch_bytecode);
+ ik->methods_do(unpatch_bytecode, _thread);
+ }
+}
+
+u8 VM_EnhancedRedefineClasses::next_id() {
+ while (true) {
+ u8 id = _id_counter;
+ u8 next_id = id + 1;
+ u8 result = Atomic::cmpxchg(&_id_counter, id, next_id);
+ if (result == id) {
+ return next_id;
+ }
}
}
@@ -1512,31 +1542,8 @@ 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() {
+void VM_EnhancedRedefineClasses::update_jmethod_ids(TRAPS) {
for (int j = 0; j < _matching_methods_length; ++j) {
Method* old_method = _matching_old_methods[j];
jmethodID jmid = old_method->find_jmethod_id_or_null();
@@ -1547,10 +1554,10 @@ void VM_EnhancedRedefineClasses::update_jmethod_ids() {
if (jmid != NULL) {
// There is a jmethodID, change it to point to the new method
- methodHandle new_method_h(_matching_new_methods[j]);
+ methodHandle new_method_h(THREAD, _matching_new_methods[j]);
if (old_method->new_version() == NULL) {
- methodHandle old_method_h(_matching_old_methods[j]);
+ methodHandle old_method_h(THREAD, _matching_old_methods[j]);
jmethodID new_jmethod_id = Method::make_jmethod_id(old_method_h->method_holder()->class_loader_data(), old_method_h());
bool result = InstanceKlass::cast(old_method_h->method_holder())->update_jmethod_id(old_method_h(), new_jmethod_id);
} else {
@@ -1887,7 +1894,7 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
// track number of methods that are EMCP for add_previous_version() call below
check_methods_and_mark_as_obsolete();
- update_jmethod_ids();
+ update_jmethod_ids(THREAD);
_any_class_has_resolved_methods = the_class->has_resolved_methods() || _any_class_has_resolved_methods;
@@ -2119,12 +2126,12 @@ jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
Handle protection_domain(THREAD, klass->protection_domain());
+ ClassLoadInfo cl_info(protection_domain);
+
ClassFileParser parser(&st,
klass->name(),
klass->class_loader_data(),
- protection_domain,
- NULL, // host_klass
- NULL, // cp_patches
+ &cl_info,
ClassFileParser::INTERNAL, // publicity level
true,
THREAD);
@@ -2134,7 +2141,7 @@ jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
links.append(KlassPair(super_klass, klass));
}
- Array<Klass*>* local_interfaces = parser.local_interfaces();
+ Array<InstanceKlass*>* local_interfaces = parser.local_interfaces();
for (int j = 0; j < local_interfaces->length(); j++) {
Klass* iface = local_interfaces->at(j);
if (iface != NULL && _affected_klasses->contains(iface)) {
@@ -2157,7 +2164,7 @@ jvmtiError VM_EnhancedRedefineClasses::do_topological_class_sorting(TRAPS) {
links.append(KlassPair(super_klass, klass));
}
- Array<Klass*>* local_interfaces = klass->local_interfaces();
+ Array<InstanceKlass*>* local_interfaces = klass->local_interfaces();
for (int j = 0; j < local_interfaces->length(); j++) {
Klass* interfaceKlass = local_interfaces->at(j);
if (_affected_klasses->contains(interfaceKlass)) {
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 4c0412d343d..0066088b3b0 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -32,7 +32,7 @@
#include "memory/resourceArea.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/objArrayOop.hpp"
-#include "gc/shared/vmGCOperations.hpp"
+#include "gc/shared/gcVMOperations.hpp"
#include "../../../java.base/unix/native/include/jni_md.h"
//
@@ -59,6 +59,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
static int _deleted_methods_length;
static int _added_methods_length;
static Klass* _the_class_oop;
+ static u8 _id_counter;
// The instance fields are used to pass information from
// doit_prologue() to doit() and doit_epilogue().
@@ -91,6 +92,9 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
elapsedTimer _timer_heap_iterate;
elapsedTimer _timer_heap_full_gc;
+ // Redefinition id used by JFR
+ u8 _id;
+
// These routines are roughly in call order unless otherwise noted.
// Load and link new classes (either redefined or affected by redefinition - subclass, ...)
@@ -118,15 +122,14 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
static void mark_as_scavengable(nmethod* nm);
static void unregister_nmethod_g1(nmethod* nm);
static void register_nmethod_g1(nmethod* nm);
- static void unpatch_bytecode(Method* method);
- static void fix_invoke_method(Method* method);
+ static void unpatch_bytecode(Method* method, TRAPS);
// Figure out which new methods match old methods in name and signature,
// which methods have been added, and which are no longer present
void compute_added_deleted_matching_methods();
// Change jmethodIDs to point to the new methods
- void update_jmethod_ids();
+ void update_jmethod_ids(TRAPS);
// marking methods as old and/or obsolete
void check_methods_and_mark_as_obsolete();
@@ -141,6 +144,8 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
void flush_dependent_code(InstanceKlass* k_h, TRAPS);
+ u8 next_id();
+
static void check_class(InstanceKlass* k_oop, TRAPS);
static void dump_methods();
@@ -181,6 +186,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
bool allow_nested_vm_operations() const { return true; }
jvmtiError check_error() { return _res; }
+ u8 id() { return _id; }
// Modifiable test must be shared between IsModifiableClass query
// and redefine implementation
diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp
index b6838ac034d..fba0f48abd7 100644
--- a/src/hotspot/share/prims/jvmtiEnv.cpp
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp
@@ -456,20 +456,23 @@ JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) {
EventRetransformClasses event;
jvmtiError error;
+ u8 op_id;
if (AllowEnhancedClassRedefinition) {
MutexLocker sd_mutex(EnhancedRedefineClasses_lock);
VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
VMThread::execute(&op);
+ op_id = op.id();
error = (op.check_error());
} else {
VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
VMThread::execute(&op);
+ op_id = op.id();
error = op.check_error();
}
if (error == JVMTI_ERROR_NONE) {
event.set_classCount(class_count);
- event.set_redefinitionId(op.id());
+ event.set_redefinitionId(op_id);
event.commit();
}
return error;
@@ -484,19 +487,23 @@ JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_de
EventRedefineClasses event;
jvmtiError error;
+ u8 op_id;
+
if (AllowEnhancedClassRedefinition) {
MutexLocker sd_mutex(EnhancedRedefineClasses_lock);
VM_EnhancedRedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
VMThread::execute(&op);
+ op_id = op.id();
error = (op.check_error());
} else {
VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
VMThread::execute(&op);
+ op_id = op.id();
error = op.check_error();
}
if (error == JVMTI_ERROR_NONE) {
event.set_classCount(class_count);
- event.set_redefinitionId(op.id());
+ event.set_redefinitionId(op_id);
event.commit();
}
return error;
diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
index a7840848e10..346eac7c431 100644
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
@@ -1271,6 +1271,7 @@ jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
the_class_loader,
&st,
cl_info,
+ NULL,
THREAD);
// Clear class_being_redefined just to be sure.
state->clear_class_being_redefined();
diff --git a/src/hotspot/share/prims/methodHandles.hpp b/src/hotspot/share/prims/methodHandles.hpp
index 54f36202a5f..917d31efd77 100644
--- a/src/hotspot/share/prims/methodHandles.hpp
+++ b/src/hotspot/share/prims/methodHandles.hpp
@@ -180,6 +180,9 @@ public:
assert(ref_kind_is_valid(ref_kind), "");
return (ref_kind & 1) != 0;
}
+ static bool ref_kind_is_static(int ref_kind) {
+ return !ref_kind_has_receiver(ref_kind) && (ref_kind != JVM_REF_newInvokeSpecial);
+ }
static int ref_kind_to_flags(int ref_kind);
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index d05a2893498..3a92b8869dc 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -2128,13 +2128,15 @@ bool Arguments::check_gc_consistency() {
// of collectors.
uint i = 0;
if (UseSerialGC) i++;
- if (UseConcMarkSweepGC) i++;
- if (UseParallelGC || UseParallelOldGC) i++;
+ if (UseParallelGC) i++;
if (UseG1GC) i++;
+ if (UseEpsilonGC) i++;
+ if (UseZGC) i++;
+ if (UseShenandoahGC) i++;
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 && !UseG1GC) && i >= 1) {
+ if (!UseSerialGC && !UseG1GC && i >= 1) {
jio_fprintf(defaultStream::error_stream(),
"Must use the Serial or G1 GC with enhanced class redefinition.\n");
return false;
@@ -4494,18 +4496,18 @@ void Arguments::setup_hotswap_agent() {
// 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++);
+ create_numbered_module_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++);
+ create_numbered_module_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++);
+ create_numbered_module_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++);
+ create_numbered_module_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++);
+ create_numbered_module_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++);
+ create_numbered_module_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++);
+ create_numbered_module_property("jdk.module.addopens", "java.desktop/com.sun.beans.util=ALL-UNNAMED", addopens_count++);
}
diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp
index 6f982072909..14a3ed730fe 100644
--- a/src/hotspot/share/runtime/mutexLocker.cpp
+++ b/src/hotspot/share/runtime/mutexLocker.cpp
@@ -287,7 +287,7 @@ void mutex_init() {
def(InitCompleted_lock , PaddedMonitor, leaf, true, _safepoint_check_never);
def(VtableStubs_lock , PaddedMutex , nonleaf, true, _safepoint_check_never);
def(Notify_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always);
- def(EnhancedRedefineClasses_lock , PaddedMutex , nonleaf+7, false, Monitor::_safepoint_check_always); // for ensuring that class redefinition is not done in parallel
+ def(EnhancedRedefineClasses_lock , PaddedMutex , nonleaf+7, false, _safepoint_check_always); // for ensuring that class redefinition is not done in parallel
def(JNICritical_lock , PaddedMonitor, nonleaf, true, _safepoint_check_always); // used for JNI critical regions
def(AdapterHandlerLibrary_lock , PaddedMutex , nonleaf, true, _safepoint_check_always);
--
2.23.0

View File

@@ -1,25 +0,0 @@
From 336cab4f72c6e642e3077ea8d1a4860de33f5a4d Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Tue, 17 Nov 2020 17:40:24 +0100
Subject: [PATCH 20/34] dcevm15 - G1 fixes
---
src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
index 2f06b9617e4..476728a5d26 100644
--- a/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
+++ b/src/hotspot/share/gc/g1/g1FullGCPrepareTask.cpp
@@ -240,7 +240,7 @@ void G1FullGCPrepareTask::prepare_serial_compaction_dcevm() {
// collect remaining, not forwarded rescued oops using serial compact point
while (cp->last_rescued_oop() < cp->rescued_oops()->length()) {
- HeapRegion* hr = G1CollectedHeap::heap()->new_region(HeapRegion::GrainBytes / HeapWordSize, false, true);
+ HeapRegion* hr = G1CollectedHeap::heap()->new_region(HeapRegion::GrainBytes / HeapWordSize, HeapRegionType::Eden, true, G1NUMA::AnyNodeIndex);
if (hr == NULL) {
vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "G1 - not enough of free regions after redefinition.");
}
--
2.23.0

View File

@@ -1,133 +0,0 @@
From cea4e2cca3c37233c728be7235f8f9d8be136cb5 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Tue, 17 Nov 2020 18:52:57 +0100
Subject: [PATCH 21/34] dcevm15 - Fix flush dependent code
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 57 +++++++------------
.../prims/jvmtiEnhancedRedefineClasses.hpp | 4 +-
2 files changed, 25 insertions(+), 36 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 619e3988e3a..efaf11e1666 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -508,7 +508,7 @@ 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) {
- flush_dependent_code(NULL, thread);
+ flush_dependent_code(thread);
// }
// Adjust constantpool caches for all classes that reference methods of the evolved class.
@@ -647,17 +647,8 @@ void VM_EnhancedRedefineClasses::doit() {
//MethodDataCleaner clean_weak_method_links;
//ClassLoaderDataGraph::classes_do(&clean_weak_method_links);
- // Disable any dependent concurrent compilations
- // SystemDictionary::notice_modification();
-
JvmtiExport::increment_redefinition_count();
- // Set flag indicating that some invariants are no longer true.
- // See jvmtiExport.hpp for detailed explanation.
-
- // dcevm15: handled by _redefinition_count
- // JvmtiExport::set_has_redefined_a_class();
-
#ifdef PRODUCT
if (log_is_enabled(Trace, redefine, class, obsolete, metadata)) {
#endif
@@ -1746,6 +1737,18 @@ void VM_EnhancedRedefineClasses::transfer_old_native_function_registrations(Inst
transfer.transfer_registrations(_matching_old_methods, _matching_methods_length);
}
+// First step is to walk the code cache for each class redefined and mark
+// dependent methods. Wait until all classes are processed to deoptimize everything.
+void VM_EnhancedRedefineClasses::mark_dependent_code(InstanceKlass* ik) {
+ assert_locked_or_safepoint(Compile_lock);
+
+ // All dependencies have been recorded from startup or this is a second or
+ // subsequent use of RedefineClasses
+ if (0 && JvmtiExport::all_dependencies_are_recorded()) {
+ CodeCache::mark_for_evol_deoptimization(ik);
+ }
+}
+
// DCEVM - it always deoptimizes everything! (because it is very difficult to find only correct dependencies)
// Deoptimize all compiled code that depends on this class.
//
@@ -1762,33 +1765,21 @@ void VM_EnhancedRedefineClasses::transfer_old_native_function_registrations(Inst
// subsequent calls to RedefineClasses need only throw away code
// that depends on the class.
//
-void VM_EnhancedRedefineClasses::flush_dependent_code(InstanceKlass* k_h, TRAPS) {
+void VM_EnhancedRedefineClasses::flush_dependent_code(TRAPS) {
assert_locked_or_safepoint(Compile_lock);
// All dependencies have been recorded from startup or this is a second or
// subsequent use of RedefineClasses
// FIXME: for now, deoptimize all!
- 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();
+ if (0 && JvmtiExport::all_dependencies_are_recorded()) {
+ int deopt = CodeCache::mark_dependents_for_evol_deoptimization();
+ log_debug(redefine, class, nmethod)("Marked %d dependent nmethods for deopt", deopt);
+ if (deopt != 0) {
+ CodeCache::flush_evol_dependents();
}
} else {
- CodeCache::mark_all_nmethods_for_deoptimization();
-
- ResourceMark rm(THREAD);
- DeoptimizationMarker dm;
-
- // Deoptimize all activations depending on marked nmethods
- Deoptimization::deoptimize_dependents();
-
- // Make the dependent methods not entrant
- CodeCache::make_marked_nmethods_not_entrant();
-
- // From now on we know that the dependency information is complete
+ CodeCache::mark_all_nmethods_for_evol_deoptimization();
+ CodeCache::flush_evol_dependents();
JvmtiExport::set_all_dependencies_are_recorded(true);
}
}
@@ -1881,11 +1872,7 @@ void VM_EnhancedRedefineClasses::redefine_single_class(InstanceKlass* new_class_
JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
jvmti_breakpoints.clearall_in_class_at_safepoint(the_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);
-// }
+ mark_dependent_code(the_class);
_old_methods = the_class->methods();
_new_methods = new_class->methods();
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index 0066088b3b0..bd5e7d153be 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -142,7 +142,9 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
// and in all direct and indirect subclasses.
void increment_class_counter(InstanceKlass *ik, TRAPS);
- void flush_dependent_code(InstanceKlass* k_h, TRAPS);
+ void mark_dependent_code(InstanceKlass* ik);
+
+ void flush_dependent_code(TRAPS);
u8 next_id();
--
2.23.0

View File

@@ -1,211 +0,0 @@
From 4f88dcec830d39452f69d1117729469fdb768a8f Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 22 Nov 2020 12:05:26 +0100
Subject: [PATCH 22/34] dcevm15 - fix ResolvedMethodTable
---
src/hotspot/share/classfile/javaClasses.cpp | 5 -
src/hotspot/share/classfile/javaClasses.hpp | 1 -
.../share/prims/resolvedMethodTable.cpp | 139 +++++++++++-------
3 files changed, 84 insertions(+), 61 deletions(-)
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index 9b086a241f7..9a627786d0f 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -3996,11 +3996,6 @@ void java_lang_invoke_ResolvedMethodName::set_vmholder(oop resolved_method, oop
resolved_method->obj_field_put(_vmholder_offset, holder);
}
-void java_lang_invoke_ResolvedMethodName::set_vmholder_offset(oop resolved_method, Method* m) {
- assert(is_instance(resolved_method), "wrong type");
- resolved_method->obj_field_put(_vmholder_offset, m->method_holder()->java_mirror());
-}
-
oop java_lang_invoke_ResolvedMethodName::find_resolved_method(const methodHandle& m, TRAPS) {
const Method* method = m();
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index 9abf2e1d105..8f5993b7225 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -1107,7 +1107,6 @@ class java_lang_invoke_ResolvedMethodName : AllStatic {
static Method* vmtarget(oop resolved_method);
static void set_vmtarget(oop resolved_method, Method* method);
- static void set_vmholder_offset(oop resolved_method, Method* method);
static void set_vmholder(oop resolved_method, oop holder);
diff --git a/src/hotspot/share/prims/resolvedMethodTable.cpp b/src/hotspot/share/prims/resolvedMethodTable.cpp
index eb9fcda44f3..d0f1667b967 100644
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp
@@ -375,6 +375,67 @@ public:
}
};
+class AdjustMethodEntriesDcevm : public StackObj {
+ bool* _trace_name_printed;
+ GrowableArray<oop>* _oops_to_add;
+public:
+ AdjustMethodEntriesDcevm(GrowableArray<oop>* oops_to_add, bool* trace_name_printed) : _trace_name_printed(trace_name_printed), _oops_to_add(oops_to_add) {};
+ bool operator()(WeakHandle<vm_resolved_method_table_data>* entry) {
+ oop mem_name = entry->peek();
+ if (mem_name == NULL) {
+ // Removed
+ return true;
+ }
+
+ Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
+
+ 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()) {
+ newer_method = Universe::throw_no_such_method_error();
+ } else {
+ newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
+
+ log_debug(redefine, class, update)("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");
+
+ Thread* thread = Thread::current();
+ ResolvedMethodTableLookup lookup(thread, method_hash(newer_method), newer_method);
+ ResolvedMethodGet rmg(thread, newer_method);
+
+ if (_local_table->get(thread, lookup, rmg)) {
+ // old method was already adjusted if new method exists in _the_table
+ return true;
+ }
+ }
+
+ java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, newer_method);
+ java_lang_invoke_ResolvedMethodName::set_vmholder(mem_name, newer_method->method_holder()->java_mirror());
+
+ newer_klass->set_has_resolved_methods();
+ _oops_to_add->append(mem_name);
+
+ ResourceMark rm;
+ if (!(*_trace_name_printed)) {
+ log_debug(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)",
+ newer_method->name()->as_C_string(), newer_method->signature()->as_C_string());
+ }
+
+ return true;
+ }
+};
+
// 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");
@@ -382,73 +443,41 @@ void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
AdjustMethodEntries adjust(trace_name_printed);
_local_table->do_safepoint_scan(adjust);
}
-#endif // INCLUDE_JVMTI
-// (DCEVM) It is called at safepoint only for RedefineClasses
+// 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>();
-
- 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()) {
-
- InstanceKlass* newer_klass = InstanceKlass::cast(old_method->method_holder()->new_version());
- Method* newer_method;
-
- // Method* new_method;
- if (old_method->is_deleted()) {
- newer_method = Universe::throw_no_such_method_error();
- } else {
- newer_method = newer_klass->method_with_idnum(old_method->orig_method_idnum());
-
- log_debug(redefine, class, update)("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");
-
- if (_the_table->lookup(newer_method) != NULL) {
- // old method was already adjusted if new method exists in _the_table
- continue;
- }
- }
+ GrowableArray<oop> oops_to_add(0);
+ AdjustMethodEntriesDcevm adjust(&oops_to_add, trace_name_printed);
+ _local_table->do_safepoint_scan(adjust);
+ Thread* thread = Thread::current();
+ for (int i = 0; i < oops_to_add.length(); i++) {
+ oop mem_name = oops_to_add.at(i);
+ Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
- java_lang_invoke_ResolvedMethodName::set_vmtarget(mem_name, newer_method);
- java_lang_invoke_ResolvedMethodName::set_vmholder_offset(mem_name, newer_method);
+ // The hash table takes ownership of the WeakHandle, even if it's not inserted.
- newer_klass->set_has_resolved_methods();
- oops_to_add->append(mem_name);
+ ResolvedMethodTableLookup lookup(thread, method_hash(method), method);
+ ResolvedMethodGet rmg(thread, method);
- ResourceMark rm;
- if (!(*trace_name_printed)) {
- log_debug(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)",
- newer_method->name()->as_C_string(), newer_method->signature()->as_C_string());
+ while (true) {
+ if (_local_table->get(thread, lookup, rmg)) {
+ break;
+ }
+ WeakHandle<vm_resolved_method_table_data> wh = WeakHandle<vm_resolved_method_table_data>::create(Handle(thread, mem_name));
+ // The hash table takes ownership of the WeakHandle, even if it's not inserted.
+ if (_local_table->insert(thread, lookup, wh)) {
+ log_insert(method);
+ wh.resolve();
+ break;
}
- }
- for (int i = 0; i < oops_to_add->length(); i++) {
- oop mem_name = oops_to_add->at(i);
- Method* method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
- _the_table->basic_add(method, Handle(Thread::current(), mem_name));
}
}
}
+#endif // INCLUDE_JVMTI
+
// Verification
class VerifyResolvedMethod : StackObj {
public:
--
2.23.0

View File

@@ -1,88 +0,0 @@
From 5379e56465d3d3930ec7ea91b1c64db2cdf70170 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 22 Nov 2020 12:05:50 +0100
Subject: [PATCH 23/34] dcevm15 - fix Universe::root_oops_do
---
src/hotspot/share/memory/universe.cpp | 38 +++++++++------------------
1 file changed, 12 insertions(+), 26 deletions(-)
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
index f6e4253b5a5..8dad437bd51 100644
--- a/src/hotspot/share/memory/universe.cpp
+++ b/src/hotspot/share/memory/universe.cpp
@@ -39,6 +39,7 @@
#include "gc/shared/gcConfig.hpp"
#include "gc/shared/gcLogPrecious.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
+#include "gc/shared/weakProcessor.hpp"
#include "interpreter/interpreter.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
@@ -75,6 +76,7 @@
#include "runtime/thread.inline.hpp"
#include "runtime/timerTrace.hpp"
#include "runtime/vmOperations.hpp"
+#include "services/management.hpp"
#include "services/memoryService.hpp"
#include "utilities/align.hpp"
#include "utilities/copy.hpp"
@@ -180,45 +182,29 @@ void Universe::basic_type_classes_do(KlassClosure *closure) {
// 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 {
- public:
- void do_object(oop p) { ShouldNotReachHere(); }
- bool do_object_b(oop p) { return true; }
- };
- AlwaysTrueClosure always_true;
-
Universe::oops_do(oopClosure);
// ReferenceProcessor::oops_do(oopClosure); (tw) check why no longer there
JNIHandles::oops_do(oopClosure); // Global (strong) JNI handles
Threads::oops_do(oopClosure, NULL);
ObjectSynchronizer::oops_do(oopClosure);
- // TODO: review, flat profiler was removed in j10
- // FlatProfiler::oops_do(oopClosure);
- JvmtiExport::oops_do(oopClosure);
+ // (DCEVM) TODO: Check if this is correct?
+ Management::oops_do(oopClosure);
+ OopStorageSet::vm_global()->oops_do(oopClosure);
+ CLDToOopClosure cld_closure(oopClosure, ClassLoaderData::_claim_none);
+ ClassLoaderDataGraph::cld_do(&cld_closure);
// Now adjust pointers in remaining weak roots. (All of which should
// have been cleared if they pointed to non-surviving objects.)
// Global (weak) JNI handles
- JNIHandles::weak_oops_do(&always_true, oopClosure);
+ WeakProcessor::oops_do(oopClosure);
CodeBlobToOopClosure blobClosure(oopClosure, CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&blobClosure);
- StringTable::oops_do(oopClosure);
+ AOT_ONLY(AOTLoader::oops_do(oopClosure);)
+ // StringTable::oops_do was removed in j15
+ // StringTable::oops_do(oopClosure);
- // (DCEVM) TODO: Check if this is correct?
- //CodeCache::scavenge_root_nmethods_oops_do(oopClosure);
- //Management::oops_do(oopClosure);
- //ref_processor()->weak_oops_do(&oopClosure);
- //PSScavenge::reference_processor()->weak_oops_do(&oopClosure);
-
-#if INCLUDE_AOT
- if (UseAOT) {
- AOTLoader::oops_do(oopClosure);
- }
-#endif
- // SO_AllClasses
- SystemDictionary::oops_do(oopClosure);
+ // PSScavenge::reference_processor()->weak_oops_do(oopClosure);
}
void Universe::oops_do(OopClosure* f) {
--
2.23.0

View File

@@ -1,67 +0,0 @@
From c6ea68e66d37d70739f7b0ee74131322b4526a68 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 22 Nov 2020 12:03:32 +0100
Subject: [PATCH 24/34] Cleanup dcevm comments
---
src/hotspot/share/classfile/classLoaderDataGraph.hpp | 2 +-
src/hotspot/share/classfile/systemDictionary.hpp | 2 +-
src/hotspot/share/gc/shared/gcConfig.cpp | 2 +-
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/hotspot/share/classfile/classLoaderDataGraph.hpp b/src/hotspot/share/classfile/classLoaderDataGraph.hpp
index f380aa3fa34..8ce94cccb47 100644
--- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp
@@ -104,7 +104,7 @@ class ClassLoaderDataGraph : public AllStatic {
static void dictionary_classes_do(KlassClosure* klass_closure);
- // Enhanced class redefinition
+ // (DCEVM) Enhanced class redefinition
static void rollback_redefinition();
// VM_CounterDecay iteration support
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
index 931e655d631..1019dbd0d04 100644
--- a/src/hotspot/share/classfile/systemDictionary.hpp
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -455,7 +455,7 @@ public:
static bool is_well_known_klass(Symbol* class_name);
#endif
- // Enhanced class redefinition
+ // (DCEVM) Enhanced class redefinition
static void remove_from_hierarchy(InstanceKlass* k);
static void update_constraints_after_redefinition();
diff --git a/src/hotspot/share/gc/shared/gcConfig.cpp b/src/hotspot/share/gc/shared/gcConfig.cpp
index 5c1a09390f1..23fbf715378 100644
--- a/src/hotspot/share/gc/shared/gcConfig.cpp
+++ b/src/hotspot/share/gc/shared/gcConfig.cpp
@@ -99,7 +99,7 @@ void GCConfig::fail_if_non_included_gc_is_selected() {
void GCConfig::select_gc_ergonomically() {
if (AllowEnhancedClassRedefinition && !UseG1GC) {
- // Enhanced class redefinition only supports serial GC at the moment
+ // (DCEVM) Enhanced class redefinition only supports serial GC at the moment
FLAG_SET_ERGO(UseSerialGC, true);
} else if (os::is_server_class_machine()) {
#if INCLUDE_G1GC
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
index bd5e7d153be..5de375fb888 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.hpp
@@ -78,7 +78,7 @@ class VM_EnhancedRedefineClasses: public VM_GC_Operation {
// have any entries.
bool _any_class_has_resolved_methods;
- // Enhanced class redefinition, affected klasses contain all classes which should be redefined
+ // (DCEVM) Enhanced class redefinition, affected klasses contain all classes which should be redefined
// either because of redefine, class hierarchy or interface change
GrowableArray<Klass*>* _affected_klasses;
--
2.23.0

View File

@@ -1,43 +0,0 @@
From 507d97966c7145d0ae2533459cc504c7b0d6d5b6 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 22 Nov 2020 18:49:05 +0100
Subject: [PATCH 25/34] Fix cpCache in not AllowEnhancedClassRedefinition mode
---
src/hotspot/share/oops/cpCache.hpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/hotspot/share/oops/cpCache.hpp b/src/hotspot/share/oops/cpCache.hpp
index 121a13b1dda..64dcf6223f5 100644
--- a/src/hotspot/share/oops/cpCache.hpp
+++ b/src/hotspot/share/oops/cpCache.hpp
@@ -148,13 +148,13 @@ class ConstantPoolCacheEntry {
void set_bytecode_2(Bytecodes::Code code);
void set_f1(Metadata* f1) {
Metadata* existing_f1 = _f1; // read once
- //assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
+ assert(AllowEnhancedClassRedefinition || existing_f1 == NULL || existing_f1 == f1, "illegal field change");
_f1 = f1;
}
void release_set_f1(Metadata* f1);
void set_f2(intx f2) {
intx existing_f2 = _f2; // read once
- //assert(existing_f2 == 0 || existing_f2 == f2, "illegal field change");
+ assert(AllowEnhancedClassRedefinition || existing_f2 == 0 || existing_f2 == f2, "illegal field change");
_f2 = f2;
}
void set_f2_as_vfinal_method(Method* f2) {
@@ -215,7 +215,9 @@ class ConstantPoolCacheEntry {
void initialize_resolved_reference_index(int ref_index) {
assert(_f2 == 0, "set once"); // note: ref_index might be zero also
_f2 = ref_index;
- _flags = 1 << is_resolved_ref_shift;
+ if (AllowEnhancedClassRedefinition) {
+ _flags = 1 << is_resolved_ref_shift;
+ }
}
void set_field( // sets entry to resolved field state
--
2.23.0

View File

@@ -1,32 +0,0 @@
From b516b615c20fafa2094dfb9f4cb08245b26418d0 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 22 Nov 2020 19:51:46 +0100
Subject: [PATCH 26/34] dcevm15 - add ClassLoaderDataGraph_lock on
ClassLoaderDataGraph::classes_do
ClassLoaderDataGraph::classes_do need safepoint or lock,
find_sorted_affected_classes is not in safepoint therefore it must be
locked
---
src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index efaf11e1666..197e1c0029f 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -2063,7 +2063,10 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
AffectedKlassClosure closure(_affected_klasses);
// Updated in j10, from original SystemDictionary::classes_do
- ClassLoaderDataGraph::classes_do(&closure);
+ {
+ MutexLocker mcld(ClassLoaderDataGraph_lock);
+ ClassLoaderDataGraph::classes_do(&closure);
+ }
//ClassLoaderDataGraph::dictionary_classes_do(&closure);
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());
--
2.23.0

View File

@@ -1,29 +0,0 @@
From c6498946006879314bdc6218ee72da5d9c88f237 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sat, 28 Nov 2020 19:29:42 +0100
Subject: [PATCH 27/34] dcevm15 - check if has_nestmate_access_to has newest
host class
---
src/hotspot/share/oops/instanceKlass.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 5e40d78a87e..1d9623f2446 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -445,6 +445,11 @@ bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
return false;
}
+ if (AllowEnhancedClassRedefinition) {
+ // TODO: (DCEVM) check if it correct. It fix problems with lambdas (hidden)
+ cur_host = InstanceKlass::cast(cur_host->newest_version());
+ }
+
Klass* k_nest_host = k->nest_host(CHECK_false);
if (k_nest_host == NULL) {
return false;
--
2.23.0

View File

@@ -1,24 +0,0 @@
From 86c27155386c1c40642c99c63a242d1f5d8601a5 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sat, 28 Nov 2020 19:31:08 +0100
Subject: [PATCH 28/34] Remove unused fieldType
---
src/hotspot/share/classfile/vmSymbols.hpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index 6a3b234b222..eb06684a288 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -465,7 +465,6 @@
template(static_offset_name, "staticOffset") \
template(static_base_name, "staticBase") \
template(field_offset_name, "fieldOffset") \
- template(field_type_name, "fieldType") \
\
/* name symbols needed by intrinsics */ \
\
--
2.23.0

View File

@@ -1,54 +0,0 @@
From 025d0d2903963fb79f83cf0d90418783d3ef6813 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 29 Nov 2020 17:18:16 +0100
Subject: [PATCH 29/34] mark_as_scavengable only alive methods
---
.../share/prims/jvmtiEnhancedRedefineClasses.cpp | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index 197e1c0029f..e00fac1f693 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -223,19 +223,21 @@ class FieldCopier : public FieldClosure {
// TODO: review...
void VM_EnhancedRedefineClasses::mark_as_scavengable(nmethod* nm) {
- ScavengableNMethods::register_nmethod(nm);
+ if (nm->is_alive()) {
+ ScavengableNMethods::register_nmethod(nm);
+ }
}
void VM_EnhancedRedefineClasses::unregister_nmethod_g1(nmethod* nm) {
// It should work not only for G1 but also for another GCs, but this way is safer now
- if (!nm->is_zombie() && !nm->is_unloaded()) {
+ if (nm->is_alive()) {
Universe::heap()->unregister_nmethod(nm);
}
}
void VM_EnhancedRedefineClasses::register_nmethod_g1(nmethod* nm) {
// It should work not only for G1 but also for another GCs, but this way is safer now
- if (!nm->is_zombie() && !nm->is_unloaded()) {
+ if (nm->is_alive()) {
Universe::heap()->register_nmethod(nm);
}
}
@@ -511,9 +513,9 @@ void VM_EnhancedRedefineClasses::doit() {
flush_dependent_code(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);
+ // 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) {
--
2.23.0

View File

@@ -1,28 +0,0 @@
From 27aabfefe7d799545049bb81ba19d4ed2ff6379c Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 29 Nov 2020 17:20:11 +0100
Subject: [PATCH 30/34] dcevm15 - lock on
ClassLoaderDataGraph::rollback_redefinition
rollback is not in safepoint, therefore must be locked
---
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 e00fac1f693..db5fb1c472b 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -1382,7 +1382,9 @@ 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.
void VM_EnhancedRedefineClasses::rollback() {
log_info(redefine, class, load)("Rolling back redefinition, result=%d", _res);
+ ClassLoaderDataGraph_lock->lock();
ClassLoaderDataGraph::rollback_redefinition();
+ ClassLoaderDataGraph_lock->unlock();
for (int i = 0; i < _new_classes->length(); i++) {
SystemDictionary::remove_from_hierarchy(_new_classes->at(i));
--
2.23.0

View File

@@ -1,28 +0,0 @@
From 9b405cb642d5935c39c8dbd522ea2fdecfc29ef3 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 29 Nov 2020 19:59:50 +0100
Subject: [PATCH 31/34] ResourceMark in G1IterateObjectClosureTask fixing
memory leaks
G1IterateObjectClosureTask is used only in redefinition full GC run
---
src/hotspot/share/gc/g1/g1CollectedHeap.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
index a29d2dddc2d..2af6df6c1e4 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -2362,6 +2362,9 @@ class G1IterateObjectClosureTask : public AbstractGangTask {
_cl(cl), _g1h(g1h), _hrclaimer(g1h->workers()->active_workers()) { }
virtual void work(uint worker_id) {
+ Thread *thread = Thread::current();
+ HandleMark hm(thread); // make sure any handles created are deleted
+ ResourceMark rm(thread);
IterateObjectClosureRegionClosure blk(_cl);
_g1h->heap_region_par_iterate_from_worker_offset(&blk, &_hrclaimer, worker_id);
}
--
2.23.0

View File

@@ -1,91 +0,0 @@
From 40fe40884d4efc50864bb3f2dd88f0a2e7122d5a Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 29 Nov 2020 20:05:03 +0100
Subject: [PATCH 32/34] dcevm15 - fix hidded classes
---
.../prims/jvmtiEnhancedRedefineClasses.cpp | 41 ++++++++++++++-----
1 file changed, 30 insertions(+), 11 deletions(-)
diff --git a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
index db5fb1c472b..590f7fdfafe 100644
--- a/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiEnhancedRedefineClasses.cpp
@@ -722,7 +722,8 @@ bool VM_EnhancedRedefineClasses::is_modifiable_class(oop klass_mirror) {
}
// Cannot redefine or retransform an anonymous class.
- if (InstanceKlass::cast(k)->is_unsafe_anonymous()) {
+ // TODO: check if is correct in j15
+ if (InstanceKlass::cast(k)->is_unsafe_anonymous() || InstanceKlass::cast(k)->is_hidden()) {
return false;
}
return true;
@@ -808,21 +809,27 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
InstanceKlass* k;
- if (InstanceKlass::cast(the_class)->is_unsafe_anonymous()) {
- const InstanceKlass* host_class = the_class->unsafe_anonymous_host();
+ if (the_class->is_unsafe_anonymous() || the_class->is_hidden()) {
+ InstanceKlass* dynamic_host_class = NULL;
+ InstanceKlass* unsafe_anonymous_host = NULL;
- // Make sure it's the real host class, not another anonymous class.
- while (host_class != NULL && host_class->is_unsafe_anonymous()) {
- host_class = host_class->unsafe_anonymous_host();
+ if (the_class->is_hidden()) {
+ log_debug(redefine, class, load)("loading hidden class %s", the_class->name()->as_C_string());
+ dynamic_host_class = the_class->nest_host(THREAD);
+ }
+
+ if (the_class->is_unsafe_anonymous()) {
+ log_debug(redefine, class, load)("loading usafe anonymous %s", the_class->name()->as_C_string());
+ unsafe_anonymous_host = the_class->unsafe_anonymous_host();
}
ClassLoadInfo cl_info(protection_domain,
- host_class,
- NULL, // dynamic_nest_host
+ unsafe_anonymous_host,
NULL, // cp_patches
+ dynamic_host_class, // dynamic_nest_host
Handle(), // classData
- false, // is_hidden
- false, // is_strong_hidden
+ the_class->is_hidden(), // is_hidden
+ !the_class->is_non_strong_hidden(), // is_strong_hidden
true); // FIXME: check if correct. can_access_vm_annotations
k = SystemDictionary::parse_stream(the_class_sym,
@@ -833,7 +840,17 @@ jvmtiError VM_EnhancedRedefineClasses::load_new_class_versions(TRAPS) {
THREAD);
k->class_loader_data()->exchange_holders(the_class->class_loader_data());
- the_class->class_loader_data()->inc_keep_alive();
+
+ if (the_class->is_hidden()) {
+ // from jvm_lookup_define_class() (jvm.cpp):
+ // The hidden class loader data has been artificially been kept alive to
+ // this point. The mirror and any instances of this class have to keep
+ // it alive afterwards.
+ the_class->class_loader_data()->dec_keep_alive();
+ } else {
+ the_class->class_loader_data()->inc_keep_alive();
+ }
+
} else {
k = SystemDictionary::resolve_from_stream(the_class_sym,
the_class_loader,
@@ -1475,6 +1492,8 @@ void VM_EnhancedRedefineClasses::ClearCpoolCacheAndUnpatch::do_klass(Klass* k) {
ik->set_unsafe_anonymous_host(InstanceKlass::cast(ik->unsafe_anonymous_host()->newest_version()));
}
+ // FIXME: check new nest_host for hidden
+
// Update implementor if there is only one, in this case implementor() can reference old class
if (ik->is_interface()) {
Klass* implKlass = ik->implementor();
--
2.23.0

View File

@@ -1,27 +0,0 @@
From 29920b076b4ad96d85adbce0a1d947e5022ba3ad Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 29 Nov 2020 20:08:57 +0100
Subject: [PATCH 33/34] dcevm15 - DON'T clear F2 in CP cache after indy
unevolving
It's not clear why it was cleared in dcevm7-11
---
src/hotspot/share/oops/cpCache.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp
index 79a38dbeff0..650e6fab42d 100644
--- a/src/hotspot/share/oops/cpCache.cpp
+++ b/src/hotspot/share/oops/cpCache.cpp
@@ -650,7 +650,7 @@ void ConstantPoolCacheEntry::clear_entry() {
if (clearData) {
if (!is_resolved_reference()) {
- _f2 = 0;
+ // _f2 = 0;
}
// FIXME: (DCEVM) we want to clear flags, but parameter size is actually used
// after we return from the method, before entry is re-initialized. So let's
--
2.23.0

View File

@@ -1,49 +0,0 @@
From 1f13b20ab5553182680045b7d7324ff92da7e7f0 Mon Sep 17 00:00:00 2001
From: Vladimir Dvorak <vladimir.dvorak@jetbrains.com>
Date: Sun, 29 Nov 2020 21:28:06 +0100
Subject: [PATCH 34/34] dcevm15 - fix Universe::root_oops_do
Removed ClassLoaderDataGraph::cld_do was cause of crashes due multiple
oop patching. ClassLoaderDataGraph::cld_do replaced in dcevm15
previously used and removed SystemDictionary:oops_do
---
src/hotspot/share/memory/universe.cpp | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
index 8dad437bd51..0199962a684 100644
--- a/src/hotspot/share/memory/universe.cpp
+++ b/src/hotspot/share/memory/universe.cpp
@@ -190,21 +190,26 @@ void Universe::root_oops_do(OopClosure *oopClosure) {
// (DCEVM) TODO: Check if this is correct?
Management::oops_do(oopClosure);
OopStorageSet::vm_global()->oops_do(oopClosure);
- CLDToOopClosure cld_closure(oopClosure, ClassLoaderData::_claim_none);
- ClassLoaderDataGraph::cld_do(&cld_closure);
+ // CLDToOopClosure cld_closure(oopClosure, ClassLoaderData::_claim_none);
+ // ClassLoaderDataGraph::cld_do(&cld_closure);
// Now adjust pointers in remaining weak roots. (All of which should
// have been cleared if they pointed to non-surviving objects.)
// Global (weak) JNI handles
WeakProcessor::oops_do(oopClosure);
+ JvmtiExport::oops_do(oopClosure);
+
CodeBlobToOopClosure blobClosure(oopClosure, CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&blobClosure);
+
AOT_ONLY(AOTLoader::oops_do(oopClosure);)
+
// StringTable::oops_do was removed in j15
// StringTable::oops_do(oopClosure);
- // PSScavenge::reference_processor()->weak_oops_do(oopClosure);
+ // OopStorageSet::vm_global()->oops_do(oopClosure);
+
}
void Universe::oops_do(OopClosure* f) {
--
2.23.0

View File

@@ -1,119 +0,0 @@
#!/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:
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_win_x64
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
WORK_DIR=$(pwd)
JCEF_PATH=${JCEF_PATH:=$WORK_DIR/jcef_win_x64}
source jb/project/tools/common/scripts/common.sh
function create_image_bundle {
__bundle_name=$1
__modules_path=$2
__modules=$3
[ -d $__bundle_name ] && rm -rf $__bundle_name
echo Running jlink ...
${JSDK}/bin/jlink \
--module-path $__modules_path --no-man-pages --compress=2 \
--add-modules $__modules --output $__bundle_name || do_exit $?
grep -v "^JAVA_VERSION" "$JSDK"/release | grep -v "^MODULES" >> $__bundle_name/release
if [ "$__bundle_name" == "$JBRSDK_BUNDLE" ]; then
sed 's/JBR/JBRSDK/g' $__bundle_name/release > release
mv release $__bundle_name/release
fi
}
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=windows-x86_64-server-release
case "$bundle_type" in
"jcef")
do_reset_changes=1
;;
"dcevm")
HEAD_REVISION=$(git rev-parse HEAD)
git am jb/project/tools/patches/dcevm/*.patch || do_exit $?
do_reset_dcevm=1
do_reset_changes=1
;;
"nomod" | "")
bundle_type=""
;;
"fd")
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=windows-x86_64-server-fastdebug
;;
esac
sh ./configure \
--disable-warnings-as-errors \
$WITH_DEBUG_LEVEL \
--with-vendor-name="$VENDOR_NAME" \
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
--with-version-pre= \
--with-version-build=$JDK_BUILD_NUMBER \
--with-version-opt=b${build_number} \
--with-toolchain-version=$TOOLCHAIN_VERSION \
--with-boot-jdk=$BOOT_JDK \
--disable-ccache \
--enable-cds=yes || do_exit $?
if [ -z "$bundle_type" ]; then
make LOG=info CONF=$RELEASE_NAME clean images test-image || do_exit $?
else
make LOG=info CONF=$RELEASE_NAME clean images || do_exit $?
fi
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk
JSDK_MODS_DIR=$IMAGES_DIR/jmods
JBRSDK_BUNDLE=jbrsdk
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module.patch || do_exit $?
update_jsdk_mods "$JSDK" "$JCEF_PATH"/jmods "$JSDK"/jmods "$JSDK_MODS_DIR" || do_exit $?
cp $JCEF_PATH/jmods/* ${JSDK_MODS_DIR} # $JSDK/jmods is not unchanged
jbr_name_postfix="_${bundle_type}"
fi
# create runtime image bundle
modules=$(xargs < modules.list | sed s/" "//g) || do_exit $?
create_image_bundle "jbr${jbr_name_postfix}" $JSDK_MODS_DIR "$modules" || do_exit $?
# create sdk image bundle
modules=$(cat ${JSDK}/release | grep MODULES | sed s/MODULES=//g | sed s/' '/,/g | sed s/\"//g | sed s/\\r//g | sed s/\\n//g)
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "dcevm" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle "$JBRSDK_BUNDLE" "$JSDK_MODS_DIR" "$modules" || do_exit $?
do_exit 0

View File

@@ -1,63 +0,0 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
#
# 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/scripts/common.sh
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
WORK_DIR=$(pwd)
[ -z "$bundle_type" ] && (git apply -p0 < jb/project/tools/patches/exclude_jcef_module.patch || exit $?)
PATH="/usr/local/bin:/usr/bin:${PATH}"
./configure \
--disable-warnings-as-errors \
--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

@@ -1,77 +0,0 @@
#!/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)
#
source jb/project/tools/common/scripts/common.sh
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" == "dcevm" ] || [ "$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 [ -z "$bundle_type" ]; 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

@@ -1,42 +0,0 @@
#!/bin/bash -x
# The following parameters must be specified:
# JBSDK_VERSION - specifies the current version of OpenJDK e.g. 11_0_6
# JDK_BUILD_NUMBER - specifies the number of OpenJDK build or the value of --with-version-build argument to configure
# build_number - specifies the number of JetBrainsRuntime build
#
# 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

@@ -1,54 +0,0 @@
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.sctp,
jdk.security.auth,
jdk.security.jgss,
jdk.unsupported,
jdk.xml.dom,
jdk.zipfs,
jdk.hotspot.agent

View File

@@ -147,7 +147,7 @@ int StubAssembler::call_RT(Register oop_result1, Register metadata_result, addre
if (arg1 == c_rarg2 || arg1 == c_rarg3 ||
arg2 == c_rarg1 || arg2 == c_rarg3 ||
arg3 == c_rarg1 || arg3 == c_rarg2) {
stp(arg3, arg2, Address(pre(sp, 2 * wordSize)));
stp(arg3, arg2, Address(pre(sp, -2 * wordSize)));
stp(arg1, zr, Address(pre(sp, -2 * wordSize)));
ldp(c_rarg1, zr, Address(post(sp, 2 * wordSize)));
ldp(c_rarg3, c_rarg2, Address(post(sp, 2 * wordSize)));

View File

@@ -3603,6 +3603,7 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
Register current = (src != noreg) ? src : dst; // Klass is in dst if no src provided. (dst == src) also possible.
address base = CompressedKlassPointers::base();
int shift = CompressedKlassPointers::shift();
bool need_zero_extend = base != 0;
assert(UseCompressedClassPointers, "only for compressed klass ptrs");
BLOCK_COMMENT("cKlass encoder {");
@@ -3619,28 +3620,76 @@ void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
bind(ok);
#endif
if (base != NULL) {
unsigned int base_h = ((unsigned long)base)>>32;
unsigned int base_l = (unsigned int)((unsigned long)base);
if ((base_h != 0) && (base_l == 0) && VM_Version::has_HighWordInstr()) {
lgr_if_needed(dst, current);
z_aih(dst, -((int)base_h)); // Base has no set bits in lower half.
} else if ((base_h == 0) && (base_l != 0)) {
lgr_if_needed(dst, current);
z_agfi(dst, -(int)base_l);
} else {
load_const(Z_R0, base);
lgr_if_needed(dst, current);
z_sgr(dst, Z_R0);
}
current = dst;
}
// Scale down the incoming klass pointer first.
// We then can be sure we calculate an offset that fits into 32 bit.
// More generally speaking: all subsequent calculations are purely 32-bit.
if (shift != 0) {
assert (LogKlassAlignmentInBytes == shift, "decode alg wrong");
z_srlg(dst, current, shift);
current = dst;
}
lgr_if_needed(dst, current); // Move may be required (if neither base nor shift != 0).
if (base != NULL) {
// Use scaled-down base address parts to match scaled-down klass pointer.
unsigned int base_h = ((unsigned long)base)>>(32+shift);
unsigned int base_l = (unsigned int)(((unsigned long)base)>>shift);
// General considerations:
// - when calculating (current_h - base_h), all digits must cancel (become 0).
// Otherwise, we would end up with a compressed klass pointer which doesn't
// fit into 32-bit.
// - Only bit#33 of the difference could potentially be non-zero. For that
// to happen, (current_l < base_l) must hold. In this case, the subtraction
// will create a borrow out of bit#32, nicely killing bit#33.
// - With the above, we only need to consider current_l and base_l to
// calculate the result.
// - Both values are treated as unsigned. The unsigned subtraction is
// replaced by adding (unsigned) the 2's complement of the subtrahend.
if (base_l == 0) {
// - By theory, the calculation to be performed here (current_h - base_h) MUST
// cancel all high-word bits. Otherwise, we would end up with an offset
// (i.e. compressed klass pointer) that does not fit into 32 bit.
// - current_l remains unchanged.
// - Therefore, we can replace all calculation with just a
// zero-extending load 32 to 64 bit.
// - Even that can be replaced with a conditional load if dst != current.
// (this is a local view. The shift step may have requested zero-extension).
} else {
if ((base_h == 0) && is_uimm(base_l, 31)) {
// If we happen to find that (base_h == 0), and that base_l is within the range
// which can be represented by a signed int, then we can use 64bit signed add with
// (-base_l) as 32bit signed immediate operand. The add will take care of the
// upper 32 bits of the result, saving us the need of an extra zero extension.
// For base_l to be in the required range, it must not have the most significant
// bit (aka sign bit) set.
lgr_if_needed(dst, current); // no zero/sign extension in this case!
z_agfi(dst, -(int)base_l); // base_l must be passed as signed.
need_zero_extend = false;
current = dst;
} else {
// To begin with, we may need to copy and/or zero-extend the register operand.
// We have to calculate (current_l - base_l). Because there is no unsigend
// subtract instruction with immediate operand, we add the 2's complement of base_l.
if (need_zero_extend) {
z_llgfr(dst, current);
need_zero_extend = false;
} else {
llgfr_if_needed(dst, current);
}
current = dst;
z_alfi(dst, -base_l);
}
}
}
if (need_zero_extend) {
// We must zero-extend the calculated result. It may have some leftover bits in
// the hi-word because we only did optimized calculations.
z_llgfr(dst, current);
} else {
llgfr_if_needed(dst, current); // zero-extension while copying comes at no extra cost.
}
BLOCK_COMMENT("} cKlass encoder");
}

View File

@@ -447,6 +447,7 @@ char* UNICODE::as_utf8(const T* base, int& length) {
}
char* UNICODE::as_utf8(const jchar* base, int length, char* buf, int buflen) {
assert(buflen > 0, "zero length output buffer");
u_char* p = (u_char*)buf;
for (int index = 0; index < length; index++) {
jchar c = base[index];
@@ -459,6 +460,7 @@ char* UNICODE::as_utf8(const jchar* base, int length, char* buf, int buflen) {
}
char* UNICODE::as_utf8(const jbyte* base, int length, char* buf, int buflen) {
assert(buflen > 0, "zero length output buffer");
u_char* p = (u_char*)buf;
for (int index = 0; index < length; index++) {
jbyte c = base[index];

View File

@@ -105,27 +105,6 @@ class LinuxFileStore
throw new IOException("Mount point not found");
}
// returns true if extended attributes enabled on file system where given
// file resides, returns false if disabled or unable to determine.
private boolean isExtendedAttributesEnabled(UnixPath path) {
int fd = -1;
try {
fd = path.openForAttributeAccess(false);
// fgetxattr returns size if called with size==0
byte[] name = Util.toBytes("user.java");
LinuxNativeDispatcher.fgetxattr(fd, name, 0L, 0);
return true;
} catch (UnixException e) {
// attribute does not exist
if (e.errno() == UnixConstants.ENODATA)
return true;
} finally {
UnixNativeDispatcher.close(fd);
}
return false;
}
// get kernel version as a three element array {major, minor, micro}
private static int[] getKernelVersion() {
Pattern pattern = Pattern.compile("\\D+");

View File

@@ -69,7 +69,7 @@ class LinuxFileSystem extends UnixFileSystem {
@Override
void copyNonPosixAttributes(int ofd, int nfd) {
LinuxUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd);
UnixUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd);
}
/**

View File

@@ -69,61 +69,6 @@ class LinuxNativeDispatcher extends UnixNativeDispatcher {
*/
static native void endmntent(long stream) throws UnixException;
/**
* ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);
*/
static int fgetxattr(int filedes, byte[] name, long valueAddress,
int valueLen) throws UnixException
{
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
return fgetxattr0(filedes, buffer.address(), valueAddress, valueLen);
} finally {
buffer.release();
}
}
private static native int fgetxattr0(int filedes, long nameAddress,
long valueAddress, int valueLen) throws UnixException;
/**
* fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags);
*/
static void fsetxattr(int filedes, byte[] name, long valueAddress,
int valueLen) throws UnixException
{
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
fsetxattr0(filedes, buffer.address(), valueAddress, valueLen);
} finally {
buffer.release();
}
}
private static native void fsetxattr0(int filedes, long nameAddress,
long valueAddress, int valueLen) throws UnixException;
/**
* fremovexattr(int filedes, const char *name);
*/
static void fremovexattr(int filedes, byte[] name) throws UnixException {
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
fremovexattr0(filedes, buffer.address());
} finally {
buffer.release();
}
}
private static native void fremovexattr0(int filedes, long nameAddress)
throws UnixException;
/**
* size_t flistxattr(int filedes, const char *list, size_t size)
*/
static native int flistxattr(int filedes, long listAddress, int size)
throws UnixException;
// initialize
private static native void init();

View File

@@ -25,351 +25,17 @@
package sun.nio.fs;
import java.nio.file.*;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.*;
import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixConstants.*;
import static sun.nio.fs.LinuxNativeDispatcher.*;
/**
* Linux implementation of UserDefinedFileAttributeView using extended attributes.
*/
class LinuxUserDefinedFileAttributeView
extends AbstractUserDefinedFileAttributeView
extends UnixUserDefinedFileAttributeView
{
private static final Unsafe unsafe = Unsafe.getUnsafe();
// namespace for extended user attributes
private static final String USER_NAMESPACE = "user.";
// maximum bytes in extended attribute name (includes namespace)
private static final int XATTR_NAME_MAX = 255;
private byte[] nameAsBytes(UnixPath file, String name) throws IOException {
if (name == null)
throw new NullPointerException("'name' is null");
name = USER_NAMESPACE + name;
byte[] bytes = Util.toBytes(name);
if (bytes.length > XATTR_NAME_MAX) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "'" + name + "' is too big");
}
return bytes;
}
// Parses buffer as array of NULL-terminated C strings.
private List<String> asList(long address, int size) {
List<String> list = new ArrayList<>();
int start = 0;
int pos = 0;
while (pos < size) {
if (unsafe.getByte(address + pos) == 0) {
int len = pos - start;
byte[] value = new byte[len];
unsafe.copyMemory(null, address+start, value,
Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
String s = Util.toString(value);
if (s.startsWith(USER_NAMESPACE)) {
s = s.substring(USER_NAMESPACE.length());
list.add(s);
}
start = pos + 1;
}
pos++;
}
return list;
}
private final UnixPath file;
private final boolean followLinks;
LinuxUserDefinedFileAttributeView(UnixPath file, boolean followLinks) {
this.file = file;
this.followLinks = followLinks;
super(file, followLinks);
}
@Override
public List<String> list() throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
NativeBuffer buffer = null;
try {
int size = 1024;
buffer = NativeBuffers.getNativeBuffer(size);
for (;;) {
try {
int n = flistxattr(fd, buffer.address(), size);
List<String> list = asList(buffer.address(), n);
return Collections.unmodifiableList(list);
} catch (UnixException x) {
// allocate larger buffer if required
if (x.errno() == ERANGE && size < 32*1024) {
buffer.release();
size *= 2;
buffer = null;
buffer = NativeBuffers.getNativeBuffer(size);
continue;
}
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to get list of extended attributes: " +
x.getMessage());
}
}
} finally {
if (buffer != null)
buffer.release();
close(fd);
}
protected int maxNameLength() {
return 255;
}
@Override
public int size(String name) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
// fgetxattr returns size if called with size==0
return fgetxattr(fd, nameAsBytes(file,name), 0L, 0);
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to get size of extended attribute '" + name +
"': " + x.getMessage());
} finally {
close(fd);
}
}
@Override
public int read(String name, ByteBuffer dst) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
if (dst.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
int pos = dst.position();
int lim = dst.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
NativeBuffer nb;
long address;
if (dst instanceof sun.nio.ch.DirectBuffer) {
nb = null;
address = ((sun.nio.ch.DirectBuffer)dst).address() + pos;
} else {
// substitute with native buffer
nb = NativeBuffers.getNativeBuffer(rem);
address = nb.address();
}
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
try {
int n = fgetxattr(fd, nameAsBytes(file,name), address, rem);
// if remaining is zero then fgetxattr returns the size
if (rem == 0) {
if (n > 0)
throw new UnixException(ERANGE);
return 0;
}
// copy from buffer into backing array if necessary
if (nb != null) {
int off = dst.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
unsafe.copyMemory(null, address, dst.array(), off, n);
}
dst.position(pos + n);
return n;
} catch (UnixException x) {
String msg = (x.errno() == ERANGE) ?
"Insufficient space in buffer" : x.getMessage();
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Error reading extended attribute '" + name + "': " + msg);
} finally {
close(fd);
}
} finally {
if (nb != null)
nb.release();
}
}
@Override
public int write(String name, ByteBuffer src) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), false, true);
int pos = src.position();
int lim = src.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
NativeBuffer nb;
long address;
if (src instanceof sun.nio.ch.DirectBuffer) {
nb = null;
address = ((sun.nio.ch.DirectBuffer)src).address() + pos;
} else {
// substitute with native buffer
nb = NativeBuffers.getNativeBuffer(rem);
address = nb.address();
if (src.hasArray()) {
// copy from backing array into buffer
int off = src.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
unsafe.copyMemory(src.array(), off, null, address, rem);
} else {
// backing array not accessible so transfer via temporary array
byte[] tmp = new byte[rem];
src.get(tmp);
src.position(pos); // reset position as write may fail
unsafe.copyMemory(tmp, Unsafe.ARRAY_BYTE_BASE_OFFSET, null,
address, rem);
}
}
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
try {
fsetxattr(fd, nameAsBytes(file,name), address, rem);
src.position(pos + rem);
return rem;
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Error writing extended attribute '" + name + "': " +
x.getMessage());
} finally {
close(fd);
}
} finally {
if (nb != null)
nb.release();
}
}
@Override
public void delete(String name) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), false, true);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
fremovexattr(fd, nameAsBytes(file,name));
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to delete extended attribute '" + name + "': " + x.getMessage());
} finally {
close(fd);
}
}
/**
* Used by copyTo/moveTo to copy extended attributes from source to target.
*
* @param ofd
* file descriptor for source file
* @param nfd
* file descriptor for target file
*/
static void copyExtendedAttributes(int ofd, int nfd) {
NativeBuffer buffer = null;
try {
// call flistxattr to get list of extended attributes.
int size = 1024;
buffer = NativeBuffers.getNativeBuffer(size);
for (;;) {
try {
size = flistxattr(ofd, buffer.address(), size);
break;
} catch (UnixException x) {
// allocate larger buffer if required
if (x.errno() == ERANGE && size < 32*1024) {
buffer.release();
size *= 2;
buffer = null;
buffer = NativeBuffers.getNativeBuffer(size);
continue;
}
// unable to get list of attributes
return;
}
}
// parse buffer as array of NULL-terminated C strings.
long address = buffer.address();
int start = 0;
int pos = 0;
while (pos < size) {
if (unsafe.getByte(address + pos) == 0) {
// extract attribute name and copy attribute to target.
// FIXME: We can avoid needless copying by using address+pos
// as the address of the name.
int len = pos - start;
byte[] name = new byte[len];
unsafe.copyMemory(null, address+start, name,
Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
try {
copyExtendedAttribute(ofd, name, nfd);
} catch (UnixException ignore) {
// ignore
}
start = pos + 1;
}
pos++;
}
} finally {
if (buffer != null)
buffer.release();
}
}
private static void copyExtendedAttribute(int ofd, byte[] name, int nfd)
throws UnixException
{
int size = fgetxattr(ofd, name, 0L, 0);
NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
try {
long address = buffer.address();
size = fgetxattr(ofd, name, address, size);
fsetxattr(nfd, name, address, size);
} finally {
buffer.release();
}
}
}

View File

@@ -36,16 +36,6 @@
#include "sun_nio_fs_LinuxNativeDispatcher.h"
typedef size_t fgetxattr_func(int fd, const char* name, void* value, size_t size);
typedef int fsetxattr_func(int fd, const char* name, void* value, size_t size, int flags);
typedef int fremovexattr_func(int fd, const char* name);
typedef int flistxattr_func(int fd, char* list, size_t size);
fgetxattr_func* my_fgetxattr_func = NULL;
fsetxattr_func* my_fsetxattr_func = NULL;
fremovexattr_func* my_fremovexattr_func = NULL;
flistxattr_func* my_flistxattr_func = NULL;
static jfieldID entry_name;
static jfieldID entry_dir;
static jfieldID entry_fstype;
@@ -62,11 +52,6 @@ static void throwUnixException(JNIEnv* env, int errnum) {
JNIEXPORT void JNICALL
Java_sun_nio_fs_LinuxNativeDispatcher_init(JNIEnv *env, jclass clazz)
{
my_fgetxattr_func = (fgetxattr_func*)dlsym(RTLD_DEFAULT, "fgetxattr");
my_fsetxattr_func = (fsetxattr_func*)dlsym(RTLD_DEFAULT, "fsetxattr");
my_fremovexattr_func = (fremovexattr_func*)dlsym(RTLD_DEFAULT, "fremovexattr");
my_flistxattr_func = (flistxattr_func*)dlsym(RTLD_DEFAULT, "flistxattr");
clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
CHECK_NULL(clazz);
entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
@@ -79,78 +64,6 @@ Java_sun_nio_fs_LinuxNativeDispatcher_init(JNIEnv *env, jclass clazz)
CHECK_NULL(entry_options);
}
JNIEXPORT jint JNICALL
Java_sun_nio_fs_LinuxNativeDispatcher_fgetxattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
{
size_t res = -1;
const char* name = jlong_to_ptr(nameAddress);
void* value = jlong_to_ptr(valueAddress);
if (my_fgetxattr_func == NULL) {
errno = ENOTSUP;
} else {
/* EINTR not documented */
res = (*my_fgetxattr_func)(fd, name, value, valueLen);
}
if (res == (size_t)-1)
throwUnixException(env, errno);
return (jint)res;
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_LinuxNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
{
int res = -1;
const char* name = jlong_to_ptr(nameAddress);
void* value = jlong_to_ptr(valueAddress);
if (my_fsetxattr_func == NULL) {
errno = ENOTSUP;
} else {
/* EINTR not documented */
res = (*my_fsetxattr_func)(fd, name, value, valueLen, 0);
}
if (res == -1)
throwUnixException(env, errno);
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_LinuxNativeDispatcher_fremovexattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress)
{
int res = -1;
const char* name = jlong_to_ptr(nameAddress);
if (my_fremovexattr_func == NULL) {
errno = ENOTSUP;
} else {
/* EINTR not documented */
res = (*my_fremovexattr_func)(fd, name);
}
if (res == -1)
throwUnixException(env, errno);
}
JNIEXPORT jint JNICALL
Java_sun_nio_fs_LinuxNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz,
jint fd, jlong listAddress, jint size)
{
size_t res = -1;
char* list = jlong_to_ptr(listAddress);
if (my_flistxattr_func == NULL) {
errno = ENOTSUP;
} else {
/* EINTR not documented */
res = (*my_flistxattr_func)(fd, list, (size_t)size);
}
if (res == (size_t)-1)
throwUnixException(env, errno);
return (jint)res;
}
JNIEXPORT jlong JNICALL
Java_sun_nio_fs_LinuxNativeDispatcher_setmntent0(JNIEnv* env, jclass this, jlong pathAddress,
jlong modeAddress)

View File

@@ -80,27 +80,6 @@ class BsdFileStore
throw new IOException("Mount point not found in fstab");
}
// returns true if extended attributes enabled on file system where given
// file resides, returns false if disabled or unable to determine.
private boolean isExtendedAttributesEnabled(UnixPath path) {
int fd = -1;
try {
fd = path.openForAttributeAccess(false);
// fgetxattr returns size if called with size==0
byte[] name = Util.toBytes("user.java");
BsdNativeDispatcher.fgetxattr(fd, name, 0L, 0);
return true;
} catch (UnixException e) {
// attribute does not exist
if (e.errno() == UnixConstants.ENOATTR)
return true;
} finally {
UnixNativeDispatcher.close(fd);
}
return false;
}
@Override
public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
// support UserDefinedAttributeView if extended attributes enabled

View File

@@ -69,6 +69,7 @@ class BsdFileSystem extends UnixFileSystem {
@Override
void copyNonPosixAttributes(int ofd, int nfd) {
UnixUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd);
}
/**

View File

@@ -62,67 +62,6 @@ class BsdNativeDispatcher extends UnixNativeDispatcher {
}
static native byte[] getmntonname0(long pathAddress) throws UnixException;
/**
* ssize_t fgetxattr(int fd, const char *name, void *value, size_t size,
* u_int32_t position, int options);
*/
static int fgetxattr(int fd, byte[] name, long valueAddress,
int valueLen) throws UnixException
{
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
return fgetxattr0(fd, buffer.address(), valueAddress, valueLen, 0L, 0);
} finally {
buffer.release();
}
}
private static native int fgetxattr0(int fd, long nameAddress,
long valueAddress, int valueLen, long position, int options) throws UnixException;
/**
* int fsetxattr(int fd, const char *name, void *value, size_t size,
* u_int32_t position, int options);
*/
static void fsetxattr(int fd, byte[] name, long valueAddress,
int valueLen) throws UnixException
{
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
fsetxattr0(fd, buffer.address(), valueAddress, valueLen, 0L, 0);
} finally {
buffer.release();
}
}
private static native void fsetxattr0(int fd, long nameAddress,
long valueAddress, int valueLen, long position, int options) throws UnixException;
/**
* int fremovexattr(int fd, const char *name, int options);
*/
static void fremovexattr(int fd, byte[] name) throws UnixException {
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
fremovexattr0(fd, buffer.address(), 0);
} finally {
buffer.release();
}
}
private static native void fremovexattr0(int fd, long nameAddress, int options)
throws UnixException;
/**
* ssize_t flistxattr(int fd, char *namebuf, size_t size, int options);
*/
static int flistxattr(int fd, long nameBufAddress, int size) throws UnixException {
return flistxattr0(fd, nameBufAddress, size, 0);
}
private static native int flistxattr0(int fd, long nameBufAddress, int size,
int options) throws UnixException;
// initialize field IDs
private static native void initIDs();

View File

@@ -25,352 +25,18 @@
package sun.nio.fs;
import java.nio.file.*;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.*;
import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixConstants.*;
import static sun.nio.fs.BsdNativeDispatcher.*;
/**
* BSD implementation of UserDefinedFileAttributeView using extended attributes.
*/
class BsdUserDefinedFileAttributeView
extends AbstractUserDefinedFileAttributeView
extends UnixUserDefinedFileAttributeView
{
private static final Unsafe unsafe = Unsafe.getUnsafe();
// namespace for extended user attributes
private static final String USER_NAMESPACE = "user.";
// maximum bytes in extended attribute name (includes namespace),
// see XATTR_MAXNAMELEN in https://github.com/apple/darwin-xnu/blob/master/bsd/sys/xattr.h
private static final int XATTR_NAME_MAX = 127;
private byte[] nameAsBytes(UnixPath file, String name) throws IOException {
if (name == null)
throw new NullPointerException("'name' is null");
name = USER_NAMESPACE + name;
byte[] bytes = Util.toBytes(name);
if (bytes.length > XATTR_NAME_MAX) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "'" + name + "' is too big");
}
return bytes;
}
// Parses buffer as array of NULL-terminated C strings.
private List<String> asList(long address, int size) {
List<String> list = new ArrayList<>();
int start = 0;
int pos = 0;
while (pos < size) {
if (unsafe.getByte(address + pos) == 0) {
int len = pos - start;
byte[] value = new byte[len];
unsafe.copyMemory(null, address+start, value,
Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
String s = Util.toString(value);
if (s.startsWith(USER_NAMESPACE)) {
s = s.substring(USER_NAMESPACE.length());
list.add(s);
}
start = pos + 1;
}
pos++;
}
return list;
}
private final UnixPath file;
private final boolean followLinks;
BsdUserDefinedFileAttributeView(UnixPath file, boolean followLinks) {
this.file = file;
this.followLinks = followLinks;
super(file, followLinks);
}
@Override
public List<String> list() throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
NativeBuffer buffer = null;
try {
int size = 1024;
buffer = NativeBuffers.getNativeBuffer(size);
for (;;) {
try {
int n = flistxattr(fd, buffer.address(), size);
List<String> list = asList(buffer.address(), n);
return Collections.unmodifiableList(list);
} catch (UnixException x) {
// allocate larger buffer if required
if (x.errno() == ERANGE && size < 32*1024) {
buffer.release();
size *= 2;
buffer = null;
buffer = NativeBuffers.getNativeBuffer(size);
continue;
}
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to get list of extended attributes: " +
x.getMessage());
}
}
} finally {
if (buffer != null)
buffer.release();
close(fd);
}
protected int maxNameLength() {
// see XATTR_MAXNAMELEN in https://github.com/apple/darwin-xnu/blob/master/bsd/sys/xattr.h
return 127;
}
@Override
public int size(String name) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
// fgetxattr returns size if called with size==0
return fgetxattr(fd, nameAsBytes(file,name), 0L, 0);
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to get size of extended attribute '" + name +
"': " + x.getMessage());
} finally {
close(fd);
}
}
@Override
public int read(String name, ByteBuffer dst) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
if (dst.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
int pos = dst.position();
int lim = dst.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
NativeBuffer nb;
long address;
if (dst instanceof sun.nio.ch.DirectBuffer) {
nb = null;
address = ((sun.nio.ch.DirectBuffer)dst).address() + pos;
} else {
// substitute with native buffer
nb = NativeBuffers.getNativeBuffer(rem);
address = nb.address();
}
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
try {
int n = fgetxattr(fd, nameAsBytes(file,name), address, rem);
// if remaining is zero then fgetxattr returns the size
if (rem == 0) {
if (n > 0)
throw new UnixException(ERANGE);
return 0;
}
// copy from buffer into backing array if necessary
if (nb != null) {
int off = dst.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
unsafe.copyMemory(null, address, dst.array(), off, n);
}
dst.position(pos + n);
return n;
} catch (UnixException x) {
String msg = (x.errno() == ERANGE) ?
"Insufficient space in buffer" : x.getMessage();
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Error reading extended attribute '" + name + "': " + msg);
} finally {
close(fd);
}
} finally {
if (nb != null)
nb.release();
}
}
@Override
public int write(String name, ByteBuffer src) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), false, true);
int pos = src.position();
int lim = src.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
NativeBuffer nb;
long address;
if (src instanceof sun.nio.ch.DirectBuffer) {
nb = null;
address = ((sun.nio.ch.DirectBuffer)src).address() + pos;
} else {
// substitute with native buffer
nb = NativeBuffers.getNativeBuffer(rem);
address = nb.address();
if (src.hasArray()) {
// copy from backing array into buffer
int off = src.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
unsafe.copyMemory(src.array(), off, null, address, rem);
} else {
// backing array not accessible so transfer via temporary array
byte[] tmp = new byte[rem];
src.get(tmp);
src.position(pos); // reset position as write may fail
unsafe.copyMemory(tmp, Unsafe.ARRAY_BYTE_BASE_OFFSET, null,
address, rem);
}
}
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
try {
fsetxattr(fd, nameAsBytes(file,name), address, rem);
src.position(pos + rem);
return rem;
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Error writing extended attribute '" + name + "': " +
x.getMessage());
} finally {
close(fd);
}
} finally {
if (nb != null)
nb.release();
}
}
@Override
public void delete(String name) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), false, true);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
fremovexattr(fd, nameAsBytes(file,name));
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to delete extended attribute '" + name + "': " + x.getMessage());
} finally {
close(fd);
}
}
/**
* Used by copyTo/moveTo to copy extended attributes from source to target.
*
* @param ofd
* file descriptor for source file
* @param nfd
* file descriptor for target file
*/
static void copyExtendedAttributes(int ofd, int nfd) {
NativeBuffer buffer = null;
try {
// call flistxattr to get list of extended attributes.
int size = 1024;
buffer = NativeBuffers.getNativeBuffer(size);
for (;;) {
try {
size = flistxattr(ofd, buffer.address(), size);
break;
} catch (UnixException x) {
// allocate larger buffer if required
if (x.errno() == ERANGE && size < 32*1024) {
buffer.release();
size *= 2;
buffer = null;
buffer = NativeBuffers.getNativeBuffer(size);
continue;
}
// unable to get list of attributes
return;
}
}
// parse buffer as array of NULL-terminated C strings.
long address = buffer.address();
int start = 0;
int pos = 0;
while (pos < size) {
if (unsafe.getByte(address + pos) == 0) {
// extract attribute name and copy attribute to target.
// FIXME: We can avoid needless copying by using address+pos
// as the address of the name.
int len = pos - start;
byte[] name = new byte[len];
unsafe.copyMemory(null, address+start, name,
Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
try {
copyExtendedAttribute(ofd, name, nfd);
} catch (UnixException ignore) {
// ignore
}
start = pos + 1;
}
pos++;
}
} finally {
if (buffer != null)
buffer.release();
}
}
private static void copyExtendedAttribute(int ofd, byte[] name, int nfd)
throws UnixException
{
int size = fgetxattr(ofd, name, 0L, 0);
NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
try {
long address = buffer.address();
size = fgetxattr(ofd, name, address, size);
fsetxattr(nfd, name, address, size);
} finally {
buffer.release();
}
}
}

View File

@@ -30,7 +30,6 @@
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/xattr.h>
#ifdef ST_RDONLY
#define statfs statvfs
#define getfsstat getvfsstat
@@ -225,52 +224,3 @@ Java_sun_nio_fs_BsdNativeDispatcher_getmntonname0(JNIEnv *env, jclass this,
return mntonname;
}
JNIEXPORT jint JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_fgetxattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress, jlong valueAddress, jint valueLen, jlong position, jint options)
{
const char* name = jlong_to_ptr(nameAddress);
void* value = jlong_to_ptr(valueAddress);
ssize_t res = fgetxattr(fd, name, value, valueLen, (u_int32_t)position, options);
if (res == (ssize_t)-1)
throwUnixException(env, errno);
return (jint)res;
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress, jlong valueAddress, jint valueLen, jlong position, jint options)
{
const char* name = jlong_to_ptr(nameAddress);
void* value = jlong_to_ptr(valueAddress);
int res = fsetxattr(fd, name, value, valueLen, (u_int32_t)position, options);
if (res == -1)
throwUnixException(env, errno);
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_fremovexattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress, jint options)
{
const char* name = jlong_to_ptr(nameAddress);
int res = fremovexattr(fd, name, options);
if (res == -1)
throwUnixException(env, errno);
}
JNIEXPORT jint JNICALL
Java_sun_nio_fs_BsdNativeDispatcher_flistxattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameBufAddress, jint size, jint options)
{
char* nameBuf = jlong_to_ptr(nameBufAddress);
ssize_t res = flistxattr(fd, nameBuf, (size_t)size, options);
if (res == (ssize_t)-1)
throwUnixException(env, errno);
return (jint)res;
}

View File

@@ -39,7 +39,14 @@ public class HttpRetryException extends IOException {
@java.io.Serial
private static final long serialVersionUID = -9186022286469111381L;
/**
* The response code.
*/
private int responseCode;
/**
* The URL to be redirected to.
*/
private String location;
/**

View File

@@ -557,11 +557,15 @@ class Inet6Address extends InetAddress {
}
/**
* @serialField ipaddress byte[]
* @serialField scope_id int
* @serialField scope_id_set boolean
* @serialField scope_ifname_set boolean
* @serialField ifname String
* @serialField ipaddress byte[] holds a 128-bit (16 bytes) IPv6 address
* @serialField scope_id int the address scope id. {@code 0} if undefined
* @serialField scope_id_set boolean {@code true} when the scope_id field
* contains a valid integer scope_id
* @serialField scope_ifname_set boolean {@code true} if the object is
* constructed with a scoped interface instead of a numeric
* scope id
* @serialField ifname String the name of the scoped network interface.
* {@code null} if undefined
*/
@java.io.Serial
private static final ObjectStreamField[] serialPersistentFields = {
@@ -578,9 +582,13 @@ class Inet6Address extends InetAddress {
Inet6Address.class, "holder6");
/**
* restore the state of this object from stream
* including the scope information, only if the
* scoped interface name is valid on this system
* Restores the state of this object from the stream.
* This includes the scope information, but only if the
* scoped interface name is valid on this system.
*
* @param s the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject(ObjectInputStream s)
@@ -642,9 +650,12 @@ class Inet6Address extends InetAddress {
}
/**
* default behavior is overridden in order to write the
* scope_ifname field as a String, rather than a NetworkInterface
* which is not serializable
* The default behavior of this method is overridden in order to
* write the scope_ifname field as a {@code String}, rather than a
* {@code NetworkInterface} which is not serializable.
*
* @param s the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
*/
@java.io.Serial
private synchronized void writeObject(ObjectOutputStream s)

View File

@@ -1712,6 +1712,9 @@ public class InetAddress implements java.io.Serializable {
return (InetAddressImpl) impl;
}
/**
* Initializes an empty InetAddress.
*/
@java.io.Serial
private void readObjectNoData () {
if (getClass().getClassLoader() != null) {
@@ -1724,6 +1727,13 @@ public class InetAddress implements java.io.Serializable {
private static final long FIELDS_OFFSET
= UNSAFE.objectFieldOffset(InetAddress.class, "holder");
/**
* Restores the state of this object from the stream.
*
* @param s the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject (ObjectInputStream s) throws
IOException, ClassNotFoundException {
@@ -1744,9 +1754,10 @@ public class InetAddress implements java.io.Serializable {
/* needed because the serializable fields no longer exist */
/**
* @serialField hostName String
* @serialField address int
* @serialField family int
* @serialField hostName String the hostname for this address
* @serialField address int holds a 32-bit IPv4 address.
* @serialField family int specifies the address family type, for instance,
* {@code '1'} for IPv4 addresses, and {@code '2'} for IPv6 addresses.
*/
@java.io.Serial
private static final ObjectStreamField[] serialPersistentFields = {
@@ -1755,6 +1766,12 @@ public class InetAddress implements java.io.Serializable {
new ObjectStreamField("family", int.class),
};
/**
* Writes the state of this object to the stream.
*
* @param s the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
*/
@java.io.Serial
private void writeObject (ObjectOutputStream s) throws
IOException {

View File

@@ -264,9 +264,9 @@ public class InetSocketAddress
}
/**
* @serialField hostname String
* @serialField addr InetAddress
* @serialField port int
* @serialField hostname String the hostname of the Socket Address
* @serialField addr InetAddress the IP address of the Socket Address
* @serialField port int the port number of the Socket Address
*/
@java.io.Serial
private static final ObjectStreamField[] serialPersistentFields = {
@@ -274,6 +274,12 @@ public class InetSocketAddress
new ObjectStreamField("addr", InetAddress.class),
new ObjectStreamField("port", int.class)};
/**
* Writes the state of this object to the stream.
*
* @param out the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
*/
@java.io.Serial
private void writeObject(ObjectOutputStream out)
throws IOException
@@ -286,6 +292,13 @@ public class InetSocketAddress
out.writeFields();
}
/**
* Restores the state of this object from the stream.
*
* @param in the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
@@ -308,6 +321,10 @@ public class InetSocketAddress
UNSAFE.putReference(this, FIELDS_OFFSET, h);
}
/**
* Throws {@code InvalidObjectException}, always.
* @throws ObjectStreamException always
*/
@java.io.Serial
private void readObjectNoData()
throws ObjectStreamException

View File

@@ -1189,9 +1189,12 @@ public final class SocketPermission extends Permission
}
/**
* WriteObject is called to save the state of the SocketPermission
* to a stream. The actions are serialized, and the superclass
* takes care of the name.
* {@code writeObject} is called to save the state of the
* {@code SocketPermission} to a stream. The actions are serialized,
* and the superclass takes care of the name.
*
* @param s the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
*/
@java.io.Serial
private synchronized void writeObject(java.io.ObjectOutputStream s)
@@ -1205,8 +1208,12 @@ public final class SocketPermission extends Permission
}
/**
* readObject is called to restore the state of the SocketPermission from
* a stream.
* {@code readObject} is called to restore the state of the
* {@code SocketPermission} from a stream.
*
* @param s the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private synchronized void readObject(java.io.ObjectInputStream s)
@@ -1488,7 +1495,11 @@ final class SocketPermissionCollection extends PermissionCollection
};
/**
* Writes the state of this object to the stream.
* @serialData "permissions" field (a Vector containing the SocketPermissions).
*
* @param out the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
*/
/*
* Writes the contents of the perms field out as a Vector for
@@ -1506,8 +1517,13 @@ final class SocketPermissionCollection extends PermissionCollection
out.writeFields();
}
/*
* Reads in a Vector of SocketPermissions and saves them in the perms field.
/**
* Reads in a {@code Vector} of {@code SocketPermission} and saves
* them in the perms field.
*
* @param in the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject(ObjectInputStream in)

View File

@@ -1777,6 +1777,9 @@ public final class URI
*
* @param os The object-output stream to which this object
* is to be written
*
* @throws IOException
* If an I/O error occurs
*/
@java.io.Serial
private void writeObject(ObjectOutputStream os)
@@ -1795,6 +1798,12 @@ public final class URI
*
* @param is The object-input stream from which this object
* is being read
*
* @throws IOException
* If an I/O error occurs
*
* @throws ClassNotFoundException
* If a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject(ObjectInputStream is)

View File

@@ -41,7 +41,15 @@ public class URISyntaxException
@java.io.Serial
private static final long serialVersionUID = 2137979680897488891L;
/**
* The input string.
*/
private String input;
/**
* The index at which the parse error occurred,
* or {@code -1} if the index is not known.
*/
private int index;
/**

View File

@@ -1481,19 +1481,20 @@ public final class URL implements java.io.Serializable {
}
/**
* @serialField protocol String
* @serialField protocol String the protocol to use (ftp, http, nntp, ... etc.)
*
* @serialField host String
* @serialField host String the host name to connect to
*
* @serialField port int
* @serialField port int the protocol port to connect to
*
* @serialField authority String
* @serialField authority String the authority part of this URL
*
* @serialField file String
* @serialField file String the specified file name on that host. {@code file} is
* defined as {@code path[?query]}
*
* @serialField ref String
* @serialField ref String the fragment part of this URL
*
* @serialField hashCode int
* @serialField hashCode int the hashCode of this URL
*
*/
@java.io.Serial
@@ -1515,6 +1516,9 @@ public final class URL implements java.io.Serializable {
* the reader must ensure that calling getURLStreamHandler with
* the protocol variable returns a valid URLStreamHandler and
* throw an IOException if it does not.
*
* @param s the {@code ObjectOutputStream} to which data is written
* @throws IOException if an I/O error occurs
*/
@java.io.Serial
private synchronized void writeObject(java.io.ObjectOutputStream s)
@@ -1527,6 +1531,10 @@ public final class URL implements java.io.Serializable {
* readObject is called to restore the state of the URL from the
* stream. It reads the components of the URL and finds the local
* stream handler.
*
* @param s the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private synchronized void readObject(java.io.ObjectInputStream s)

View File

@@ -162,6 +162,9 @@ public final class URLPermission extends Permission {
private transient Authority authority;
// serialized field
/**
* The actions string
*/
private String actions;
/**
@@ -504,7 +507,11 @@ public final class URLPermission extends Permission {
}
/**
* restore the state of this object from stream
* Restores the state of this object from stream.
*
* @param s the {@code ObjectInputStream} from which data is read
* @throws IOException if an I/O error occurs
* @throws ClassNotFoundException if a serialized class cannot be loaded
*/
@java.io.Serial
private void readObject(ObjectInputStream s)

View File

@@ -93,8 +93,9 @@ public final class UnixDomainSocketAddress extends SocketAddress {
* <a href="{@docRoot}/serialized-form.html#java.net.UnixDomainSocketAddress.Ser">
* Ser</a> containing the path name of this instance.
*
* @return a {@link Ser}
* representing the path name of this instance
* @return a {@link Ser} representing the path name of this instance
*
* @throws ObjectStreamException if an error occurs
*/
@java.io.Serial
private Object writeReplace() throws ObjectStreamException {

View File

@@ -33,7 +33,7 @@ import jdk.internal.ref.CleanerFactory;
* A light-weight buffer in native memory.
*/
class NativeBuffer {
class NativeBuffer implements AutoCloseable {
private static final Unsafe unsafe = Unsafe.getUnsafe();
private final long address;
@@ -61,6 +61,11 @@ class NativeBuffer {
.register(this, new Deallocator(address));
}
@Override
public void close() {
release();
}
void release() {
NativeBuffers.releaseNativeBuffer(this);
}

View File

@@ -117,9 +117,14 @@ class UnixConstants {
static final int PREFIX_ENODATA = ENODATA;
#endif
#ifdef ENOATTR
// BSD uses ENOATTR instead of ENODATA during xattr calls
static final int PREFIX_ENOATTR = ENOATTR;
// fgetxattr error codes for absent attributes depend on the OS:
#ifdef _ALLBSD_SOURCE
static final int PREFIX_XATTR_NOT_FOUND = ENOATTR;
#elif __linux__
static final int PREFIX_XATTR_NOT_FOUND = ENODATA;
#else
// not supported (dummy values will not be used at runtime).
static final int PREFIX_XATTR_NOT_FOUND = 00;
#endif
static final int PREFIX_ERANGE = ERANGE;

View File

@@ -172,6 +172,31 @@ abstract class UnixFileStore
throw new UnsupportedOperationException("'" + attribute + "' not recognized");
}
/**
* Checks whether extended attributes are enabled on the file system where the given file resides.
*
* @param path A path pointing to an existing node, such as the file system's root
* @return <code>true</code> if enabled, <code>false</code> if disabled or unable to determine
*/
protected boolean isExtendedAttributesEnabled(UnixPath path) {
int fd = -1;
try {
fd = path.openForAttributeAccess(false);
// fgetxattr returns size if called with size==0
byte[] name = Util.toBytes("user.java");
UnixNativeDispatcher.fgetxattr(fd, name, 0L, 0);
return true;
} catch (UnixException e) {
// attribute does not exist
if (e.errno() == UnixConstants.XATTR_NOT_FOUND)
return true;
} finally {
UnixNativeDispatcher.close(fd);
}
return false;
}
@Override
public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
if (type == null)

View File

@@ -563,6 +563,52 @@ class UnixNativeDispatcher {
*/
static native byte[] strerror(int errnum);
/**
* ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size);
*/
static int fgetxattr(int filedes, byte[] name, long valueAddress,
int valueLen) throws UnixException
{
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
return fgetxattr0(filedes, buffer.address(), valueAddress, valueLen);
}
}
private static native int fgetxattr0(int filedes, long nameAddress,
long valueAddress, int valueLen) throws UnixException;
/**
* fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags);
*/
static void fsetxattr(int filedes, byte[] name, long valueAddress,
int valueLen) throws UnixException
{
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
fsetxattr0(filedes, buffer.address(), valueAddress, valueLen);
}
}
private static native void fsetxattr0(int filedes, long nameAddress,
long valueAddress, int valueLen) throws UnixException;
/**
* fremovexattr(int filedes, const char *name);
*/
static void fremovexattr(int filedes, byte[] name) throws UnixException {
try (NativeBuffer buffer = NativeBuffers.asNativeBuffer(name)) {
fremovexattr0(filedes, buffer.address());
}
}
private static native void fremovexattr0(int filedes, long nameAddress)
throws UnixException;
/**
* size_t flistxattr(int filedes, const char *list, size_t size)
*/
static native int flistxattr(int filedes, long listAddress, int size)
throws UnixException;
/**
* Capabilities
*/

View File

@@ -0,0 +1,375 @@
/*
* Copyright (c) 2008, 2015, 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 sun.nio.fs;
import java.nio.file.*;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.*;
import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixConstants.*;
import static sun.nio.fs.UnixNativeDispatcher.*;
/**
* Unix implementation of UserDefinedFileAttributeView using extended attributes.
*/
abstract class UnixUserDefinedFileAttributeView
extends AbstractUserDefinedFileAttributeView
{
private static final Unsafe unsafe = Unsafe.getUnsafe();
// namespace for extended user attributes
private static final String USER_NAMESPACE = "user.";
private byte[] nameAsBytes(UnixPath file, String name) throws IOException {
if (name == null)
throw new NullPointerException("'name' is null");
name = USER_NAMESPACE + name;
byte[] bytes = Util.toBytes(name);
if (bytes.length > maxNameLength()) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "'" + name + "' is too big");
}
return bytes;
}
// Parses buffer as array of NULL-terminated C strings.
private List<String> asList(long address, int size) {
List<String> list = new ArrayList<>();
int start = 0;
int pos = 0;
while (pos < size) {
if (unsafe.getByte(address + pos) == 0) {
int len = pos - start;
byte[] value = new byte[len];
unsafe.copyMemory(null, address+start, value,
Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
String s = Util.toString(value);
if (s.startsWith(USER_NAMESPACE)) {
s = s.substring(USER_NAMESPACE.length());
list.add(s);
}
start = pos + 1;
}
pos++;
}
return list;
}
private final UnixPath file;
private final boolean followLinks;
UnixUserDefinedFileAttributeView(UnixPath file, boolean followLinks) {
this.file = file;
this.followLinks = followLinks;
}
/**
* @return the maximum supported length of xattr names (in bytes, including namespace)
*/
protected abstract int maxNameLength();
@Override
public List<String> list() throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
NativeBuffer buffer = null;
try {
int size = 1024;
buffer = NativeBuffers.getNativeBuffer(size);
for (;;) {
try {
int n = flistxattr(fd, buffer.address(), size);
List<String> list = asList(buffer.address(), n);
return Collections.unmodifiableList(list);
} catch (UnixException x) {
// allocate larger buffer if required
if (x.errno() == ERANGE && size < 32*1024) {
buffer.release();
size *= 2;
buffer = null;
buffer = NativeBuffers.getNativeBuffer(size);
continue;
}
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to get list of extended attributes: " +
x.getMessage());
}
}
} finally {
if (buffer != null)
buffer.release();
close(fd);
}
}
@Override
public int size(String name) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
// fgetxattr returns size if called with size==0
return fgetxattr(fd, nameAsBytes(file,name), 0L, 0);
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to get size of extended attribute '" + name +
"': " + x.getMessage());
} finally {
close(fd);
}
}
@Override
public int read(String name, ByteBuffer dst) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), true, false);
if (dst.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
int pos = dst.position();
int lim = dst.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
NativeBuffer nb;
long address;
if (dst instanceof sun.nio.ch.DirectBuffer) {
nb = null;
address = ((sun.nio.ch.DirectBuffer)dst).address() + pos;
} else {
// substitute with native buffer
nb = NativeBuffers.getNativeBuffer(rem);
address = nb.address();
}
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
try {
int n = fgetxattr(fd, nameAsBytes(file,name), address, rem);
// if remaining is zero then fgetxattr returns the size
if (rem == 0) {
if (n > 0)
throw new UnixException(ERANGE);
return 0;
}
// copy from buffer into backing array if necessary
if (nb != null) {
int off = dst.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
unsafe.copyMemory(null, address, dst.array(), off, n);
}
dst.position(pos + n);
return n;
} catch (UnixException x) {
String msg = (x.errno() == ERANGE) ?
"Insufficient space in buffer" : x.getMessage();
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Error reading extended attribute '" + name + "': " + msg);
} finally {
close(fd);
}
} finally {
if (nb != null)
nb.release();
}
}
public int write(String name, ByteBuffer src) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), false, true);
int pos = src.position();
int lim = src.limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
NativeBuffer nb;
long address;
if (src instanceof sun.nio.ch.DirectBuffer) {
nb = null;
address = ((sun.nio.ch.DirectBuffer)src).address() + pos;
} else {
// substitute with native buffer
nb = NativeBuffers.getNativeBuffer(rem);
address = nb.address();
if (src.hasArray()) {
// copy from backing array into buffer
int off = src.arrayOffset() + pos + Unsafe.ARRAY_BYTE_BASE_OFFSET;
unsafe.copyMemory(src.array(), off, null, address, rem);
} else {
// backing array not accessible so transfer via temporary array
byte[] tmp = new byte[rem];
src.get(tmp);
src.position(pos); // reset position as write may fail
unsafe.copyMemory(tmp, Unsafe.ARRAY_BYTE_BASE_OFFSET, null,
address, rem);
}
}
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
try {
fsetxattr(fd, nameAsBytes(file,name), address, rem);
src.position(pos + rem);
return rem;
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Error writing extended attribute '" + name + "': " +
x.getMessage());
} finally {
close(fd);
}
} finally {
if (nb != null)
nb.release();
}
}
@Override
public void delete(String name) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), false, true);
int fd = -1;
try {
fd = file.openForAttributeAccess(followLinks);
} catch (UnixException x) {
x.rethrowAsIOException(file);
}
try {
fremovexattr(fd, nameAsBytes(file,name));
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to delete extended attribute '" + name + "': " + x.getMessage());
} finally {
close(fd);
}
}
/**
* Used by copyTo/moveTo to copy extended attributes from source to target.
*
* @param ofd
* file descriptor for source file
* @param nfd
* file descriptor for target file
*/
static void copyExtendedAttributes(int ofd, int nfd) {
NativeBuffer buffer = null;
try {
// call flistxattr to get list of extended attributes.
int size = 1024;
buffer = NativeBuffers.getNativeBuffer(size);
for (;;) {
try {
size = flistxattr(ofd, buffer.address(), size);
break;
} catch (UnixException x) {
// allocate larger buffer if required
if (x.errno() == ERANGE && size < 32*1024) {
buffer.release();
size *= 2;
buffer = null;
buffer = NativeBuffers.getNativeBuffer(size);
continue;
}
// unable to get list of attributes
return;
}
}
// parse buffer as array of NULL-terminated C strings.
long address = buffer.address();
int start = 0;
int pos = 0;
while (pos < size) {
if (unsafe.getByte(address + pos) == 0) {
// extract attribute name and copy attribute to target.
// FIXME: We can avoid needless copying by using address+pos
// as the address of the name.
int len = pos - start;
byte[] name = new byte[len];
unsafe.copyMemory(null, address+start, name,
Unsafe.ARRAY_BYTE_BASE_OFFSET, len);
try {
copyExtendedAttribute(ofd, name, nfd);
} catch (UnixException ignore) {
// ignore
}
start = pos + 1;
}
pos++;
}
} finally {
if (buffer != null)
buffer.release();
}
}
private static void copyExtendedAttribute(int ofd, byte[] name, int nfd)
throws UnixException
{
int size = fgetxattr(ofd, name, 0L, 0);
NativeBuffer buffer = NativeBuffers.getNativeBuffer(size);
try {
long address = buffer.address();
size = fgetxattr(ofd, name, address, size);
fsetxattr(nfd, name, address, size);
} finally {
buffer.release();
}
}
}

View File

@@ -41,6 +41,10 @@
#endif
#include <sys/time.h>
#if defined(__linux__) || defined(_ALLBSD_SOURCE)
#include <sys/xattr.h>
#endif
/* For POSIX-compliant getpwuid_r */
#include <pwd.h>
#include <grp.h>
@@ -1241,3 +1245,83 @@ Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0(JNIEnv* env, jclass this,
return gid;
}
JNIEXPORT jint JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_fgetxattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
{
size_t res = -1;
const char* name = jlong_to_ptr(nameAddress);
void* value = jlong_to_ptr(valueAddress);
#ifdef __linux__
res = fgetxattr(fd, name, value, valueLen);
#elif _ALLBSD_SOURCE
res = fgetxattr(fd, name, value, valueLen, 0, 0);
#else
throwUnixException(env, ENOTSUP);
#endif
if (res == (size_t)-1)
throwUnixException(env, errno);
return (jint)res;
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_fsetxattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress, jlong valueAddress, jint valueLen)
{
int res = -1;
const char* name = jlong_to_ptr(nameAddress);
void* value = jlong_to_ptr(valueAddress);
#ifdef __linux__
res = fsetxattr(fd, name, value, valueLen, 0);
#elif _ALLBSD_SOURCE
res = fsetxattr(fd, name, value, valueLen, 0, 0);
#else
throwUnixException(env, ENOTSUP);
#endif
if (res == -1)
throwUnixException(env, errno);
}
JNIEXPORT void JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_fremovexattr0(JNIEnv* env, jclass clazz,
jint fd, jlong nameAddress)
{
int res = -1;
const char* name = jlong_to_ptr(nameAddress);
#ifdef __linux__
res = fremovexattr(fd, name);
#elif _ALLBSD_SOURCE
res = fremovexattr(fd, name, 0);
#else
throwUnixException(env, ENOTSUP);
#endif
if (res == -1)
throwUnixException(env, errno);
}
JNIEXPORT jint JNICALL
Java_sun_nio_fs_UnixNativeDispatcher_flistxattr(JNIEnv* env, jclass clazz,
jint fd, jlong listAddress, jint size)
{
size_t res = -1;
char* list = jlong_to_ptr(listAddress);
#ifdef __linux__
res = flistxattr(fd, list, (size_t)size);
#elif _ALLBSD_SOURCE
res = flistxattr(fd, list, (size_t)size, 0);
#else
throwUnixException(env, ENOTSUP);
#endif
if (res == (size_t)-1)
throwUnixException(env, errno);
return (jint)res;
}

View File

@@ -25,7 +25,6 @@
package sun.font;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
@@ -48,10 +47,10 @@ class FreetypeFontScaler extends FontScaler {
/* At the moment fontmanager library depends on freetype library
and therefore no need to load it explicitly here */
FontManagerNativeLibrary.load();
initIDs(FreetypeFontScaler.class, Toolkit.class, PhysicalFont.class);
initIDs(FreetypeFontScaler.class);
}
private static native void initIDs(Class<?> FFS, Class<?> toolkitClass, Class<?> pfClass);
private static native void initIDs(Class<?> FFS);
private void invalidateScaler() throws FontScalerException {
nativeScaler = 0;

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@
#include "jni.h"
#include "jni_util.h"
#include "jvm_md.h"
#include "jlong.h"
#include "sunfontids.h"
#include "sun_font_FreetypeFontScaler.h"
@@ -33,10 +33,8 @@
#if !defined(_WIN32) && !defined(__APPLE_)
#include <dlfcn.h>
#endif
#include <stdlib.h>
#include <math.h>
#include "ft2build.h"
#include FT_LCD_FILTER_H
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include FT_BBOX_H
@@ -45,12 +43,6 @@
#include FT_SYNTHESIS_H
#include FT_LCD_FILTER_H
#include FT_MODULE_H
#include FT_LCD_FILTER_H
#ifndef _WIN32
/* Use bundled fontconfig.h for now */
#include "fontconfig.h"
#endif
#include "fontscaler.h"
@@ -58,22 +50,6 @@
#define FloatToFTFixed(f) (FT_Fixed)((f) * (float)(ftFixed1))
#define FTFixedToFloat(x) ((x) / (float)(ftFixed1))
#define FT26Dot6ToFloat(x) ((x) / ((float) (1<<6)))
#define ROUND(x) ((int) ((x<0) ? (x-0.5) : (x+0.5)))
#define FT26Dot6ToDouble(x) ((x) / ((double) (1<<6)))
#define DEFAULT_DPI 72
#define ADJUST_FONT_SIZE(X, DPI) (((X)*DEFAULT_DPI + ((DPI)>>1))/(DPI))
#ifndef _WIN32
#define FONTCONFIG_DLL JNI_LIB_NAME("fontconfig")
#define FONTCONFIG_DLL_VERSIONED VERSIONED_JNI_LIB_NAME("fontconfig", "1")
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
typedef struct {
/* Important note:
@@ -105,12 +81,7 @@ typedef struct FTScalerContext {
jint fmType; /* fractional metrics - on/off */
jboolean doBold; /* perform algorithmic bolding? */
jboolean doItalize; /* perform algorithmic italicizing? */
/* Fontconfig info */
FT_Render_Mode renderFlags;
FT_Int32 loadFlags;
FT_LcdFilter lcdFilter;
int renderFlags; /* configuration specific to particular engine */
int pathType;
int ptsz; /* size in points */
} FTScalerContext;
@@ -126,117 +97,12 @@ void z_error(char *s) {}
/**************** Error handling utilities *****************/
static jmethodID invalidateScalerMID;
static jmethodID getDefaultToolkitMID;
static jclass tkClass;
static jmethodID getScreenResolutionMID;
static jfieldID platNameFID;
#ifndef _WIN32
typedef FcBool (*FcPatternAddPtrType) (FcPattern *p, const char *object, FcValue value, FcBool append);
typedef FcBool (*FcPatternAddBoolPtrType) (FcPattern *p, const char *object, FcBool b);
typedef FcBool (*FcPatternAddDoublePtrType) (FcPattern *p, const char *object, double d);
typedef FcBool (*FcConfigSubstitutePtrType) (FcConfig *config, FcPattern *p, FcMatchKind kind);
typedef void (*FcDefaultSubstitutePtrType) (FcPattern *pattern);
typedef FcPattern* (*FcPatternCreatePtrType) ();
typedef FcPattern* (*FcFontMatchPtrType) (FcConfig *config, FcPattern *p, FcResult *result);
typedef void (*FcPatternDestroyPtrType) (FcPattern *p);
typedef FcResult (*FcPatternGetBoolPtrType) (const FcPattern *p, const char *object, int n, FcBool *b);
typedef FcResult (*FcPatternGetIntegerPtrType) (const FcPattern *p, const char *object, int n, int *i);
#endif
static void *libFontConfig = NULL;
static jboolean logFC = JNI_FALSE;
#ifndef _WIN32
static FcPatternAddPtrType FcPatternAddPtr;
static FcPatternAddBoolPtrType FcPatternAddBoolPtr;
static FcPatternAddDoublePtrType FcPatternAddDoublePtr;
static FcConfigSubstitutePtrType FcConfigSubstitutePtr;
static FcDefaultSubstitutePtrType FcDefaultSubstitutePtr;
static FcPatternCreatePtrType FcPatternCreatePtr;
static FcFontMatchPtrType FcFontMatchPtr;
static FcPatternDestroyPtrType FcPatternDestroyPtr;
static FcPatternGetBoolPtrType FcPatternGetBoolPtr;
static FcPatternGetIntegerPtrType FcPatternGetIntegerPtr;
#endif
static void* openFontConfig() {
void* libfontconfig = NULL;
#ifndef _WIN32
char *fcLogEnabled = getenv("OPENJDK_FFS_LOG_FC");
if (fcLogEnabled != NULL && !strcmp(fcLogEnabled, "yes")) {
logFC = JNI_TRUE;
}
char *useFC = getenv("OPENJDK_FFS_USE_FC");
if (useFC != NULL && !strcmp(useFC, "no")) {
if (logFC) fprintf(stderr, "FC_LOG: fontconfig disabled in freetypescaler\n");
return NULL;
}
libfontconfig = dlopen(FONTCONFIG_DLL_VERSIONED, RTLD_LOCAL | RTLD_LAZY);
if (libfontconfig == NULL) {
libfontconfig = dlopen(FONTCONFIG_DLL, RTLD_LOCAL | RTLD_LAZY);
if (libfontconfig == NULL) {
if (logFC) fprintf(stderr, "FC_LOG: cannot open %s\n", FONTCONFIG_DLL);
return NULL;
}
}
#endif
return libfontconfig;
}
JNIEXPORT void JNICALL
Java_sun_font_FreetypeFontScaler_initIDs(
JNIEnv *env, jobject scaler, jclass FFSClass, jclass TKClass, jclass PFClass) {
JNIEnv *env, jobject scaler, jclass FFSClass) {
invalidateScalerMID =
(*env)->GetMethodID(env, FFSClass, "invalidateScaler", "()V");
getDefaultToolkitMID =
(*env)->GetStaticMethodID(env, TKClass, "getDefaultToolkit",
"()Ljava/awt/Toolkit;");
getScreenResolutionMID =
(*env)->GetMethodID(env, TKClass, "getScreenResolution", "()I");
tkClass = (*env)->NewGlobalRef(env, TKClass);
platNameFID = (*env)->GetFieldID(env, PFClass, "platName", "Ljava/lang/String;");
libFontConfig = openFontConfig();
#ifndef _WIN32
if (libFontConfig) {
FcPatternAddPtr = (FcPatternAddPtrType) dlsym(libFontConfig, "FcPatternAdd");
FcPatternAddBoolPtr = (FcPatternAddBoolPtrType) dlsym(libFontConfig, "FcPatternAddBool");
FcPatternAddDoublePtr = (FcPatternAddDoublePtrType) dlsym(libFontConfig, "FcPatternAddDouble");
FcConfigSubstitutePtr = (FcConfigSubstitutePtrType) dlsym(libFontConfig, "FcConfigSubstitute");
FcDefaultSubstitutePtr = (FcDefaultSubstitutePtrType) dlsym(libFontConfig, "FcDefaultSubstitute");
FcPatternCreatePtr = (FcPatternCreatePtrType) dlsym(libFontConfig, "FcPatternCreate");
FcFontMatchPtr = (FcFontMatchPtrType) dlsym(libFontConfig, "FcFontMatch");
FcPatternDestroyPtr = (FcPatternDestroyPtrType) dlsym(libFontConfig, "FcPatternDestroy");
FcPatternGetBoolPtr = (FcPatternGetBoolPtrType) dlsym(libFontConfig, "FcPatternGetBool");
FcPatternGetIntegerPtr = (FcPatternGetIntegerPtrType) dlsym(libFontConfig, "FcPatternGetInteger");
}
#endif
}
static char* getPhysFontName(JNIEnv *env, jobject font2d) {
jstring jstr;
jstr = (*env)->GetObjectField(env, font2d, platNameFID);
return (char*)(*env)->GetStringUTFChars(env, jstr, NULL);
}
static int getScreenResolution(JNIEnv *env) {
jthrowable exc;
jclass tk = (*env)->CallStaticObjectMethod(
env, tkClass, getDefaultToolkitMID);
int dpi = (*env)->CallIntMethod(env, tk, getScreenResolutionMID);
/* Test if there is no exception here (can get java.awt.HeadlessException)
* Fallback to default DPI otherwise
*/
exc = (*env)->ExceptionOccurred(env);
if (exc) {
(*env)->ExceptionClear(env);
return DEFAULT_DPI;
}
return dpi;
}
static void freeNativeResources(JNIEnv *env, FTScalerInfo* scalerInfo) {
@@ -696,237 +562,27 @@ static void setupTransform(FT_Matrix* target, FTScalerContext *context) {
static int setupFTContext(JNIEnv *env,
jobject font2D,
FTScalerInfo *scalerInfo,
FTScalerContext *context,
FT_Bool configureFont) {
FTScalerContext *context) {
FT_Matrix matrix;
int errCode = 0;
scalerInfo->env = env;
scalerInfo->font2D = font2D;
if (context != NULL) {
setupTransform(&matrix, context);
FT_Set_Transform(scalerInfo->face, &matrix, NULL);
FT_UInt dpi = (FT_UInt) getScreenResolution(env);
errCode = FT_Set_Char_Size(scalerInfo->face, 0, ADJUST_FONT_SIZE(context->ptsz, dpi), dpi, dpi);
if (errCode) return errCode;
errCode = FT_Set_Char_Size(scalerInfo->face, 0, context->ptsz, 72, 72);
errCode = FT_Activate_Size(scalerInfo->face->size);
if (errCode) return errCode;
if (configureFont) {
context->renderFlags = FT_RENDER_MODE_NORMAL;
context->lcdFilter = FT_LCD_FILTER_NONE;
context->loadFlags = FT_LOAD_DEFAULT;
if (libFontConfig == NULL) {
if (context->aaType == TEXT_AA_OFF) {
context->loadFlags = FT_LOAD_TARGET_MONO;
} else if (context->aaType == TEXT_AA_ON) {
context->loadFlags = FT_LOAD_TARGET_LIGHT;
} else {
context->lcdFilter = FT_LCD_FILTER_LIGHT;
if (context->aaType == TEXT_AA_LCD_HRGB ||
context->aaType == TEXT_AA_LCD_HBGR) {
context->loadFlags = FT_LOAD_TARGET_LCD;
} else {
context->loadFlags = FT_LOAD_TARGET_LCD_V;
}
}
context->renderFlags = FT_LOAD_TARGET_MODE(context->loadFlags);
return 0;
}
#ifndef _WIN32
FcPattern *fcPattern = 0;
fcPattern = (*FcPatternCreatePtr)();
FcValue fcValue;
fcValue.type = FcTypeString;
char *fontName = getPhysFontName(env, font2D);
if (logFC) fprintf(stderr, "FC_LOG: %s ", fontName);
fcValue.u.s = fontName;
(*FcPatternAddPtr)(fcPattern, FC_FILE, fcValue, FcTrue);
(*FcPatternAddBoolPtr)(fcPattern, FC_SCALABLE, FcTrue);
double fcSize = FT26Dot6ToDouble(ADJUST_FONT_SIZE(context->ptsz, dpi));
(*FcPatternAddDoublePtr)(fcPattern, FC_SIZE, fcSize);
if (logFC) fprintf(stderr, " size=%f", fcSize);
(*FcConfigSubstitutePtr)(0, fcPattern, FcMatchPattern);
(*FcConfigSubstitutePtr)(0, fcPattern, FcMatchFont);
(*FcDefaultSubstitutePtr)(fcPattern);
FcResult matchResult = FcResultNoMatch;
FcPattern *resultPattern = 0;
resultPattern = (*FcFontMatchPtr)(0, fcPattern, &matchResult);
if (matchResult != FcResultMatch) {
(*FcPatternDestroyPtr)(fcPattern);
if (logFC) fprintf(stderr, " - NOT FOUND\n");
return 1;
}
if (logFC) fprintf(stderr, "\nFC_LOG: ");
(*FcPatternDestroyPtr)(fcPattern);
FcPattern *pattern = resultPattern;
FcBool fcHinting = FcFalse;
FcBool fcHintingSet = (*FcPatternGetBoolPtr)(pattern, FC_HINTING, 0, &fcHinting) == FcResultMatch;
if (logFC && fcHintingSet) fprintf(stderr, "FC_HINTING(%d) ", fcHinting);
int fcHintStyle = FC_HINT_NONE;
FcBool fcHintStyleSet = (*FcPatternGetIntegerPtr)(pattern, FC_HINT_STYLE, 0, &fcHintStyle) == FcResultMatch;
if (logFC && fcHintStyleSet) {
switch (fcHintStyle) {
case FC_HINT_NONE:
fprintf(stderr, "FC_HINT_NONE ");
break;
case FC_HINT_SLIGHT:
fprintf(stderr, "FC_HINT_SLIGHT ");
break;
case FC_HINT_MEDIUM:
fprintf(stderr, "FC_HINT_MEDIUM ");
break;
case FC_HINT_FULL:
fprintf(stderr, "FC_HINT_FULL ");
break;
default:
fprintf(stderr, "FC_HINT_UNKNOWN ");
break;
}
}
if (fcHintingSet && !fcHinting) {
fcHintStyleSet = FcTrue;
fcHintStyle = FC_HINT_NONE;
}
if (fcHintStyleSet && fcHintStyle == FC_HINT_NONE) {
fcHintingSet = FcTrue;
fcHinting = FcFalse;
}
FcBool fcAntialias = FcFalse;
FcBool fcAntialiasSet = (*FcPatternGetBoolPtr)(pattern, FC_ANTIALIAS, 0, &fcAntialias) == FcResultMatch;
if (logFC) {
switch(context->aaType) {
case TEXT_AA_ON:
fprintf(stderr, "JDK_AA_ON ");
break;
case TEXT_AA_OFF:
fprintf(stderr, "JDK_AA_OFF ");
break;
case TEXT_AA_LCD_HRGB:
fprintf(stderr, "JDK_AA_LCD_HRGB ");
break;
case TEXT_AA_LCD_HBGR:
fprintf(stderr, "JDK_AA_LCD_HBGR ");
break;
default:
fprintf(stderr, "JDK_AA_UNKNOWN ");
break;
}
if (fcAntialiasSet) fprintf(stderr, "FC_ANTIALIAS(%d) ", fcAntialias);
}
if (context->aaType == TEXT_AA_ON) { // Greyscale AA
context->renderFlags = FT_RENDER_MODE_NORMAL;
if (fcHintingSet) {
switch (fcHintStyle) {
case FC_HINT_NONE:
context->loadFlags = FT_LOAD_NO_HINTING;
break;
case FC_HINT_SLIGHT:
context->loadFlags = FT_LOAD_TARGET_LIGHT;
break;
case FC_HINT_MEDIUM:
case FC_HINT_FULL:
default:
break;
}
}
}
else if (context->aaType == TEXT_AA_OFF) { // No AA
context->renderFlags = FT_RENDER_MODE_MONO;
context->loadFlags = (!fcHintingSet || fcHinting) ? FT_LOAD_TARGET_MONO : FT_LOAD_NO_HINTING;
} else {
int fcRGBA = FC_RGBA_UNKNOWN;
if (fcAntialiasSet && fcAntialias) {
if ((*FcPatternGetIntegerPtr)(pattern, FC_RGBA, 0, &fcRGBA) == FcResultMatch) {
switch (fcRGBA) {
case FC_RGBA_RGB:
case FC_RGBA_BGR:
if (logFC) fprintf(stderr, fcRGBA == FC_RGBA_RGB ? "FC_RGBA_RGB " : "FC_RGBA_BGR ");
context->loadFlags = FT_LOAD_TARGET_LCD;
context->renderFlags = FT_RENDER_MODE_LCD;
break;
case FC_RGBA_VRGB:
case FC_RGBA_VBGR:
if (logFC) fprintf(stderr, fcRGBA == FC_RGBA_VRGB ? "FC_RGBA_VRGB " : "FC_RGBA_VBGR ");
context->loadFlags = FT_LOAD_TARGET_LCD_V;
context->renderFlags = FT_RENDER_MODE_LCD_V;
break;
default:
if (logFC) fprintf(stderr, "FC_RGBA_UNKNOWN ");
break;
}
}
}
if (fcRGBA == FC_RGBA_UNKNOWN) {
if (context->aaType == TEXT_AA_LCD_HRGB ||
context->aaType == TEXT_AA_LCD_HBGR) {
context->loadFlags = FT_LOAD_TARGET_LCD;
context->renderFlags = FT_RENDER_MODE_LCD;
} else {
context->loadFlags = FT_LOAD_TARGET_LCD_V;
context->renderFlags = FT_RENDER_MODE_LCD_V;
}
}
}
FcBool fcAutohint = FcFalse;
FcBool fcAutohintSet = (*FcPatternGetBoolPtr)(pattern, FC_AUTOHINT, 0, &fcAutohint) == FcResultMatch;
if (logFC && fcAutohintSet) fprintf(stderr, "FC_AUTOHINT(%d) ", fcAutohint);
if (fcAutohintSet && fcAutohint) {
context->loadFlags |= FT_LOAD_FORCE_AUTOHINT;
}
FT_LcdFilter fcLCDFilter;
FcBool fcLCDFilterSet = (*FcPatternGetIntegerPtr)(pattern, FC_LCD_FILTER, 0, &fcLCDFilter) == FcResultMatch;
context->lcdFilter = FT_LCD_FILTER_DEFAULT;
if (fcLCDFilterSet) {
switch (fcLCDFilter) {
case FC_LCD_NONE:
if (logFC) fprintf(stderr, "FC_LCD_NONE");
context->lcdFilter = FT_LCD_FILTER_NONE;
break;
case FC_LCD_LIGHT:
if (logFC) fprintf(stderr, "FC_LCD_LIGHT");
context->lcdFilter = FT_LCD_FILTER_LIGHT;
break;
case FC_LCD_LEGACY:
if (logFC) fprintf(stderr, "FC_LCD_LEGACY");
context->lcdFilter = FT_LCD_FILTER_LEGACY;
break;
case FC_LCD_DEFAULT:
if (logFC) fprintf(stderr, "FC_LCD_DEFAULT");
break;
default:
if (logFC) fprintf(stderr, "FC_LCD_UNKNOWN");
;
}
}
(*FcPatternDestroyPtr)(pattern);
if (logFC) fprintf(stderr, "\n");
#endif
if (errCode == 0) {
errCode = FT_Activate_Size(scalerInfo->face->size);
}
FT_Library_SetLcdFilter(scalerInfo->library, FT_LCD_FILTER_DEFAULT);
}
return 0;
return errCode;
}
// using same values as for the transformation matrix
@@ -943,7 +599,7 @@ Java_sun_font_FreetypeFontScaler_getFontMetricsNative(
jlong pScalerContext, jlong pScaler) {
jobject metrics;
jfloat ax, ay, dx, dy, bx, by, lx, ly, mx, my, txx, txy, tyx, tyy;
jfloat ax, ay, dx, dy, bx, by, lx, ly, mx, my;
jfloat f0 = 0.0;
FTScalerContext *context =
(FTScalerContext*) jlong_to_ptr(pScalerContext);
@@ -959,7 +615,7 @@ Java_sun_font_FreetypeFontScaler_getFontMetricsNative(
f0, f0, f0, f0, f0, f0, f0, f0, f0, f0);
}
errCode = setupFTContext(env, font2D, scalerInfo, context, FALSE);
errCode = setupFTContext(env, font2D, scalerInfo, context);
if (errCode) {
metrics = (*env)->NewObject(env,
@@ -1022,20 +678,6 @@ Java_sun_font_FreetypeFontScaler_getFontMetricsNative(
scalerInfo->face->size->metrics.y_scale));
my = 0;
// apply transformation matrix
txx = (jfloat) FTFixedToFloat(context->transform.xx);
txy = (jfloat) -FTFixedToFloat(context->transform.xy);
tyx = (jfloat) -FTFixedToFloat(context->transform.yx);
tyy = (jfloat) FTFixedToFloat(context->transform.yy);
ax = txy * ay;
ay = tyy * ay;
dx = txy * dy;
dy = tyy * dy;
lx = txy * ly;
ly = tyy * ly;
my = tyx * mx;
mx = txx * mx;
metrics = (*env)->NewObject(env,
sunFontIDs.strikeMetricsClass,
sunFontIDs.strikeMetricsCtr,
@@ -1258,8 +900,6 @@ static jlong
GlyphInfo *glyphInfo;
int renderFlags = FT_LOAD_DEFAULT, target;
FT_GlyphSlot ftglyph;
FT_LcdFilter lcdFilter = FT_LCD_FILTER_NONE;
FT_Library library;
FTScalerContext* context =
(FTScalerContext*) jlong_to_ptr(pScalerContext);
@@ -1270,7 +910,7 @@ static jlong
return ptr_to_jlong(getNullGlyphImage());
}
error = setupFTContext(env, font2D, scalerInfo, context, TRUE);
error = setupFTContext(env, font2D, scalerInfo, context);
if (error) {
invalidateJavaScaler(env, scaler, scalerInfo);
return ptr_to_jlong(getNullGlyphImage());
@@ -1317,8 +957,6 @@ static jlong
}
ftglyph = scalerInfo->face->glyph;
library = ftglyph->library;
FT_Library_SetLcdFilter (library, context->lcdFilter);
/* apply styles */
if (context->doBold) { /* if bold style */
@@ -1469,7 +1107,7 @@ Java_sun_font_FreetypeFontScaler_disposeNativeScaler(
/* Freetype functions *may* cause callback to java
that can use cached values. Make sure our cache is up to date.
NB: scaler context is not important at this point, can use NULL. */
int errCode = setupFTContext(env, font2D, scalerInfo, NULL, FALSE);
int errCode = setupFTContext(env, font2D, scalerInfo, NULL);
if (errCode) {
return;
}
@@ -1532,7 +1170,7 @@ Java_sun_font_FreetypeFontScaler_getGlyphCodeNative(
/* Freetype functions *may* cause callback to java
that can use cached values. Make sure our cache is up to date.
Scaler context is not important here, can use NULL. */
errCode = setupFTContext(env, font2D, scalerInfo, NULL, FALSE);
errCode = setupFTContext(env, font2D, scalerInfo, NULL);
if (errCode) {
return 0;
}
@@ -1555,7 +1193,7 @@ static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D,
return NULL;
}
error = setupFTContext(env, font2D, scalerInfo, context, TRUE);
error = setupFTContext(env, font2D, scalerInfo, context);
if (error) {
return NULL;
}
@@ -1997,11 +1635,3 @@ Java_sun_font_FreetypeFontScaler_getGlyphPointNative(
return (*env)->NewObject(env, sunFontIDs.pt2DFloatClass,
sunFontIDs.pt2DFloatCtr, x, y);
}
void JNI_OnUnload(JavaVM *vm, void *reserved) {
if (libFontConfig != NULL) {
#ifndef _WIN32
dlclose(libFontConfig);
#endif
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
@@ -1235,8 +1235,12 @@ StatusDrawCallback(XIC ic, XPointer client_data,
statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
} else {
char *mbstr = wcstombsdmp(text->string.wide_char, text->length);
if (mbstr == NULL) {
goto finally;
}
strncpy(statusWindow->status, mbstr, MAX_STATUS_LEN);
statusWindow->status[MAX_STATUS_LEN - 1] = '\0';
free(mbstr);
}
statusWindow->on = True;
onoffStatusWindow(pX11IMData, statusWindow->parent, True);

View File

@@ -3877,7 +3877,9 @@ public class Lower extends TreeTranslator {
stmtList.append(switch2);
return make.Block(0L, stmtList.toList());
JCBlock res = make.Block(0L, stmtList.toList());
res.endpos = TreeInfo.endPos(tree);
return res;
} else {
JCSwitchExpression switch2 = make.SwitchExpression(make.Ident(dollar_tmp), lb.toList());

View File

@@ -2821,6 +2821,7 @@ public class JavacParser implements Parser {
accept(LBRACE);
List<JCCase> cases = switchBlockStatementGroups();
JCSwitch t = to(F.at(pos).Switch(selector, cases));
t.endpos = token.endPos;
accept(RBRACE);
return t;
}

View File

@@ -1246,6 +1246,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public static class JCSwitch extends JCStatement implements SwitchTree {
public JCExpression selector;
public List<JCCase> cases;
/** Position of closing brace, optional. */
public int endpos = Position.NOPOS;
protected JCSwitch(JCExpression selector, List<JCCase> cases) {
this.selector = selector;
this.cases = cases;

View File

@@ -427,6 +427,9 @@ public class TreeInfo {
JCTry t = (JCTry) tree;
return endPos((t.finalizer != null) ? t.finalizer
: (t.catchers.nonEmpty() ? t.catchers.last().body : t.body));
} else if (tree.hasTag(SWITCH) &&
((JCSwitch) tree).endpos != Position.NOPOS) {
return ((JCSwitch) tree).endpos;
} else if (tree.hasTag(SWITCH_EXPRESSION) &&
((JCSwitchExpression) tree).endpos != Position.NOPOS) {
return ((JCSwitchExpression) tree).endpos;

View File

@@ -1,6 +1,6 @@
/*
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, NTT DATA.
* Copyright (c) 2019, 2021, NTT DATA.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -190,18 +190,18 @@ static void fillThreadsAndLoadObjects(JNIEnv* env, jobject this_obj, struct ps_p
// add load objects
n = get_num_libs(ph);
for (i = 0; i < n; i++) {
uintptr_t base;
uintptr_t base, memsz;
const char* name;
jobject loadObject;
jobject loadObjectList;
jstring str;
base = get_lib_base(ph, i);
get_lib_addr_range(ph, i, &base, &memsz);
name = get_lib_name(ph, i);
str = env->NewStringUTF(name);
CHECK_EXCEPTION;
loadObject = env->CallObjectMethod(this_obj, createLoadObject_ID, str, (jlong)0, (jlong)base);
loadObject = env->CallObjectMethod(this_obj, createLoadObject_ID, str, (jlong)memsz, (jlong)base);
CHECK_EXCEPTION;
loadObjectList = env->GetObjectField(this_obj, loadObjectList_ID);
CHECK_EXCEPTION;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, 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
@@ -97,6 +97,9 @@ const char* get_lib_name(struct ps_prochandle* ph, int index);
// get base of lib
uintptr_t get_lib_base(struct ps_prochandle* ph, int index);
// get address range of lib
void get_lib_addr_range(struct ps_prochandle* ph, int index, uintptr_t* base, uintptr_t* memsz);
// returns true if given library is found in lib list
bool find_lib(struct ps_prochandle* ph, const char *lib_name);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, 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
@@ -159,13 +159,20 @@ lib_info* add_lib_info(struct ps_prochandle* ph, const char* libname, uintptr_t
return add_lib_info_fd(ph, libname, -1, base);
}
static bool fill_instr_info(lib_info* lib) {
static inline uintptr_t align_down(uintptr_t ptr, size_t page_size) {
return (ptr & ~(page_size - 1));
}
static inline uintptr_t align_up(uintptr_t ptr, size_t page_size) {
return ((ptr + page_size - 1) & ~(page_size - 1));
}
static bool fill_addr_info(lib_info* lib) {
off_t current_pos;
ELF_EHDR ehdr;
ELF_PHDR* phbuf = NULL;
ELF_PHDR* ph = NULL;
int cnt;
long align = sysconf(_SC_PAGE_SIZE);
current_pos = lseek(lib->fd, (off_t)0L, SEEK_CUR);
lseek(lib->fd, (off_t)0L, SEEK_SET);
@@ -175,32 +182,35 @@ static bool fill_instr_info(lib_info* lib) {
return false;
}
lib->end = (uintptr_t)-1L;
lib->exec_start = (uintptr_t)-1L;
lib->exec_end = (uintptr_t)-1L;
for (ph = phbuf, cnt = 0; cnt < ehdr.e_phnum; cnt++, ph++) {
if ((ph->p_type == PT_LOAD) && (ph->p_flags & PF_X)) {
print_debug("[%d] vaddr = 0x%lx, memsz = 0x%lx, filesz = 0x%lx\n", cnt, ph->p_vaddr, ph->p_memsz, ph->p_filesz);
if ((lib->exec_start == -1L) || (lib->exec_start > ph->p_vaddr)) {
lib->exec_start = ph->p_vaddr;
if (ph->p_type == PT_LOAD) {
uintptr_t aligned_start = align_down(lib->base + ph->p_vaddr, ph->p_align);
uintptr_t aligned_end = align_up(aligned_start + ph->p_filesz, ph->p_align);
if ((lib->end == (uintptr_t)-1L) || (lib->end < aligned_end)) {
lib->end = aligned_end;
}
if ((lib->exec_end == (uintptr_t)-1L) || (lib->exec_end < (ph->p_vaddr + ph->p_memsz))) {
lib->exec_end = ph->p_vaddr + ph->p_memsz;
print_debug("%s [%d] 0x%lx-0x%lx: base = 0x%lx, "
"vaddr = 0x%lx, memsz = 0x%lx, filesz = 0x%lx\n",
lib->name, cnt, aligned_start, aligned_end, lib->base,
ph->p_vaddr, ph->p_memsz, ph->p_filesz);
if (ph->p_flags & PF_X) {
if ((lib->exec_start == -1L) || (lib->exec_start > aligned_start)) {
lib->exec_start = aligned_start;
}
if ((lib->exec_end == (uintptr_t)-1L) || (lib->exec_end < aligned_end)) {
lib->exec_end = aligned_end;
}
}
align = ph->p_align;
}
}
free(phbuf);
lseek(lib->fd, current_pos, SEEK_SET);
if ((lib->exec_start == -1L) || (lib->exec_end == -1L)) {
return false;
} else {
lib->exec_start = (lib->exec_start + lib->base) & ~(align - 1);
lib->exec_end = (lib->exec_end + lib->base + align) & ~(align - 1);
return true;
}
return (lib->end != -1L) && (lib->exec_start != -1L) && (lib->exec_end != -1L);
}
bool read_eh_frame(struct ps_prochandle* ph, lib_info* lib) {
@@ -275,7 +285,7 @@ lib_info* add_lib_info_fd(struct ps_prochandle* ph, const char* libname, int fd,
print_debug("symbol table build failed for %s\n", newlib->name);
}
if (fill_instr_info(newlib)) {
if (fill_addr_info(newlib)) {
if (!read_eh_frame(ph, newlib)) {
print_debug("Could not find .eh_frame section in %s\n", newlib->name);
}
@@ -431,6 +441,21 @@ uintptr_t get_lib_base(struct ps_prochandle* ph, int index) {
return (uintptr_t)NULL;
}
// get address range of lib
void get_lib_addr_range(struct ps_prochandle* ph, int index, uintptr_t* base, uintptr_t* memsz) {
int count = 0;
lib_info* lib = ph->libs;
while (lib) {
if (count == index) {
*base = lib->base;
*memsz = lib->end - lib->base;
return;
}
count++;
lib = lib->next;
}
}
bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
lib_info *p = ph->libs;
while (p) {

View File

@@ -46,6 +46,7 @@ typedef struct eh_frame_info {
typedef struct lib_info {
char name[BUF_SIZE];
uintptr_t base;
uintptr_t end;
uintptr_t exec_start;
uintptr_t exec_end;
eh_frame_info eh_frame;

View File

@@ -973,17 +973,17 @@ static void fillLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle*
// add load objects
n = get_num_libs(ph);
for (i = 0; i < n; i++) {
uintptr_t base;
uintptr_t base, memsz;
const char* name;
jobject loadObject;
jstring nameString;
base = get_lib_base(ph, i);
get_lib_addr_range(ph, i, &base, &memsz);
name = get_lib_name(ph, i);
nameString = (*env)->NewStringUTF(env, name);
CHECK_EXCEPTION;
loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID,
nameString, (jlong)0, (jlong)base);
nameString, (jlong)memsz, (jlong)base);
CHECK_EXCEPTION;
(*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject);
CHECK_EXCEPTION;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, 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
@@ -132,6 +132,9 @@ const char* get_lib_name(struct ps_prochandle* ph, int index);
// get base of lib
uintptr_t get_lib_base(struct ps_prochandle* ph, int index);
// get address range of lib
void get_lib_addr_range(struct ps_prochandle* ph, int index, uintptr_t* base, uintptr_t* memsz);
// returns true if given library is found in lib list
bool find_lib(struct ps_prochandle* ph, const char *lib_name);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, 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
@@ -486,6 +486,21 @@ uintptr_t get_lib_base(struct ps_prochandle* ph, int index) {
return (uintptr_t)NULL;
}
// get address range of lib
void get_lib_addr_range(struct ps_prochandle* ph, int index, uintptr_t* base, uintptr_t* memsz) {
int count = 0;
lib_info* lib = ph->libs;
while (lib) {
if (count == index) {
*base = lib->base;
*memsz = lib->memsz;
return;
}
count++;
lib = lib->next;
}
}
bool find_lib(struct ps_prochandle* ph, const char *lib_name) {
lib_info *p = ph->libs;
while (p) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2021, 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
@@ -24,7 +24,6 @@
package sun.jvm.hotspot.debugger.bsd;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@@ -85,11 +84,10 @@ public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
}
// called by native method attach0
private LoadObject createLoadObject(String fileName, long textsize,
private LoadObject createLoadObject(String fileName, long size,
long base) {
File f = new File(fileName);
Address baseAddr = newAddress(base);
return new SharedObject(this, fileName, f.length(), baseAddr);
return new SharedObject(this, fileName, size, baseAddr);
}
// native methods

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2021, 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
@@ -24,7 +24,6 @@
package sun.jvm.hotspot.debugger.linux;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
@@ -91,11 +90,10 @@ public class LinuxDebuggerLocal extends DebuggerBase implements LinuxDebugger {
}
// called by native method attach0
private LoadObject createLoadObject(String fileName, long textsize,
private LoadObject createLoadObject(String fileName, long size,
long base) {
File f = new File(fileName);
Address baseAddr = newAddress(base);
return new SharedObject(this, fileName, f.length(), baseAddr);
return new SharedObject(this, fileName, size, baseAddr);
}
// native methods

View File

@@ -25,7 +25,22 @@
#include "utilities/utf8.hpp"
#include "unittest.hpp"
TEST(utf8, length) {
static void stamp(char* p, size_t len) {
if (len > 0) {
::memset(p, 'A', len);
}
}
static bool test_stamp(const char* p, size_t len) {
for (const char* q = p; q < p + len; q++) {
if (*q != 'A') {
return false;
}
}
return true;
}
TEST_VM(utf8, jchar_length) {
char res[60];
jchar str[20];
@@ -35,16 +50,56 @@ TEST(utf8, length) {
str[19] = (jchar) '\0';
// The resulting string in UTF-8 is 3*19 bytes long, but should be truncated
stamp(res, sizeof(res));
UNICODE::as_utf8(str, 19, res, 10);
ASSERT_EQ(strlen(res), (size_t) 9) << "string should be truncated here";
ASSERT_TRUE(test_stamp(res + 10, sizeof(res) - 10));
stamp(res, sizeof(res));
UNICODE::as_utf8(str, 19, res, 18);
ASSERT_EQ(strlen(res), (size_t) 15) << "string should be truncated here";
ASSERT_TRUE(test_stamp(res + 18, sizeof(res) - 18));
stamp(res, sizeof(res));
UNICODE::as_utf8(str, 19, res, 20);
ASSERT_EQ(strlen(res), (size_t) 18) << "string should be truncated here";
ASSERT_TRUE(test_stamp(res + 20, sizeof(res) - 20));
// Test with an "unbounded" buffer
UNICODE::as_utf8(str, 19, res, INT_MAX);
ASSERT_EQ(strlen(res), (size_t) 3 * 19) << "string should end here";
// Test that we do not overflow the output buffer
for (int i = 1; i < 5; i ++) {
stamp(res, sizeof(res));
UNICODE::as_utf8(str, 19, res, i);
EXPECT_TRUE(test_stamp(res + i, sizeof(res) - i));
}
}
TEST_VM(utf8, jbyte_length) {
char res[60];
jbyte str[20];
for (int i = 0; i < 19; i++) {
str[i] = 0x42;
}
str[19] = '\0';
stamp(res, sizeof(res));
UNICODE::as_utf8(str, 19, res, 10);
ASSERT_EQ(strlen(res), (size_t) 9) << "string should be truncated here";
ASSERT_TRUE(test_stamp(res + 10, sizeof(res) - 10));
UNICODE::as_utf8(str, 19, res, INT_MAX);
ASSERT_EQ(strlen(res), (size_t) 19) << "string should end here";
// Test that we do not overflow the output buffer
for (int i = 1; i < 5; i ++) {
stamp(res, sizeof(res));
UNICODE::as_utf8(str, 19, res, i);
EXPECT_TRUE(test_stamp(res + i, sizeof(res) - i));
}
}

View File

@@ -32,7 +32,8 @@
*
* @modules jdk.incubator.foreign
*
* @run main/othervm -Dforeign.restricted=permit -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive TestLinkToNativeRBP
* @run main/othervm -Dforeign.restricted=permit -XX:+UnlockDiagnosticVMOptions
* -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive TestLinkToNativeRBP
*
*/

View File

@@ -1,159 +0,0 @@
#
# Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#############################################################################
#
# List of quarantined tests -- tests that should not be run by default, because
# they may fail due to known reason. The reason (CR#) must be mandatory specified.
#
# List items are testnames followed by labels, all MUST BE commented
# as to why they are here and use a label:
# generic-all Problems on all platforms
# generic-ARCH Where ARCH is one of: x64, i586, ppc64, ppc64le, s390x etc.
# OSNAME-all Where OSNAME is one of: linux, windows, macosx, aix
# OSNAME-ARCH Specific on to one OSNAME and ARCH, e.g. macosx-x64
# OSNAME-REV Specific on to one OSNAME and REV, e.g. macosx-10.7.4
#
# More than one label is allowed but must be on the same line.
#
#############################################################################
# :hotspot_compiler
compiler/ciReplay/TestSAServer.java 8029528 generic-all
compiler/codecache/jmx/PoolsIndependenceTest.java 8167015 generic-all
compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java 8225370 generic-all
compiler/jvmci/compilerToVM/GetFlagValueTest.java 8204459 generic-all
compiler/tiered/LevelTransitionTest.java 8067651 generic-all
compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java 8190680 generic-all
compiler/runtime/Test8168712.java 8211769,8211771 generic-ppc64,generic-ppc64le,linux-s390x
compiler/rtm/locking/TestRTMAbortRatio.java 8183263 generic-x64
compiler/rtm/locking/TestRTMAbortThreshold.java 8183263 generic-x64
compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java 8183263 generic-x64
compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java 8183263 generic-x64
compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java 8183263 generic-x64
compiler/rtm/locking/TestRTMLockingCalculationDelay.java 8183263 generic-x64
compiler/rtm/locking/TestRTMLockingThreshold.java 8183263 generic-x64
compiler/rtm/locking/TestRTMSpinLoopCount.java 8183263 generic-x64
compiler/rtm/locking/TestUseRTMDeopt.java 8183263 generic-x64
compiler/rtm/locking/TestUseRTMXendForLockBusy.java 8183263 generic-x64
compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java 8183263 generic-x64
compiler/c2/Test8004741.java 8235801 generic-all
#############################################################################
# :hotspot_gc
gc/epsilon/TestMemoryMXBeans.java 8206434 generic-all
gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all
gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all
gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
gc/stress/gclocker/TestGCLockerWithG1.java 8180622 generic-all
gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all
gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64
#############################################################################
# :hotspot_runtime
runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP_JFR.java 8253437 windows-x64
runtime/cds/DeterministicDump.java 8253495 generic-all
runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64
runtime/ReservedStack/ReservedStackTest.java 8231031 generic-all
containers/docker/TestJFRWithJMX.java 8256417 linux-5.4.17-2011.5.3.el8uek.x86_64
#############################################################################
# :hotspot_serviceability
serviceability/sa/sadebugd/DebugdConnectTest.java 8239062 macosx-x64
serviceability/sa/TestRevPtrsForInvokeDynamic.java 8241235 generic-all
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatIntervalTest.java 8214032 generic-all
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorStatArrayCorrectnessTest.java 8224150 generic-all
serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java 8225354 windows-all
serviceability/attach/RemovingUnixDomainSocketTest.java 8248162 linux-x64
#############################################################################
# :hotspot_misc
#############################################################################
#############################################################################
# :vmTestbase_*
#############################################################################
vmTestbase/nsk/monitoring/MemoryPoolMBean/isCollectionUsageThresholdExceeded/isexceeded003/TestDescription.java 8153598 generic-all
vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded001/TestDescription.java 8198668 generic-all
vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded002/TestDescription.java 8153598 generic-all
vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded003/TestDescription.java 8198668 generic-all
vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded004/TestDescription.java 8153598 generic-all
vmTestbase/nsk/monitoring/MemoryPoolMBean/isUsageThresholdExceeded/isexceeded005/TestDescription.java 8153598 generic-all
vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Deadlock/JavaDeadlock001/TestDescription.java 8060733 generic-all
vmTestbase/nsk/jdi/ThreadReference/stop/stop001/TestDescription.java 7034630 generic-all
vmTestbase/nsk/jdb/eval/eval001/eval001.java 8221503 generic-all
vmTestbase/metaspace/gc/firstGC_10m/TestDescription.java 8208250 generic-all
vmTestbase/metaspace/gc/firstGC_50m/TestDescription.java 8208250 generic-all
vmTestbase/metaspace/gc/firstGC_99m/TestDescription.java 8208250 generic-all
vmTestbase/metaspace/gc/firstGC_default/TestDescription.java 8208250 generic-all
vmTestbase/nsk/jvmti/AttachOnDemand/attach045/TestDescription.java 8202971 generic-all
vmTestbase/nsk/jvmti/scenarios/jni_interception/JI05/ji05t001/TestDescription.java 8219652 aix-ppc64
vmTestbase/nsk/jvmti/scenarios/jni_interception/JI06/ji06t001/TestDescription.java 8219652 aix-ppc64
vmTestbase/nsk/jvmti/SetJNIFunctionTable/setjniftab001/TestDescription.java 8219652 aix-ppc64
vmTestbase/gc/lock/jni/jnilock002/TestDescription.java 8192647 generic-all
vmTestbase/jit/escape/LockCoarsening/LockCoarsening001.java 8148743 generic-all
vmTestbase/jit/escape/LockCoarsening/LockCoarsening002.java 8208259 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/redefineClassInBootstrap/TestDescription.java 8013267 generic-all
vmTestbase/vm/mlvm/meth/func/java/throwException/Test.java 8058176 generic-all
vmTestbase/vm/mlvm/meth/stress/compiler/deoptimize/Test.java#id1 8058176 generic-all
vmTestbase/vm/mlvm/meth/stress/compiler/i2c_c2i/Test.java 8058176 generic-all
vmTestbase/vm/mlvm/meth/stress/compiler/sequences/Test.java 8058176 generic-all
vmTestbase/vm/mlvm/meth/stress/gc/callSequencesDuringGC/Test.java 8058176 generic-all
vmTestbase/vm/mlvm/meth/stress/java/sequences/Test.java 8058176 generic-all
vmTestbase/vm/mlvm/meth/stress/jdi/breakpointInCompiledCode/Test.java 8058176 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/TestDescription.java 8013267 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/TestDescription.java 8013267 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_b/TestDescription.java 8013267 generic-all
vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn001/forceEarlyReturn001.java 7199837 generic-all
#############################################################################

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