Compare commits

..

3 Commits

Author SHA1 Message Date
Vitaly Provodin
50fbed1202 JBR-4099 add env.JBSDK_VERSION into test binaries 2022-02-01 16:34:15 +07:00
Vitaly Provodin
8386fdac72 JBR-4099 make test-image on jbrsdk_jcef step followup 2022-01-31 16:41:00 +07:00
Vitaly Provodin
86079256d3 JBR-4099 make test-image on jbrsdk_jcef step 2022-01-31 14:21:09 +07:00
244 changed files with 1836 additions and 7878 deletions

View File

@@ -11,7 +11,6 @@ can be found on the [releases page](https://github.com/JetBrains/JetBrainsRuntim
| IDE Version | Latest JBR | Date Released |
| --- | --- | --- |
| 2022.1 | [17_0_2-b315.1](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr17_0_2b315.1) | 09-Feb-2022 |
| 2021.3 | [17_0_1-b164.8](https://github.com/JetBrains/JetBrainsRuntime/releases/tag/jbr17_0_1b164.8) | 15-Nov-2021 |
## Contents

View File

@@ -31,7 +31,6 @@ RUN export DEBIAN_FRONTEND=noninteractive \
libxt-dev \
libxtst-dev \
make \
rsync \
tar \
unzip \
zip && \

View File

@@ -1,22 +0,0 @@
# NOTE: This Dockerfile is meant to be used from the mkdocker_musl_aarch64.sh script.
# Pull a concrete version of Linux that does NOT recieve updates after it's
# been created. This is so that the image is as stable as possible to make
# image creation reproducible.
# NB: this also means there may be no security-related fixes there, need to
# move the version to the next manually.
FROM arm64v8/alpine:3.12
# Install the necessary build tools
RUN apk --no-cache add --update bash grep tar zip bzip2 rsync fontconfig build-base \
git libx11-dev libxext-dev libxrandr-dev libxrender-dev libxt-dev \
libxtst-dev autoconf freetype-dev cups-dev alsa-lib-dev file \
fontconfig fontconfig-dev linux-headers
# Set up boot JDK for building
COPY boot_jdk_musl_aarch64.tar.gz /jdk17/
RUN cd /jdk17 && tar --strip-components=1 -xzf boot_jdk_musl_aarch64.tar.gz && rm /jdk17/boot_jdk_musl_aarch64.tar.gz
ENV BOOT_JDK=/jdk17
RUN git config --global user.email "teamcity@jetbrains.com" && \
git config --global user.name "builduser"

View File

@@ -1,22 +0,0 @@
# NOTE: This Dockerfile is meant to be used from the mkdocker_musl_x64.sh script.
# Pull a concrete version of Linux that does NOT recieve updates after it's
# been created. This is so that the image is as stable as possible to make
# image creation reproducible.
# NB: this also means there may be no security-related fixes there, need to
# move the version to the next manually.
FROM alpine:3.5
# Install the necessary build tools
RUN apk --no-cache add --update bash grep tar zip bzip2 rsync fontconfig build-base \
git libx11-dev libxext-dev libxrandr-dev libxrender-dev libxt-dev \
libxtst-dev autoconf freetype-dev cups-dev alsa-lib-dev file \
fontconfig fontconfig-dev linux-headers
# Set up boot JDK for building
COPY boot_jdk_musl_amd64.tar.gz /jdk17/
RUN cd /jdk17 && tar --strip-components=1 -xzf boot_jdk_musl_amd64.tar.gz && rm /jdk17/boot_jdk_musl_amd64.tar.gz
ENV BOOT_JDK=/jdk17
RUN git config --global user.email "teamcity@jetbrains.com" && \
git config --global user.name "builduser"

View File

@@ -1,26 +0,0 @@
#!/bin/bash -x
# This script creates a Docker image suitable for building musl AArch64 variant
# of the JetBrains Runtime version 17.
BOOT_JDK_REMOTE_FILE=zulu17.32.13-ca-jdk17.0.2-linux_musl_aarch64.tar.gz
BOOT_JDK_SHA=6b920559abafbe9bdef386a20ecf3a2f318bc1f0d8359eb1f95aee26606bbc70
BOOT_JDK_LOCAL_FILE=boot_jdk_musl_aarch64.tar.gz
if [ ! -f $BOOT_JDK_LOCAL_FILE ]; then
# Obtain "boot JDK" from outside of the container.
wget -nc https://cdn.azul.com/zulu/bin/${BOOT_JDK_REMOTE_FILE} -O $BOOT_JDK_LOCAL_FILE
else
echo "boot JDK \"$BOOT_JDK_LOCAL_FILE\" present, skipping download"
fi
# Verify that what we've downloaded can be trusted.
sha256sum -c - <<EOF
$BOOT_JDK_SHA *$BOOT_JDK_LOCAL_FILE
EOF
docker build -t jbr17buildenv -f Dockerfile.musl_aarch64 .
# NB: the resulting container can (and should) be used without the network
# connection (--network none) during build in order to reduce the chance
# of build contamination.

View File

@@ -1,26 +0,0 @@
#!/bin/bash -x
# This script creates a Docker image suitable for building musl-x64 variant
# of the JetBrains Runtime version 17.
BOOT_JDK_REMOTE_FILE=zulu17.32.13-ca-jdk17.0.2-linux_musl_x64.tar.gz
BOOT_JDK_SHA=bcc5342011bd9f3643372aadbdfa68d47463ff0d8621668a0bdf2910614d95c6
BOOT_JDK_LOCAL_FILE=boot_jdk_musl_amd64.tar.gz
if [ ! -f $BOOT_JDK_LOCAL_FILE ]; then
# Obtain "boot JDK" from outside of the container.
wget -nc https://cdn.azul.com/zulu/bin/${BOOT_JDK_REMOTE_FILE} -O $BOOT_JDK_LOCAL_FILE
else
echo "boot JDK \"$BOOT_JDK_LOCAL_FILE\" present, skipping download"
fi
# Verify that what we've downloaded can be trusted.
sha256sum -c - <<EOF
$BOOT_JDK_SHA *$BOOT_JDK_LOCAL_FILE
EOF
docker build -t jbr17buildenv -f Dockerfile.musl_x64 .
# NB: the resulting container can (and should) be used without the network
# connection (--network none) during build in order to reduce the chance
# of build contamination.

View File

@@ -1,18 +1,6 @@
#!/bin/bash -x
function do_maketest() {
if [ "${bundle_type: -1}" == "t" ]; then
echo ${bundle_type%?}
return 1
else
echo ${bundle_type}
return 0
fi
}
function getVersionProp() {
grep "^${1}" make/conf/version-numbers.conf | cut -d'=' -f2
}
tag_prefix="jbr-"
while getopts ":i?" o; do
case "${o}" in
@@ -24,25 +12,27 @@ while getopts ":i?" o; do
done
shift $((OPTIND-1))
build_number=$1
bundle_type=$2
architecture=$3 # aarch64 or x64
if [ $# -le $min_parameters_count ]; then
build_number=$1
bundle_type=$2
architecture=$3 # aarch64 or x64
else
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
architecture=$5 # aarch64 or x64
fi
bundle_type=$(do_maketest)
do_maketest=$?
tag_prefix="jbr-"
OPENJDK_TAG=$(git log --simplify-by-decoration --decorate=short --pretty=short | grep "$tag_prefix" | cut -d "(" -f2 | cut -d ")" -f1 | awk '{print $2}' | sort -t "-" -k 2 -g | tail -n 1 | tr -d ",")
VERSION_FEATURE=$(getVersionProp "DEFAULT_VERSION_FEATURE")
VERSION_INTERIM=$(getVersionProp "DEFAULT_VERSION_INTERIM")
VERSION_UPDATE=$(getVersionProp "DEFAULT_VERSION_UPDATE")
[[ $VERSION_UPDATE = 0 ]] && JBSDK_VERSION="$VERSION_FEATURE" || JBSDK_VERSION="${VERSION_FEATURE}.${VERSION_INTERIM}.${VERSION_UPDATE}"
OPENJDK_TAG=$(git log --simplify-by-decoration --decorate=short --pretty=short | grep "$tag_prefix" | cut -d "(" -f2 | cut -d ")" -f1 | awk '{print $2}' | sort -t "-" -k 2 -g | tail -n 1)
JBSDK_VERSION=${JBSDK_VERSION:=$(echo $OPENJDK_TAG | awk -F "-|[+]" '{print $2}')}
echo "##teamcity[setParameter name='env.JBSDK_VERSION' value='${JBSDK_VERSION}']"
JDK_BUILD_NUMBER=${JDK_BUILD_NUMBER:=$(echo $OPENJDK_TAG | awk -F "-|[+]" '{print $3}')}
[ -z $JDK_BUILD_NUMBER ] && JDK_BUILD_NUMBER=1
echo "##teamcity[setParameter name='env.JDK_UPDATE_NUMBER' value='${JDK_BUILD_NUMBER}']"
JBSDK_VERSION_WITH_DOTS=$(echo $JBSDK_VERSION | sed 's/_/\./g')
VENDOR_NAME="JetBrains s.r.o."
VENDOR_VERSION_STRING="JBR-${JBSDK_VERSION}+${JDK_BUILD_NUMBER}-${build_number}"
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
@@ -64,40 +54,26 @@ case "$OS_NAME" in
BUILD_TIME="$(date --utc --date=@$SOURCE_DATE_EPOCH +%F)"
REPRODUCIBLE_TAR_OPTS="--mtime=@$SOURCE_DATE_EPOCH --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime"
;;
CYGWIN*)
COPYRIGHT_YEAR="$(date --utc --date=@$SOURCE_DATE_EPOCH +%Y)"
BUILD_TIME="$(date --utc --date=@$SOURCE_DATE_EPOCH +%F)"
REPRODUCIBLE_TAR_OPTS="--mtime=@$SOURCE_DATE_EPOCH --owner=0 --group=0 --numeric-owner --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime"
;;
Darwin)
COPYRIGHT_YEAR="$(date -u -r $SOURCE_DATE_EPOCH +%Y)"
BUILD_TIME="$(date -u -r $SOURCE_DATE_EPOCH +%F)"
TOUCH_TIME="$(date -u -r $SOURCE_DATE_EPOCH +%Y%m%d%H%M.%S)"
REPRODUCIBLE_TAR_OPTS="--uid 0 --gid 0 --numeric-owner"
;;
*)
# TODO: Windows
;;
esac
WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS="--with-native-debug-symbols=zipped"
REPRODUCIBLE_BUILD_OPTS="--enable-reproducible-build
--with-source-date=$SOURCE_DATE_EPOCH
--with-hotspot-build-time=$BUILD_TIME
--with-copyright-year=$COPYRIGHT_YEAR
--disable-absolute-paths-in-output"
function zip_native_debug_symbols() {
image_bundle_path=$(echo $1 | cut -d"/" -f-4)
jbr_diz_name=$2
(cd $image_bundle_path && find . -name '*.diz' -exec rsync -R {} ../../../../dizfiles \; )
(cd dizfiles && find . -print0 | COPYFILE_DISABLE=1 \
tar --no-recursion --null -T - -czf ../"$jbr_diz_name".tar.gz) || do_exit $?
}
function do_exit() {
exit_code=$1
[ $do_reset_changes -eq 1 ] && git checkout HEAD jb/project/tools/common/modules.list src/java.desktop/share/classes/module-info.java
[ $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

View File

@@ -1,153 +1,82 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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
# 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
#
# This script makes test-image along with JDK images when bundle_type is set to "jcef".
# If the character 't' is added at the end of bundle_type then it also makes test-image along with JDK images.
# 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:
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument
# to configure
# By default JDK_BUILD_NUMBER is set zero
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_linux_aarch64
min_parameters_count=1
source jb/project/tools/common/scripts/common.sh
JCEF_PATH=${JCEF_PATH:=./jcef_linux_aarch64}
JBRSDK_BASE_NAME=jbrsdk-${JBSDK_VERSION}
function do_configure {
sh configure \
$WITH_DEBUG_LEVEL \
--with-vendor-name="$VENDOR_NAME" \
--with-vendor-version-string="$VENDOR_VERSION_STRING" \
--with-jvm-features=shenandoahgc \
--with-version-pre= \
--with-version-build="$JDK_BUILD_NUMBER" \
--with-version-opt=b"$build_number" \
--with-boot-jdk="$BOOT_JDK" \
--enable-cds=yes \
$REPRODUCIBLE_BUILD_OPTS \
$WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS \
|| do_exit $?
}
sh configure \
--with-debug-level=release \
--with-vendor-name="${VENDOR_NAME}" \
--with-vendor-version-string="${VENDOR_VERSION_STRING}" \
--with-jvm-features=shenandoahgc \
--with-version-pre= \
--with-version-build="${JDK_BUILD_NUMBER}" \
--with-version-opt=b${build_number} \
--with-boot-jdk=${BOOT_JDK} \
--enable-cds=yes \
$REPRODUCIBLE_BUILD_OPTS \
|| exit $?
make clean CONF=linux-aarch64-server-release || exit $?
make images CONF=linux-aarch64-server-release test-image || exit $?
function is_musl {
libc=$(ldd /bin/ls | grep 'musl' | head -1 | cut -d ' ' -f1)
if [ -z $libc ]; then
# This is not Musl, return 1 == false
return 1
fi
return 0
}
function create_image_bundle {
__bundle_name=$1
__arch_name=$2
__modules_path=$3
__modules=$4
libc_type_suffix=''
if is_musl; then libc_type_suffix='musl-' ; fi
[ "$bundle_type" == "fd" ] && [ "$__arch_name" == "$JBRSDK_BUNDLE" ] && __bundle_name=$__arch_name && fastdebug_infix="fastdebug-"
JBR=${__bundle_name}-${JBSDK_VERSION}-linux-${libc_type_suffix}aarch64-${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 [ "$__arch_name" == "$JBRSDK_BUNDLE" ]; then
sed 's/JBR/JBRSDK/g' "$IMAGES_DIR"/"$__arch_name"/release > release
mv release "$IMAGES_DIR"/"$__arch_name"/release
copy_jmods "$__modules" "$__modules_path" "$IMAGES_DIR"/"$__arch_name"/jmods
zip_native_debug_symbols $IMAGES_DIR/jdk "${JBR}_diz"
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 ...
(cd "$IMAGES_DIR" &&
find "$__arch_name" -print0 | LC_ALL=C sort -z | \
tar $REPRODUCIBLE_TAR_OPTS \
--no-recursion --null -T - -cf "$JBR".tar) || do_exit $?
mv "$IMAGES_DIR"/"$JBR".tar ./"$JBR".tar
[ -f "$JBR".tar.gz ] && rm "$JBR.tar.gz"
touch -c -d "@$SOURCE_DATE_EPOCH" "$JBR".tar
gzip "$JBR".tar || do_exit $?
rm -rf "${IMAGES_DIR:?}"/"$__arch_name"
}
WITH_DEBUG_LEVEL="--with-debug-level=release"
RELEASE_NAME=linux-aarch64-server-release
case "$bundle_type" in
"jcef")
do_reset_changes=1
do_maketest=1
;;
"nomod" | "")
bundle_type=""
;;
"fd")
do_reset_changes=1
WITH_DEBUG_LEVEL="--with-debug-level=fastdebug"
RELEASE_NAME=linux-aarch64-server-fastdebug
;;
esac
if [ -z "$INC_BUILD" ]; then
do_configure || do_exit $?
make clean CONF=$RELEASE_NAME || do_exit $?
fi
make images CONF=$RELEASE_NAME || do_exit $?
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk
JSDK_MODS_DIR=$IMAGES_DIR/jmods
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
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
git apply -p0 < jb/project/tools/patches/add_jcef_module_aarch64.patch || do_exit $?
update_jsdk_mods $JSDK $JCEF_PATH/jmods $JSDK/jmods $JSDK_MODS_DIR || do_exit $?
cp $JCEF_PATH/jmods/* $JSDK_MODS_DIR # $JSDK/jmods is not changed
rm -rf $BASE_DIR/$JBRSDK_BUNDLE
cp -r $JSDK $BASE_DIR/$JBRSDK_BUNDLE || exit $?
jbr_name_postfix="_${bundle_type}"
fi
echo Creating $JBSDK.tar.gz ...
sed 's/JBR/JBRSDK/g' ${BASE_DIR}/${JBRSDK_BUNDLE}/release > release
mv release ${BASE_DIR}/${JBRSDK_BUNDLE}/release
# create runtime image bundle
modules=$(xargs < jb/project/tools/common/modules.list | sed s/" "//g) || do_exit $?
create_image_bundle "jbr${jbr_name_postfix}" "jbr" $JSDK_MODS_DIR "$modules" || do_exit $?
# NB: --sort=name requires tar1.28
tar $REPRODUCIBLE_TAR_OPTS --sort=name -pcf $JBSDK.tar \
--exclude=*.debuginfo --exclude=demo --exclude=sample --exclude=man \
-C $BASE_DIR ${JBRSDK_BUNDLE} || exit $?
touch -c -d @$SOURCE_DATE_EPOCH $JBRSDK.tar
gzip $JBSDK.tar || exit $?
# create sdk image bundle
modules=$(cat $JSDK/release | grep MODULES | sed s/MODULES=//g | sed s/' '/','/g | sed s/\"//g | sed s/\\n//g) || do_exit $?
if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type" == "$JBRSDK_BUNDLE" ]; then
modules=${modules},$(get_mods_list "$JCEF_PATH"/jmods)
fi
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" $JBRSDK_BUNDLE $JSDK_MODS_DIR "$modules" || do_exit $?
JBR_BUNDLE=jbr
JBR_BASE_NAME=jbr-$JBSDK_VERSION
rm -rf $BASE_DIR/$JBR_BUNDLE
if [ $do_maketest -eq 1 ]; then
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-linux-${libc_type_suffix}test-aarch64-b${build_number}
echo Creating "$JBRSDK_TEST" ...
[ $do_reset_changes -eq 1 ] && git checkout HEAD jb/project/tools/common/modules.list src/java.desktop/share/classes/module-info.java
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
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 $?
do_exit 0
echo Modifying release info ...
grep -v \"^JAVA_VERSION\" ${JSDK}/release | grep -v \"^MODULES\" >> ${BASE_DIR}/${JBR_BUNDLE}/release
echo Creating $JBR.tar.gz ...
tar $REPRODUCIBLE_TAR_OPTS --sort=name -pcf $JBR.tar -C $BASE_DIR ${JBR_BUNDLE} || exit $?
touch -c -d @$SOURCE_DATE_EPOCH $JBR.tar
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,22 +1,27 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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
# 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
#
# This script makes test-image along with JDK images when bundle_type is set to "jcef".
# If the character 't' is added at the end of bundle_type then it also makes test-image along with JDK images.
# 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:
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument
# to configure
# By default JDK_BUILD_NUMBER is set zero
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_linux_x64
min_parameters_count=2
source jb/project/tools/common/scripts/common.sh
JCEF_PATH=${JCEF_PATH:=./jcef_linux_x64}
@@ -33,31 +38,17 @@ function do_configure {
--with-boot-jdk="$BOOT_JDK" \
--enable-cds=yes \
$REPRODUCIBLE_BUILD_OPTS \
$WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS \
|| do_exit $?
}
function is_musl {
libc=$(ldd /bin/ls | grep 'musl' | head -1 | cut -d ' ' -f1)
if [ -z $libc ]; then
# This is not Musl, return 1 == false
return 1
fi
return 0
}
function create_image_bundle {
__bundle_name=$1
__arch_name=$2
__modules_path=$3
__modules=$4
libc_type_suffix=''
if is_musl; then libc_type_suffix='musl-' ; fi
[ "$bundle_type" == "fd" ] && [ "$__arch_name" == "$JBRSDK_BUNDLE" ] && __bundle_name=$__arch_name && fastdebug_infix="fastdebug-"
JBR=${__bundle_name}-${JBSDK_VERSION}-linux-${libc_type_suffix}x64-${fastdebug_infix}b${build_number}
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"
@@ -70,7 +61,6 @@ function create_image_bundle {
sed 's/JBR/JBRSDK/g' "$IMAGES_DIR"/"$__arch_name"/release > release
mv release "$IMAGES_DIR"/"$__arch_name"/release
copy_jmods "$__modules" "$__modules_path" "$IMAGES_DIR"/"$__arch_name"/jmods
zip_native_debug_symbols $IMAGES_DIR/jdk "${JBR}_diz"
fi
# jmod does not preserve file permissions (JDK-8173610)
@@ -95,7 +85,6 @@ RELEASE_NAME=linux-x86_64-server-release
case "$bundle_type" in
"jcef")
do_reset_changes=1
do_maketest=1
;;
"nomod" | "")
bundle_type=""
@@ -130,7 +119,7 @@ if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
fi
# create runtime image bundle
modules=$(xargs < jb/project/tools/common/modules.list | sed s/" "//g) || do_exit $?
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
@@ -140,10 +129,10 @@ if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type
fi
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" $JBRSDK_BUNDLE $JSDK_MODS_DIR "$modules" || do_exit $?
if [ $do_maketest -eq 1 ]; then
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-linux-${libc_type_suffix}test-x64-b${build_number}
if [ "$bundle_type" == "jcef" ]; then
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-linux-test-x64-b${build_number}
echo Creating "$JBRSDK_TEST" ...
[ $do_reset_changes -eq 1 ] && git checkout HEAD jb/project/tools/common/modules.list src/java.desktop/share/classes/module-info.java
[ $do_reset_changes -eq 1 ] && git checkout HEAD modules.list src/java.desktop/share/classes/module-info.java
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"

View File

@@ -61,7 +61,7 @@ JBR_BASE_NAME=jbr-$JBSDK_VERSION
rm -rf $BASE_DIR/$JBR_BUNDLE
JBR=$JBR_BASE_NAME-linux-x86-b$build_number
grep -v javafx jb/project/tools/common/modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.x86
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 \
@@ -77,4 +77,4 @@ 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 $?
gzip $JBRSDK_TEST.tar || exit $?

View File

@@ -1,24 +1,29 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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
# 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
#
# This script makes test-image along with JDK images when bundle_type is set to "jcef".
# If the character 't' is added at the end of bundle_type then it also makes test-image along with JDK images.
# 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:
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument
# to configure
# By default JDK_BUILD_NUMBER is set zero
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_mac
# MACOSX_VERSION_MAX - specifies value for the --with-macosx-version-max parameter. By default it is 10.12.00 for x64
# and 11.00.00 for aarch64
min_parameters_count=3
source jb/project/tools/common/scripts/common.sh
JCEF_PATH=${JCEF_PATH:=./jcef_mac}
@@ -45,7 +50,6 @@ function do_configure {
--with-extra-cxxflags="-F$(pwd)/Frameworks" \
--with-extra-ldflags="-F$(pwd)/Frameworks" \
$REPRODUCIBLE_BUILD_OPTS \
$WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS \
|| do_exit $?
else
sh configure \
@@ -62,7 +66,6 @@ function do_configure {
--with-macosx-version-max="${MACOSX_VERSION_MAX:="10.12.00"}" \
--enable-cds=yes \
$REPRODUCIBLE_BUILD_OPTS \
$WITH_ZIPPED_NATIVE_DEBUG_SYMBOLS \
|| do_exit $?
fi
}
@@ -92,7 +95,6 @@ function create_image_bundle {
sed 's/JBR/JBRSDK/g' $JRE_CONTENTS/Home/release > release
mv release $JRE_CONTENTS/Home/release
copy_jmods "$__modules" "$__modules_path" "$JRE_CONTENTS"/Home/jmods
zip_native_debug_symbols $IMAGES_DIR/jdk-bundle/jdk-$JBSDK_VERSION.jdk "${JBR}_diz"
fi
cp -R "$JSDK"/../MacOS "$JRE_CONTENTS"
@@ -122,7 +124,6 @@ RELEASE_NAME=macosx-${CONF_ARCHITECTURE}-server-release
case "$bundle_type" in
"jcef")
do_reset_changes=1
do_maketest=1
;;
"nomod" | "")
bundle_type=""
@@ -143,7 +144,10 @@ make images CONF=$RELEASE_NAME || do_exit $?
IMAGES_DIR=build/$RELEASE_NAME/images
JSDK=$IMAGES_DIR/jdk-bundle/jdk-$JBSDK_VERSION.jdk/Contents/Home
major_version=$(echo "$JBSDK_VERSION_WITH_DOTS" | awk -F "." '{print $1}')
minor_version=$(echo "$JBSDK_VERSION_WITH_DOTS" | awk -F "." '{print $3}')
[ -z "$minor_version" -o "$minor_version" = "0" ] && version_dir=$major_version || version_dir=$JBSDK_VERSION_WITH_DOTS
JSDK=$IMAGES_DIR/jdk-bundle/jdk-$version_dir.jdk/Contents/Home
JSDK_MODS_DIR=$IMAGES_DIR/jmods
JBRSDK_BUNDLE=jbrsdk
@@ -156,7 +160,7 @@ if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
fi
# create runtime image bundle
modules=$(xargs < jb/project/tools/common/modules.list | sed s/" "//g) || do_exit $?
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
@@ -166,10 +170,10 @@ if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type
fi
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" "$JBRSDK_BUNDLE" "$JSDK_MODS_DIR" "$modules" || do_exit $?
if [ $do_maketest -eq 1 ]; then
if [ "$bundle_type" == "jcef" ]; then
JBRSDK_TEST=${JBRSDK_BUNDLE}-${JBSDK_VERSION}-osx-test-${architecture}-b${build_number}
echo Creating "$JBRSDK_TEST" ...
[ $do_reset_changes -eq 1 ] && git checkout HEAD jb/project/tools/common/modules.list src/java.desktop/share/classes/module-info.java
[ $do_reset_changes -eq 1 ] && git checkout HEAD modules.list src/java.desktop/share/classes/module-info.java
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 $?

View File

@@ -1,8 +1,8 @@
diff --git jb/project/tools/common/modules.list jb/project/tools/common/modules.list
index 522acb7cb43..c40e689d5de 100644
--- jb/project/tools/common/modules.list
+++ jb/project/tools/common/modules.list
@@ -51,4 +51,7 @@ jdk.unsupported.desktop,
diff --git modules.list modules.list
index 054f21d1ee0..d9a121f0273 100644
--- modules.list
+++ modules.list
@@ -49,4 +49,7 @@ jdk.unsupported,
jdk.xml.dom,
jdk.zipfs,
jdk.hotspot.agent,

View File

@@ -1,30 +0,0 @@
diff --git jb/project/tools/common/modules.list jb/project/tools/common/modules.list
index 522acb7..c40e689 100644
--- jb/project/tools/common/modules.list
+++ jb/project/tools/common/modules.list
@@ -51,4 +51,7 @@ jdk.unsupported.desktop,
jdk.xml.dom,
jdk.zipfs,
jdk.hotspot.agent,
-jdk.jcmd
+jdk.jcmd,
+jcef,
+gluegen.rt,
+jogl.all
diff --git src/java.desktop/share/classes/module-info.java src/java.desktop/share/classes/module-info.java
index 897647e..781d180 100644
--- src/java.desktop/share/classes/module-info.java
+++ src/java.desktop/share/classes/module-info.java
@@ -116,7 +116,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;

View File

@@ -1,16 +1,5 @@
#!/bin/bash
while getopts ":t" o; do
case "${o}" in
t)
t="With Teamcity tests info"
TC_PRINT=1
;;
esac
done
shift $((OPTIND-1))
NEWFILEPATH=$1
CONFIGID=$2
BUILDID=$3
@@ -18,7 +7,6 @@ TOKEN=$4
#
# Get the size of new artifact
#
unameOut="$(uname -s)"
case "${unameOut}" in
Linux*)
@@ -28,11 +16,7 @@ case "${unameOut}" in
NEWFILESIZE=$(stat -f%z "$NEWFILEPATH")
;;
CYGWIN*)
NEWFILESIZE=$(stat -c%s$4
#
# Get the size of new artifact
#
"$NEWFILEPATH")
NEWFILESIZE=$(stat -c%s "$NEWFILEPATH")
;;
MINGW*)
NEWFILESIZE=$(stat -c%s "$NEWFILEPATH")
@@ -41,88 +25,32 @@ case "${unameOut}" in
echo "Unknown machine: ${unameOut}"
exit 1
esac
FILENAME=$(basename ${NEWFILEPATH})
#
# Get pattern of artifact name
# Base filename pattern: <BUNDLE_TYPE>-<JDK_VERSION>-<OS>-<ARCH>-b<BUILD>.tar.gz: jbr_dcevm-17.0.2-osx-x64-b1234.tar.gz
# BUNDLE_TYPE: jbr, jbrsdk, jbr_dcevm, jbrsdk_jcef etc.
# OS_ARCH_PATTERN - <os_architecture>: osx-x64, linux-aarch64, windows-x64 etc.
echo "New size of $NEWFILEPATH = $NEWFILESIZE bytes."
BUNDLE_TYPE=jbrsdk
OS_ARCH_PATTERN=""
FILE_EXTENSION=tar.gz
# example: IntellijCustomJdk_Jdk17_Master_LinuxX64jcef
re='(jbr[a-z_]*).*-[0-9_\.]+-(.+)-b[0-9]+(.+)'
if [[ $FILENAME =~ $re ]]; then
BUNDLE_TYPE=${BASH_REMATCH[1]}
OS_ARCH_PATTERN=${BASH_REMATCH[2]}
FILE_EXTENSION=${BASH_REMATCH[3]}
fi
if [ $TC_PRINT -eq 1 ]; then
testname_file_ext=`echo $FILE_EXTENSION | sed 's/\./_/g'`
testname=$BUNDLE_TYPE"_"$OS_ARCH_PATTERN$testname_file_ext
echo \#\#teamcity[testStarted name=\'$testname\']
fi
echo "BUNDLE_TYPE: " $BUNDLE_TYPE
echo "OS_ARCH_PATTERN: " $OS_ARCH_PATTERN
echo "FILE_EXTENSION: " $FILE_EXTENSION
echo "New size of $FILENAME = $NEWFILESIZE bytes."
function test_failed_msg() {
if [ $3 -eq 1 ]; then
echo \#\#teamcity[testFailed name=\'$1\' message=\'$2\']
fi
}
function test_finished_msg() {
if [ $2 -eq 1 ]; then
echo \#\#teamcity[testFinished name=\'$1\']
fi
}
#
# Get previous successful build ID
# Example:
# CONFIGID=IntellijCustomJdk_Jdk17_Master_LinuxX64jcef
# BUILDID=12345678
#
# expected return value
# id="123".number="567"
#
CURL_RESPONSE=$(curl --header "Authorization: Bearer $TOKEN" "https://buildserver.labs.intellij.net/app/rest/builds/?locator=buildType:(id:$CONFIGID),status:success,count:1,finishDate:(build:$BUILDID,condition:before)")
re='id=\"([0-9]+)\".+number=\"([0-9\.]+)\"'
# ID: Previous successful build id
re='id=\"([0-9]+)\".+number=\"([0-9]+)\"'
ID=0
if [[ $CURL_RESPONSE =~ $re ]]; then
ID=${BASH_REMATCH[1]}
echo "BUILD Number: ${BASH_REMATCH[2]}"
else
msg="ERROR: can't find previous build"
echo $msg
echo "ERROR: can't find previous build"
echo $CURL_RESPONSE
test_failed_msg $testname $msg $TC_PRINT
test_finished_msg $testname $TC_PRINT
exit 1
fi
#
# Get artifacts from previous successful build
#
# expected return value
# name="jbrsdk_jcef*.tar.gz size="123'
#
CURL_RESPONSE=$(curl --header "Authorization: Bearer $TOKEN" "https://buildserver.labs.intellij.net/app/rest/builds/$ID?fields=id,number,artifacts(file(name,size))")
echo "Atrifacts of previous build of $CONFIGID :"
echo "Atrifacts of last pinned build of $CONFIGID :\n"
echo $CURL_RESPONSE
# Find binary size (in response) with reg exp
re='name=\"('$BUNDLE_TYPE'[^\"]+'${OS_ARCH_PATTERN}'[^\"]+'${FILE_EXTENSION}')\" size=\"([0-9]+)\"'
# Find size (in response) with reg exp
re='name=\"(jbrsdk_jcef[^\"]+\.tar\.gz)\" size=\"([0-9]+)\"'
if [[ $CURL_RESPONSE =~ $re ]]; then
OLDFILENAME=${BASH_REMATCH[1]}
@@ -133,20 +61,12 @@ if [[ $CURL_RESPONSE =~ $re ]]; then
let allowedSize=OLDFILESIZE+OLDFILESIZE/20 # use 5% threshold
echo "Allowed size = $allowedSize"
if [[ "$NEWFILESIZE" -gt "$allowedSize" ]]; then
msg="ERROR: new size is significally greater than prev size (need to investigate)"
echo $msg
test_failed_msg $testname $msg $TC_PRINT
test_finished_msg $testname $TC_PRINT
echo "ERROR: new size is significally greater than prev size (need to investigate)"
exit 1
else
echo "PASSED"
test_finished_msg $testname $TC_PRINT
fi
else
msg="ERROR: can't find string with size in xml response:"
echo $msg
echo "ERROR: can't find string with size in xml response:"
echo $CURL_RESPONSE
test_failed_msg $testname $msg $TC_PRINT
test_finished_msg $testname $TC_PRINT
exit 1
fi

View File

@@ -1,22 +1,27 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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
# 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
#
# This script makes test-image along with JDK images when bundle_type is set to "jcef".
# If the character 't' is added at the end of bundle_type then it also makes test-image along with JDK images.
# 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:
# JDK_BUILD_NUMBER - specifies update release of OpenJDK build or the value of --with-version-build argument
# to configure
# By default JDK_BUILD_NUMBER is set zero
# JCEF_PATH - specifies the path to the directory with JCEF binaries.
# By default JCEF binaries should be located in ./jcef_win_x64
min_parameters_count=2
source jb/project/tools/common/scripts/common.sh
WORK_DIR=$(pwd)
@@ -34,9 +39,7 @@ function do_configure {
--with-toolchain-version=$TOOLCHAIN_VERSION \
--with-boot-jdk=$BOOT_JDK \
--disable-ccache \
--enable-cds=yes \
$REPRODUCIBLE_BUILD_OPTS \
|| do_exit $?
--enable-cds=yes || do_exit $?
}
function create_image_bundle {
@@ -66,7 +69,6 @@ RELEASE_NAME=windows-x86_64-server-release
case "$bundle_type" in
"jcef")
do_reset_changes=0
do_maketest=1
;;
"nomod" | "")
bundle_type=""
@@ -80,13 +82,13 @@ esac
if [ -z "$INC_BUILD" ]; then
do_configure || do_exit $?
if [ $do_maketest -eq 1 ]; then
if [ "$bundle_type" == "jcef" ]; then
make LOG=info CONF=$RELEASE_NAME clean images test-image || do_exit $?
else
make LOG=info CONF=$RELEASE_NAME clean images || do_exit $?
fi
else
if [ $do_maketest -eq 1 ]; then
if [ "$bundle_type" == "jcef" ]; then
make LOG=info CONF=$RELEASE_NAME images test-image || do_exit $?
else
make LOG=info CONF=$RELEASE_NAME images || do_exit $?
@@ -106,9 +108,8 @@ if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ]; then
jbr_name_postfix="_${bundle_type}"
fi
# create runtime image bundlef
modules=$(xargs < jb/project/tools/common/modules.list | sed s/" "//g) || do_exit $?
modules+=",jdk.crypto.mscapi"
# 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
@@ -118,4 +119,4 @@ if [ "$bundle_type" == "jcef" ] || [ "$bundle_type" == "fd" ] || [ "$bundle_type
fi
create_image_bundle "$JBRSDK_BUNDLE${jbr_name_postfix}" "$JBRSDK_BUNDLE" "$JSDK_MODS_DIR" "$modules" || do_exit $?
do_exit 0
do_exit 0

View File

@@ -53,8 +53,7 @@ mv release ${JBRSDK_BUNDLE}/release
JBR_BUNDLE=jbr
rm -rf ${JBR_BUNDLE}
grep -v javafx jb/project/tools/common/modules.list | grep -v "jdk.internal.vm\|jdk.aot\|jcef" > modules.list.x86
echo ",jdk.crypto.mscapi" >> modules.list.x86
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 $?

View File

@@ -1,19 +1,29 @@
#!/bin/bash -x
# The following parameters must be specified:
# 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
# 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
#
# This script packs test-image along with JDK images when bundle_type is set to "jcef".
# If the character 't' is added at the end of bundle_type then it also makes test-image along with JDK images.
# 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
[ "$bundle_type" == "jcef" ] && do_maketest=1
JBSDK_VERSION=$1
JDK_BUILD_NUMBER=$2
build_number=$3
bundle_type=$4
function pack_jbr {
__bundle_name=$1
@@ -41,7 +51,7 @@ fi
pack_jbr jbr${jbr_name_postfix} jbr
pack_jbr jbrsdk${jbr_name_postfix} jbrsdk
if [ $do_maketest -eq 1 ]; then
if [ "$bundle_type" == "jcef" ]; then
JBRSDK_TEST=$JBRSDK_BUNDLE-$JBSDK_VERSION-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 $?

View File

@@ -95,24 +95,8 @@ AC_DEFUN([FLAGS_SETUP_DEBUG_SYMBOLS],
# info flags for toolchains unless we know they work.
# See JDK-8207057.
ASFLAGS_DEBUG_SYMBOLS=""
# Debug prefix mapping if supported by compiler
DEBUG_PREFIX_CFLAGS=
# Debug symbols
if test "x$TOOLCHAIN_TYPE" = xgcc; then
if test "x$ALLOW_ABSOLUTE_PATHS_IN_OUTPUT" = "xfalse"; then
# Check if compiler supports -fdebug-prefix-map. If so, use that to make
# the debug symbol paths resolve to paths relative to the workspace root.
workspace_root_trailing_slash="${WORKSPACE_ROOT%/}/"
DEBUG_PREFIX_CFLAGS="-fdebug-prefix-map=${workspace_root_trailing_slash}="
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${DEBUG_PREFIX_CFLAGS}],
IF_FALSE: [
DEBUG_PREFIX_CFLAGS=
]
)
fi
CFLAGS_DEBUG_SYMBOLS="-g"
ASFLAGS_DEBUG_SYMBOLS="-g"
elif test "x$TOOLCHAIN_TYPE" = xclang; then
@@ -124,11 +108,6 @@ AC_DEFUN([FLAGS_SETUP_DEBUG_SYMBOLS],
CFLAGS_DEBUG_SYMBOLS="-Z7"
fi
if test "x$DEBUG_PREFIX_CFLAGS" != x; then
CFLAGS_DEBUG_SYMBOLS="$CFLAGS_DEBUG_SYMBOLS $DEBUG_PREFIX_CFLAGS"
ASFLAGS_DEBUG_SYMBOLS="$ASFLAGS_DEBUG_SYMBOLS $DEBUG_PREFIX_CFLAGS"
fi
AC_SUBST(CFLAGS_DEBUG_SYMBOLS)
AC_SUBST(ASFLAGS_DEBUG_SYMBOLS)
])
@@ -799,12 +778,16 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
FILE_MACRO_CFLAGS=
]
)
# -fdebug-prefix-map is supported by all modern versions of gcc/clang
DEBUG_PREFIX_CFLAGS=" -fdebug-prefix-map=${workspace_root_trailing_slash}="
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft &&
test "x$ENABLE_REPRODUCIBLE_BUILD" = xtrue; then
# There is a known issue with the pathmap if the mapping is made to the
# empty string. Add a minimal string "s" as prefix to work around this.
workspace_root_win=`$FIXPATH_BASE print "${WORKSPACE_ROOT%/}"`
# PATHMAP_FLAGS is also added to LDFLAGS in flags-ldflags.m4.
PATHMAP_FLAGS="-pathmap:${WORKSPACE_ROOT}=s"
PATHMAP_FLAGS="-pathmap:${workspace_root_win//\//\\\\}=s \
-pathmap:${workspace_root_win}=s"
FILE_MACRO_CFLAGS="$PATHMAP_FLAGS"
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${FILE_MACRO_CFLAGS}],
PREFIX: $3,
@@ -829,12 +812,12 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
$TOOLCHAIN_CFLAGS_JVM ${$1_TOOLCHAIN_CFLAGS_JVM} \
$OS_CFLAGS $OS_CFLAGS_JVM $CFLAGS_OS_DEF_JVM $DEBUG_CFLAGS_JVM \
$WARNING_CFLAGS $WARNING_CFLAGS_JVM $JVM_PICFLAG $FILE_MACRO_CFLAGS \
$REPRODUCIBLE_CFLAGS"
$REPRODUCIBLE_CFLAGS $DEBUG_PREFIX_CFLAGS"
CFLAGS_JDK_COMMON="$ALWAYS_CFLAGS_JDK $ALWAYS_DEFINES_JDK $TOOLCHAIN_CFLAGS_JDK \
$OS_CFLAGS $CFLAGS_OS_DEF_JDK $DEBUG_CFLAGS_JDK $DEBUG_OPTIONS_FLAGS_JDK \
$WARNING_CFLAGS $WARNING_CFLAGS_JDK $DEBUG_SYMBOLS_CFLAGS_JDK \
$FILE_MACRO_CFLAGS $REPRODUCIBLE_CFLAGS"
$FILE_MACRO_CFLAGS $REPRODUCIBLE_CFLAGS $DEBUG_PREFIX_CFLAGS"
# Use ${$2EXTRA_CFLAGS} to block EXTRA_CFLAGS to be added to build flags.
# (Currently we don't have any OPENJDK_BUILD_EXTRA_CFLAGS, but that might

View File

@@ -82,6 +82,14 @@ AC_DEFUN([FLAGS_SETUP_ASFLAGS],
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
BASIC_ASFLAGS="-nologo -c"
fi
if test "x$ALLOW_ABSOLUTE_PATHS_IN_OUTPUT" = "xfalse"; then
if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then
workspace_root_trailing_slash="${WORKSPACE_ROOT%/}/"
BASIC_ASFLAGS+=" -fdebug-prefix-map=${workspace_root_trailing_slash}="
fi
fi
AC_SUBST(BASIC_ASFLAGS)
if test "x$OPENJDK_TARGET_OS" = xmacosx; then

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 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
@@ -230,6 +230,8 @@ AC_DEFUN([UTIL_GET_MATCHING_VALUES],
# Converts an ISO-8601 date/time string to a unix epoch timestamp. If no
# suitable conversion method was found, an empty string is returned.
#
# Sets the specified variable to the resulting list.
#
# $1: result variable name
# $2: input date/time string
AC_DEFUN([UTIL_GET_EPOCH_TIMESTAMP],
@@ -239,16 +241,11 @@ AC_DEFUN([UTIL_GET_EPOCH_TIMESTAMP],
timestamp=$($DATE --utc --date=$2 +"%s" 2> /dev/null)
else
# BSD date
# ISO-8601 date&time in Zulu 'date'T'time'Z
timestamp=$($DATE -u -j -f "%FT%TZ" "$2" "+%s" 2> /dev/null)
timestamp=$($DATE -u -j -f "%F %T" "$2" "+%s" 2> /dev/null)
if test "x$timestamp" = x; then
# BSD date cannot handle trailing milliseconds.
# Try again ignoring characters at end
timestamp=$($DATE -u -j -f "%Y-%m-%dT%H:%M:%S" "$2" "+%s" 2> /dev/null)
fi
if test "x$timestamp" = x; then
# Perhaps the time was missing.
timestamp=$($DATE -u -j -f "%FT%TZ" "$2""T00:00:00Z" "+%s" 2> /dev/null)
# Perhaps the time was missing
timestamp=$($DATE -u -j -f "%F %T" "$2 00:00:00" "+%s" 2> /dev/null)
# If this did not work, we give up and return the empty string
fi
fi
$1=$timestamp

View File

@@ -0,0 +1,55 @@
#
# Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# 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.
#
# Default version, product, and vendor information to use,
# unless overridden by configure
DEFAULT_VERSION_FEATURE=15
DEFAULT_VERSION_INTERIM=0
DEFAULT_VERSION_UPDATE=0
DEFAULT_VERSION_PATCH=0
DEFAULT_VERSION_EXTRA1=0
DEFAULT_VERSION_EXTRA2=0
DEFAULT_VERSION_EXTRA3=0
DEFAULT_VERSION_DATE=2020-09-15
DEFAULT_VERSION_CLASSFILE_MAJOR=59 # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
DEFAULT_VERSION_CLASSFILE_MINOR=0
DEFAULT_ACCEPTABLE_BOOT_VERSIONS="14 15"
DEFAULT_JDK_SOURCE_TARGET_VERSION=15
DEFAULT_PROMOTED_VERSION_PRE=
LAUNCHER_NAME=openjdk
PRODUCT_NAME=OpenJDK
PRODUCT_SUFFIX="Runtime Environment"
JDK_RC_PLATFORM_NAME=Platform
COMPANY_NAME=N/A
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
# Might need better names for these
MACOSX_BUNDLE_NAME_BASE="OpenJDK"
MACOSX_BUNDLE_ID_BASE="net.java.openjdk"

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 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
@@ -193,8 +193,7 @@ define SetupJarArchiveBody
$1_UPDATE_CONTENTS=\
if [ "`$(WC) -l $$($1_BIN)/_the.$$($1_JARNAME)_contents | $(AWK) '{ print $$$$1 }'`" -gt "0" ]; then \
$(ECHO) " updating" `$(WC) -l $$($1_BIN)/_the.$$($1_JARNAME)_contents | $(AWK) '{ print $$$$1 }'` files && \
$(SORT) $$($1_BIN)/_the.$$($1_JARNAME)_contents > $$($1_BIN)/_the.$$($1_JARNAME)_contents_sorted && \
$$($1_JAR_CMD) --update $$($1_JAR_OPTIONS) --file $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents_sorted; \
$$($1_JAR_CMD) --update $$($1_JAR_OPTIONS) --file $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents; \
fi $$(NEWLINE)
# The s-variants of the above macros are used when the jar is created from scratch.
# NOTICE: please leave the parentheses space separated otherwise the AIX build will break!
@@ -213,9 +212,7 @@ define SetupJarArchiveBody
| $(SED) 's|$$(src)/|-C $$(src) |g' >> \
$$($1_BIN)/_the.$$($1_JARNAME)_contents) $$(NEWLINE) )
endif
$1_SUPDATE_CONTENTS=\
$(SORT) $$($1_BIN)/_the.$$($1_JARNAME)_contents > $$($1_BIN)/_the.$$($1_JARNAME)_contents_sorted && \
$$($1_JAR_CMD) --update $$($1_JAR_OPTIONS) --file $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents_sorted $$(NEWLINE)
$1_SUPDATE_CONTENTS=$$($1_JAR_CMD) --update $$($1_JAR_OPTIONS) --file $$@ @$$($1_BIN)/_the.$$($1_JARNAME)_contents $$(NEWLINE)
# Use a slightly shorter name for logging, but with enough path to identify this jar.
$1_NAME:=$$(subst $$(OUTPUTDIR)/,,$$($1_JAR))

View File

@@ -1,5 +1,5 @@
#
# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2011, 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
@@ -358,20 +358,6 @@ define SetupCompileNativeFileBody
# Compile as preprocessed assembler file
$1_FLAGS := $(BASIC_ASFLAGS) $$($1_BASE_ASFLAGS)
$1_COMPILER := $(AS)
# gcc assembly files must contain an appropriate relative .file
# path for reproducible builds.
ifeq ($(TOOLCHAIN_TYPE), gcc)
# If no absolute paths allowed, work out relative source file path
# for assembly .file substitution, otherwise use full file path
ifeq ($(ALLOW_ABSOLUTE_PATHS_IN_OUTPUT), false)
$1_REL_ASM_SRC := $$(call RelativePath, $$($1_FILE), $(WORKSPACE_ROOT))
else
$1_REL_ASM_SRC := $$($1_FILE)
endif
$1_FLAGS := $$($1_FLAGS) -DASSEMBLY_SRC_FILE='"$$($1_REL_ASM_SRC)"' \
-include $(TOPDIR)/make/data/autoheaders/assemblyprefix.h
endif
else ifneq ($$(filter %.cpp %.cc %.mm, $$($1_FILENAME)), )
# Compile as a C++ or Objective-C++ file
$1_FLAGS := $(CFLAGS_CCACHE) $$($1_USE_PCH_FLAGS) $$($1_BASE_CXXFLAGS) \
@@ -403,12 +389,6 @@ define SetupCompileNativeFileBody
$1_OBJ_DEPS := $$($1_SRC_FILE) $$($$($1_BASE)_COMPILE_VARDEPS_FILE) \
$$($$($1_BASE)_EXTRA_DEPS) $$($1_VARDEPS_FILE)
$1_COMPILE_OPTIONS := $$($1_FLAGS) $(CC_OUT_OPTION)$$($1_OBJ) $$($1_SRC_FILE)
# For reproducible builds with gcc ensure random symbol generation is seeded deterministically
ifeq ($(TOOLCHAIN_TYPE), gcc)
ifeq ($$(ENABLE_REPRODUCIBLE_BUILD), true)
$1_COMPILE_OPTIONS += -frandom-seed="$$($1_FILENAME)"
endif
endif
$$($1_OBJ_JSON): $$($1_OBJ_DEPS)
$$(call WriteCompileCommandsFragment, $$@, $$(PWD), $$($1_SRC_FILE), \

View File

@@ -1,29 +0,0 @@
#
# Copyright (c) 2022, 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.
#
// ASSEMBLY_SRC_FILE gets replaced by relative or absolute file path
// in NativeCompilation.gmk for gcc tooling on Linux. This ensures a
// reproducible object file through a predictable value of the STT_FILE
// symbol, and subsequently a reproducible .debuginfo.
.file ASSEMBLY_SRC_FILE

View File

@@ -58,9 +58,6 @@ ifeq ($(call check-jvm-feature, compiler2), true)
ADLC_CFLAGS += -I$(TOPDIR)/src/hotspot/share
# Add file macro mappings
ADLC_CFLAGS += $(FILE_MACRO_CFLAGS)
$(eval $(call SetupNativeCompilation, BUILD_ADLC, \
NAME := adlc, \
TYPE := EXECUTABLE, \

View File

@@ -84,7 +84,7 @@ ifneq ($(call check-jvm-feature, jvmti), true)
jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \
jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \
jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \
jvmtiClassFileReconstituter.cpp jvmtiTagMapTable.cpp jvmtiEnhancedRedefineClasses.cpp
jvmtiClassFileReconstituter.cpp jvmtiTagMapTable.cpp
endif
ifneq ($(call check-jvm-feature, jvmci), true)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 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
@@ -204,10 +204,6 @@ public class MakeZipReproducible {
entry.setTimeLocal(timestamp);
}
// Ensure "extra" field is not set from original ZipEntry info that may be not deterministic
// eg.may contain specific UID/GID
entry.setExtra(null);
zos.putNextEntry(entry);
if (entry.getSize() > 0 && entryInputStream != null) {
entryInputStream.transferTo(zos);

View File

@@ -84,7 +84,7 @@ TARGETS += $(COPY_LEGAL)
################################################################################
FONTFILE_SRC_DIR := $(TOPDIR)/src/java.desktop/share
FONTFILE_SRCS := $(wildcard $(FONTFILE_SRC_DIR)/fonts/*.ttf) $(wildcard $(FONTFILE_SRC_DIR)/fonts/*.otf) $(FONTFILE_SRC_DIR)/fonts/fonts.dir $(FONTFILE_SRC_DIR)/fonts/font.conf
FONTFILE_SRCS := $(wildcard $(FONTFILE_SRC_DIR)/fonts/*.ttf) $(FONTFILE_SRC_DIR)/fonts/fonts.dir $(FONTFILE_SRC_DIR)/fonts/font.conf
FONTFILE_TARGET_FILES := $(subst $(FONTFILE_SRC_DIR),$(LIB_DST_DIR),$(FONTFILE_SRCS))
$(LIB_DST_DIR)/fonts/%: $(FONTFILE_SRC_DIR)/fonts/%

View File

@@ -31,6 +31,7 @@
#define ELF_TYPE(name, description) .type name,description
#endif
.file "bsd_x86_32.S"
.globl SYMBOL(fixcw)
# NOTE WELL! The _Copy functions are called directly

View File

@@ -30,6 +30,7 @@
#define ELF_TYPE(name, description) .type name,description
#endif
.file "bsd_x86_64.S"
# NOTE WELL! The _Copy functions are called directly
# from server-compiler-generated code via CallLeafNoFP,
# which means that they *must* either not use floating

View File

@@ -19,6 +19,7 @@
// or visit www.oracle.com if you need additional information or have any
// questions.
.file "atomic_linux_aarch64.S"
.text

View File

@@ -21,6 +21,8 @@
* questions.
*
*/
.file "copy_linux_aarch64.S"
.global _Copy_conjoint_words
.global _Copy_disjoint_words

View File

@@ -19,6 +19,8 @@
// or visit www.oracle.com if you need additional information or have any
// questions.
.file "threadLS_linux_aarch64.S"
// JavaThread::aarch64_get_thread_helper()
//
// Return the current thread pointer in x0.

View File

@@ -21,6 +21,7 @@
# questions.
#
.file "linux_arm_32.S"
# NOTE WELL! The _Copy functions are called directly
# from server-compiler-generated code via CallLeafNoFP,

View File

@@ -22,6 +22,8 @@
#
.file "linux_x86_32.S"
# NOTE WELL! The _Copy functions are called directly
# from server-compiler-generated code via CallLeafNoFP,
# which means that they *must* either not use floating

View File

@@ -21,6 +21,8 @@
# questions.
#
.file "linux_x86_64.S"
# NOTE WELL! The _Copy functions are called directly
# from server-compiler-generated code via CallLeafNoFP,
# which means that they *must* either not use floating

View File

@@ -335,6 +335,16 @@ void ClassLoaderData::classes_do(KlassClosure* klass_closure) {
}
}
void ClassLoaderData::initialized_classes_do(KlassClosure* klass_closure) {
// Lock-free access requires load_acquire
for (Klass* k = Atomic::load_acquire(&_klasses); k != NULL; k = k->next_link()) {
if (k->is_instance_klass() && InstanceKlass::cast(k)->is_initialized()) {
klass_closure->do_klass(k);
}
assert(k != k->next_link(), "no loops!");
}
}
void ClassLoaderData::classes_do(void f(Klass * const)) {
// Lock-free access requires load_acquire
for (Klass* k = Atomic::load_acquire(&_klasses); k != NULL; k = k->next_link()) {

View File

@@ -272,6 +272,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
void oops_do(OopClosure* f, int claim_value, bool clear_modified_oops = false);
void classes_do(KlassClosure* klass_closure);
void initialized_classes_do(KlassClosure* klass_closure);
Klass* klasses() { return _klasses; }
JNIMethodBlock* jmethod_ids() const { return _jmethod_ids; }

View File

@@ -361,6 +361,13 @@ void ClassLoaderDataGraph::classes_do(KlassClosure* klass_closure) {
}
}
void ClassLoaderDataGraph::initialized_classes_do(KlassClosure* klass_closure) {
ClassLoaderDataGraphIterator iter;
while (ClassLoaderData* cld = iter.get_next()) {
cld->initialized_classes_do(klass_closure);
}
}
void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
ClassLoaderDataGraphIterator iter;
while (ClassLoaderData* cld = iter.get_next()) {

View File

@@ -79,6 +79,9 @@ class ClassLoaderDataGraph : public AllStatic {
// Walking the ClassLoaderDataGraph also includes hidden classes.
static void classes_do(KlassClosure* klass_closure);
// Enhanced class redefinition
static void initialized_classes_do(KlassClosure* klass_closure);
static void classes_do(void f(Klass* const));
static void methods_do(void f(Method*));
static void modules_do(void f(ModuleEntry*));

View File

@@ -68,7 +68,6 @@ static bool enable() {
}
_enabled = FlightRecorder;
assert(_enabled, "invariant");
AllowEnhancedClassRedefinition = false;
return _enabled;
}

View File

@@ -341,9 +341,9 @@ void PhaseIdealLoop::clone_skeleton_predicates_to_unswitched_loop(IdealLoopTree*
assert(predicate->is_Proj() && predicate->as_Proj()->is_IfProj(), "predicate must be a projection of an if node");
IfProjNode* predicate_proj = predicate->as_IfProj();
ProjNode* fast_proj = clone_skeleton_predicate_for_unswitched_loops(iff, predicate_proj, reason, iffast_pred);
ProjNode* fast_proj = clone_skeleton_predicate_for_unswitched_loops(iff, predicate_proj, uncommon_proj, reason, iffast_pred, loop);
assert(skeleton_predicate_has_opaque(fast_proj->in(0)->as_If()), "must find skeleton predicate for fast loop");
ProjNode* slow_proj = clone_skeleton_predicate_for_unswitched_loops(iff, predicate_proj, reason, ifslow_pred);
ProjNode* slow_proj = clone_skeleton_predicate_for_unswitched_loops(iff, predicate_proj, uncommon_proj, reason, ifslow_pred, loop);
assert(skeleton_predicate_has_opaque(slow_proj->in(0)->as_If()), "must find skeleton predicate for slow loop");
// Update control dependent data nodes.
@@ -397,10 +397,10 @@ void PhaseIdealLoop::get_skeleton_predicates(Node* predicate, Unique_Node_List&
// Clone a skeleton predicate for an unswitched loop. OpaqueLoopInit and OpaqueLoopStride nodes are cloned and uncommon
// traps are kept for the predicate (a Halt node is used later when creating pre/main/post loops and copying this cloned
// predicate again).
ProjNode* PhaseIdealLoop::clone_skeleton_predicate_for_unswitched_loops(Node* iff, ProjNode* predicate,
Deoptimization::DeoptReason reason,
ProjNode* output_proj) {
Node* bol = clone_skeleton_predicate_bool(iff, NULL, NULL, output_proj);
ProjNode* PhaseIdealLoop::clone_skeleton_predicate_for_unswitched_loops(Node* iff, ProjNode* predicate, Node* uncommon_proj,
Deoptimization::DeoptReason reason, ProjNode* output_proj,
IdealLoopTree* loop) {
Node* bol = clone_skeleton_predicate_bool(iff, NULL, NULL, predicate, uncommon_proj, output_proj, loop);
ProjNode* proj = create_new_if_for_predicate(output_proj, NULL, reason, iff->Opcode(), predicate->is_IfTrue());
_igvn.replace_input_of(proj->in(0), 1, bol);
_igvn.replace_input_of(output_proj->in(0), 0, proj);

View File

@@ -1264,12 +1264,10 @@ void PhaseIdealLoop::copy_skeleton_predicates_to_main_loop_helper(Node* predicat
// Clone the skeleton predicate twice and initialize one with the initial
// value of the loop induction variable. Leave the other predicate
// to be initialized when increasing the stride during loop unrolling.
prev_proj = clone_skeleton_predicate_for_main_or_post_loop(iff, opaque_init, NULL, predicate, uncommon_proj,
current_proj, outer_loop, prev_proj);
prev_proj = clone_skeleton_predicate_for_main_loop(iff, opaque_init, NULL, predicate, uncommon_proj, current_proj, outer_loop, prev_proj);
assert(skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()), "");
prev_proj = clone_skeleton_predicate_for_main_or_post_loop(iff, init, stride, predicate, uncommon_proj,
current_proj, outer_loop, prev_proj);
prev_proj = clone_skeleton_predicate_for_main_loop(iff, init, stride, predicate, uncommon_proj, current_proj, outer_loop, prev_proj);
assert(!skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()), "");
// Rewire any control inputs from the cloned skeleton predicates down to the main and post loop for data nodes that are part of the
@@ -1346,7 +1344,8 @@ bool PhaseIdealLoop::skeleton_predicate_has_opaque(IfNode* iff) {
// Clone the skeleton predicate bool for a main or unswitched loop:
// Main loop: Set new_init and new_stride nodes as new inputs.
// Unswitched loop: new_init and new_stride are both NULL. Clone OpaqueLoopInit and OpaqueLoopStride instead.
Node* PhaseIdealLoop::clone_skeleton_predicate_bool(Node* iff, Node* new_init, Node* new_stride, Node* control) {
Node* PhaseIdealLoop::clone_skeleton_predicate_bool(Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj,
Node* control, IdealLoopTree* outer_loop) {
Node_Stack to_clone(2);
to_clone.push(iff->in(1), 1);
uint current = C->unique();
@@ -1422,9 +1421,9 @@ Node* PhaseIdealLoop::clone_skeleton_predicate_bool(Node* iff, Node* new_init, N
// Clone a skeleton predicate for the main loop. new_init and new_stride are set as new inputs. Since the predicates cannot fail at runtime,
// Halt nodes are inserted instead of uncommon traps.
Node* PhaseIdealLoop::clone_skeleton_predicate_for_main_or_post_loop(Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj,
Node* control, IdealLoopTree* outer_loop, Node* input_proj) {
Node* result = clone_skeleton_predicate_bool(iff, new_init, new_stride, control);
Node* PhaseIdealLoop::clone_skeleton_predicate_for_main_loop(Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj,
Node* control, IdealLoopTree* outer_loop, Node* input_proj) {
Node* result = clone_skeleton_predicate_bool(iff, new_init, new_stride, predicate, uncommon_proj, control, outer_loop);
Node* proj = predicate->clone();
Node* other_proj = uncommon_proj->clone();
Node* new_iff = iff->clone();
@@ -1438,8 +1437,8 @@ Node* PhaseIdealLoop::clone_skeleton_predicate_for_main_or_post_loop(Node* iff,
C->root()->add_req(halt);
new_iff->set_req(0, input_proj);
register_control(new_iff, outer_loop == _ltree_root ? _ltree_root : outer_loop->_parent, input_proj);
register_control(proj, outer_loop == _ltree_root ? _ltree_root : outer_loop->_parent, new_iff);
register_control(new_iff, outer_loop->_parent, input_proj);
register_control(proj, outer_loop->_parent, new_iff);
register_control(other_proj, _ltree_root, new_iff);
register_control(halt, _ltree_root, other_proj);
return proj;
@@ -1522,8 +1521,7 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n
// Add the post loop
const uint idx_before_pre_post = Compile::current()->unique();
CountedLoopNode *post_head = NULL;
Node* post_incr = incr;
Node* main_exit = insert_post_loop(loop, old_new, main_head, main_end, post_incr, limit, post_head);
Node *main_exit = insert_post_loop(loop, old_new, main_head, main_end, incr, limit, post_head);
const uint idx_after_post_before_pre = Compile::current()->unique();
//------------------------------
@@ -1622,7 +1620,6 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n
assert(post_head->in(1)->is_IfProj(), "must be zero-trip guard If node projection of the post loop");
copy_skeleton_predicates_to_main_loop(pre_head, castii, stride, outer_loop, outer_main_head, dd_main_head,
idx_before_pre_post, idx_after_post_before_pre, min_taken, post_head->in(1), old_new);
copy_skeleton_predicates_to_post_loop(outer_main_head, post_head, post_incr, stride);
// Step B4: Shorten the pre-loop to run only 1 iteration (for now).
// RCE and alignment may change this later.
@@ -1745,7 +1742,6 @@ void PhaseIdealLoop::insert_vector_post_loop(IdealLoopTree *loop, Node_List &old
// In this case we throw away the result as we are not using it to connect anything else.
CountedLoopNode *post_head = NULL;
insert_post_loop(loop, old_new, main_head, main_end, incr, limit, post_head);
copy_skeleton_predicates_to_post_loop(main_head->skip_strip_mined(), post_head, incr, main_head->stride());
// It's difficult to be precise about the trip-counts
// for post loops. They are usually very short,
@@ -1792,7 +1788,6 @@ void PhaseIdealLoop::insert_scalar_rced_post_loop(IdealLoopTree *loop, Node_List
// In this case we throw away the result as we are not using it to connect anything else.
CountedLoopNode *post_head = NULL;
insert_post_loop(loop, old_new, main_head, main_end, incr, limit, post_head);
copy_skeleton_predicates_to_post_loop(main_head->skip_strip_mined(), post_head, incr, main_head->stride());
// It's difficult to be precise about the trip-counts
// for post loops. They are usually very short,
@@ -1809,9 +1804,9 @@ void PhaseIdealLoop::insert_scalar_rced_post_loop(IdealLoopTree *loop, Node_List
//------------------------------insert_post_loop-------------------------------
// Insert post loops. Add a post loop to the given loop passed.
Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new,
CountedLoopNode* main_head, CountedLoopEndNode* main_end,
Node*& incr, Node* limit, CountedLoopNode*& post_head) {
Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree *loop, Node_List &old_new,
CountedLoopNode *main_head, CountedLoopEndNode *main_end,
Node *incr, Node *limit, CountedLoopNode *&post_head) {
IfNode* outer_main_end = main_end;
IdealLoopTree* outer_loop = loop;
if (main_head->is_strip_mined()) {
@@ -1895,8 +1890,8 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new,
}
// CastII for the new post loop:
incr = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head);
assert(incr != NULL, "no castII inserted");
Node* castii = cast_incr_before_loop(zer_opaq->in(1), zer_taken, post_head);
assert(castii != NULL, "no castII inserted");
return new_main_exit;
}
@@ -1938,8 +1933,7 @@ void PhaseIdealLoop::update_main_loop_skeleton_predicates(Node* ctrl, CountedLoo
_igvn.replace_input_of(iff, 1, iff->in(1)->in(2));
} else {
// Add back predicates updated for the new stride.
prev_proj = clone_skeleton_predicate_for_main_or_post_loop(iff, init, max_value, entry, proj, ctrl, outer_loop,
prev_proj);
prev_proj = clone_skeleton_predicate_for_main_loop(iff, init, max_value, entry, proj, ctrl, outer_loop, prev_proj);
assert(!skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()), "unexpected");
}
}
@@ -1951,34 +1945,6 @@ void PhaseIdealLoop::update_main_loop_skeleton_predicates(Node* ctrl, CountedLoo
}
}
void PhaseIdealLoop::copy_skeleton_predicates_to_post_loop(LoopNode* main_loop_head, CountedLoopNode* post_loop_head, Node* init, Node* stride) {
// Go over the skeleton predicates of the main loop and make a copy for the post loop with its initial iv value and
// stride as inputs.
Node* post_loop_entry = post_loop_head->in(LoopNode::EntryControl);
Node* main_loop_entry = main_loop_head->in(LoopNode::EntryControl);
IdealLoopTree* post_loop = get_loop(post_loop_head);
Node* ctrl = main_loop_entry;
Node* prev_proj = post_loop_entry;
while (ctrl != NULL && ctrl->is_Proj() && ctrl->in(0)->is_If()) {
IfNode* iff = ctrl->in(0)->as_If();
ProjNode* proj = iff->proj_out(1 - ctrl->as_Proj()->_con);
if (proj->unique_ctrl_out()->Opcode() != Op_Halt) {
break;
}
if (iff->in(1)->Opcode() == Op_Opaque4 && skeleton_predicate_has_opaque(iff)) {
prev_proj = clone_skeleton_predicate_for_main_or_post_loop(iff, init, stride, ctrl, proj, post_loop_entry,
post_loop, prev_proj);
assert(!skeleton_predicate_has_opaque(prev_proj->in(0)->as_If()), "unexpected");
}
ctrl = ctrl->in(0)->in(0);
}
if (prev_proj != post_loop_entry) {
_igvn.replace_input_of(post_loop_head, LoopNode::EntryControl, prev_proj);
set_idom(post_loop_head, prev_proj, dom_depth(post_loop_head));
}
}
//------------------------------do_unroll--------------------------------------
// Unroll the loop body one step - make each trip do 2 iterations.
void PhaseIdealLoop::do_unroll(IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip) {

View File

@@ -2150,14 +2150,12 @@ Node* CountedLoopNode::skip_predicates_from_entry(Node* ctrl) {
}
Node* CountedLoopNode::skip_predicates() {
Node* ctrl = in(LoopNode::EntryControl);
if (is_main_loop()) {
ctrl = skip_strip_mined()->in(LoopNode::EntryControl);
}
if (is_main_loop() || is_post_loop()) {
Node* ctrl = skip_strip_mined()->in(LoopNode::EntryControl);
return skip_predicates_from_entry(ctrl);
}
return ctrl;
return in(LoopNode::EntryControl);
}
@@ -3714,11 +3712,11 @@ bool PhaseIdealLoop::only_has_infinite_loops() {
//----------------------------build_and_optimize-------------------------------
// Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to
// its corresponding LoopNode. If 'optimize' is true, do some loop cleanups.
void PhaseIdealLoop::build_and_optimize() {
void PhaseIdealLoop::build_and_optimize(LoopOptsMode mode) {
assert(!C->post_loop_opts_phase(), "no loop opts allowed");
bool do_split_ifs = (_mode == LoopOptsDefault);
bool skip_loop_opts = (_mode == LoopOptsNone);
bool do_split_ifs = (mode == LoopOptsDefault);
bool skip_loop_opts = (mode == LoopOptsNone);
int old_progress = C->major_progress();
uint orig_worklist_size = _igvn._worklist.size();
@@ -3789,9 +3787,9 @@ void PhaseIdealLoop::build_and_optimize() {
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
// Nothing to do, so get out
bool stop_early = !C->has_loops() && !skip_loop_opts && !do_split_ifs && !_verify_me && !_verify_only &&
!bs->is_gc_specific_loop_opts_pass(_mode);
!bs->is_gc_specific_loop_opts_pass(mode);
bool do_expensive_nodes = C->should_optimize_expensive_nodes(_igvn);
bool strip_mined_loops_expanded = bs->strip_mined_loops_expanded(_mode);
bool strip_mined_loops_expanded = bs->strip_mined_loops_expanded(mode);
if (stop_early && !do_expensive_nodes) {
return;
}
@@ -3883,7 +3881,7 @@ void PhaseIdealLoop::build_and_optimize() {
if (_verify_only) {
C->restore_major_progress(old_progress);
assert(C->unique() == unique, "verification _mode made Nodes? ? ?");
assert(C->unique() == unique, "verification mode made Nodes? ? ?");
assert(_igvn._worklist.size() == orig_worklist_size, "shouldn't push anything");
return;
}
@@ -3913,8 +3911,8 @@ void PhaseIdealLoop::build_and_optimize() {
#ifndef PRODUCT
C->verify_graph_edges();
if (_verify_me) { // Nested verify pass?
// Check to see if the verify _mode is broken
assert(C->unique() == unique, "non-optimize _mode made Nodes? ? ?");
// Check to see if the verify mode is broken
assert(C->unique() == unique, "non-optimize mode made Nodes? ? ?");
return;
}
if (VerifyLoopOptimizations) verify();
@@ -3928,7 +3926,7 @@ void PhaseIdealLoop::build_and_optimize() {
return;
}
if (_mode == LoopOptsMaxUnroll) {
if (mode == LoopOptsMaxUnroll) {
for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
IdealLoopTree* lpt = iter.current();
if (lpt->is_innermost() && lpt->_allow_optimizations && !lpt->_has_call && lpt->is_counted()) {
@@ -3949,7 +3947,7 @@ void PhaseIdealLoop::build_and_optimize() {
return;
}
if (bs->optimize_loops(this, _mode, visited, nstack, worklist)) {
if (bs->optimize_loops(this, mode, visited, nstack, worklist)) {
return;
}
@@ -5353,45 +5351,38 @@ void PhaseIdealLoop::build_loop_late_post_work(Node *n, bool pinned) {
}
assert(early == legal || legal != C->root(), "bad dominance of inputs");
if (least != early) {
// Move the node above predicates as far up as possible so a
// following pass of loop predication doesn't hoist a predicate
// that depends on it above that node.
Node* new_ctrl = least;
for (;;) {
if (!new_ctrl->is_Proj()) {
break;
}
CallStaticJavaNode* call = new_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none);
if (call == NULL) {
break;
}
int req = call->uncommon_trap_request();
Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req);
if (trap_reason != Deoptimization::Reason_loop_limit_check &&
trap_reason != Deoptimization::Reason_predicate &&
trap_reason != Deoptimization::Reason_profile_predicate) {
break;
}
Node* c = new_ctrl->in(0)->in(0);
if (is_dominator(c, early) && c != early) {
break;
}
new_ctrl = c;
}
least = new_ctrl;
}
// Try not to place code on a loop entry projection
// which can inhibit range check elimination.
if (least != early && !BarrierSet::barrier_set()->barrier_set_c2()->is_gc_specific_loop_opts_pass(_mode)) {
if (least != early) {
Node* ctrl_out = least->unique_ctrl_out();
if (ctrl_out && ctrl_out->is_Loop() &&
least == ctrl_out->in(LoopNode::EntryControl) &&
(ctrl_out->is_CountedLoop() || ctrl_out->is_OuterStripMinedLoop())) {
Node* least_dom = idom(least);
if (get_loop(least_dom)->is_member(get_loop(least))) {
least = least_dom;
least == ctrl_out->in(LoopNode::EntryControl)) {
// Move the node above predicates as far up as possible so a
// following pass of loop predication doesn't hoist a predicate
// that depends on it above that node.
Node* new_ctrl = least;
for (;;) {
if (!new_ctrl->is_Proj()) {
break;
}
CallStaticJavaNode* call = new_ctrl->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none);
if (call == NULL) {
break;
}
int req = call->uncommon_trap_request();
Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req);
if (trap_reason != Deoptimization::Reason_loop_limit_check &&
trap_reason != Deoptimization::Reason_predicate &&
trap_reason != Deoptimization::Reason_profile_predicate) {
break;
}
Node* c = new_ctrl->in(0)->in(0);
if (is_dominator(c, early) && c != early) {
break;
}
new_ctrl = c;
}
least = new_ctrl;
}
}

View File

@@ -915,13 +915,13 @@ private:
void copy_skeleton_predicates_to_main_loop(CountedLoopNode* pre_head, Node* init, Node* stride, IdealLoopTree* outer_loop, LoopNode* outer_main_head,
uint dd_main_head, const uint idx_before_pre_post, const uint idx_after_post_before_pre,
Node* zero_trip_guard_proj_main, Node* zero_trip_guard_proj_post, const Node_List &old_new);
Node* clone_skeleton_predicate_for_main_or_post_loop(Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj, Node* control,
IdealLoopTree* outer_loop, Node* input_proj);
Node* clone_skeleton_predicate_bool(Node* iff, Node* new_init, Node* new_stride, Node* control);
Node* clone_skeleton_predicate_for_main_loop(Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj, Node* control,
IdealLoopTree* outer_loop, Node* input_proj);
Node* clone_skeleton_predicate_bool(Node* iff, Node* new_init, Node* new_stride, Node* predicate, Node* uncommon_proj, Node* control,
IdealLoopTree* outer_loop);
static bool skeleton_predicate_has_opaque(IfNode* iff);
static void get_skeleton_predicates(Node* predicate, Unique_Node_List& list, bool get_opaque = false);
void update_main_loop_skeleton_predicates(Node* ctrl, CountedLoopNode* loop_head, Node* init, int stride_con);
void copy_skeleton_predicates_to_post_loop(LoopNode* main_loop_head, CountedLoopNode* post_loop_head, Node* init, Node* stride);
void insert_loop_limit_check(ProjNode* limit_check_proj, Node* cmp_limit, Node* bol);
#ifdef ASSERT
bool only_has_infinite_loops();
@@ -1050,10 +1050,9 @@ private:
Node **_idom; // Array of immediate dominators
uint *_dom_depth; // Used for fast LCA test
GrowableArray<uint>* _dom_stk; // For recomputation of dom depth
LoopOptsMode _mode;
// build the loop tree and perform any requested optimizations
void build_and_optimize();
void build_and_optimize(LoopOptsMode mode);
// Dominators for the sea of nodes
void Dominators();
@@ -1064,10 +1063,9 @@ private:
_igvn(igvn),
_verify_me(nullptr),
_verify_only(false),
_mode(mode),
_nodes_required(UINT_MAX) {
assert(mode != LoopOptsVerify, "wrong constructor to verify IdealLoop");
build_and_optimize();
build_and_optimize(mode);
}
#ifndef PRODUCT
@@ -1078,9 +1076,8 @@ private:
_igvn(igvn),
_verify_me(verify_me),
_verify_only(verify_me == nullptr),
_mode(LoopOptsVerify),
_nodes_required(UINT_MAX) {
build_and_optimize();
build_and_optimize(LoopOptsVerify);
}
#endif
@@ -1247,9 +1244,9 @@ public:
void insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_new, bool peel_only );
// Add post loop after the given loop.
Node *insert_post_loop(IdealLoopTree* loop, Node_List& old_new,
CountedLoopNode* main_head, CountedLoopEndNode* main_end,
Node*& incr, Node* limit, CountedLoopNode*& post_head);
Node *insert_post_loop(IdealLoopTree *loop, Node_List &old_new,
CountedLoopNode *main_head, CountedLoopEndNode *main_end,
Node *incr, Node *limit, CountedLoopNode *&post_head);
// Add an RCE'd post loop which we will multi-version adapt for run time test path usage
void insert_scalar_rced_post_loop( IdealLoopTree *loop, Node_List &old_new );
@@ -1582,9 +1579,8 @@ private:
Node_List* old_new = NULL);
void clone_skeleton_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new, Deoptimization::DeoptReason reason,
ProjNode* old_predicate_proj, ProjNode* iffast_pred, ProjNode* ifslow_pred);
ProjNode* clone_skeleton_predicate_for_unswitched_loops(Node* iff, ProjNode* predicate,
Deoptimization::DeoptReason reason,
ProjNode* output_proj);
ProjNode* clone_skeleton_predicate_for_unswitched_loops(Node* iff, ProjNode* predicate, Node* uncommon_proj, Deoptimization::DeoptReason reason,
ProjNode* output_proj, IdealLoopTree* loop);
static void check_created_predicate_for_unswitching(const Node* new_entry) PRODUCT_RETURN;
bool _created_loop_node;

View File

@@ -2562,7 +2562,6 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
assert(n->Opcode() == Op_LoopLimit ||
n->Opcode() == Op_Opaque2 ||
n->Opcode() == Op_Opaque3 ||
n->Opcode() == Op_Opaque4 ||
BarrierSet::barrier_set()->barrier_set_c2()->is_gc_barrier_node(n),
"unknown node type in macro list");
}
@@ -2624,19 +2623,6 @@ bool PhaseMacroExpand::expand_macro_nodes() {
_igvn.replace_node(n, repl);
success = true;
#endif
} else if (n->Opcode() == Op_Opaque4) {
// With Opaque4 nodes, the expectation is that the test of input 1
// is always equal to the constant value of input 2. So we can
// remove the Opaque4 and replace it by input 2. In debug builds,
// leave the non constant test in instead to sanity check that it
// never fails (if it does, that subgraph was constructed so, at
// runtime, a Halt node is executed).
#ifdef ASSERT
_igvn.replace_node(n, n->in(1));
#else
_igvn.replace_node(n, n->in(2));
#endif
success = true;
} else if (n->Opcode() == Op_OuterStripMinedLoop) {
n->as_OuterStripMinedLoop()->adjust_strip_mined_loop(&_igvn);
C->remove_macro_node(n);

View File

@@ -60,6 +60,25 @@ bool Opaque2Node::cmp( const Node &n ) const {
return (&n == this); // Always fail except on self
}
Node* Opaque4Node::Identity(PhaseGVN* phase) {
if (phase->C->post_loop_opts_phase()) {
// With Opaque4 nodes, the expectation is that the test of input 1
// is always equal to the constant value of input 2. So we can
// remove the Opaque4 and replace it by input 2. In debug builds,
// leave the non constant test in instead to sanity check that it
// never fails (if it does, that subgraph was constructed so, at
// runtime, a Halt node is executed).
#ifdef ASSERT
return this->in(1);
#else
return this->in(2);
#endif
} else {
phase->C->record_for_post_loop_opts_igvn(this);
}
return this;
}
const Type* Opaque4Node::Value(PhaseGVN* phase) const {
return phase->type(in(1));
}

View File

@@ -114,13 +114,11 @@ class Opaque3Node : public Opaque2Node {
// GraphKit::must_be_not_null().
class Opaque4Node : public Node {
public:
Opaque4Node(Compile* C, Node *tst, Node* final_tst) : Node(NULL, tst, final_tst) {
init_flags(Flag_is_macro);
C->add_macro_node(this);
}
Opaque4Node(Compile* C, Node *tst, Node* final_tst) : Node(NULL, tst, final_tst) {}
virtual int Opcode() const;
virtual const Type *bottom_type() const { return TypeInt::BOOL; }
virtual Node* Identity(PhaseGVN* phase);
virtual const Type* Value(PhaseGVN* phase) const;
};

View File

@@ -200,24 +200,6 @@ bool PhaseIdealLoop::split_up( Node *n, Node *blk1, Node *blk2 ) {
return true;
}
}
if (n->Opcode() == Op_OpaqueLoopStride || n->Opcode() == Op_OpaqueLoopInit) {
Unique_Node_List wq;
wq.push(n);
for (uint i = 0; i < wq.size(); i++) {
Node* m = wq.at(i);
if (m->is_If()) {
assert(skeleton_predicate_has_opaque(m->as_If()), "opaque node not reachable from if?");
Node* bol = clone_skeleton_predicate_bool(m, NULL, NULL, m->in(0));
_igvn.replace_input_of(m, 1, bol);
} else {
assert(!m->is_CFG(), "not CFG expected");
for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) {
Node* u = m->fast_out(j);
wq.push(u);
}
}
}
}
// See if splitting-up a Store. Any anti-dep loads must go up as
// well. An anti-dep load might be in the wrong block, because in

View File

@@ -2129,11 +2129,6 @@ class AffectedKlassClosure : public KlassClosure {
void do_klass(Klass* klass) {
assert(!_affected_klasses->contains(klass), "must not occur more than once!");
// allow only loaded classes
if (!klass->is_instance_klass() || !InstanceKlass::cast(klass)->is_loaded()) {
return;
}
if (klass->new_version() != NULL) {
return;
}
@@ -2190,8 +2185,12 @@ jvmtiError VM_EnhancedRedefineClasses::find_sorted_affected_classes(TRAPS) {
{
MutexLocker mcld(ClassLoaderDataGraph_lock);
// Hidden classes are not in SystemDictionary, so we have to iterate ClassLoaderDataGraph
ClassLoaderDataGraph::classes_do(&closure);
// We can't use ClassLoaderDataGraph::classes_do since classes can be uninitialized in cld,
// fully initialized class is in system dictionary, but hidden classes are excluded. Therefore
// we use special method iterating over initialized classes only
// ClassLoaderDataGraph::classes_do(&closure);
ClassLoaderDataGraph::initialized_classes_do(&closure);
}
log_trace(redefine, class, load)("%d classes affected", _affected_klasses->length());

View File

@@ -372,12 +372,10 @@ public:
};
class AdjustMethodEntriesDcevm : public StackObj {
GrowableArray<oop>* _oops_to_update;
GrowableArray<Method*>* _old_methods;
bool* _trace_name_printed;
GrowableArray<oop>* _oops_to_add;
public:
AdjustMethodEntriesDcevm(GrowableArray<oop>* oops_to_update, GrowableArray<Method*>* old_methods) :
_oops_to_update(oops_to_update), _old_methods(old_methods) {};
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* entry) {
oop mem_name = entry->peek();
if (mem_name == NULL) {
@@ -388,8 +386,46 @@ public:
Method* old_method = (Method*)java_lang_invoke_ResolvedMethodName::vmtarget(mem_name);
if (old_method->is_old()) {
_oops_to_update->append(mem_name);
_old_methods->append(old_method);
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;
@@ -404,70 +440,36 @@ void ResolvedMethodTable::adjust_method_entries(bool * trace_name_printed) {
_local_table->do_safepoint_scan(adjust);
}
// It is called at safepoint only for EnhancedRedefineClasses
// 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");
GrowableArray<oop> oops_to_update(0);
GrowableArray<Method*> old_methods(0);
AdjustMethodEntriesDcevm adjust(&oops_to_update, &old_methods);
// For each entry in RMT, change to new method
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);
for (int i = 0; i < oops_to_update.length(); i++) {
oop mem_name = oops_to_update.at(i);
Method *old_method = old_methods.at(i);
// The hash table takes ownership of the WeakHandle, even if it's not inserted.
// 1. Remove old method, since we are going to update class that could be used for hash evaluation in parallel running ServiceThread
ResolvedMethodTableLookup lookup(thread, method_hash(old_method), old_method);
_local_table->remove(thread, lookup);
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());
assert(newer_method != NULL, "method_with_idnum() should not be NULL");
assert(newer_klass == newer_method->method_holder(), "call after swapping redefined guts");
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);
ResolvedMethodTableLookup lookup(thread, method_hash(method), method);
ResolvedMethodGet rmg(thread, method);
while (true) {
if (_local_table->get(thread, lookup, rmg)) {
// old method was already adjusted if new method exists in _the_table
continue;
break;
}
WeakHandle wh(_oop_storage, 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;
}
}
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());
// 2. Update method
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();
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());
// 3. add updated method to table again
add_method(newer_method, Handle(thread, mem_name));
}
}
#endif // INCLUDE_JVMTI

View File

@@ -117,7 +117,7 @@ const char* Abstract_VM_Version::vm_vendor() {
#ifdef VENDOR
return VENDOR;
#else
return "JetBrains s.r.o.";
return "Oracle Corporation";
#endif
}

View File

@@ -1337,7 +1337,6 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop
log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
}
if (strcmp(key, "jdk.module.showModuleResolution") == 0 ||
strcmp(key, "jdk.module.illegalAccess") == 0 ||
strcmp(key, "jdk.module.validation") == 0 ||
strcmp(key, "java.system.class.loader") == 0) {
MetaspaceShared::disable_full_module_graph();
@@ -2132,8 +2131,7 @@ bool Arguments::parse_uintx(const char* value,
}
bool Arguments::create_module_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
assert(is_internal_module_property(prop_name) ||
strcmp(prop_name, "jdk.module.illegalAccess") == 0, "unknown module property: '%s'", prop_name);
assert(is_internal_module_property(prop_name), "unknown module property: '%s'", prop_name);
size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
char* property = AllocateHeap(prop_len, mtArguments);
int ret = jio_snprintf(property, prop_len, "%s=%s", prop_name, prop_value);
@@ -2505,11 +2503,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
char version[256];
JDK_Version::jdk(17).to_string(version, sizeof(version));
warning("Ignoring option %s; support was removed in %s", option->optionString, version);
} else if (match_option(option, "--jbr-illegal-access", &tail)) {
warning("Option --jbr-illegal-access is deprecated and will be removed in a future release.");
if (!create_module_property("jdk.module.illegalAccess", "permit", ExternalProperty)) {
return JNI_ENOMEM;
}
// -agentlib and -agentpath
} else if (match_option(option, "-agentlib:", &tail) ||
(is_absolute_path = match_option(option, "-agentpath:", &tail))) {
@@ -4034,9 +4027,9 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
// Set object alignment values.
set_object_alignment();
#if INCLUDE_JFR
#ifndef ZERO
if (FlightRecorder) {
if (AllowEnhancedClassRedefinition || StartFlightRecording != NULL) {
if (AllowEnhancedClassRedefinition) {
warning("EnhancedClassRedefinition was disabled, it is not allowed in FlightRecorder.");
AllowEnhancedClassRedefinition = false;
}

View File

@@ -16,8 +16,6 @@
package com.jetbrains.internal;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@@ -105,10 +103,9 @@ public class JBRApi {
JBRApi.outerLookup = outerLookup;
try {
Class<?> metadataClass = outerLookup.findClass("com.jetbrains.JBR$Metadata");
Lookup lookup = MethodHandles.privateLookupIn(metadataClass, outerLookup);
knownServices = Set.of((String[]) lookup.findStaticVarHandle(metadataClass,
knownServices = Set.of((String[]) outerLookup.findStaticVarHandle(metadataClass,
"KNOWN_SERVICES", String[].class).get());
knownProxies = Set.of((String[]) lookup.findStaticVarHandle(metadataClass,
knownProxies = Set.of((String[]) outerLookup.findStaticVarHandle(metadataClass,
"KNOWN_PROXIES", String[].class).get());
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
@@ -159,52 +156,13 @@ public class JBRApi {
RegisteredProxyInfo info = registeredProxyInfoByTargetName.get(targetName);
if (info == null) return null;
try {
return (info.type().isPublicApi() ? outerLookup : info.apiModule())
return (info.type() == ProxyInfo.Type.CLIENT_PROXY ? info.apiModule() : outerLookup)
.findClass(info.interfaceName());
} catch (ClassNotFoundException | IllegalAccessException e) {
return null;
}
}
public static InternalServiceBuilder internalServiceBuilder(Lookup interFace, String target) {
return new InternalServiceBuilder(new RegisteredProxyInfo(
interFace, interFace.lookupClass().getName(), target, ProxyInfo.Type.INTERNAL_SERVICE, new ArrayList<>()));
}
public static class InternalServiceBuilder {
private final RegisteredProxyInfo info;
private InternalServiceBuilder(RegisteredProxyInfo info) {
this.info = info;
}
public InternalServiceBuilder withStatic(String methodName, String clazz) {
return withStatic(methodName, clazz, methodName);
}
public InternalServiceBuilder withStatic(String interfaceMethodName, String clazz, String methodName) {
info.staticMethods().add(
new RegisteredProxyInfo.StaticMethodMapping(interfaceMethodName, clazz, methodName));
return this;
}
public Object build() {
ProxyInfo info = ProxyInfo.resolve(this.info);
if (info == null) return null;
ProxyGenerator generator = new ProxyGenerator(info);
if (!generator.areAllMethodsImplemented()) return null;
generator.defineClasses();
MethodHandle constructor = generator.findConstructor();
generator.init();
try {
return constructor.invoke();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
/**
* Called by {@linkplain com.jetbrains.bootstrap.JBRApiBootstrap#MODULES registry classes}
* to register a new mapping for corresponding modules.

View File

@@ -78,7 +78,7 @@ class ProxyGenerator {
*/
ProxyGenerator(ProxyInfo info) {
this.info = info;
generateBridge = info.type.isPublicApi();
generateBridge = info.type != ProxyInfo.Type.CLIENT_PROXY;
int nameId = nameCounter.getAndIncrement();
proxyName = Type.getInternalName(info.interFace) + "$$JBRApiProxy$" + nameId;
bridgeName = generateBridge ? info.apiModule.lookupClass().getPackageName().replace('.', '/') + "/" +
@@ -153,7 +153,7 @@ class ProxyGenerator {
} else {
MethodHandle c = generatedProxy.findConstructor(generatedProxy.lookupClass(),
MethodType.methodType(void.class, Object.class));
if (info.type.isService()) {
if (info.type == ProxyInfo.Type.SERVICE) {
try {
return MethodHandles.foldArguments(c, info.target.findConstructor(info.target.lookupClass(),
MethodType.methodType(void.class)).asType(MethodType.methodType(Object.class)));

View File

@@ -66,7 +66,7 @@ class ProxyInfo {
}
Lookup getInterfaceLookup() {
return type == Type.CLIENT_PROXY || type == Type.INTERNAL_SERVICE ? apiModule : JBRApi.outerLookup;
return type == Type.CLIENT_PROXY ? apiModule : JBRApi.outerLookup;
}
Lookup getTargetLookup() {
@@ -74,18 +74,12 @@ class ProxyInfo {
}
private Lookup lookup(Lookup lookup, String clazz) {
String[] nestedClasses = clazz.split("\\$");
clazz = "";
for (int i = 0; i < nestedClasses.length; i++) {
try {
if (i != 0) clazz += "$";
clazz += nestedClasses[i];
lookup = MethodHandles.privateLookupIn(lookup.findClass(clazz), lookup);
} catch (ClassNotFoundException | IllegalAccessException ignore) {
return null;
}
try {
return MethodHandles.privateLookupIn(lookup.findClass(clazz), lookup);
} catch (ClassNotFoundException | IllegalAccessException e) {
if (lookup == JBRApi.outerLookup) return null;
else throw new RuntimeException(e);
}
return lookup;
}
record StaticMethodMapping(Lookup lookup, String methodName) {}
@@ -96,15 +90,6 @@ class ProxyInfo {
enum Type {
PROXY,
SERVICE,
CLIENT_PROXY,
INTERNAL_SERVICE;
public boolean isPublicApi() {
return this == PROXY || this == SERVICE;
}
public boolean isService() {
return this == SERVICE || this == INTERNAL_SERVICE;
}
CLIENT_PROXY
}
}

View File

@@ -68,14 +68,4 @@ class ExplodedSystemModules implements SystemModules {
public Map<String, Set<String>> moduleReads() {
throw new InternalError();
}
@Override
public Map<String, Set<String>> concealedPackagesToOpen() {
return Map.of();
}
@Override
public Map<String, Set<String>> exportedPackagesToOpen() {
return Map.of();
}
}

View File

@@ -1,130 +0,0 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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 jdk.internal.module;
import sun.nio.cs.UTF_8;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Generates the maps of concealed and exported packages to open at run-time.
*
* This is used at run-time for exploded builds, and at link-time to generate
* the maps for the system modules in the run-time image.
*/
public class IllegalAccessMaps {
private final Map<String, Set<String>> concealedPackagesToOpen;
private final Map<String, Set<String>> exportedPackagesToOpen;
private IllegalAccessMaps(Map<String, Set<String>> map1,
Map<String, Set<String>> map2) {
this.concealedPackagesToOpen = map1;
this.exportedPackagesToOpen = map2;
}
/**
* Returns the map of concealed packages to open. The map key is the
* module name, the value is the set of concealed packages to open.
*/
public Map<String, Set<String>> concealedPackagesToOpen() {
return concealedPackagesToOpen;
}
/**
* Returns the map of exported packages to open. The map key is the
* module name, the value is the set of exported packages to open.
*/
public Map<String, Set<String>> exportedPackagesToOpen() {
return exportedPackagesToOpen;
}
/**
* Generate the maps of module to concealed and exported packages for
* the system modules that are observable with the given module finder.
*/
public static IllegalAccessMaps generate(ModuleFinder finder) {
Map<String, ModuleDescriptor> map = new HashMap<>();
finder.findAll().stream()
.map(ModuleReference::descriptor)
.forEach(md -> md.packages().forEach(pn -> map.putIfAbsent(pn, md)));
Map<String, Set<String>> concealedPackagesToOpen = new HashMap<>();
Map<String, Set<String>> exportedPackagesToOpen = new HashMap<>();
String rn = "jdk8_packages.dat";
InputStream in = IllegalAccessMaps.class.getResourceAsStream(rn);
if (in == null) {
throw new InternalError(rn + " not found");
}
try (BufferedReader br = new BufferedReader(
new InputStreamReader(in, UTF_8.INSTANCE)))
{
br.lines()
.filter(line -> !line.isEmpty() && !line.startsWith("#"))
.forEach(pn -> {
ModuleDescriptor descriptor = map.get(pn);
if (descriptor != null && !isOpen(descriptor, pn)) {
String name = descriptor.name();
if (isExported(descriptor, pn)) {
exportedPackagesToOpen.computeIfAbsent(name,
k -> new HashSet<>()).add(pn);
} else {
concealedPackagesToOpen.computeIfAbsent(name,
k -> new HashSet<>()).add(pn);
}
}
});
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
return new IllegalAccessMaps(concealedPackagesToOpen, exportedPackagesToOpen);
}
private static boolean isExported(ModuleDescriptor descriptor, String pn) {
return descriptor.exports()
.stream()
.anyMatch(e -> e.source().equals(pn) && !e.isQualified());
}
private static boolean isOpen(ModuleDescriptor descriptor, String pn) {
return descriptor.opens()
.stream()
.anyMatch(e -> e.source().equals(pn) && !e.isQualified());
}
}

View File

@@ -147,8 +147,7 @@ public final class ModuleBootstrap {
getProperty("jdk.module.limitmods") == null && // --limit-modules
getProperty("jdk.module.addreads.0") == null && // --add-reads
getProperty("jdk.module.addexports.0") == null && // --add-exports
getProperty("jdk.module.addopens.0") == null && // --add-opens
getProperty("jdk.module.illegalAccess") == null; // --jbr-illegal-access
getProperty("jdk.module.addopens.0") == null; // --add-opens
}
/**
@@ -189,7 +188,6 @@ public final class ModuleBootstrap {
String mainModule = System.getProperty("jdk.module.main");
Set<String> addModules = addModules();
Set<String> limitModules = limitModules();
String illegalAccess = getAndRemoveProperty("jdk.module.illegalAccess");
PrintStream traceOutput = null;
String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
@@ -221,8 +219,7 @@ public final class ModuleBootstrap {
&& !haveModulePath
&& addModules.isEmpty()
&& limitModules.isEmpty()
&& !isPatched
&& illegalAccess == null) {
&& !isPatched) {
systemModuleFinder = archivedModuleGraph.finder();
hasSplitPackages = archivedModuleGraph.hasSplitPackages();
hasIncubatorModules = archivedModuleGraph.hasIncubatorModules();
@@ -457,19 +454,10 @@ public final class ModuleBootstrap {
checkIncubatingStatus(cf);
}
// --add-reads, --add-exports/--add-opens, and --jbr-illegal-access
// --add-reads, --add-exports/--add-opens
addExtraReads(bootLayer);
boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
if (illegalAccess != null) {
assert systemModules != null;
addIllegalAccess(illegalAccess,
systemModules,
upgradeModulePath,
bootLayer,
extraExportsOrOpens);
}
// add enable native access
addEnableNativeAccess(bootLayer);
@@ -825,74 +813,6 @@ public final class ModuleBootstrap {
return modules;
}
/**
* Process the --jbr-illegal-access option to open packages of system modules
* in the boot layer to code in unnamed modules.
*/
private static void addIllegalAccess(String illegalAccess,
SystemModules systemModules,
ModuleFinder upgradeModulePath,
ModuleLayer bootLayer,
boolean extraExportsOrOpens) {
Map<String, Set<String>> concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
Map<String, Set<String>> exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
// need to generate (exploded build)
IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
concealedPackagesToOpen = maps.concealedPackagesToOpen();
exportedPackagesToOpen = maps.exportedPackagesToOpen();
}
// open specific packages in the system modules
Set<String> emptySet = Set.of();
for (Module m : bootLayer.modules()) {
ModuleDescriptor descriptor = m.getDescriptor();
String name = m.getName();
// skip open modules
if (descriptor.isOpen()) {
continue;
}
// skip modules loaded from the upgrade module path
if (upgradeModulePath != null
&& upgradeModulePath.find(name).isPresent()) {
continue;
}
Set<String> concealedPackages = concealedPackagesToOpen.getOrDefault(name, emptySet);
Set<String> exportedPackages = exportedPackagesToOpen.getOrDefault(name, emptySet);
// refresh the set of concealed and exported packages if needed
if (extraExportsOrOpens) {
concealedPackages = new HashSet<>(concealedPackages);
exportedPackages = new HashSet<>(exportedPackages);
Iterator<String> iterator = concealedPackages.iterator();
while (iterator.hasNext()) {
String pn = iterator.next();
if (m.isExported(pn, BootLoader.getUnnamedModule())) {
// concealed package is exported to ALL-UNNAMED
iterator.remove();
exportedPackages.add(pn);
}
}
iterator = exportedPackages.iterator();
while (iterator.hasNext()) {
String pn = iterator.next();
if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
// exported package is opened to ALL-UNNAMED
iterator.remove();
}
}
}
// open the packages to unnamed modules
JLA.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
}
}
/**
* Decodes the values of --add-reads, -add-exports, --add-opens or
* --patch-modules options that are encoded in system properties.

View File

@@ -83,16 +83,4 @@ interface SystemModules {
* by this SystemModules object.
*/
Map<String, Set<String>> moduleReads();
/**
* Returns the map of module concealed packages to open. The map key is the
* module name, the value is the set of concealed packages to open.
*/
Map<String, Set<String>> concealedPackagesToOpen();
/**
* Returns the map of module exported packages to open. The map key is the
* module name, the value is the set of exported packages to open.
*/
Map<String, Set<String>> exportedPackagesToOpen();
}

View File

@@ -188,10 +188,6 @@ java.launcher.X.usage=\n\
\ --add-opens <module>/<package>=<target-module>(,<target-module>)*\n\
\ updates <module> to open <package> to\n\
\ <target-module>, regardless of module declaration.\n\
\ --jbr-illegal-access\n\
\ permit access to members of types in named modules\n\
\ by code in unnamed modules.\n\
\ This option will be removed in a future release.\n\
\ --limit-modules <module name>[,<module name>...]\n\
\ limit the universe of observable modules\n\
\ --patch-module <module>=<file>({0}<file>)*\n\

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 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
@@ -47,6 +47,7 @@ import java.util.regex.Pattern;
import jdk.internal.access.JavaIOFileDescriptorAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.ref.CleanerFactory;
import sun.security.action.GetBooleanAction;
import sun.security.action.GetPropertyAction;
/* This class is for the exclusive use of ProcessBuilder.start() to
@@ -268,22 +269,11 @@ final class ProcessImpl extends Process {
// command line parser. The case of the [""] tail escape
// sequence could not be realized due to the argument validation
// procedure.
if (verificationType == VERIFICATION_WIN32_SAFE ||
verificationType == VERIFICATION_LEGACY) {
int count = countLeadingBackslash(verificationType, s, s.length());
while (count-- > 0) {
cmdbuf.append(BACKSLASH); // double the number of backslashes
}
int count = countLeadingBackslash(verificationType, s, s.length());
while (count-- > 0) {
cmdbuf.append(BACKSLASH); // double the number of backslashes
}
cmdbuf.append('"');
} else if (verificationType == VERIFICATION_WIN32_SAFE &&
(s.startsWith("\"") && s.endsWith("\"") && s.length() > 2)) {
// Check that quoted argument does not escape the final quote
cmdbuf.append(s);
int count = countLeadingBackslash(verificationType, s, s.length() - 1);
while (count-- > 0) {
cmdbuf.insert(cmdbuf.length() - 1, BACKSLASH); // double the number of backslashes
}
} else {
cmdbuf.append(s);
}
@@ -292,7 +282,9 @@ final class ProcessImpl extends Process {
}
/**
* Return the argument without quotes (first and last) if quoted, otherwise the arg.
* Return the argument without quotes (1st and last) if properly quoted, else the arg.
* A properly quoted string has first and last characters as quote and
* the last quote is not escaped.
* @param str a string
* @return the string without quotes
*/
@@ -300,6 +292,9 @@ final class ProcessImpl extends Process {
if (!str.startsWith("\"") || !str.endsWith("\"") || str.length() < 2)
return str; // no beginning or ending quote, or too short not quoted
if (str.endsWith("\\\"")) {
return str; // not properly quoted, treat as unquoted
}
// Strip leading and trailing quotes
return str.substring(1, str.length() - 1);
}

View File

@@ -41,14 +41,12 @@ import sun.java2d.SunGraphicsEnvironment;
import sun.java2d.MacOSFlags;
import sun.java2d.metal.MTLGraphicsConfig;
import sun.java2d.opengl.CGLGraphicsConfig;
import sun.util.logging.PlatformLogger;
import static java.awt.peer.ComponentPeer.SET_BOUNDS;
public final class CGraphicsDevice extends GraphicsDevice
implements DisplayChangedListener {
private static final PlatformLogger logger = PlatformLogger.getLogger(CGraphicsDevice.class.getName());
/**
* CoreGraphics display ID. This identifier can become non-valid at any time
* therefore methods, which is using this id should be ready to it.
@@ -383,7 +381,6 @@ public final class CGraphicsDevice extends GraphicsDevice
}
private void initScaleFactor() {
int _scale = scale;
if (SunGraphicsEnvironment.isUIScaleEnabled()) {
double debugScale = SunGraphicsEnvironment.getDebugScale();
scale = (int) (debugScale >= 1
@@ -392,9 +389,6 @@ public final class CGraphicsDevice extends GraphicsDevice
} else {
scale = 1;
}
if (_scale != scale && logger.isLoggable(PlatformLogger.Level.FINE)) {
logger.fine("current scale = " + _scale + ", new scale = " + scale + " (" + this + ")");
}
}
private static native double nativeGetScaleFactor(int displayID);

View File

@@ -128,12 +128,8 @@ public class CCharToGlyphMapper extends CharToGlyphMapper {
};
}
// This mapper returns either the glyph code, or if the character can be
// replaced on-the-fly using CoreText substitution; the negative unicode
// value. If this "glyph code int" is treated as an opaque code, it will
// strike and measure exactly as a real glyph code - whether the character
// is present or not. Missing characters for any font on the system will
// be returned as 0, as the getMissingGlyphCode() function above indicates.
// Missing characters for any font on the system will be returned as 0,
// as the getMissingGlyphCode() function above indicates.
private static native void nativeCharsToGlyphs(final long nativeFontPtr,
int count, char[] unicodes,
int[] glyphs);

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2000-2018 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sun.font;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
public final class CCompositeFont extends CompositeFont {
private final List<CFont> fallbackFonts = new ArrayList<>();
public CCompositeFont(CFont font) {
super(new PhysicalFont[]{font});
mapper = new CCompositeGlyphMapper(this);
}
@Override
public synchronized int getNumSlots() {
return super.getNumSlots();
}
@Override
public CFont getSlotFont(int slot) {
if (slot == 0) return (CFont) super.getSlotFont(0);
synchronized (this) {
return fallbackFonts.get(slot - 1);
}
}
@Override
synchronized FontStrike getStrike(FontStrikeDesc desc, boolean copy) {
return super.getStrike(desc, copy);
}
@Override
protected synchronized int getValidatedGlyphCode(int glyphCode) {
return super.getValidatedGlyphCode(glyphCode);
}
@Override
public boolean hasSupplementaryChars() {
return false;
}
@Override
public boolean useAAForPtSize(int ptsize) {
return true;
}
public synchronized int findSlot(String fontName) {
for (int slot = 0; slot < numSlots; slot++) {
CFont slotFont = getSlotFont(slot);
if (fontName.equals(slotFont.getNativeFontName())) {
return slot;
}
}
return -1;
}
public synchronized int addSlot(CFont font) {
int slot = findSlot(font.getNativeFontName());
if (slot >= 0) return slot;
fallbackFonts.add(font);
lastFontStrike = new SoftReference<>(null);
strikeCache.clear();
return numSlots++;
}
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. 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.font;
import java.awt.*;
public final class CCompositeGlyphMapper extends CompositeGlyphMapper {
public CCompositeGlyphMapper(CCompositeFont compFont) {
super(compFont);
}
@Override
protected int convertToGlyph(int unicode) {
CCompositeFont compositeFont = (CCompositeFont) font;
CFont mainFont = (CFont) font.getSlotFont(0);
String[] fallbackFontInfo = new String[2];
int glyphCode = nativeCodePointToGlyph(mainFont.getNativeFontPtr(), unicode, fallbackFontInfo);
if (glyphCode == missingGlyph) {
setCachedGlyphCode(unicode, missingGlyph);
return missingGlyph;
}
String fallbackFontName = fallbackFontInfo[0];
String fallbackFontFamilyName = fallbackFontInfo[1];
if (fallbackFontName == null || fallbackFontFamilyName == null) {
int result = compositeGlyphCode(0, glyphCode);
setCachedGlyphCode(unicode, result);
return result;
}
int slot = compositeFont.findSlot(fallbackFontName);
if (slot < 0) {
Font2D fallbackFont = FontManagerFactory.getInstance().findFont2D(fallbackFontName,
Font.PLAIN, FontManager.NO_FALLBACK);
if (!(fallbackFont instanceof CFont) ||
!fallbackFontName.equals(((CFont) fallbackFont).getNativeFontName())) {
// Native font fallback mechanism can return "hidden" fonts - their names start with dot,
// and they are not returned in a list of fonts available in system, but they can still be used
// if requested explicitly.
fallbackFont = new CFont(fallbackFontName, fallbackFontFamilyName, null);
}
if (mainFont.isFakeItalic()) fallbackFont = ((CFont)fallbackFont).createItalicVariant(false);
slot = compositeFont.addSlot((CFont) fallbackFont);
}
int result = compositeGlyphCode(slot, glyphCode);
setCachedGlyphCode(unicode, result);
return result;
}
// This invokes native font fallback mechanism, returning information about font (its Postscript and family names)
// able to display a given character, and corresponding glyph code
private static native int nativeCodePointToGlyph(long nativeFontPtr, int codePoint, String[] result);
}

View File

@@ -31,6 +31,9 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;
// Right now this class is final to avoid a problem with native code.
// For some reason the JNI IsInstanceOf was not working correctly
@@ -175,14 +178,12 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
isFakeItalic = other.isFakeItalic;
}
public CFont createItalicVariant(boolean updateStyle) {
public CFont createItalicVariant() {
CFont font = new CFont(this, familyName);
font.nativeFontName = fullName;
font.fullName =
fullName + (style == Font.BOLD ? "" : "-") + "Italic-Derived";
if (updateStyle) {
font.style |= Font.ITALIC;
}
font.style |= Font.ITALIC;
font.isFakeItalic = true;
return font;
}
@@ -204,11 +205,51 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
return getCGFontPtrNative(getNativeFontPtr());
}
static native void getCascadeList(long nativeFontPtr, ArrayList<String> listOfString);
private CompositeFont createCompositeFont() {
ArrayList<String> listOfString = new ArrayList<String>();
getCascadeList(getNativeFontPtr(), listOfString);
Set<String> components = new LinkedHashSet<>(listOfString);
// In some italic cases the standard Mac cascade list is missing Arabic.
components.add("GeezaPro");
CFontManager fm = (CFontManager) FontManagerFactory.getInstance();
components.addAll(fm.getAdditionalFallbackVariants());
int numFonts = 1 + components.size();
PhysicalFont[] fonts = new PhysicalFont[numFonts];
fonts[0] = this;
int idx = 1;
if (FontUtilities.isLogging()) {
FontUtilities.logInfo("Cascading list for " + this + " :");
}
for (String s : components) {
if (FontUtilities.isLogging()) {
FontUtilities.logInfo("Fallback:" + s);
}
if (s.equals(".AppleSymbolsFB")) {
// Don't know why we get the weird name above .. replace.
s = "AppleSymbols";
}
Font2D f2d = fm.getOrCreateFallbackFont(s);
if (f2d == null || f2d == this) {
continue;
}
fonts[idx++] = (PhysicalFont)f2d;
}
if (idx < fonts.length) {
PhysicalFont[] orig = fonts;
fonts = new PhysicalFont[idx];
System.arraycopy(orig, 0, fonts, 0, idx);
}
return new CompositeFont(fonts);
}
private CompositeFont compFont;
public CompositeFont getCompositeFont2D() {
if (compFont == null) {
compFont = new CCompositeFont(this);
compFont = createCompositeFont();
}
return compFont;
}
@@ -236,14 +277,6 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
return new CStrike(this, desc);
}
boolean isFakeItalic() {
return isFakeItalic;
}
String getNativeFontName() {
return nativeFontName;
}
@Override
public String getTypographicSubfamilyName() {
return faceName == null ? super.getTypographicSubfamilyName() : faceName;
@@ -276,8 +309,4 @@ public final class CFont extends PhysicalFont implements FontSubstitution, FontW
", familyName: " + familyName + ", style: " + style +
" } aka: " + super.toString();
}
public Font2D createItalic() {
return this.createItalicVariant(true);
}
}

View File

@@ -30,20 +30,27 @@ import java.io.File;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import javax.swing.plaf.FontUIResource;
import sun.awt.FontConfiguration;
import sun.awt.HeadlessToolkit;
import sun.lwawt.macosx.*;
import sun.security.action.GetBooleanAction;
import sun.util.logging.PlatformLogger;
public final class CFontManager extends SunFontManager {
private static Hashtable<String, Font2D> genericFonts = new Hashtable<String, Font2D>();
private final Map<String, Font2D> fallbackFonts = new ConcurrentHashMap<>();
private final List<String> extFallbackVariants = new ArrayList<>();
@Override
protected FontConfiguration createFontConfiguration() {
@@ -230,6 +237,7 @@ public final class CFontManager extends SunFontManager {
public Object run() {
if (!loadedAllFonts) {
loadNativeFonts();
collectAdditionalFallbackVariants();
loadedAllFonts = true;
}
return null;
@@ -337,4 +345,40 @@ public final class CFontManager extends SunFontManager {
@Override
protected void populateFontFileNameMap(HashMap<String, String> fontToFileMap, HashMap<String, String> fontToFamilyNameMap,
HashMap<String, ArrayList<String>> familyToFontListMap, Locale locale) {}
@SuppressWarnings("removal")
private void collectAdditionalFallbackVariants() {
if (AccessController.doPrivileged(new GetBooleanAction("mac.ext.font.fallback"))) {
for (String fontName : genericFonts.keySet()) {
boolean accept = false;
if (fontName.equals("ArialUnicodeMS")) {
accept = true;
} else if (fontName.startsWith("NotoSans")) {
int pos = fontName.indexOf('-');
accept = pos == -1 || fontName.substring(pos + 1).equals("Regular");
}
if (accept) {
extFallbackVariants.add(fontName);
}
}
Collections.sort(extFallbackVariants); // ensure predictable order
}
}
List<String> getAdditionalFallbackVariants() {
return extFallbackVariants;
}
Font2D getOrCreateFallbackFont(String fontName) {
Font2D font2D = findFont2D(fontName, Font.PLAIN, FontManager.NO_FALLBACK);
if (font2D != null || fontName.startsWith(".")) {
return font2D;
} else {
// macOS doesn't list some system fonts in [NSFontManager availableFontFamilies] output,
// so they are not registered in font manager as part of 'loadNativeFonts'.
// These fonts are present in [NSFontManager availableFonts] output though,
// and can be accessed in the same way as other system fonts.
return fallbackFonts.computeIfAbsent(fontName, name -> new CFont(name, null, null));
}
}
}

View File

@@ -358,18 +358,14 @@ public final class CStrike extends PhysicalStrike {
}
}
// This class stores glyph pointers, and is indexed based on glyph codes,
// and negative unicode values. See the comments in
// CCharToGlyphMapper for more details on our glyph code strategy.
// This class stores glyph pointers, and is indexed based on glyph codes.
private static class GlyphInfoCache extends CStrikeDisposer {
private static final int FIRST_LAYER_SIZE = 256;
private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
// rdar://problem/5204197
private final AtomicBoolean disposed = new AtomicBoolean(false);
private final long[] firstLayerCache;
private SparseBitShiftingTwoLayerArray secondLayerCache;
private HashMap<Integer, Long> generalCache;
GlyphInfoCache(final Font2D nativeFont, final FontStrikeDesc desc) {
@@ -378,19 +374,9 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized long get(final int index) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
// catch common unicodes
if (secondLayerCache == null) {
return 0L;
}
return secondLayerCache.get(-index);
}
} else {
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
return firstLayerCache[index];
}
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
return firstLayerCache[index];
}
if (generalCache == null) {
@@ -404,21 +390,10 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized void put(final int index, final long value) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
// catch common unicodes
if (secondLayerCache == null) {
secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
}
secondLayerCache.put(-index, value);
return;
}
} else {
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
firstLayerCache[index] = value;
return;
}
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
firstLayerCache[index] = value;
return;
}
if (generalCache == null) {
@@ -441,14 +416,6 @@ public final class CStrike extends PhysicalStrike {
// clean out the first array
disposeLongArray(firstLayerCache);
// clean out the two layer arrays
if (secondLayerCache != null) {
final long[][] secondLayerLongArrayArray = secondLayerCache.cache;
for (final long[] longArray : secondLayerLongArrayArray) {
if (longArray != null) disposeLongArray(longArray);
}
}
// clean up everyone else
if (generalCache != null) {
for (Long aLong : generalCache.values()) {
@@ -485,56 +452,18 @@ public final class CStrike extends PhysicalStrike {
}
}
}
private static class SparseBitShiftingTwoLayerArray {
final long[][] cache;
final int shift;
final int secondLayerLength;
SparseBitShiftingTwoLayerArray(final int size, final int shift) {
this.shift = shift;
this.cache = new long[1 << shift][];
this.secondLayerLength = size >> shift;
}
public long get(final int index) {
final int firstIndex = index >> shift;
final long[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) return 0L;
return firstLayerRow[index - (firstIndex * (1 << shift))];
}
public void put(final int index, final long value) {
final int firstIndex = index >> shift;
long[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) {
cache[firstIndex] = firstLayerRow = new long[secondLayerLength];
}
firstLayerRow[index - (firstIndex * (1 << shift))] = value;
}
}
}
private static class GlyphAdvanceCache {
private static final int FIRST_LAYER_SIZE = 256;
private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128
private final float[] firstLayerCache = new float[FIRST_LAYER_SIZE];
private SparseBitShiftingTwoLayerArray secondLayerCache;
private HashMap<Integer, Float> generalCache;
public synchronized float get(final int index) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
// catch common unicodes
if (secondLayerCache == null) return 0;
return secondLayerCache.get(-index);
}
} else {
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
return firstLayerCache[index];
}
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
return firstLayerCache[index];
}
if (generalCache == null) return 0;
@@ -544,21 +473,10 @@ public final class CStrike extends PhysicalStrike {
}
public synchronized void put(final int index, final float value) {
if (index < 0) {
if (-index < SECOND_LAYER_SIZE) {
// catch common unicodes
if (secondLayerCache == null) {
secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
}
secondLayerCache.put(-index, value);
return;
}
} else {
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
firstLayerCache[index] = value;
return;
}
if (index < FIRST_LAYER_SIZE) {
// catch common glyphcodes
firstLayerCache[index] = value;
return;
}
if (generalCache == null) {
@@ -567,34 +485,5 @@ public final class CStrike extends PhysicalStrike {
generalCache.put(Integer.valueOf(index), Float.valueOf(value));
}
private static class SparseBitShiftingTwoLayerArray {
final float[][] cache;
final int shift;
final int secondLayerLength;
SparseBitShiftingTwoLayerArray(final int size, final int shift) {
this.shift = shift;
this.cache = new float[1 << shift][];
this.secondLayerLength = size >> shift;
}
public float get(final int index) {
final int firstIndex = index >> shift;
final float[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) return 0L;
return firstLayerRow[index - (firstIndex * (1 << shift))];
}
public void put(final int index, final float value) {
final int firstIndex = index >> shift;
float[] firstLayerRow = cache[firstIndex];
if (firstLayerRow == null) {
cache[firstIndex] = firstLayerRow =
new float[secondLayerLength];
}
firstLayerRow[index - (firstIndex * (1 << shift))] = value;
}
}
}
}

View File

@@ -29,13 +29,10 @@ import sun.java2d.NullSurfaceData;
import sun.java2d.SurfaceData;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.macosx.CFLayer;
import sun.util.logging.PlatformLogger;
import java.awt.GraphicsConfiguration;
import java.awt.Insets;
public class MTLLayer extends CFLayer {
private static final PlatformLogger logger = PlatformLogger.getLogger(MTLLayer.class.getName());
private native long nativeCreateLayer();
private static native void nativeSetScale(long layerPtr, double scale);
@@ -52,14 +49,6 @@ public class MTLLayer extends CFLayer {
setPtr(nativeCreateLayer());
this.peer = peer;
MTLGraphicsConfig gc = (MTLGraphicsConfig)getGraphicsConfiguration();
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
logger.fine("device = " + (gc != null ? gc.getDevice() : "null"));
}
if (gc != null) {
setScale(gc.getDevice().getScaleFactor());
}
}
public SurfaceData replaceSurfaceData() {
@@ -110,10 +99,6 @@ public class MTLLayer extends CFLayer {
private void setScale(final int _scale) {
if (scale != _scale) {
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
MTLGraphicsConfig gc = (MTLGraphicsConfig)getGraphicsConfiguration();
logger.fine("current scale = " + scale + ", new scale = " + _scale + " (device = " + (gc != null ? gc.getDevice() : "null") + ")");
}
scale = _scale;
execute(ptr -> nativeSetScale(ptr, scale));
}

View File

@@ -31,10 +31,8 @@ import sun.java2d.NullSurfaceData;
import sun.lwawt.LWWindowPeer;
import sun.java2d.SurfaceData;
import sun.lwawt.macosx.CFLayer;
import sun.util.logging.PlatformLogger;
public class CGLLayer extends CFLayer {
private static final PlatformLogger logger = PlatformLogger.getLogger(CGLLayer.class.getName());
private native long nativeCreateLayer();
private static native void nativeSetScale(long layerPtr, double scale);
@@ -48,14 +46,6 @@ public class CGLLayer extends CFLayer {
setPtr(nativeCreateLayer());
this.peer = peer;
CGraphicsConfig gc = (CGraphicsConfig)getGraphicsConfiguration();
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
logger.fine("device = " + (gc != null ? gc.getDevice() : "null"));
}
if (gc != null) {
setScale(gc.getDevice().getScaleFactor());
}
}
public SurfaceData replaceSurfaceData() {
@@ -104,12 +94,8 @@ public class CGLLayer extends CFLayer {
super.dispose();
}
private void setScale(int _scale) {
private void setScale(final int _scale) {
if (scale != _scale) {
if (logger.isLoggable(PlatformLogger.Level.FINE)) {
CGraphicsConfig gc = (CGraphicsConfig)getGraphicsConfiguration();
logger.fine("current scale = " + scale + ", new scale = " + _scale + " (device = " + (gc != null ? gc.getDevice() : "null") + ")");
}
scale = _scale;
execute(ptr -> nativeSetScale(ptr, scale));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 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
@@ -59,7 +59,6 @@ import java.awt.peer.KeyboardFocusManagerPeer;
import java.awt.peer.WindowPeer;
import java.util.List;
import java.util.Objects;
import javax.swing.JComponent;
import sun.awt.AWTAccessor;
@@ -284,16 +283,6 @@ public class LWWindowPeer
super.disposeImpl();
}
@Override
public void setBackground(final Color c) {
Color oldBg = getBackground();
if (Objects.equals(oldBg, c)) {
return;
}
super.setBackground(c);
updateOpaque();
}
@Override
protected void setVisibleImpl(final boolean visible) {
if (!visible && warningWindow != null) {
@@ -302,6 +291,10 @@ public class LWWindowPeer
updateFocusableWindowState();
super.setVisibleImpl(visible);
// TODO: update graphicsConfig, see 4868278
if (visible) {
// Set correct background for a window before making it visible
platformWindow.setOpaque(!isTranslucent());
}
platformWindow.setVisible(visible);
}

View File

@@ -38,10 +38,11 @@ import java.beans.PropertyChangeListener;
import java.lang.annotation.Native;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.PrivilegedAction;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.Arrays;
@@ -75,18 +76,24 @@ import sun.lwawt.LWWindowPeer;
@SuppressWarnings("removal")
class CAccessibility implements PropertyChangeListener {
private static Set<String> ignoredRoles;
private static final int INVOKE_TIMEOUT_SECONDS_DEFAULT = 1;
private static final int INVOKE_TIMEOUT_SECONDS;
static {
// (-1) for the infinite timeout
@SuppressWarnings("removal")
int value = java.security.AccessController.doPrivileged(
(PrivilegedAction<Integer>) () -> {
// Need to load the native library for this code.
System.loadLibrary("awt");
return Integer.getInteger("sun.lwawt.macosx.CAccessibility.invokeTimeoutSeconds", 1);
AtomicInteger invokeTimeoutSecondsRef = new AtomicInteger();
// Need to load the native library for this code.
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("awt");
invokeTimeoutSecondsRef.set(
// (-1) for the infinite timeout
Integer.getInteger("sun.lwawt.macosx.CAccessibility.invokeTimeoutSeconds",
INVOKE_TIMEOUT_SECONDS_DEFAULT));
return null;
}
});
INVOKE_TIMEOUT_SECONDS = value;
INVOKE_TIMEOUT_SECONDS = invokeTimeoutSecondsRef.get();
}
static CAccessibility sAccessibility;

View File

@@ -205,10 +205,8 @@ class CAccessible extends CFRetainedResource implements Accessible {
} else if (oldValue != null &&
((AccessibleState) oldValue) == AccessibleState.VISIBLE) {
execute(ptr -> menuClosed(ptr));
execute(ptr -> unregisterFromCocoaAXSystem(ptr));
}
} else if (thisRole == AccessibleRole.MENU_ITEM ||
((parentRole == AccessibleRole.POPUP_MENU) && (thisRole == AccessibleRole.MENU))) {
} else if (thisRole == AccessibleRole.MENU_ITEM) {
if (newValue != null &&
((AccessibleState) newValue) == AccessibleState.FOCUSED) {
execute(ptr -> menuItemSelected(ptr));

View File

@@ -25,7 +25,6 @@
package sun.lwawt.macosx;
import sun.awt.AWTThreading;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
@@ -65,14 +64,14 @@ public class CMenu extends CMenuItem implements MenuPeer {
LWCToolkit.targetToPeer(getTarget().getParent());
if (parent instanceof CMenu) {
return AWTThreading.executeWaitToolkit(() -> parent.executeGet(this::nativeCreateSubMenu));
return parent.executeGet(this::nativeCreateSubMenu);
}
if (parent instanceof CMenuBar) {
MenuBar parentContainer = (MenuBar)getTarget().getParent();
boolean isHelpMenu = parentContainer.getHelpMenu() == getTarget();
int insertionLocation = ((CMenuBar)parent).getNextInsertionIndex();
return AWTThreading.executeWaitToolkit(() -> parent.executeGet(ptr -> nativeCreateMenu(ptr, isHelpMenu,
insertionLocation)));
return parent.executeGet(ptr -> nativeCreateMenu(ptr, isHelpMenu,
insertionLocation));
}
throw new InternalError("Parent must be CMenu or CMenuBar");
}
@@ -85,7 +84,7 @@ public class CMenu extends CMenuItem implements MenuPeer {
@Override
public final void delItem(final int index) {
AWTThreading.executeWaitToolkit(() -> execute(ptr -> nativeDeleteItem(ptr, index)));
execute(ptr -> nativeDeleteItem(ptr, index));
}
@Override

View File

@@ -33,7 +33,6 @@ import java.awt.event.KeyEvent;
import java.awt.peer.MenuItemPeer;
import java.util.concurrent.atomic.AtomicBoolean;
import sun.awt.AWTThreading;
import sun.awt.SunToolkit;
import sun.lwawt.LWToolkit;
@@ -62,7 +61,7 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer {
@Override
long createModel() {
CMenuComponent parent = (CMenuComponent)LWToolkit.targetToPeer(getTarget().getParent());
return AWTThreading.executeWaitToolkit(() -> parent.executeGet(ptr->nativeCreate(ptr, isSeparator())));
return parent.executeGet(ptr->nativeCreate(ptr, isSeparator()));
}
@SuppressWarnings("deprecation")
public void setLabel(String label, char keyChar, int keyCode, int modifiers) {

View File

@@ -66,7 +66,6 @@ import sun.awt.AWTAccessor.ComponentAccessor;
import sun.awt.AWTAccessor.WindowAccessor;
import sun.awt.AWTThreading;
import sun.java2d.SurfaceData;
import sun.lwawt.LWComponentPeer;
import sun.lwawt.LWLightweightFramePeer;
import sun.lwawt.LWToolkit;
import sun.lwawt.LWWindowPeer;
@@ -106,7 +105,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
private static native boolean nativeDelayShowing(long nsWindowPtr);
private static native void nativeRaiseLevel(long nsWindowPtr, boolean popup, boolean onlyIfParentIsActive);
private static native void nativeSetTransparentTitleBarHeight(long nsWindowPtr, float height);
private static native void nativeCallDeliverMoveResizeEvent(long nsWindowPtr);
// Loger to report issues happened during execution but that do not affect functionality
private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
@@ -292,7 +290,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
new Property<CPlatformWindow>(WINDOW_TRANSPARENT_TITLE_BAR_HEIGHT) {
public void applyProperty(final CPlatformWindow c, final Object value) {
if (value != null && (value instanceof Float)) {
c.execute(ptr -> AWTThreading.executeWaitToolkit(wait -> nativeSetTransparentTitleBarHeight(ptr, (float) value)));
c.execute(ptr -> nativeSetTransparentTitleBarHeight(ptr, (float) value));
}
}
}
@@ -1197,10 +1195,6 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
responder.handleWindowFocusEvent(gained, oppositePeer);
}
public void doDeliverMoveResizeEvent() {
execute(ptr -> nativeCallDeliverMoveResizeEvent(ptr));
}
protected void deliverMoveResizeEvent(int x, int y, int width, int height,
boolean byUser) {
AtomicBoolean ref = new AtomicBoolean();
@@ -1345,7 +1339,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
// which is going to become 'main window', are placed above their siblings.
CPlatformWindow rootOwner = getRootOwner();
if (rootOwner.isVisible() && !rootOwner.isIconified() && !rootOwner.isActive()) {
rootOwner.execute(CWrapper.NSWindow::orderFrontIfOnActiveSpace);
rootOwner.execute(CWrapper.NSWindow::orderFront);
}
// Do not order child windows of iconified owner.
@@ -1381,7 +1375,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
}
pwUnder.execute(underPtr -> {
pw.execute(ptr -> {
CWrapper.NSWindow.orderWindowIfOnActiveSpace(ptr, CWrapper.NSWindow.NSWindowAbove, underPtr);
CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, underPtr);
});
});
pwUnder = pw;
@@ -1462,20 +1456,28 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
isFullScreenAnimationOn = false;
}
// JBR API internals
private static void setCustomDecorationTitleBarHeight(Window target, ComponentPeer peer, float height) {
if (peer instanceof LWComponentPeer) {
PlatformWindow platformWindow = ((LWComponentPeer<?, ?>) peer).getPlatformWindow();
if (platformWindow instanceof CPlatformWindow) {
((CPlatformWindow) platformWindow).execute(ptr -> {
AWTThreading.executeWaitToolkit(wait -> nativeSetTransparentTitleBarHeight(ptr, height));
});
if (target instanceof javax.swing.RootPaneContainer) {
final javax.swing.JRootPane rootpane = ((javax.swing.RootPaneContainer)target).getRootPane();
if (rootpane != null) rootpane.putClientProperty(WINDOW_TRANSPARENT_TITLE_BAR_HEIGHT, height);
}
}
// called from client via reflection
private void setTransparentTitleBarHeight(float height) {
execute(ptr -> {
nativeSetTransparentTitleBarHeight(ptr, height);
});
}
private volatile List<Rectangle> customDecorHitTestSpots;
// called from client via reflection
private void setCustomDecorationHitTestSpots(List<Rectangle> hitTestSpots) {
this.customDecorHitTestSpots = new CopyOnWriteArrayList<>(hitTestSpots);
}
// called from native
private boolean hitTestCustomDecoration(float x, float y) {
List<Rectangle> spots = customDecorHitTestSpots;
if (spots == null) return false;
for (Rectangle spot : spots) {
if (spot.contains(x, y)) return true;
}
return false;
}
}

View File

@@ -56,10 +56,8 @@ final class CWrapper {
static native boolean isKeyWindow(long window);
static native void orderFront(long window);
static native void orderFrontIfOnActiveSpace(long window);
static native void orderFrontRegardless(long window);
static native void orderWindow(long window, int ordered, long relativeTo);
static native void orderWindowIfOnActiveSpace(long window, int ordered, long relativeTo);
/**
* Removes the window from the screen.

View File

@@ -89,7 +89,6 @@ import java.net.URL;
import java.security.*;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
@@ -112,7 +111,6 @@ import sun.lwawt.PlatformComponent;
import sun.lwawt.PlatformDropTarget;
import sun.lwawt.PlatformWindow;
import sun.lwawt.SecurityWarningWindow;
import sun.security.action.GetBooleanAction;
import sun.util.logging.PlatformLogger;
@SuppressWarnings("serial") // JDK implementation class
@@ -142,13 +140,6 @@ public final class LWCToolkit extends LWToolkit {
private static CInputMethodDescriptor sInputMethodDescriptor;
// Listens to EDT state in invokeAndWait() and disposes the invocation event
// when EDT becomes free but the invocation event is not yet dispatched (considered lost).
// This prevents a deadlock and makes the invocation return some default result.
@SuppressWarnings("removal")
private static final boolean DISPOSE_INVOCATION_ON_EDT_FREE =
AccessController.doPrivileged(new GetBooleanAction("sun.lwawt.macosx.LWCToolkit.invokeAndWait.disposeOnEDTFree"));
static {
System.err.flush();
@@ -195,7 +186,7 @@ public final class LWCToolkit extends LWToolkit {
*/
private static final boolean inAWT;
private static final PlatformLogger log = PlatformLogger.getLogger(LWCToolkit.class.getName());
private static final PlatformLogger log = PlatformLogger.getLogger("sun.lwawt.macosx.LWCToolkit");
public LWCToolkit() {
final String extraButtons = "sun.awt.enableExtraMouseButtons";
@@ -504,8 +495,7 @@ public final class LWCToolkit extends LWToolkit {
if (!(gd instanceof CGraphicsDevice)) {
return AWTThreading.executeWaitToolkit(() -> super.getScreenInsets(gc));
}
CGraphicsDevice cgd = (CGraphicsDevice) gd;
return cgd.getScreenInsets();
return AWTThreading.executeWaitToolkit(() -> ((CGraphicsDevice)gd).getScreenInsets());
}
@Override
@@ -685,12 +675,30 @@ public final class LWCToolkit extends LWToolkit {
return invokeAndWait(callable, component, -1);
}
public static <T> T invokeAndWait(final Callable<T> callable, Component component, int timeoutSeconds) throws Exception {
static <T> T invokeAndWait(final Callable<T> callable, Component component, int timeoutSeconds) throws Exception {
final CallableWrapper<T> wrapper = new CallableWrapper<>(callable);
invokeAndWait(wrapper, component, false, timeoutSeconds);
return wrapper.getResult();
}
static final class CancelableRunnable implements Runnable {
volatile Runnable runnable;
public CancelableRunnable(Runnable runnable) {
this.runnable = runnable;
}
@Override
public void run() {
Runnable r = runnable;
if (r != null) r.run();
}
public void cancel() {
runnable = null;
}
}
static final class CallableWrapper<T> implements Runnable {
final Callable<T> callable;
T object;
@@ -720,6 +728,30 @@ public final class LWCToolkit extends LWToolkit {
}
}
private static final AtomicInteger blockingRunLoopCounter = new AtomicInteger(0);
private static final AtomicBoolean priorityInvocationPending = new AtomicBoolean(false);
@Override
public void unsafeNonblockingExecute(Runnable runnable) {
if (!EventQueue.isDispatchThread()) {
throw new Error("the method must be called on the Event Dispatching thread");
}
if (runnable == null) return;
synchronized (priorityInvocationPending) {
priorityInvocationPending.set(true);
}
AWTAccessor.getEventQueueAccessor().createSecondaryLoop(
getSystemEventQueue(),
() -> blockingRunLoopCounter.get() > 0).enter();
try {
runnable.run();
} finally {
priorityInvocationPending.set(false);
}
}
/**
* Kicks an event over to the appropriate eventqueue and waits for it to
* finish To avoid deadlocking, we manually run the NSRunLoop while waiting
@@ -744,32 +776,32 @@ public final class LWCToolkit extends LWToolkit {
invokeAndWait(runnable, component, false, -1);
}
public static void invokeAndWait(Runnable runnable, Component component, boolean processEvents, int timeoutSeconds)
static void invokeAndWait(Runnable runnable, Component component, boolean processEvents, int timeoutSeconds)
throws InvocationTargetException
{
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("invokeAndWait started: " + runnable);
}
if (isBlockingEventDispatchThread()) {
String msg = "invokeAndWait is discarded as the EventDispatch thread is currently blocked";
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine(msg, new Throwable());
log.fine(AWTThreading.getInstance(component).printEventDispatchThreadStackTrace().toString());
} else if (log.isLoggable(PlatformLogger.Level.INFO)) {
StackTraceElement[] stack = new Throwable().getStackTrace();
log.info(msg + ". Originated at " + stack[stack.length - 1]);
Thread dispatchThread = AWTThreading.getInstance(component).getEventDispatchThread();
log.info(dispatchThread.getName() + " at: " + dispatchThread.getStackTrace()[0].toString());
}
return;
boolean nonBlockingRunLoop;
CancelableRunnable cancelableRunnable = new CancelableRunnable(runnable);
synchronized (priorityInvocationPending) {
nonBlockingRunLoop = priorityInvocationPending.get();
if (!nonBlockingRunLoop) blockingRunLoopCounter.incrementAndGet();
}
AWTThreading.TrackedInvocationEvent invocationEvent =
AWTThreading.createAndTrackInvocationEvent(component, runnable, true);
final long mediator = createAWTRunLoopMediator();
long mediator = createAWTRunLoopMediator();
invocationEvent.onDone(() -> stopAWTRunLoop(mediator));
InvocationEvent invocationEvent =
AWTThreading.createAndTrackInvocationEvent(component,
cancelableRunnable,
() -> {
if (mediator != 0) {
stopAWTRunLoop(mediator);
}
},
true);
if (component != null) {
AppContext appContext = SunToolkit.targetToAppContext(component);
@@ -783,21 +815,11 @@ public final class LWCToolkit extends LWToolkit {
((LWCToolkit)Toolkit.getDefaultToolkit()).getSystemEventQueueForInvokeAndWait().postEvent(invocationEvent);
}
if (DISPOSE_INVOCATION_ON_EDT_FREE) {
CompletableFuture<Void> eventDispatchThreadFreeFuture =
AWTThreading.getInstance(component).onEventDispatchThreadFree(() -> {
if (!invocationEvent.isCompleted(true)) {
// EventQueue is now empty but the posted InvocationEvent is still not dispatched,
// consider it lost then.
invocationEvent.dispose("InvocationEvent was lost");
}
});
invocationEvent.onDone(() -> eventDispatchThreadFreeFuture.cancel(false));
}
if (!doAWTRunLoop(mediator, false, timeoutSeconds)) {
invocationEvent.dispose("InvocationEvent has timed out");
if (!doAWTRunLoop(mediator, nonBlockingRunLoop, timeoutSeconds)) {
new Throwable("Invocation timed out (" + timeoutSeconds + "sec)").printStackTrace();
cancelableRunnable.cancel();
}
if (!nonBlockingRunLoop) blockingRunLoopCounter.decrementAndGet();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("invokeAndWait finished: " + runnable);
@@ -806,8 +828,6 @@ public final class LWCToolkit extends LWToolkit {
checkException(invocationEvent);
}
private static native boolean isBlockingEventDispatchThread();
public static void invokeLater(Runnable event, Component component)
throws InvocationTargetException {
Objects.requireNonNull(component, "Null component provided to invokeLater");
@@ -850,11 +870,6 @@ public final class LWCToolkit extends LWToolkit {
*/
static native void performOnMainThreadAfterDelay(Runnable r, long delay);
/**
* Schedules a {@code Runnable} execution on the Appkit thread and waits for completion.
*/
public static native void performOnMainThreadAndWait(Runnable r);
// DnD support
@Override

View File

@@ -50,10 +50,6 @@
NSWindowTabbingMode javaWindowTabbingMode;
BOOL isEnterFullScreen;
CGFloat _transparentTitleBarHeight;
id<NSObject> _windowWillEnterFullScreenNotification;
id<NSObject> _windowWillExitFullScreenNotification;
id<NSObject> _windowDidExitFullScreenNotification;
NSMutableArray* _transparentTitleBarConstraints;
NSLayoutConstraint *_transparentTitleBarHeightConstraint;
NSMutableArray *_transparentTitleBarButtonCenterXConstraints;
}

View File

@@ -26,7 +26,6 @@
#include <objc/objc-runtime.h>
#import <Cocoa/Cocoa.h>
#include <java_awt_Window_CustomWindowDecoration.h>
#import "sun_lwawt_macosx_CPlatformWindow.h"
#import "com_apple_eawt_event_GestureHandler.h"
#import "com_apple_eawt_FullScreenHandler.h"
@@ -70,9 +69,6 @@ static NSPoint lastTopLeftPoint;
static BOOL ignoreResizeWindowDuringAnotherWindowEnd = NO;
static BOOL fullScreenTransitionInProgress = NO;
static BOOL orderingScheduled = NO;
// --------------------------------------------------------------
// NSWindow/NSPanel descendants implementation
#define AWT_NS_WINDOW_IMPLEMENTATION \
@@ -403,11 +399,10 @@ AWT_NS_WINDOW_IMPLEMENTATION
if (IS(mask, FULLSCREENABLE) && [self.nsWindow respondsToSelector:@selector(toggleFullScreen:)]) {
if (IS(bits, FULLSCREENABLE)) {
self.nsWindow.collectionBehavior = self.nsWindow.collectionBehavior |
NSWindowCollectionBehaviorFullScreenPrimary;
[self.nsWindow setCollectionBehavior:
NSWindowCollectionBehaviorFullScreenPrimary | NSWindowCollectionBehaviorManaged];
} else {
self.nsWindow.collectionBehavior = self.nsWindow.collectionBehavior &
~NSWindowCollectionBehaviorFullScreenPrimary;
[self.nsWindow setCollectionBehavior: NSWindowCollectionBehaviorManaged];
}
}
@@ -483,7 +478,6 @@ AWT_ASSERT_APPKIT_THREAD;
self.isJustCreated = YES;
self.javaWindowTabbingMode = [self getJavaWindowTabbingMode];
self.nsWindow.collectionBehavior = NSWindowCollectionBehaviorManaged;
self.isEnterFullScreen = NO;
return self;
@@ -647,9 +641,8 @@ AWT_ASSERT_APPKIT_THREAD;
- (BOOL) delayShowing {
AWT_ASSERT_APPKIT_THREAD;
return ownerWindow != nil &&
([ownerWindow delayShowing] || !ownerWindow.nsWindow.onActiveSpace) &&
!nsWindow.visible;
return ownerWindow != nil && ([ownerWindow delayShowing] || !ownerWindow.nsWindow.onActiveSpace)
&& !nsWindow.visible;
}
- (BOOL) checkBlockingAndOrder {
@@ -670,19 +663,14 @@ AWT_ASSERT_APPKIT_THREAD;
+ (void)activeSpaceDidChange {
AWT_ASSERT_APPKIT_THREAD;
if (fullScreenTransitionInProgress) {
orderingScheduled = YES;
return;
}
// show delayed windows
for (NSWindow *window in NSApp.windows) {
if ([AWTWindow isJavaPlatformWindowVisible:window] && !window.visible) {
for (NSWindow* window in [NSApp windows]) {
if (window.onActiveSpace && window.mainWindow && [AWTWindow isJavaPlatformWindowVisible:window]) {
AWTWindow *awtWindow = (AWTWindow *)[window delegate];
while (awtWindow.ownerWindow != nil) {
awtWindow = awtWindow.ownerWindow;
}
if (awtWindow.nsWindow.visible && awtWindow.nsWindow.onActiveSpace) {
// there can be only one current blocker per window hierarchy,
// so we're checking just hierarchy root
if (awtWindow.ownerWindow == nil) {
// this should ensure that delayed blocking windows
// show up on space activation
[awtWindow checkBlockingAndOrder];
}
}
@@ -731,6 +719,11 @@ AWT_ASSERT_APPKIT_THREAD;
// back to normal window level
[window setLevel:NSNormalWindowLevel];
}
if (window.onActiveSpace && owner.onActiveSpace) {
// The childWindow should be displayed in front of
// its nearest parentWindow
[window orderWindow:NSWindowAbove relativeTo:[owner windowNumber]];
}
}
}];
}
@@ -776,7 +769,7 @@ AWT_ASSERT_APPKIT_THREAD;
// NSWindowDelegate methods
- (void) _deliverMoveResizeEvent {
AWT_ASSERT_APPKIT_THREAD;
AWT_ASSERT_APPKIT_THREAD;
// deliver the event if this is a user-initiated live resize or as a side-effect
// of a Java initiated resize, because AppKit can override the bounds and force
@@ -785,19 +778,11 @@ AWT_ASSERT_APPKIT_THREAD;
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = (*env)->NewLocalRef(env, self.javaPlatformWindow);
if (platformWindow == NULL) {
NSLog(@"[AWTWindow _deliverMoveResizeEvent]: platformWindow == NULL");
return;
}
NSRect frame;
@try {
frame = ConvertNSScreenRect(env, [self.nsWindow frame]);
} @catch (NSException *e) {
NSLog(@"WARNING: suppressed exception from ConvertNSScreenRect() in [AWTWindow _deliverMoveResizeEvent]");
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
[NSApplicationAWT logException:e forProcess:processInfo];
return;
// TODO: create generic AWT assert
}
NSRect frame = ConvertNSScreenRect(env, [self.nsWindow frame]);
GET_CPLATFORM_WINDOW_CLASS();
DECLARE_METHOD(jm_deliverMoveResizeEvent, jc_CPlatformWindow, "deliverMoveResizeEvent", "(IIIIZ)V");
(*env)->CallVoidMethod(env, platformWindow, jm_deliverMoveResizeEvent,
@@ -1018,7 +1003,7 @@ AWT_ASSERT_APPKIT_THREAD;
#ifdef DEBUG
NSLog(@"resigned key: %d %@ %@", [self.nsWindow isMainWindow], [self.nsWindow title], [self menuBarForWindow]);
#endif
if (![self.nsWindow isMainWindow] || [NSApp keyWindow] == self.nsWindow) {
if (![self.nsWindow isMainWindow]) {
[self deactivateWindow];
}
}
@@ -1047,9 +1032,7 @@ AWT_ASSERT_APPKIT_THREAD;
NSWindow *keyWindow = [NSApp keyWindow];
AWTWindow *opposite = nil;
if ([AWTWindow isAWTWindow: keyWindow]) {
if (keyWindow != self.nsWindow) {
opposite = (AWTWindow *)[keyWindow delegate];
}
opposite = (AWTWindow *)[keyWindow delegate];
[AWTWindow setLastKeyWindow: self];
} else {
[AWTWindow setLastKeyWindow: nil];
@@ -1097,26 +1080,13 @@ AWT_ASSERT_APPKIT_THREAD;
[self processVisibleChildren:^void(AWTWindow* child){
NSWindow *window = child.nsWindow;
NSWindowCollectionBehavior behavior = window.collectionBehavior;
behavior &= ~(NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorTransient);
behavior &= !(NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorTransient);
behavior |= allow ? NSWindowCollectionBehaviorTransient : NSWindowCollectionBehaviorManaged;
window.collectionBehavior = behavior;
}];
}
- (void) fullScreenTransitionStarted {
fullScreenTransitionInProgress = YES;
}
- (void) fullScreenTransitionFinished {
fullScreenTransitionInProgress = NO;
if (orderingScheduled) {
orderingScheduled = NO;
[self checkBlockingAndOrder];
}
}
- (void)windowWillEnterFullScreen:(NSNotification *)notification {
[self fullScreenTransitionStarted];
[self allowMovingChildrenBetweenSpaces:YES];
self.isEnterFullScreen = YES;
@@ -1137,7 +1107,6 @@ AWT_ASSERT_APPKIT_THREAD;
self.isEnterFullScreen = YES;
[self allowMovingChildrenBetweenSpaces:NO];
[self fullScreenTransitionFinished];
JNIEnv *env = [ThreadUtilities getJNIEnv];
GET_CPLATFORM_WINDOW_CLASS();
@@ -1155,8 +1124,6 @@ AWT_ASSERT_APPKIT_THREAD;
- (void)windowWillExitFullScreen:(NSNotification *)notification {
self.isEnterFullScreen = NO;
[self fullScreenTransitionStarted];
JNIEnv *env = [ThreadUtilities getJNIEnv];
GET_CPLATFORM_WINDOW_CLASS();
DECLARE_METHOD(jm_windowWillExitFullScreen, jc_CPlatformWindow, "windowWillExitFullScreen", "()V");
@@ -1177,8 +1144,6 @@ AWT_ASSERT_APPKIT_THREAD;
- (void)windowDidExitFullScreen:(NSNotification *)notification {
self.isEnterFullScreen = NO;
[self fullScreenTransitionFinished];
JNIEnv *env = [ThreadUtilities getJNIEnv];
jobject platformWindow = (*env)->NewLocalRef(env, self.javaPlatformWindow);
if (platformWindow != NULL) {
@@ -1305,10 +1270,10 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
NSView* titlebarContainer = titlebar.superview;
NSView* themeFrame = titlebarContainer.superview;
_transparentTitleBarConstraints = [[NSMutableArray alloc] init];
NSMutableArray* newConstraints = [[NSMutableArray alloc] init];
titlebarContainer.translatesAutoresizingMaskIntoConstraints = NO;
_transparentTitleBarHeightConstraint = [titlebarContainer.heightAnchor constraintEqualToConstant:_transparentTitleBarHeight];
[_transparentTitleBarConstraints addObjectsFromArray:@[
[newConstraints addObjectsFromArray:@[
[titlebarContainer.leftAnchor constraintEqualToAnchor:themeFrame.leftAnchor],
[titlebarContainer.widthAnchor constraintEqualToAnchor:themeFrame.widthAnchor],
[titlebarContainer.topAnchor constraintEqualToAnchor:themeFrame.topAnchor],
@@ -1321,7 +1286,7 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
for (NSView* view in @[titlebar, windowDragView])
{
view.translatesAutoresizingMaskIntoConstraints = NO;
[_transparentTitleBarConstraints addObjectsFromArray:@[
[newConstraints addObjectsFromArray:@[
[view.leftAnchor constraintEqualToAnchor:titlebarContainer.leftAnchor],
[view.rightAnchor constraintEqualToAnchor:titlebarContainer.rightAnchor],
[view.topAnchor constraintEqualToAnchor:titlebarContainer.topAnchor],
@@ -1337,7 +1302,7 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
button.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint* buttonCenterXConstraint = [button.centerXAnchor constraintEqualToAnchor:titlebarContainer.leftAnchor constant:(_transparentTitleBarHeight/2.0 + (index * horizontalButtonOffset))];
[_transparentTitleBarButtonCenterXConstraints addObject:buttonCenterXConstraint];
[_transparentTitleBarConstraints addObjectsFromArray:@[
[newConstraints addObjectsFromArray:@[
[button.widthAnchor constraintLessThanOrEqualToAnchor:titlebarContainer.heightAnchor multiplier:0.5],
// Those corrections are required to keep the icons perfectly round because macOS adds a constant 2 px in resulting height to their frame
[button.heightAnchor constraintEqualToAnchor: button.widthAnchor multiplier:14.0/12.0 constant:-2.0],
@@ -1346,7 +1311,7 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
]];
}];
[NSLayoutConstraint activateConstraints:_transparentTitleBarConstraints];
[NSLayoutConstraint activateConstraints:newConstraints];
}
- (void) updateTransparentTitleBarConstraints
@@ -1372,22 +1337,20 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
NSView* titlebarContainer = titlebar.superview;
NSView* themeFrame = titlebarContainer.superview;
[NSLayoutConstraint deactivateConstraints:_transparentTitleBarConstraints];
AWTWindowDragView* windowDragView;
for (NSView* view in titlebar.subviews) {
if ([view isMemberOfClass:[AWTWindowDragView class]]) {
windowDragView = view;
}
if (view.translatesAutoresizingMaskIntoConstraints == NO) {
[view removeConstraints:view.constraints];
view.translatesAutoresizingMaskIntoConstraints = YES;
}
}
[windowDragView removeFromSuperview];
[titlebarContainer removeConstraints:titlebarContainer.constraints];
titlebarContainer.translatesAutoresizingMaskIntoConstraints = YES;
titlebar.translatesAutoresizingMaskIntoConstraints = YES;
_transparentTitleBarConstraints = nil;
_transparentTitleBarHeightConstraint = nil;
_transparentTitleBarButtonCenterXConstraints = nil;
}
@@ -1416,44 +1379,23 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
});
NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
NSOperationQueue* mainQueue = [NSOperationQueue mainQueue];
_windowWillEnterFullScreenNotification = [defaultCenter addObserverForName:NSWindowWillEnterFullScreenNotification object:self.nsWindow queue:mainQueue usingBlock:^(NSNotification* notification) {
[defaultCenter addObserverForName:NSWindowWillEnterFullScreenNotification object:self.nsWindow queue:mainQueue usingBlock:^(NSNotification* notification) {
[self resetTitleBar];
}];
_windowWillExitFullScreenNotification = [defaultCenter addObserverForName:NSWindowWillExitFullScreenNotification object:self.nsWindow queue:mainQueue usingBlock:^(NSNotification* notification) {
[defaultCenter addObserverForName:NSWindowWillExitFullScreenNotification object:self.nsWindow queue:mainQueue usingBlock:^(NSNotification* notification) {
[self setWindowControlsHidden:YES];
}];
_windowDidExitFullScreenNotification = [defaultCenter addObserverForName:NSWindowDidExitFullScreenNotification object:self.nsWindow queue:mainQueue usingBlock:^(NSNotification* notification) {
[defaultCenter addObserverForName:NSWindowDidExitFullScreenNotification object:self.nsWindow queue:mainQueue usingBlock:^(NSNotification* notification) {
[self setUpTransparentTitleBar];
[self setWindowControlsHidden:NO];
}];
}
- (void) configureWindowAndListenersForDefaultTitleBar
{
dispatch_sync(dispatch_get_main_queue(), ^{
[self.nsWindow setTitlebarAppearsTransparent:NO];
[self.nsWindow setTitleVisibility:NSWindowTitleVisible];
[self.nsWindow setStyleMask:[self.nsWindow styleMask]&(~NSWindowStyleMaskFullSizeContentView)];
if (!self.isFullScreen) {
[self resetTitleBar];
}
});
NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter removeObserver:_windowWillEnterFullScreenNotification];
[defaultCenter removeObserver:_windowWillExitFullScreenNotification];
[defaultCenter removeObserver:_windowDidExitFullScreenNotification];
_windowWillEnterFullScreenNotification = _windowWillExitFullScreenNotification = _windowDidExitFullScreenNotification = nil;
}
- (void) setTransparentTitleBarHeight: (CGFloat) transparentTitleBarHeight
{
if (_transparentTitleBarHeight == transparentTitleBarHeight) return;
if (_transparentTitleBarHeight != 0.0f) {
_transparentTitleBarHeight = transparentTitleBarHeight;
if (transparentTitleBarHeight == 0.0f) {
[self configureWindowAndListenersForDefaultTitleBar];
} else if (_transparentTitleBarHeightConstraint != nil || _transparentTitleBarButtonCenterXConstraints != nil) {
if (_transparentTitleBarHeightConstraint != nil || _transparentTitleBarButtonCenterXConstraints != nil) {
[self updateTransparentTitleBarConstraints];
}
} else {
@@ -1489,18 +1431,11 @@ static const CGFloat DefaultHorizontalTitleBarButtonOffset = 20.0;
jobject platformWindow = (*env)->NewLocalRef(env, self.javaPlatformWindow);
if (platformWindow != NULL) {
GET_CPLATFORM_WINDOW_CLASS_RETURN(YES);
DECLARE_FIELD_RETURN(jf_target, jc_CPlatformWindow, "target", "Ljava/awt/Window;", YES);
DECLARE_CLASS_RETURN(jc_Window, "java/awt/Window", YES);
DECLARE_METHOD_RETURN(jm_hitTestCustomDecoration, jc_Window, "hitTestCustomDecoration", "(II)I", YES);
jobject awtWindow = (*env)->GetObjectField(env, platformWindow, jf_target);
if (awtWindow != NULL) {
NSRect frame = [self.window frame];
float windowHeight = frame.size.height;
returnValue = (*env)->CallIntMethod(env, awtWindow, jm_hitTestCustomDecoration, (jint) point.x, (jint) (windowHeight - point.y)) ==
(jint) java_awt_Window_CustomWindowDecoration_NO_HIT_SPOT ? YES : NO;
CHECK_EXCEPTION();
(*env)->DeleteLocalRef(env, awtWindow);
}
DECLARE_METHOD_RETURN(jm_hitTestCustomDecoration, jc_CPlatformWindow, "hitTestCustomDecoration", "(FF)Z", YES);
NSRect frame = [self.window frame];
float windowHeight = frame.size.height;
returnValue = (*env)->CallBooleanMethod(env, platformWindow, jm_hitTestCustomDecoration, point.x, windowHeight - point.y) == JNI_TRUE ? NO : YES;
CHECK_EXCEPTION_IN_ENV(env);
(*env)->DeleteLocalRef(env, platformWindow);
}
return returnValue;
@@ -1653,15 +1588,7 @@ JNI_COCOA_ENTER(env);
// resets the NSWindow's style mask if the mask intersects any of those bits
if (mask & MASK(_STYLE_PROP_BITMASK)) {
NSWindowStyleMask styleMask = [AWTWindow styleMaskForStyleBits:newBits];
@try {
[nsWindow setStyleMask:styleMask];
} @catch (NSException *e) {
NSLog(@"WARNING: suppressed exception from [NSWindow setStyleMask] in CPlatformWindow"
".nativeSetNSWindowStyleBits");
NSProcessInfo *processInfo = [NSProcessInfo processInfo];
[NSApplicationAWT logException:e forProcess:processInfo];
}
[nsWindow setStyleMask:[AWTWindow styleMaskForStyleBits:newBits]];
}
// calls methods on NSWindow to change other properties, based on the mask
@@ -2349,18 +2276,4 @@ JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetTransparen
[window setTransparentTitleBarHeight:((CGFloat) transparentTitleBarHeight)];
JNI_COCOA_EXIT(env);
}
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeCallDeliverMoveResizeEvent
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
JNI_COCOA_ENTER(env);
NSWindow *nsWindow = (NSWindow *)jlong_to_ptr(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
AWTWindow *window = (AWTWindow*)[nsWindow delegate];
[window _deliverMoveResizeEvent];
}];
JNI_COCOA_EXIT(env);
}
}

View File

@@ -237,7 +237,7 @@ static BOOL sNeedsEnter;
jobject transferer = [self dataTransferer:env];
jbyteArray data = nil;
if (transferer != NULL && fComponent != NULL) {
if (transferer != NULL) {
GET_DT_CLASS_RETURN(NULL);
DECLARE_METHOD_RETURN(convertDataMethod, DataTransfererClass, "convertData", "(Ljava/lang/Object;Ljava/awt/datatransfer/Transferable;JLjava/util/Map;Z)[B", NULL);
data = (*env)->CallObjectMethod(env, transferer, convertDataMethod, fComponent, fTransferable, format, fFormatMap, (jboolean) TRUE);

View File

@@ -69,9 +69,6 @@ static int* gsButtonEventNumber;
static NSTimeInterval gNextKeyEventTime;
static NSTimeInterval safeDelay;
#define KEY_CODE_COUNT 128
static CGEventFlags keyOwnFlags[KEY_CODE_COUNT];
static inline CGKeyCode GetCGKeyCode(jint javaKeyCode);
static void PostMouseEvent(const CGPoint point, CGMouseButton button,
@@ -110,20 +107,6 @@ static inline void autoDelay(BOOL isMove) {
gNextKeyEventTime = [[NSDate date] timeIntervalSinceReferenceDate] + safeDelay;
}
static void initKeyFlags() {
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStatePrivate);
for (CGKeyCode keyCode = 0; keyCode < KEY_CODE_COUNT; keyCode++) {
CGEventRef event = CGEventCreateKeyboardEvent(source, keyCode, true);
if (event != NULL) {
keyOwnFlags[keyCode] = CGEventGetFlags(event);
CFRelease(event);
}
}
if (source != NULL) {
CFRelease(source);
}
}
/*
* Class: sun_lwawt_macosx_CRobot
* Method: initRobot
@@ -172,8 +155,6 @@ Java_sun_lwawt_macosx_CRobot_initRobot
for (i = 0; i < gNumberOfButtons; ++i) {
gsButtonEventNumber[i] = ROBOT_EVENT_NUMBER_START;
}
initKeyFlags();
}];
}
}
@@ -302,20 +283,6 @@ Java_sun_lwawt_macosx_CRobot_mouseWheel
}];
}
// CGEventCreateKeyboardEvent incorrectly handles flags pertinent to non-modifier keys
// (e.g. F1-F12 keys always Fn flag set, while arrow keys always have Fn and NumPad flags set).
// Those flags are not cleared for following key presses automatically, so we need to do it ourselves.
// See JBR-4306 for details.
static void clearStickyFlags(CGEventRef event, CGKeyCode keyCode, CGEventFlags flagToCheck) {
if (keyCode < KEY_CODE_COUNT && (keyOwnFlags[keyCode] & flagToCheck) == 0) {
CGEventFlags flags = CGEventGetFlags(event);
CGEventFlags updatedFlags = flags & ~flagToCheck;
if (updatedFlags != flags) {
CGEventSetFlags(event, updatedFlags);
}
}
}
/*
* Class: sun_lwawt_macosx_CRobot
* Method: keyEvent
@@ -331,10 +298,6 @@ Java_sun_lwawt_macosx_CRobot_keyEvent
CGKeyCode keyCode = GetCGKeyCode(javaKeyCode);
CGEventRef event = CGEventCreateKeyboardEvent(source, keyCode, keyPressed);
if (event != NULL) {
// this assumes Robot isn't used to generate Fn key presses
clearStickyFlags(event, keyCode, kCGEventFlagMaskSecondaryFn);
// there is no NumPad key, so this won't hurt in any case
clearStickyFlags(event, keyCode, kCGEventFlagMaskNumericPad);
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
}

View File

@@ -41,51 +41,6 @@ static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
#pragma mark --- CoreText Support ---
// Translates a Unicode into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyphRef"
CTFontRef JavaCT_CopyCTFallbackFontAndGlyphForUnicode
(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count) {
CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font->fFont, charRef, count);
if (fallback == NULL)
{
// use the original font if we somehow got duped into trying to fallback something we can't
fallback = (CTFontRef)font->fFont;
CFRetain(fallback);
}
CTFontGetGlyphsForCharacters(fallback, charRef, glyphRef, count);
return fallback;
}
// Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyph"
CTFontRef JavaCT_CopyCTFallbackFontAndGlyphForJavaGlyphCode
(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef)
{
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
if (glyphCode >= 0)
{
*glyphRef = glyphCode;
CFRetain(font->fFont);
return (CTFontRef)font->fFont;
}
UTF16Char character = -glyphCode;
return JavaCT_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1);
}
// Breakup a 32 bit unicode value into the component surrogate pairs
void JavaCT_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) {
int value = uniChar - 0x10000;
UTF16Char low_surrogate = (value & 0x3FF) | LO_SURROGATE_START;
UTF16Char high_surrogate = (((int)(value & 0xFFC00)) >> 10) | HI_SURROGATE_START;
charRef[0] = high_surrogate;
charRef[1] = low_surrogate;
}
/*
* Callback for CoreText which uses the CoreTextProviderStruct to feed CT UniChars
* We only use it for one-off lines, and don't attempt to fragment our strings
@@ -129,7 +84,7 @@ static NSDictionary* ctsDictionaryFor(const NSFont *font, BOOL useFractionalMetr
// Itterates though each glyph, and if a transform is present for that glyph, apply it to the CGContext, and strike the glyph.
// If there is no per-glyph transform, just strike the glyph. Advances must also be transformed on-the-spot as well.
void JavaCT_DrawGlyphVector
(const QuartzSDOps *qsdo, const AWTStrike *strike, const BOOL useSubstituion, const int uniChars[], const CGGlyph glyphs[], CGSize advances[], const jint g_gvTXIndicesAsInts[], const jdouble g_gvTransformsAsDoubles[], const CFIndex length)
(const QuartzSDOps *qsdo, const AWTStrike *strike, const CGGlyph glyphs[], CGSize advances[], const jint g_gvTXIndicesAsInts[], const jdouble g_gvTransformsAsDoubles[], const CFIndex length)
{
CGPoint pt = { 0, 0 };
@@ -137,49 +92,12 @@ void JavaCT_DrawGlyphVector
CGContextRef cgRef = qsdo->cgRef;
CGAffineTransform ctmText = CGContextGetTextMatrix(cgRef);
BOOL saved = false;
CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx);
NSInteger i;
for (i = 0; i < length; i++)
{
CGGlyph glyph = glyphs[i];
int uniChar = uniChars[i];
// if we found a unichar instead of a glyph code, get the fallback font,
// find the glyph code for the fallback font, and set the font on the current context
if (uniChar != 0)
{
CTFontRef fallback;
if (uniChar > 0xFFFF) {
UTF16Char charRef[2];
JavaCT_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
CGGlyph glyphTmp[2];
fallback = JavaCT_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
glyph = glyphTmp[0];
} else {
const UTF16Char u = uniChar;
fallback = JavaCT_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, &u, (CGGlyph *)&glyph, 1);
}
if (fallback) {
const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
CFRelease(fallback);
if (cgFallback) {
if (!saved) {
CGContextSaveGState(cgRef);
saved = true;
}
CGContextSetFont(cgRef, cgFallback);
CFRelease(cgFallback);
}
}
} else {
if (saved) {
CGContextRestoreGState(cgRef);
saved = false;
}
}
// if we have per-glyph transformations
int tin = (g_gvTXIndicesAsInts == NULL) ? -1 : (g_gvTXIndicesAsInts[i] - 1) * 6;
@@ -214,10 +132,6 @@ void JavaCT_DrawGlyphVector
pt.y += advances[i].height;
}
// reset the font on the context after striking a unicode with CoreText
if (saved) {
CGContextRestoreGState(cgRef);
}
}
// Using the Quartz Surface Data context, draw a hot-substituted character run
@@ -327,24 +241,16 @@ static jclass jc_StandardGlyphVector = NULL;
// Checks the GlyphVector Java object for any transforms that were applied to individual characters. If none are present,
// strike the glyphs immediately in Core Graphics. Otherwise, obtain the arrays, and defer to above.
static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, BOOL useSubstituion, int *uniChars, CGGlyph *glyphs, CGSize *advances, size_t length)
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, CGSize *advances, size_t length)
{
// if we have no character substitution, and no per-glyph transformations - strike now!
// if we have no per-glyph transformations - strike now!
GET_SGV_CLASS();
DECLARE_FIELD(jm_StandardGlyphVector_gti, jc_StandardGlyphVector, "gti", "Lsun/font/StandardGlyphVector$GlyphTransformInfo;");
jobject gti = (*env)->GetObjectField(env, gVector, jm_StandardGlyphVector_gti);
if (gti == 0)
{
if (useSubstituion)
{
// quasi-simple case, substitution, but no per-glyph transforms
JavaCT_DrawGlyphVector(qsdo, strike, TRUE, uniChars, glyphs, advances, NULL, NULL, length);
}
else
{
// fast path, straight to CG without per-glyph transforms
CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length);
}
// fast path, straight to CG without per-glyph transforms
CGContextShowGlyphsWithAdvances(qsdo->cgRef, glyphs, advances, length);
return;
}
@@ -369,8 +275,8 @@ static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(*env)->DeleteLocalRef(env, g_gtiTXIndicesArray);
return;
}
// slowest case, we have per-glyph transforms, and possibly glyph substitution as well
JavaCT_DrawGlyphVector(qsdo, strike, useSubstituion, uniChars, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length);
// slowest case, we have per-glyph transforms
JavaCT_DrawGlyphVector(qsdo, strike, glyphs, advances, g_gvTXIndicesAsInts, g_gvTransformsAsDoubles, length);
(*env)->ReleasePrimitiveArrayCritical(env, g_gtiTransformsArray, g_gvTransformsAsDoubles, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, g_gtiTXIndicesArray, g_gvTXIndicesAsInts, JNI_ABORT);
@@ -379,35 +285,11 @@ static inline void doDrawGlyphsPipe_checkForPerGlyphTransforms
(*env)->DeleteLocalRef(env, g_gtiTXIndicesArray);
}
// Retrieves advances for translated unicodes
// Uses "glyphs" as a temporary buffer for the glyph-to-unicode translation
void JavaCT_GetAdvancesForUnichars
(const NSFont *font, const int uniChars[], CGGlyph glyphs[], const size_t length, CGSize advances[])
{
// cycle over each spot, and if we discovered a unicode to substitute, we have to calculate the advance for it
size_t i;
for (i = 0; i < length; i++)
{
UniChar uniChar = uniChars[i];
if (uniChar == 0) continue;
CGGlyph glyph = 0;
const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters((CTFontRef)font, &uniChar, 1);
if (fallback) {
CTFontGetGlyphsForCharacters(fallback, &uniChar, &glyph, 1);
CTFontGetAdvancesForGlyphs(fallback, kCTFontDefaultOrientation, &glyph, &(advances[i]), 1);
CFRelease(fallback);
}
glyphs[i] = glyph;
}
}
// Fills the glyph buffer with glyphs from the GlyphVector object. Also checks to see if the glyph's positions have been
// already caculated from GlyphVector, or we simply ask Core Graphics to make some advances for us. Pre-calculated positions
// are translated into advances, since CG only understands advances.
static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, int *uniChars, CGSize *advances, size_t length, jintArray glyphsArray)
(JNIEnv *env, QuartzSDOps *qsdo, const AWTStrike *strike, jobject gVector, CGGlyph *glyphs, CGSize *advances, size_t length, jintArray glyphsArray)
{
// fill the glyph buffer
jint *glyphsAsInts = (*env)->GetPrimitiveArrayCritical(env, glyphsArray, NULL);
@@ -415,24 +297,10 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
return;
}
// if a glyph code from Java is negative, that means it is really a unicode value
// which we can use in CoreText to strike the character in another font
size_t i;
BOOL complex = NO;
for (i = 0; i < length; i++)
{
jint code = glyphsAsInts[i];
if (code < 0)
{
complex = YES;
uniChars[i] = -code;
glyphs[i] = 0;
}
else
{
uniChars[i] = 0;
glyphs[i] = code;
}
glyphs[i] = glyphsAsInts[i];
}
(*env)->ReleasePrimitiveArrayCritical(env, glyphsArray, glyphsAsInts, JNI_ABORT);
@@ -483,15 +351,10 @@ static inline void doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers
// there were no pre-calculated positions from the glyph buffer on the Java side
AWTFont *awtFont = strike->fAWTFont;
CTFontGetAdvancesForGlyphs((CTFontRef)awtFont->fFont, kCTFontDefaultOrientation, glyphs, advances, length);
if (complex)
{
JavaCT_GetAdvancesForUnichars(awtFont->fFont, uniChars, glyphs, length, advances);
}
}
// continue on to the next stage of the pipe
doDrawGlyphsPipe_checkForPerGlyphTransforms(env, qsdo, strike, gVector, complex, uniChars, glyphs, advances, length);
doDrawGlyphsPipe_checkForPerGlyphTransforms(env, qsdo, strike, gVector, glyphs, advances, length);
}
// Obtains the glyph array to determine the number of glyphs we are dealing with. If we are dealing a large number of glyphs,
@@ -515,18 +378,16 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
{
// if we are small enough, fit everything onto the stack
CGGlyph glyphs[length];
int uniChars[length];
CGSize advances[length];
doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, uniChars, advances, length, glyphsArray);
doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, advances, length, glyphsArray);
}
else
{
// otherwise, we should malloc and free buffers for this large run
CGGlyph *glyphs = (CGGlyph *)malloc(sizeof(CGGlyph) * length);
int *uniChars = (int *)malloc(sizeof(int) * length);
CGSize *advances = (CGSize *)malloc(sizeof(CGSize) * length);
if (glyphs == NULL || uniChars == NULL || advances == NULL)
if (glyphs == NULL || advances == NULL)
{
(*env)->DeleteLocalRef(env, glyphsArray);
[NSException raise:NSMallocException format:@"%s-%s:%d", __FILE__, __FUNCTION__, __LINE__];
@@ -534,10 +395,6 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
{
free(glyphs);
}
if (uniChars)
{
free(uniChars);
}
if (advances)
{
free(advances);
@@ -545,10 +402,9 @@ static inline void doDrawGlyphsPipe_getGlyphVectorLengthAndAlloc
return;
}
doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, uniChars, advances, length, glyphsArray);
doDrawGlyphsPipe_fillGlyphAndAdvanceBuffers(env, qsdo, strike, gVector, glyphs, advances, length, glyphsArray);
free(glyphs);
free(uniChars);
free(advances);
}

View File

@@ -154,25 +154,6 @@ JNI_COCOA_ENTER(env);
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CWrapper$NSWindow
* Method: orderFrontIfOnActiveSpace
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CWrapper_00024NSWindow_orderFrontIfOnActiveSpace
(JNIEnv *env, jclass cls, jlong windowPtr)
{
JNI_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
if (window.onActiveSpace) [window orderFront:window];
}];
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CWrapper$NSWindow
* Method: nativeOrderOut
@@ -250,26 +231,6 @@ JNI_COCOA_ENTER(env);
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CWrapper$NSWindow
* Method: orderWindowIfOnActiveSpace
* Signature: (JIJ)V
*/
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CWrapper_00024NSWindow_orderWindowIfOnActiveSpace
(JNIEnv *env, jclass cls, jlong windowPtr, jint order, jlong relativeToPtr)
{
JNI_COCOA_ENTER(env);
NSWindow *window = (NSWindow *)jlong_to_ptr(windowPtr);
NSWindow *relativeTo = (NSWindow *)jlong_to_ptr(relativeToPtr);
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
if (window.onActiveSpace) [window orderWindow:(NSWindowOrderingMode)order relativeTo:[relativeTo windowNumber]];
}];
JNI_COCOA_EXIT(env);
}
// Used for CWrapper.NSWindow.setLevel() (and level() which isn't implemented yet)
static NSInteger LEVELS[sun_lwawt_macosx_CWrapper_NSWindow_MAX_WINDOW_LEVELS];
static void initLevels()

View File

@@ -161,8 +161,8 @@ void initializeActions() {
[sActions setObject:NSAccessibilityPressAction forKey:@"click"];
[sActions setObject:NSAccessibilityIncrementAction forKey:@"increment"];
[sActions setObject:NSAccessibilityDecrementAction forKey:@"decrement"];
[sActions setObject:NSAccessibilityShowMenuAction forKey:@"toggle popup"];
[sActions setObject:NSAccessibilityPressAction forKey:@"toggleexpand"];
[sActions setObject:NSAccessibilityShowMenuAction forKey:@"togglePopup"];
[sActions setObject:NSAccessibilityPressAction forKey:@"toggleExpand"];
sActionSelectors = [[NSMutableDictionary alloc] initWithCapacity:actionsCount];

View File

@@ -620,17 +620,6 @@ JNI_COCOA_EXIT(env);
return result;
}
/*
* Class: sun_lwawt_macosx_LWCToolkit
* Method: isBlockingEventDispatchThread
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_LWCToolkit_isBlockingEventDispatchThread
(JNIEnv *env, jclass clz)
{
return ThreadUtilities.blockingEventDispatchThread;
}
/*
* Class: sun_lwawt_macosx_LWCToolkit
* Method: stopAWTRunLoop
@@ -643,8 +632,6 @@ JNI_COCOA_ENTER(env);
AWTRunLoopObject* mediatorObject = (AWTRunLoopObject*)jlong_to_ptr(mediator);
if (mediatorObject == nil) return;
[ThreadUtilities performOnMainThread:@selector(endRunLoop) on:mediatorObject withObject:nil waitUntilDone:NO];
[mediatorObject release];
@@ -670,23 +657,6 @@ JNI_COCOA_ENTER(env);
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_LWCToolkit
* Method: performOnMainThreadAndWait
* Signature: (Ljava/lang/Runnable)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_LWCToolkit_performOnMainThreadAndWait
(JNIEnv *env, jclass clz, jobject runnable)
{
JNI_COCOA_ENTER(env);
jobject gRunnable = (*env)->NewGlobalRef(env, runnable);
CHECK_NULL(gRunnable);
[ThreadUtilities performOnMainThreadWaiting:YES block:^() {
JavaRunnable* performer = [[JavaRunnable alloc] initWithRunnable:gRunnable];
[performer perform];
}];
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_LWCToolkit

View File

@@ -126,7 +126,7 @@ static jobject sAccessibilityClass = NULL;
/*
* Here we should keep all the mapping between the accessibility roles and implementing classes
*/
rolesMap = [[NSMutableDictionary alloc] initWithCapacity:50];
rolesMap = [[NSMutableDictionary alloc] initWithCapacity:51];
[rolesMap setObject:@"ButtonAccessibility" forKey:@"pushbutton"];
[rolesMap setObject:@"ImageAccessibility" forKey:@"icon"];
@@ -158,6 +158,7 @@ static jobject sAccessibilityClass = NULL;
[rolesMap setObject:@"TableAccessibility" forKey:@"table"];
[rolesMap setObject:@"MenuBarAccessibility" forKey:@"menubar"];
[rolesMap setObject:@"MenuAccessibility" forKey:@"menu"];
[rolesMap setObject:@"MenuItemAccessibility" forKey:@"menuitem"];
[rolesMap setObject:@"MenuAccessibility" forKey:@"popupmenu"];
[rolesMap setObject:@"ProgressIndicatorAccessibility" forKey:@"progressbar"];
@@ -185,11 +186,10 @@ static jobject sAccessibilityClass = NULL;
[rolesMap setObject:IgnoreClassName forKey:@"viewport"];
[rolesMap setObject:IgnoreClassName forKey:@"window"];
rowRolesMapForParent = [[NSMutableDictionary alloc] initWithCapacity:3];
rowRolesMapForParent = [[NSMutableDictionary alloc] initWithCapacity:2];
[rowRolesMapForParent setObject:@"ListRowAccessibility" forKey:@"ListAccessibility"];
[rowRolesMapForParent setObject:@"OutlineRowAccessibility" forKey:@"OutlineAccessibility"];
[rowRolesMapForParent setObject:@"MenuItemAccessibility" forKey:@"MenuAccessibility"];
/*
* Initialize CAccessibility instance

View File

@@ -39,7 +39,7 @@
- (BOOL)isAccessibilityElement
{
return [[[self accessibilityParent] accessibilityRole] isEqualToString:NSAccessibilityComboBoxRole];
return YES;
}
@end

View File

@@ -1692,10 +1692,6 @@ static NSDictionary* prebuiltFamilyNames() {
@"SourceCodePro-BoldIt" : @"Source Code Pro",
@"SourceCodePro-It" : @"Source Code Pro",
@"SourceCodePro-Regular" : @"Source Code Pro",
@"Inter-Bold": @"Inter",
@"Inter-BoldItalic": @"Inter",
@"Inter-Italic": @"Inter",
@"Inter-Regular": @"Inter",
};
}
@@ -3346,6 +3342,64 @@ Java_sun_awt_FontDescriptor_initIDs
}
#endif
/*
* Class: sun_font_CFont
* Method: getCascadeList
* Signature: (JLjava/util/ArrayList;)V
*/
JNIEXPORT void JNICALL
Java_sun_font_CFont_getCascadeList
(JNIEnv *env, jclass cls, jlong awtFontPtr, jobject arrayListOfString)
{
JNI_COCOA_ENTER(env);
jclass alc = (*env)->FindClass(env, "java/util/ArrayList");
if (alc == NULL) return;
jmethodID addMID = (*env)->GetMethodID(env, alc, "add", "(Ljava/lang/Object;)Z");
if (addMID == NULL) return;
CFIndex i;
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
NSFont* nsFont = awtFont->fFont;
#ifdef DEBUG
CFStringRef base = CTFontCopyFullName((CTFontRef)nsFont);
NSLog(@"BaseFont is : %@", (NSString*)base);
CFRelease(base);
#endif
bool anotherBaseFont = false;
if (awtFont->fFallbackBase != nil) {
nsFont = awtFont->fFallbackBase;
anotherBaseFont = true;
}
CTFontRef font = (CTFontRef)nsFont;
CFArrayRef codes = CFLocaleCopyISOLanguageCodes();
CFArrayRef fds = CTFontCopyDefaultCascadeListForLanguages(font, codes);
CFRelease(codes);
CFIndex cnt = CFArrayGetCount(fds);
for (i= anotherBaseFont ? -1 : 0; i<cnt; i++) {
CFStringRef fontname;
if (i < 0) {
fontname = CTFontCopyPostScriptName(font);
} else {
CTFontDescriptorRef ref = CFArrayGetValueAtIndex(fds, i);
fontname = CTFontDescriptorCopyAttribute(ref, kCTFontNameAttribute);
}
#ifdef DEBUG
NSLog(@"Font is : %@", (NSString*)fontname);
#endif
jstring jFontName = (jstring)NSStringToJavaString(env, fontname);
CFRelease(fontname);
(*env)->CallBooleanMethod(env, arrayListOfString, addMID, jFontName);
if ((*env)->ExceptionOccurred(env)) {
CFRelease(fds);
return;
}
(*env)->DeleteLocalRef(env, jFontName);
}
CFRelease(fds);
JNI_COCOA_EXIT(env);
}
static CFStringRef EMOJI_FONT_NAME = CFSTR("Apple Color Emoji");
bool IsEmojiFont(CTFontRef font)

View File

@@ -28,7 +28,6 @@
#import "sun_font_CStrikeDisposer.h"
#import "CGGlyphImages.h"
#import "CGGlyphOutlines.h"
#import "CoreTextSupport.h"
#import "JNIUtilities.h"
#include "fontscalerdefs.h"
#import "LWCToolkit.h"
@@ -160,12 +159,8 @@ JNI_COCOA_ENTER(env);
AWTStrike *awtStrike = (AWTStrike *)jlong_to_ptr(awtStrikePtr);
AWTFont *awtFont = awtStrike->fAWTFont;
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
CGGlyph glyph;
const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
CGGlyphImages_GetGlyphMetrics(fallback, &awtStrike->fAltTx, awtStrike->fSize, awtStrike->fStyle, &glyph, 1, NULL, &advance, IS_OSX_GT10_14);
CFRelease(fallback);
CGGlyph glyph = glyphCode;
CGGlyphImages_GetGlyphMetrics((CTFontRef)awtFont->fFont, &awtStrike->fAltTx, awtStrike->fSize, awtStrike->fStyle, &glyph, 1, NULL, &advance, IS_OSX_GT10_14);
advance = CGSizeApplyAffineTransform(advance, awtStrike->fFontTx);
if (!JRSFontStyleUsesFractionalMetrics(awtStrike->fStyle)) {
advance.width = round(advance.width);
@@ -195,14 +190,9 @@ JNI_COCOA_ENTER(env);
tx.tx += x;
tx.ty += y;
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
CGGlyph glyph;
const CTFontRef fallback = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtFont, glyphCode, &glyph);
CGGlyph glyph = glyphCode;
CGRect bbox;
CGGlyphImages_GetGlyphMetrics(fallback, &tx, awtStrike->fSize, awtStrike->fStyle, &glyph, 1, &bbox, NULL, IS_OSX_GT10_14);
CFRelease(fallback);
CGGlyphImages_GetGlyphMetrics((CTFontRef)awtFont->fFont, &tx, awtStrike->fSize, awtStrike->fStyle, &glyph, 1, &bbox, NULL, IS_OSX_GT10_14);
// the origin of this bounding box is relative to the bottom-left corner baseline
CGFloat decender = -bbox.origin.y;
@@ -251,14 +241,12 @@ AWT_FONT_CLEANUP_CHECK(awtfont);
tx.tx += xPos;
tx.ty += yPos;
// get the right font and glyph for this "Java GlyphCode"
CGGlyph glyph;
const CTFontRef font = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(awtfont, glyphCode, &glyph);
CGGlyph glyph = glyphCode;
NSFont *font = awtfont->fFont;
// get the advance of this glyph
CGSize advance;
CTFontGetAdvancesForGlyphs(font, kCTFontDefaultOrientation, &glyph, &advance, 1);
CTFontGetAdvancesForGlyphs((CTFontRef)font, kCTFontDefaultOrientation, &glyph, &advance, 1);
// Create AWTPath
path = AWTPathCreate(CGSizeMake(xPos, yPos));
@@ -267,8 +255,7 @@ AWT_FONT_CLEANUP_CHECK(path);
// Get the paths
tx = awtStrike->fTx;
tx = CGAffineTransformConcat(tx, sInverseTX);
AWTGetGlyphOutline(&glyph, (NSFont *)font, &advance, &tx, 0, 1, &path);
CFRelease(font);
AWTGetGlyphOutline(&glyph, font, &advance, &tx, 0, 1, &path);
pointCoords = (*env)->NewFloatArray(env, path->fNumberOfDataElements);
AWT_FONT_CLEANUP_CHECK(pointCoords);
@@ -322,19 +309,14 @@ JNIEXPORT void JNICALL Java_sun_font_CStrike_getNativeGlyphOutlineBounds
AWT_FONT_CLEANUP_SETUP;
AWT_FONT_CLEANUP_CHECK(awtfont);
// get the right font and glyph for this "Java GlyphCode"
CGGlyph glyph;
const CTFontRef font = CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(
awtfont, glyphCode, &glyph);
CGGlyph glyph = glyphCode;
CGRect bbox = CTFontGetBoundingRectsForGlyphs(
font, kCTFontOrientationDefault, &glyph, NULL, 1);
(CTFontRef)awtfont->fFont, kCTFontOrientationDefault, &glyph, NULL, 1);
CGAffineTransform tx = CGAffineTransformConcat(awtStrike->fTx,
sInverseTX);
bbox = CGRectApplyAffineTransform (bbox, tx);
CFRelease(font);
jfloat *rawRectData =
(*env)->GetPrimitiveArrayCritical(env, rectData, NULL);

View File

@@ -29,7 +29,6 @@
#import "CoreTextSupport.h"
#import "sun_font_CCharToGlyphMapper.h"
#import "sun_font_CCompositeGlyphMapper.h"
/*
* Class: sun_font_CCharToGlyphMapper
@@ -114,28 +113,3 @@ JNI_COCOA_ENTER(env);
JNI_COCOA_EXIT(env);
}
/*
* Class: sun_font_CCompositeGlyphMapper
* Method: nativeCodePointToGlyph
* Signature: (JI[Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL
Java_sun_font_CCompositeGlyphMapper_nativeCodePointToGlyph
(JNIEnv *env, jclass clazz, jlong awtFontPtr, jint codePoint, jobjectArray resultArray)
{
JNI_COCOA_ENTER(env);
AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
CFStringRef fontNames[] = {NULL, NULL};
CGGlyph glyph = CTS_CopyGlyphAndFontNamesForCodePoint(awtFont, (UnicodeScalarValue)codePoint, fontNames);
if (glyph > 0) {
jstring fontName = NSStringToJavaString(env, (NSString *)fontNames[0]);
(*env)->SetObjectArrayElement(env, resultArray, 0, fontName);
jstring fontFamilyName = NSStringToJavaString(env, (NSString *)fontNames[1]);
(*env)->SetObjectArrayElement(env, resultArray, 1, fontFamilyName);
}
if (fontNames[0]) CFRelease(fontNames[0]);
if (fontNames[1]) CFRelease(fontNames[1]);
return glyph;
JNI_COCOA_EXIT(env);
}

View File

@@ -27,7 +27,6 @@
#import "JNIUtilities.h"
#import "CGGlyphImages.h"
#import "CoreTextSupport.h"
#import "fontscalerdefs.h" // contains the definition of GlyphInfo struct
#import "sun_awt_SunHints.h"
@@ -647,16 +646,6 @@ CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
#define RENDER_GLYPH_BATCH_SIZE 16
#define RENDER_GLYPH_ARRAY_INIT_8 glyph,glyph,glyph,glyph,glyph,glyph,glyph,glyph
#define RENDER_GLYPH_ARRAY_INIT RENDER_GLYPH_ARRAY_INIT_8,RENDER_GLYPH_ARRAY_INIT_8
static CTFontRef CopyFontWithSize(CTFontRef originalFont, CGFloat size) {
CTFontDescriptorRef descriptor = NULL;
CGFontRef cgFont = CTFontCopyGraphicsFont(originalFont, &descriptor);
CTFontRef result = CTFontCreateWithGraphicsFont(cgFont, size, NULL, descriptor);
if (cgFont) CFRelease(cgFont);
if (descriptor) CFRelease(descriptor);
return result;
}
/*
* Clears the canvas, strikes the glyph with CoreGraphics, and then
* copies the struck pixels into the GlyphInfo image.
@@ -697,7 +686,7 @@ CGGI_CreateImageForGlyph
// Set actual font size from transformation matrix for color glyphs
CGFloat fontSize = glyphDescriptor != &argb ? strike->fSize :
sqrt(fabs(matrix.a * matrix.d - matrix.b * matrix.c));
CTFontRef sizedFont = CopyFontWithSize(font, fontSize);
CTFontRef sizedFont = CTFontCreateCopyWithSymbolicTraits(font, fontSize, NULL, 0, 0);
CGFloat normFactor = 1.0 / fontSize;
CGAffineTransform normalizedMatrix = CGAffineTransformScale(matrix, normFactor, normFactor);
@@ -749,78 +738,6 @@ CGGI_CreateImageForGlyph
/*
* CoreText path...
*/
static inline GlyphInfo *
CGGI_CreateImageForUnicode
(CGGI_GlyphCanvas *canvas, const AWTStrike *strike,
const CGGI_RenderingMode *mode, const UnicodeScalarValue uniChar,
const bool isCatalinaOrAbove)
{
// save the graphics state
CGContextSaveGState(canvas->context);
// text matrix is not considered part of graphics state
CGAffineTransform originalTx = CGContextGetTextMatrix(canvas->context);
// get the glyph, measure it using CG
CGGlyph glyph;
CTFontRef fallback;
if (uniChar > 0xFFFF) {
UTF16Char charRef[2];
CTS_BreakupUnicodeIntoSurrogatePairs(uniChar, charRef);
CGGlyph glyphTmp[2];
fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, (CGGlyph *)&glyphTmp, 2);
glyph = glyphTmp[0];
} else {
UTF16Char charRef;
charRef = (UTF16Char) uniChar; // truncate.
fallback = CTS_CopyCTFallbackFontAndGlyphForUnicode(strike->fAWTFont, (const UTF16Char *)&charRef, &glyph, 1);
}
JRSFontRenderingStyle style = JRSFontAlignStyleForFractionalMeasurement(strike->fStyle);
CGGI_GlyphInfoDescriptor *glyphDescriptor = CGGI_GetGlyphInfoDescriptor(mode, fallback);
bool subpixelResolution = mode->subpixelResolution && glyphDescriptor == &grey;
CGRect bbox;
CGSize advance;
CGGlyphImages_GetGlyphMetrics(fallback, &strike->fTx, strike->fSize, style, &glyph, 1, &bbox, &advance, isCatalinaOrAbove);
// create the Sun2D GlyphInfo we are going to strike into
GlyphInfo *info = CGGI_CreateNewGlyphInfoFrom(advance, bbox, strike, glyphDescriptor, subpixelResolution);
// fix the context size, just in case the substituted character is unexpectedly large
CGGI_SizeCanvas(canvas, info->width * info->subpixelResolutionX, info->height * info->subpixelResolutionY, mode);
// align the transform for the real CoreText strike
CGContextSetTextMatrix(canvas->context, strike->fAltTx);
const CGFontRef cgFallback = CTFontCopyGraphicsFont(fallback, NULL);
CGContextSetFont(canvas->context, cgFallback);
CFRelease(cgFallback);
// clean the canvas - align, strike, and copy the glyph from the canvas into the info
CGGI_CreateImageForGlyph(canvas, glyph, info, glyphDescriptor, strike, fallback, isCatalinaOrAbove);
// restore graphics state
CGContextRestoreGState(canvas->context);
CGContextSetTextMatrix(canvas->context, originalTx);
CFRelease(fallback);
#ifdef CGGI_DEBUG
DUMP_GLYPHINFO(info);
#endif
#ifdef CGGI_DEBUG_DUMP
DUMP_IMG_PIXELS("CGGI Canvas", canvas->image);
#if 0
PRINT_CGSTATES_INFO(NULL);
#endif
#endif
return info;
}
#pragma mark --- GlyphInfo Filling and Canvas Managment ---
@@ -835,7 +752,6 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
const AWTStrike *strike,
const CGGI_RenderingMode *mode,
jlong glyphInfos[],
const UnicodeScalarValue uniChars[],
const CGGlyph glyphs[],
const CFIndex len)
{
@@ -848,13 +764,8 @@ CGGI_FillImagesForGlyphsWithSizedCanvas(CGGI_GlyphCanvas *canvas,
CFIndex i;
for (i = 0; i < len; i++) {
GlyphInfo *info = (GlyphInfo *)jlong_to_ptr(glyphInfos[i]);
if (info != NULL) {
CGGI_CreateImageForGlyph(canvas, glyphs[i], info, mode->mainFontDescriptor,
strike, (CTFontRef)strike->fAWTFont->fFont, isMojaveOrAbove);
} else {
info = CGGI_CreateImageForUnicode(canvas, strike, mode, uniChars[i], isMojaveOrAbove);
glyphInfos[i] = ptr_to_jlong(info);
}
CGGI_CreateImageForGlyph(canvas, glyphs[i], info, mode->mainFontDescriptor,
strike, (CTFontRef)strike->fAWTFont->fFont, isMojaveOrAbove);
#ifdef CGGI_DEBUG
DUMP_GLYPHINFO(info);
#endif
@@ -889,7 +800,7 @@ static NSString *threadLocalLCDCanvasKey =
static inline void
CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
const CGGI_RenderingMode *mode,
const UnicodeScalarValue uniChars[], const CGGlyph glyphs[],
const CGGlyph glyphs[],
const size_t maxWidth, const size_t maxHeight,
const CFIndex len)
{
@@ -899,8 +810,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
CGGI_GlyphCanvas *tmpCanvas = [[CGGI_GlyphCanvas alloc] init];
CGGI_InitCanvas(tmpCanvas, maxWidth, maxHeight, mode);
CGGI_FillImagesForGlyphsWithSizedCanvas(tmpCanvas, strike,
mode, glyphInfos, uniChars,
glyphs, len);
mode, glyphInfos, glyphs, len);
CGGI_FreeCanvas(tmpCanvas);
[tmpCanvas release];
@@ -920,7 +830,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
CGGI_SizeCanvas(canvas, maxWidth, maxHeight, mode);
CGGI_FillImagesForGlyphsWithSizedCanvas(canvas, strike, mode,
glyphInfos, uniChars, glyphs, len);
glyphInfos, glyphs, len);
}
/*
@@ -936,7 +846,7 @@ CGGI_FillImagesForGlyphs(jlong *glyphInfos, const AWTStrike *strike,
static inline void
CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
const CGGI_RenderingMode *mode,
const UnicodeScalarValue uniChars[], const CGGlyph glyphs[],
const CGGlyph glyphs[],
CGSize advances[], CGRect bboxes[], const CFIndex len)
{
AWTFont *font = strike->fAWTFont;
@@ -951,12 +861,6 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
CFIndex i;
for (i = 0; i < len; i++)
{
if (uniChars[i] != 0)
{
glyphInfos[i] = 0L;
continue; // will be handled later
}
CGSize advance = advances[i];
CGRect bbox = bboxes[i];
@@ -973,41 +877,29 @@ CGGI_CreateGlyphInfos(jlong *glyphInfos, const AWTStrike *strike,
glyphInfos[i] = ptr_to_jlong(glyphInfo);
}
CGGI_FillImagesForGlyphs(glyphInfos, strike, mode, uniChars,
CGGI_FillImagesForGlyphs(glyphInfos, strike, mode,
glyphs, maxWidth, maxHeight, len);
}
#pragma mark --- Temporary Buffer Allocations and Initialization ---
/*
* This stage separates the already valid glyph codes from the unicode values
* that need special handling - the rawGlyphCodes array is no longer used
* after this stage.
*/
static void
CGGI_CreateGlyphsAndScanForComplexities(jlong *glyphInfos,
const AWTStrike *strike,
const CGGI_RenderingMode *mode,
jint rawGlyphCodes[],
UnicodeScalarValue uniChars[], CGGlyph glyphs[],
CGSize advances[], CGRect bboxes[],
const CFIndex len)
CGGI_CreateGlyphs(jlong *glyphInfos,
const AWTStrike *strike,
const CGGI_RenderingMode *mode,
jint rawGlyphCodes[],
CGGlyph glyphs[],
CGSize advances[], CGRect bboxes[],
const CFIndex len)
{
CFIndex i;
for (i = 0; i < len; i++) {
jint code = rawGlyphCodes[i];
if (code < 0) {
glyphs[i] = 0;
uniChars[i] = -code;
} else {
glyphs[i] = code;
uniChars[i] = 0;
}
glyphs[i] = rawGlyphCodes[i];
}
CGGI_CreateGlyphInfos(glyphInfos, strike, mode,
uniChars, glyphs, advances, bboxes, len);
glyphs, advances, bboxes, len);
#ifdef CGGI_DEBUG_HIT_COUNT
static size_t hitCount = 0;
@@ -1033,31 +925,29 @@ CGGlyphImages_GetGlyphImagePtrs(jlong glyphInfos[],
CGRect bboxes[len];
CGSize advances[len];
CGGlyph glyphs[len];
UnicodeScalarValue uniChars[len];
CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
rawGlyphCodes, uniChars, glyphs,
advances, bboxes, len);
CGGI_CreateGlyphs(glyphInfos, strike, &mode,
rawGlyphCodes, glyphs,
advances, bboxes, len);
return;
}
// just do one malloc, and carve it up for all the buffers
void *buffer = malloc(sizeof(CGRect) * sizeof(CGSize) *
sizeof(CGGlyph) * sizeof(UnicodeScalarValue) * len);
void *buffer = malloc((sizeof(CGRect) + sizeof(CGSize) + sizeof(CGGlyph)) *
len);
if (buffer == NULL) {
[[NSException exceptionWithName:NSMallocException
reason:@"Failed to allocate memory for the temporary glyph strike and measurement buffers." userInfo:nil] raise];
}
CGRect *bboxes = (CGRect *)(buffer);
CGSize *advances = (CGSize *)(bboxes + sizeof(CGRect) * len);
CGGlyph *glyphs = (CGGlyph *)(advances + sizeof(CGGlyph) * len);
UnicodeScalarValue *uniChars = (UnicodeScalarValue *)(glyphs + sizeof(UnicodeScalarValue) * len);
CGSize *advances = (CGSize *)(bboxes + len);
CGGlyph *glyphs = (CGGlyph *)(advances + len);
CGGI_CreateGlyphsAndScanForComplexities(glyphInfos, strike, &mode,
rawGlyphCodes, uniChars, glyphs,
advances, bboxes, len);
CGGI_CreateGlyphs(glyphInfos, strike, &mode,
rawGlyphCodes, glyphs,
advances, bboxes, len);
free(buffer);
}
@@ -1081,7 +971,7 @@ CGGlyphImages_GetGlyphMetrics(const CTFontRef font,
// The logic here must match the logic in CGGI_CreateImageForGlyph,
// which performs glyph drawing.
CTFontRef sizedFont = CopyFontWithSize(font, fontSize);
CTFontRef sizedFont = CTFontCreateCopyWithSymbolicTraits(font, fontSize, NULL, 0, 0);
if (bboxes) {
// JRSFontGetBoundingBoxesForGlyphsAndStyle works incorrectly for AppleColorEmoji font:

View File

@@ -31,37 +31,13 @@
#pragma mark --- CoreText Support ---
#define HI_SURROGATE_START 0xD800
#define HI_SURROGATE_END 0xDBFF
#define LO_SURROGATE_START 0xDC00
#define LO_SURROGATE_END 0xDFFF
/*
* Transform Unicode characters into glyphs.
*
* Fills the "glyphsAsInts" array with the glyph codes for the current font,
* or the negative unicode value if we know the character can be hot-substituted.
*
* This is the heart of "Universal Font Substitution" in Java.
* Fills the "glyphsAsInts" array with the glyph codes for the current font.
*/
void CTS_GetGlyphsAsIntsForCharacters(const AWTFont *font, const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[], const size_t count);
// Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyph"
CTFontRef CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef);
// Translates a Unicode into a CGGlyph/CTFontRef pair
// Returns the substituted font, and places the appropriate glyph into "glyphRef"
CTFontRef CTS_CopyCTFallbackFontAndGlyphForUnicode(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count);
// Transform a single Unicode character code into glyph code.
// Names of the relevant font are also returned, if the substitution is used.
// Non-null components of fontNames array should always be released by the calling code, regardless of the returned value.
CGGlyph CTS_CopyGlyphAndFontNamesForCodePoint(const AWTFont *font, const UnicodeScalarValue codePoint, CFStringRef fontNames[]);
// Breakup a 32 bit unicode value into the component surrogate pairs
void CTS_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]);
// Basic struct that holds everything CoreText is interested in
typedef struct CTS_ProviderStruct {

View File

@@ -88,161 +88,18 @@ ReleaseCTStateDictionary(CFDictionaryRef ctStateDict)
CFRelease(ctStateDict); // GC
}
void GetFontsAndGlyphsForCharacters(CTFontRef font, CTFontRef fallbackBase,
const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[],
CTFontRef actualFonts[], const size_t count)
{
CTFontGetGlyphsForCharacters(font, unicodes, glyphs, count);
if (!fallbackBase) fallbackBase = font;
size_t i;
for (i = 0; i < count; i++) {
UniChar unicode = unicodes[i];
UniChar nextUnicode = (i+1) < count ? unicodes[i+1] : 0;
bool surrogatePair = unicode >= HI_SURROGATE_START && unicode <= HI_SURROGATE_END
&& nextUnicode >= LO_SURROGATE_START && nextUnicode <= LO_SURROGATE_END;
CGGlyph glyph = glyphs[i];
if (glyph > 0) {
glyphsAsInts[i] = glyph;
if (surrogatePair) i++;
continue;
}
const CTFontRef fallback = JRSFontCreateFallbackFontForCharacters(fallbackBase, &unicodes[i], surrogatePair ? 2 : 1);
if (fallback) {
CTFontGetGlyphsForCharacters(fallback, &unicodes[i], &glyphs[i], surrogatePair ? 2 : 1);
glyph = glyphs[i];
if (actualFonts && glyph > 0) {
actualFonts[i] = fallback;
} else {
CFRelease(fallback);
}
}
if (glyph > 0) {
int codePoint = surrogatePair ? (((int)(unicode - HI_SURROGATE_START)) << 10)
+ nextUnicode - LO_SURROGATE_START + 0x10000 : unicode;
glyphsAsInts[i] = -codePoint; // set the glyph code to the negative unicode value
} else {
glyphsAsInts[i] = 0; // CoreText couldn't find a glyph for this character either
}
if (surrogatePair) i++;
}
}
/*
* Transform Unicode characters into glyphs.
*
* Fills the "glyphsAsInts" array with the glyph codes for the current font,
* or the negative unicode value if we know the character can be hot-substituted.
*
* This is the heart of "Universal Font Substitution" in Java.
* Fills the "glyphsAsInts" array with the glyph codes for the current font.
*/
void CTS_GetGlyphsAsIntsForCharacters
(const AWTFont *font, const UniChar unicodes[], CGGlyph glyphs[], jint glyphsAsInts[], const size_t count)
{
GetFontsAndGlyphsForCharacters((CTFontRef)font->fFont, (CTFontRef)font->fFallbackBase,
unicodes, glyphs, glyphsAsInts, NULL, count);
}
CTFontGetGlyphsForCharacters((CTFontRef)font->fFont, unicodes, glyphs, count);
/*
* Returns glyph code for a given Unicode character.
* Names of the corresponding substituted font are also returned if substitution is performed.
*/
CGGlyph CTS_CopyGlyphAndFontNamesForCodePoint
(const AWTFont *font, const UnicodeScalarValue codePoint, CFStringRef fontNames[])
{
CTFontRef fontRef = (CTFontRef)font->fFont;
CTFontRef fallbackBase = (CTFontRef)font->fFallbackBase;
int count = codePoint >= 0x10000 ? 2 : 1;
UTF16Char unicodes[count];
if (count == 1) {
unicodes[0] = (UTF16Char)codePoint;
} else {
CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, unicodes);
}
CGGlyph glyphs[count];
jint glyphsAsInts[count];
CTFontRef actualFonts[count];
GetFontsAndGlyphsForCharacters(fontRef, fallbackBase, unicodes, glyphs, glyphsAsInts, actualFonts, count);
CGGlyph glyph = glyphs[0];
bool substitutionHappened = glyphsAsInts[0] < 0;
if (glyph > 0 && substitutionHappened) {
CTFontRef actualFont = actualFonts[0];
CFStringRef fontName = CTFontCopyPostScriptName(actualFont);
CFStringRef familyName = CTFontCopyFamilyName(actualFont);
CFRelease(actualFont);
fontNames[0] = fontName;
fontNames[1] = familyName;
if (!fontName || !familyName) glyph = 0;
}
return glyph;
}
/*
* Translates a Unicode into a CGGlyph/CTFontRef pair
* Returns the substituted font, and places the appropriate glyph into "glyphRef"
*/
CTFontRef CTS_CopyCTFallbackFontAndGlyphForUnicode
(const AWTFont *font, const UTF16Char *charRef, CGGlyph *glyphRef, int count) {
CTFontRef primary = (CTFontRef)font->fFont;
CTFontRef fallbackBase = (CTFontRef)font->fFallbackBase;
if (fallbackBase) {
CTFontGetGlyphsForCharacters(primary, charRef, glyphRef, count);
if (glyphRef[0] > 0) {
CFRetain(primary);
return primary;
}
} else {
fallbackBase = primary;
}
CTFontRef fallback = JRSFontCreateFallbackFontForCharacters(fallbackBase, charRef, count);
if (fallback == NULL)
{
// use the original font if we somehow got duped into trying to fallback something we can't
fallback = (CTFontRef)font->fFont;
CFRetain(fallback);
}
CTFontGetGlyphsForCharacters(fallback, charRef, glyphRef, count);
return fallback;
}
/*
* Translates a Java glyph code int (might be a negative unicode value) into a CGGlyph/CTFontRef pair
* Returns the substituted font, and places the appropriate glyph into "glyphRef"
*/
CTFontRef CTS_CopyCTFallbackFontAndGlyphForJavaGlyphCode
(const AWTFont *font, const jint glyphCode, CGGlyph *glyphRef)
{
// negative glyph codes are really unicodes, which were placed there by the mapper
// to indicate we should use CoreText to substitute the character
if (glyphCode >= 0)
{
*glyphRef = glyphCode;
CFRetain(font->fFont);
return (CTFontRef)font->fFont;
}
int codePoint = -glyphCode;
if (codePoint >= 0x10000) {
UTF16Char chars[2];
CGGlyph glyphs[2];
CTS_BreakupUnicodeIntoSurrogatePairs(codePoint, chars);
CTFontRef result = CTS_CopyCTFallbackFontAndGlyphForUnicode(font, chars, glyphs, 2);
*glyphRef = glyphs[0];
return result;
} else {
UTF16Char character = codePoint;
return CTS_CopyCTFallbackFontAndGlyphForUnicode(font, &character, glyphRef, 1);
size_t i;
for (i = 0; i < count; i++) {
glyphsAsInts[i] = glyphs[i];
}
}
// Breakup a 32 bit unicode value into the component surrogate pairs
void CTS_BreakupUnicodeIntoSurrogatePairs(int uniChar, UTF16Char charRef[]) {
int value = uniChar - 0x10000;
UTF16Char low_surrogate = (value & 0x3FF) | LO_SURROGATE_START;
UTF16Char high_surrogate = (((int)(value & 0xFFC00)) >> 10) | HI_SURROGATE_START;
charRef[0] = high_surrogate;
charRef[1] = low_surrogate;
}

View File

@@ -127,13 +127,6 @@ do { \
__attribute__((visibility("default")))
@interface ThreadUtilities : NSObject { } /* Extend NSObject so can call performSelectorOnMainThread */
/*
* When a blocking performSelectorOnMainThread is executed from the EventDispatch thread,
* and the executed code triggers an opposite blocking a11y call (via LWCToolkit.invokeAndWait)
* this is a deadlock case, and then this property is used to discard LWCToolkit.invokeAndWait.
*/
@property (class, nonatomic, readonly) BOOL blockingEventDispatchThread;
+ (JNIEnv*)getJNIEnv;
+ (JNIEnv*)getJNIEnvUncached;
+ (void)detachCurrentThread;

View File

@@ -50,24 +50,6 @@ static inline void attachCurrentThread(void** env) {
@implementation ThreadUtilities
static BOOL _blockingEventDispatchThread = NO;
static long eventDispatchThreadPtr = (long)nil;
static BOOL isEventDispatchThread() {
return (long)[NSThread currentThread] == eventDispatchThreadPtr;
}
// The [blockingEventDispatchThread] property is readonly, so we implement a private setter
static void setBlockingEventDispatchThread(BOOL value) {
assert([NSThread isMainThread]);
_blockingEventDispatchThread = value;
}
+ (BOOL) blockingEventDispatchThread {
assert([NSThread isMainThread]);
return _blockingEventDispatchThread;
}
+ (void)initialize {
/* All the standard modes plus ours */
javaModes = [[NSArray alloc] initWithObjects:NSDefaultRunLoopMode,
@@ -99,6 +81,13 @@ AWT_ASSERT_APPKIT_THREAD;
appkitThreadGroup = group;
}
/* This is needed because we can't directly pass a block to
* performSelectorOnMainThreadWaiting .. since it expects a selector
*/
+ (void)invokeBlock:(void (^)())block {
block();
}
/*
* When running a block where either we don't wait, or it needs to run on another thread
* we need to copy it from stack to heap, use the copy in the call and release after use.
@@ -114,7 +103,12 @@ AWT_ASSERT_APPKIT_THREAD;
if ([NSThread isMainThread] && wait == YES) {
block();
} else {
[self performOnMainThread:@selector(invokeBlockCopy:) on:self withObject:Block_copy(block) waitUntilDone:wait];
if (wait == YES) {
[self performOnMainThread:@selector(invokeBlock:) on:self withObject:block waitUntilDone:YES];
} else {
void (^blockCopy)(void) = Block_copy(block);
[self performOnMainThread:@selector(invokeBlockCopy:) on:self withObject:blockCopy waitUntilDone:NO];
}
}
}
@@ -122,19 +116,7 @@ AWT_ASSERT_APPKIT_THREAD;
if ([NSThread isMainThread] && wait == YES) {
[target performSelector:aSelector withObject:arg];
} else {
if (wait && isEventDispatchThread()) {
void (^blockCopy)(void) = Block_copy(^(){
setBlockingEventDispatchThread(YES);
@try {
[target performSelector:aSelector withObject:arg];
} @finally {
setBlockingEventDispatchThread(NO);
}
});
[self performSelectorOnMainThread:@selector(invokeBlockCopy:) withObject:blockCopy waitUntilDone:YES modes:javaModes];
} else {
[target performSelectorOnMainThread:aSelector withObject:arg waitUntilDone:wait modes:javaModes];
}
[target performSelectorOnMainThread:aSelector withObject:arg waitUntilDone:wait modes:javaModes];
}
}
@@ -161,16 +143,3 @@ JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CThreading_isMainThread
return [NSThread isMainThread];
}
/*
* Class: sun_awt_AWTThreading
* Method: notifyEventDispatchThreadStartedNative
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_awt_AWTThreading_notifyEventDispatchThreadStartedNative
(JNIEnv *env, jclass c)
{
@synchronized([ThreadUtilities class]) {
eventDispatchThreadPtr = (long)[NSThread currentThread];
}
}

View File

@@ -30,7 +30,6 @@ public class JBRApiModule {
.withStatic("getSubpixelResolution", "sun.font.FontUtilities")
.service("com.jetbrains.JBRFileDialogService", null)
.withStatic("getFileDialog", "com.jetbrains.desktop.JBRFileDialog", "get")
.proxy("com.jetbrains.JBRFileDialog", "com.jetbrains.desktop.JBRFileDialog")
.service("com.jetbrains.CustomWindowDecoration", "java.awt.Window$CustomWindowDecoration");
.proxy("com.jetbrains.JBRFileDialog", "com.jetbrains.desktop.JBRFileDialog");
}
}

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