Merge
This commit is contained in:
commit
8d141f1048
1
.hgtags
1
.hgtags
@ -590,3 +590,4 @@ cddef3bde924f3ff4f17f3d369280cf69d0450e5 jdk-14+14
|
||||
778fc2dcbdaa8981e07e929a2cacef979c72261e jdk-14+15
|
||||
d29f0181ba424a95d881aba5eabf2e393abcc70f jdk-14+16
|
||||
5c83830390baafb76a1fbe33443c57620bd45fb9 jdk-14+17
|
||||
e84d8379815ba0d3e50fb096d28c25894cb50b8c jdk-14+18
|
||||
|
@ -281,7 +281,7 @@
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align: left;">Linux</td>
|
||||
<td style="text-align: left;">gcc 8.2.0</td>
|
||||
<td style="text-align: left;">gcc 8.3.0</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">macOS</td>
|
||||
@ -293,14 +293,14 @@
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align: left;">Windows</td>
|
||||
<td style="text-align: left;">Microsoft Visual Studio 2017 update 15.9.6</td>
|
||||
<td style="text-align: left;">Microsoft Visual Studio 2017 update 15.9.16</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>All compilers are expected to be able to compile to the C99 language standard, as some C99 features are used in the source code. Microsoft Visual Studio doesn't fully support C99 so in practice shared code is limited to using C99 features that it does support.</p>
|
||||
<h3 id="gcc">gcc</h3>
|
||||
<p>The minimum accepted version of gcc is 4.8. Older versions will generate a warning by <code>configure</code> and are unlikely to work.</p>
|
||||
<p>The JDK is currently known to be able to compile with at least version 7.4 of gcc.</p>
|
||||
<p>The JDK is currently known to be able to compile with at least version 8.3 of gcc.</p>
|
||||
<p>In general, any version between these two should be usable.</p>
|
||||
<h3 id="clang">clang</h3>
|
||||
<p>The minimum accepted version of clang is 3.2. Older versions will not be accepted by <code>configure</code>.</p>
|
||||
|
@ -323,10 +323,10 @@ issues.
|
||||
|
||||
Operating system Toolchain version
|
||||
------------------ -------------------------------------------------------
|
||||
Linux gcc 8.2.0
|
||||
Linux gcc 8.3.0
|
||||
macOS Apple Xcode 10.1 (using clang 10.0.0)
|
||||
Solaris Oracle Solaris Studio 12.6 (with compiler version 5.15)
|
||||
Windows Microsoft Visual Studio 2017 update 15.9.6
|
||||
Windows Microsoft Visual Studio 2017 update 15.9.16
|
||||
|
||||
All compilers are expected to be able to compile to the C99 language standard,
|
||||
as some C99 features are used in the source code. Microsoft Visual Studio
|
||||
@ -338,7 +338,7 @@ features that it does support.
|
||||
The minimum accepted version of gcc is 4.8. Older versions will generate a warning
|
||||
by `configure` and are unlikely to work.
|
||||
|
||||
The JDK is currently known to be able to compile with at least version 7.4 of
|
||||
The JDK is currently known to be able to compile with at least version 8.3 of
|
||||
gcc.
|
||||
|
||||
In general, any version between these two should be usable.
|
||||
|
@ -86,16 +86,18 @@ endif
|
||||
# from there. These files were explicitly filtered or modified in <module>-copy
|
||||
# targets. For the rest, just pick up everything from the source legal dirs.
|
||||
LEGAL_NOTICES := \
|
||||
$(SUPPORT_OUTPUTDIR)/modules_legal/common \
|
||||
$(wildcard $(SUPPORT_OUTPUTDIR)/modules_legal/common) \
|
||||
$(if $(wildcard $(SUPPORT_OUTPUTDIR)/modules_legal/$(MODULE)), \
|
||||
$(wildcard $(SUPPORT_OUTPUTDIR)/modules_legal/$(MODULE)), \
|
||||
$(call FindModuleLegalSrcDirs, $(MODULE)) \
|
||||
)
|
||||
|
||||
LEGAL_NOTICES_PATH := $(call PathList, $(LEGAL_NOTICES))
|
||||
DEPS += $(call FindFiles, $(LEGAL_NOTICES))
|
||||
ifneq ($(strip $(LEGAL_NOTICES)), )
|
||||
LEGAL_NOTICES_PATH := $(call PathList, $(LEGAL_NOTICES))
|
||||
DEPS += $(call FindFiles, $(LEGAL_NOTICES))
|
||||
|
||||
JMOD_FLAGS += --legal-notices $(LEGAL_NOTICES_PATH)
|
||||
JMOD_FLAGS += --legal-notices $(LEGAL_NOTICES_PATH)
|
||||
endif
|
||||
|
||||
ifeq ($(filter-out jdk.incubator.%, $(MODULE)), )
|
||||
JMOD_FLAGS += --do-not-resolve-by-default
|
||||
|
@ -230,7 +230,7 @@ else ifeq ($(OPENJDK_TARGET_OS), macosx)
|
||||
NUM_CORES := $(shell /usr/sbin/sysctl -n hw.ncpu)
|
||||
MEMORY_SIZE := $(shell $(EXPR) `/usr/sbin/sysctl -n hw.memsize` / 1024 / 1024)
|
||||
else ifeq ($(OPENJDK_TARGET_OS), solaris)
|
||||
NUM_CORES := $(shell LC_MESSAGES=C /usr/sbin/psrinfo -v | $(GREP) -c on-line)
|
||||
NUM_CORES := $(shell /usr/sbin/psrinfo -v | $(GREP) -c on-line)
|
||||
MEMORY_SIZE := $(shell \
|
||||
/usr/sbin/prtconf 2> /dev/null | $(GREP) "^Memory [Ss]ize" | $(AWK) '{print $$3}' \
|
||||
)
|
||||
|
@ -27,6 +27,9 @@
|
||||
# Fake minimalistic spec file for RunTestsPrebuilt.gmk.
|
||||
################################################################################
|
||||
|
||||
# Make sure all shell commands are executed with the C locale
|
||||
export LC_ALL := C
|
||||
|
||||
define VerifyVariable
|
||||
ifeq ($$($1), )
|
||||
$$(info Error: Variable $1 is missing, needed by RunTestPrebuiltSpec.gmk)
|
||||
|
@ -427,7 +427,7 @@ AC_DEFUN_ONCE([BASIC_INIT],
|
||||
# Save the path variable before it gets changed
|
||||
ORIGINAL_PATH="$PATH"
|
||||
AC_SUBST(ORIGINAL_PATH)
|
||||
DATE_WHEN_CONFIGURED=`LANG=C date`
|
||||
DATE_WHEN_CONFIGURED=`date`
|
||||
AC_SUBST(DATE_WHEN_CONFIGURED)
|
||||
AC_MSG_NOTICE([Configuration created at $DATE_WHEN_CONFIGURED.])
|
||||
])
|
||||
|
@ -35,7 +35,7 @@ AC_DEFUN([BPERF_CHECK_CORES],
|
||||
FOUND_CORES=yes
|
||||
elif test -x /usr/sbin/psrinfo; then
|
||||
# Looks like a Solaris system
|
||||
NUM_CORES=`LC_MESSAGES=C /usr/sbin/psrinfo -v | grep -c on-line`
|
||||
NUM_CORES=`/usr/sbin/psrinfo -v | grep -c on-line`
|
||||
FOUND_CORES=yes
|
||||
elif test -x /usr/sbin/sysctl; then
|
||||
# Looks like a MacOSX system
|
||||
|
3
make/autoconf/configure
vendored
3
make/autoconf/configure
vendored
@ -43,6 +43,9 @@ fi
|
||||
export CONFIG_SHELL=$BASH
|
||||
export _as_can_reexec=no
|
||||
|
||||
# Make sure all shell commands are executed with the C locale
|
||||
export LC_ALL=C
|
||||
|
||||
if test "x$CUSTOM_CONFIG_DIR" != x; then
|
||||
custom_hook=$CUSTOM_CONFIG_DIR/custom-hook.m4
|
||||
if test ! -e $custom_hook; then
|
||||
|
@ -51,6 +51,9 @@ COMMA:=,
|
||||
# What make to use for main processing, after bootstrapping top-level Makefile.
|
||||
MAKE := @MAKE@
|
||||
|
||||
# Make sure all shell commands are executed with the C locale
|
||||
export LC_ALL := C
|
||||
|
||||
# The default make arguments
|
||||
MAKE_ARGS = $(MAKE_LOG_FLAGS) -r -R -I $(TOPDIR)/make/common SPEC=$(SPEC) \
|
||||
MAKE_LOG_FLAGS="$(MAKE_LOG_FLAGS)" $(MAKE_LOG_VARS)
|
||||
|
@ -209,6 +209,8 @@ AC_DEFUN([TOOLCHAIN_FIND_VISUAL_STUDIO_BAT_FILE],
|
||||
eval SDK_INSTALL_DIR="\${VS_SDK_INSTALLDIR_${VS_VERSION}}"
|
||||
eval VS_ENV_ARGS="\${VS_ENV_ARGS_${VS_VERSION}}"
|
||||
eval VS_TOOLSET_SUPPORTED="\${VS_TOOLSET_SUPPORTED_${VS_VERSION}}"
|
||||
|
||||
VS_ENV_CMD=""
|
||||
|
||||
# When using --with-tools-dir, assume it points to the correct and default
|
||||
# version of Visual Studio or that --with-toolchain-version was also set.
|
||||
@ -227,8 +229,6 @@ AC_DEFUN([TOOLCHAIN_FIND_VISUAL_STUDIO_BAT_FILE],
|
||||
fi
|
||||
fi
|
||||
|
||||
VS_ENV_CMD=""
|
||||
|
||||
if test "x$VS_COMNTOOLS" != x; then
|
||||
TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT([${VS_VERSION}],
|
||||
[$VS_COMNTOOLS/../..], [$VS_COMNTOOLS_VAR variable])
|
||||
|
@ -122,7 +122,7 @@ define add_file_to_clean
|
||||
$$($1_BIN)$$($1_MODULE_SUBDIR)$$($2_TARGET) : $2
|
||||
$$(call LogInfo, Cleaning $$(patsubst $(OUTPUTDIR)/%,%, $$@))
|
||||
$$(call MakeTargetDir)
|
||||
export LC_ALL=C ; ( $(CAT) $$< && $(ECHO) "" ) \
|
||||
( $(CAT) $$< && $(ECHO) "" ) \
|
||||
| $(SED) -e 's/\([^\\]\):/\1\\:/g' -e 's/\([^\\]\)=/\1\\=/g' \
|
||||
-e 's/\([^\\]\)!/\1\\!/g' -e 's/^[ ]*#.*/#/g' \
|
||||
| $(SED) -f "$(TOPDIR)/make/common/support/unicode2x.sed" \
|
||||
|
@ -944,11 +944,11 @@ var getJibProfilesProfiles = function (input, common, data) {
|
||||
var getJibProfilesDependencies = function (input, common) {
|
||||
|
||||
var devkit_platform_revisions = {
|
||||
linux_x64: "gcc8.2.0-OL6.4+1.0",
|
||||
linux_x64: "gcc8.3.0-OL6.4+1.0",
|
||||
macosx_x64: "Xcode10.1-MacOSX10.14+1.0",
|
||||
solaris_x64: "SS12u4-Solaris11u1+1.0",
|
||||
solaris_sparcv9: "SS12u6-Solaris11u3+1.0",
|
||||
windows_x64: "VS2017-15.9.6+1.0",
|
||||
windows_x64: "VS2017-15.9.16+1.0",
|
||||
linux_aarch64: "gcc8.2.0-Fedora27+1.0",
|
||||
linux_arm: "gcc8.2.0-Fedora27+1.0",
|
||||
linux_ppc64le: "gcc8.2.0-Fedora27+1.0",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 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
|
||||
@ -48,7 +48,7 @@ public class $NAME_CLZ$ extends Charset implements HistoricallyNamedCharset
|
||||
}
|
||||
|
||||
public CharsetDecoder newDecoder() {
|
||||
return new SingleByte.Decoder(this, b2c, $ASCIICOMPATIBLE$);
|
||||
return new SingleByte.Decoder(this, b2c, $ASCIICOMPATIBLE$, $LATIN1DECODABLE$);
|
||||
}
|
||||
|
||||
public CharsetEncoder newEncoder() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
File-Date: 2019-04-03
|
||||
File-Date: 2019-09-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: aa
|
||||
@ -2096,6 +2096,8 @@ Type: language
|
||||
Subtag: ais
|
||||
Description: Nataoran Amis
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-16
|
||||
Comments: see ami, szy
|
||||
%%
|
||||
Type: language
|
||||
Subtag: ait
|
||||
@ -2633,6 +2635,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: ant
|
||||
Description: Antakarinya
|
||||
Description: Antikarinya
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -3094,6 +3097,8 @@ Type: language
|
||||
Subtag: asd
|
||||
Description: Asas
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-16
|
||||
Preferred-Value: snz
|
||||
%%
|
||||
Type: language
|
||||
Subtag: ase
|
||||
@ -4135,7 +4140,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: bck
|
||||
Description: Bunaba
|
||||
Description: Bunuba
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -6930,7 +6935,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: bym
|
||||
Description: Bidyara
|
||||
Description: Bidjara
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -7564,6 +7569,11 @@ Description: Centúúm
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: cey
|
||||
Description: Ekai Chin
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: cfa
|
||||
Description: Dijim-Bwilim
|
||||
Added: 2009-07-29
|
||||
@ -9439,6 +9449,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: dif
|
||||
Description: Dieri
|
||||
Description: Diyari
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -9515,6 +9526,8 @@ Type: language
|
||||
Subtag: dit
|
||||
Description: Dirari
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-29
|
||||
Preferred-Value: dif
|
||||
%%
|
||||
Type: language
|
||||
Subtag: diu
|
||||
@ -9560,6 +9573,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: djd
|
||||
Description: Djamindjung
|
||||
Description: Ngaliwurru
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -9603,6 +9617,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: djn
|
||||
Description: Jawoyn
|
||||
Description: Djauan
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -10191,6 +10206,8 @@ Type: language
|
||||
Subtag: dud
|
||||
Description: Hun-Saare
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-16
|
||||
Comments: see uth, uss
|
||||
%%
|
||||
Type: language
|
||||
Subtag: due
|
||||
@ -10382,6 +10399,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: dyn
|
||||
Description: Dyangadi
|
||||
Description: Dhanggatti
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -10396,6 +10414,7 @@ Added: 2005-10-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: dyy
|
||||
Description: Djabugay
|
||||
Description: Dyaabugay
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -11672,7 +11691,7 @@ Comments: see wny, wrk
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gbd
|
||||
Description: Karadjeri
|
||||
Description: Karajarri
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -12056,7 +12075,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gge
|
||||
Description: Guragone
|
||||
Description: Gurr-goni
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -12169,7 +12188,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gia
|
||||
Description: Kitja
|
||||
Description: Kija
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -12955,7 +12974,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: gue
|
||||
Description: Gurinji
|
||||
Description: Gurindji
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -15292,6 +15311,7 @@ Macrolanguage: ms
|
||||
Type: language
|
||||
Subtag: jay
|
||||
Description: Yan-nhangu
|
||||
Description: Nhangu
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -15488,6 +15508,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: jig
|
||||
Description: Jingulu
|
||||
Description: Djingili
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -17222,6 +17243,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: kkp
|
||||
Description: Gugubera
|
||||
Description: Koko-Bera
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -17266,6 +17288,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: kky
|
||||
Description: Guugu Yimidhirr
|
||||
Description: Guguyimidjir
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -18320,6 +18343,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: ktd
|
||||
Description: Kokata
|
||||
Description: Kukatha
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -19341,6 +19365,7 @@ Type: language
|
||||
Subtag: lba
|
||||
Description: Lui
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lbb
|
||||
@ -19396,7 +19421,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lbn
|
||||
Description: Lamet
|
||||
Description: Rmeet
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -19446,6 +19471,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lby
|
||||
Description: Lamalama
|
||||
Description: Lamu-Lamu
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -20162,6 +20188,8 @@ Type: language
|
||||
Subtag: llo
|
||||
Description: Khlor
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-16
|
||||
Preferred-Value: ngt
|
||||
%%
|
||||
Type: language
|
||||
Subtag: llp
|
||||
@ -20654,6 +20682,11 @@ Added: 2009-07-29
|
||||
Macrolanguage: luy
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lsn
|
||||
Description: Tibetan Sign Language
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lso
|
||||
Description: Laos Sign Language
|
||||
Added: 2009-07-29
|
||||
@ -20680,6 +20713,11 @@ Description: Trinidad and Tobago Sign Language
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lsv
|
||||
Description: Sivia Sign Language
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lsy
|
||||
Description: Mauritian Sign Language
|
||||
Added: 2010-03-11
|
||||
@ -20848,6 +20886,11 @@ Description: Maku'a
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lvi
|
||||
Description: Lavi
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: lvk
|
||||
Description: Lavukaleve
|
||||
Added: 2009-07-29
|
||||
@ -21454,7 +21497,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mec
|
||||
Description: Mara
|
||||
Description: Marra
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -21523,7 +21566,7 @@ Macrolanguage: ms
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mep
|
||||
Description: Miriwung
|
||||
Description: Miriwoong
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -21660,7 +21703,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mfr
|
||||
Description: Marithiel
|
||||
Description: Marrithiyel
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -22853,12 +22896,13 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mpb
|
||||
Description: Malak Malak
|
||||
Description: Mullukmulluk
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mpc
|
||||
Description: Mangarayi
|
||||
Description: Mangarrayi
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -22889,6 +22933,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: mpj
|
||||
Description: Martu Wangka
|
||||
Description: Wangkajunga
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -24015,6 +24060,8 @@ Type: language
|
||||
Subtag: myd
|
||||
Description: Maramba
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-16
|
||||
Preferred-Value: aog
|
||||
%%
|
||||
Type: language
|
||||
Subtag: mye
|
||||
@ -24040,6 +24087,7 @@ Type: language
|
||||
Subtag: myi
|
||||
Description: Mina (India)
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: myj
|
||||
@ -24375,7 +24423,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nay
|
||||
Description: Narrinyeri
|
||||
Description: Ngarrindjeri
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -24432,7 +24480,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nbj
|
||||
Description: Ngarinman
|
||||
Description: Ngarinyman
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -24467,7 +24515,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nbr
|
||||
Description: Numana-Nunku-Gbantu-Numbu
|
||||
Description: Numana
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -24559,7 +24607,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nck
|
||||
Description: Nakara
|
||||
Description: Na-kara
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -24931,7 +24979,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: ngh
|
||||
Description: Nǀu
|
||||
Description: Nǁng
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -25176,7 +25224,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nig
|
||||
Description: Ngalakan
|
||||
Description: Ngalakgan
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -25798,6 +25846,8 @@ Type: language
|
||||
Subtag: nns
|
||||
Description: Ningye
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2019-04-16
|
||||
Preferred-Value: nbr
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nnt
|
||||
@ -26658,7 +26708,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nyh
|
||||
Description: Nyigina
|
||||
Description: Nyikina
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -26713,7 +26763,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: nys
|
||||
Description: Nyunga
|
||||
Description: Nyungar
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -28707,6 +28757,11 @@ Description: Pannei
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: pnd
|
||||
Description: Mpinda
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: pne
|
||||
Description: Western Penan
|
||||
Added: 2009-07-29
|
||||
@ -28794,6 +28849,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: pnw
|
||||
Description: Banyjima
|
||||
Description: Panytyima
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -29251,7 +29307,8 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: pti
|
||||
Description: Pintiini
|
||||
Description: Pindiini
|
||||
Description: Wangkatha
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -30133,6 +30190,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: ril
|
||||
Description: Riang Lang
|
||||
Description: Riang (Myanmar)
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -30153,7 +30211,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: rit
|
||||
Description: Ritarungo
|
||||
Description: Ritharrngu
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -30219,7 +30277,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: rmb
|
||||
Description: Rembarunga
|
||||
Description: Rembarrnga
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -30641,6 +30699,7 @@ Added: 2013-09-10
|
||||
Type: language
|
||||
Subtag: rxw
|
||||
Description: Karuwali
|
||||
Description: Garuwali
|
||||
Added: 2013-09-10
|
||||
%%
|
||||
Type: language
|
||||
@ -32206,7 +32265,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: snz
|
||||
Description: Sinsauru
|
||||
Description: Kou
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -32883,6 +32942,7 @@ Type: language
|
||||
Subtag: suj
|
||||
Description: Shubi
|
||||
Added: 2009-07-29
|
||||
Comments: see also xsj
|
||||
%%
|
||||
Type: language
|
||||
Subtag: suk
|
||||
@ -33312,6 +33372,11 @@ Description: Sawai
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: szy
|
||||
Description: Sakizaya
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: taa
|
||||
Description: Lower Tanana
|
||||
Added: 2009-07-29
|
||||
@ -33465,6 +33530,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tbh
|
||||
Description: Dharawal
|
||||
Description: Thurawal
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -33644,6 +33710,7 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: tcs
|
||||
Description: Torres Strait Creole
|
||||
Description: Yumplatok
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -34067,6 +34134,7 @@ Preferred-Value: tpo
|
||||
%%
|
||||
Type: language
|
||||
Subtag: thd
|
||||
Description: Kuuk Thaayorre
|
||||
Description: Thayore
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -34310,6 +34378,11 @@ Description: Northern Tujia
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tjj
|
||||
Description: Tjungundji
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tjl
|
||||
Description: Tai Laing
|
||||
Added: 2012-08-12
|
||||
@ -34330,6 +34403,11 @@ Description: Temacine Tamazight
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tjp
|
||||
Description: Tjupany
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tjs
|
||||
Description: Southern Tujia
|
||||
Added: 2009-07-29
|
||||
@ -35679,6 +35757,11 @@ Description: Sedoa
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tvx
|
||||
Description: Taivoan
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: tvy
|
||||
Description: Timor Pidgin
|
||||
Added: 2009-07-29
|
||||
@ -36230,7 +36313,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: ulk
|
||||
Description: Meriam
|
||||
Description: Meriam Mir
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -36280,6 +36363,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: umg
|
||||
Description: Morrobalama
|
||||
Description: Umbuygamu
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -36550,6 +36634,11 @@ Description: Uspanteco
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: uss
|
||||
Description: us-Saare
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: usu
|
||||
Description: Uya
|
||||
Added: 2009-07-29
|
||||
@ -36565,6 +36654,11 @@ Description: Ute-Southern Paiute
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: uth
|
||||
Description: ut-Hun
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: utp
|
||||
Description: Amba (Solomon Islands)
|
||||
Added: 2009-07-29
|
||||
@ -37178,7 +37272,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: waq
|
||||
Description: Wageman
|
||||
Description: Wagiman
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -37301,7 +37395,7 @@ Added: 2017-02-23
|
||||
%%
|
||||
Type: language
|
||||
Subtag: wbt
|
||||
Description: Wanman
|
||||
Description: Warnman
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -37448,6 +37542,7 @@ Added: 2010-03-11
|
||||
%%
|
||||
Type: language
|
||||
Subtag: wgg
|
||||
Description: Wangkangurru
|
||||
Description: Wangganguru
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -37521,7 +37616,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: wig
|
||||
Description: Wik-Ngathana
|
||||
Description: Wik Ngathan
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -37625,6 +37720,11 @@ Description: Kalanadi
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: wkr
|
||||
Description: Keerray-Woorroong
|
||||
Added: 2019-04-16
|
||||
%%
|
||||
Type: language
|
||||
Subtag: wku
|
||||
Description: Kunduvadi
|
||||
Added: 2009-07-29
|
||||
@ -37857,10 +37957,12 @@ Added: 2013-09-10
|
||||
Type: language
|
||||
Subtag: wny
|
||||
Description: Wanyi
|
||||
Description: Waanyi
|
||||
Added: 2012-08-12
|
||||
%%
|
||||
Type: language
|
||||
Subtag: woa
|
||||
Description: Kuwema
|
||||
Description: Tyaraity
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -37951,6 +38053,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: wrb
|
||||
Description: Waluwarra
|
||||
Description: Warluwara
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -37962,11 +38065,12 @@ Added: 2009-07-29
|
||||
Type: language
|
||||
Subtag: wrg
|
||||
Description: Warungu
|
||||
Description: Gudjal
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: wrh
|
||||
Description: Wiradhuri
|
||||
Description: Wiradjuri
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -38439,6 +38543,7 @@ Deprecated: 2016-05-30
|
||||
%%
|
||||
Type: language
|
||||
Subtag: xby
|
||||
Description: Batjala
|
||||
Description: Batyala
|
||||
Added: 2013-09-10
|
||||
%%
|
||||
@ -38998,7 +39103,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: xmh
|
||||
Description: Kuku-Muminh
|
||||
Description: Kugu-Muminh
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -39423,8 +39528,7 @@ Type: language
|
||||
Subtag: xsj
|
||||
Description: Subi
|
||||
Added: 2009-07-29
|
||||
Deprecated: 2015-02-12
|
||||
Preferred-Value: suj
|
||||
Comments: see also suj
|
||||
%%
|
||||
Type: language
|
||||
Subtag: xsl
|
||||
@ -40258,6 +40362,7 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: yin
|
||||
Description: Riang Lai
|
||||
Description: Yinchia
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
@ -41562,12 +41667,13 @@ Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: zml
|
||||
Description: Madngele
|
||||
Description: Matngala
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
Subtag: zmm
|
||||
Description: Marimanindji
|
||||
Description: Marramaninyshi
|
||||
Added: 2009-07-29
|
||||
%%
|
||||
Type: language
|
||||
@ -43019,6 +43125,13 @@ Preferred-Value: lsl
|
||||
Prefix: sgn
|
||||
%%
|
||||
Type: extlang
|
||||
Subtag: lsn
|
||||
Description: Tibetan Sign Language
|
||||
Added: 2019-04-16
|
||||
Preferred-Value: lsn
|
||||
Prefix: sgn
|
||||
%%
|
||||
Type: extlang
|
||||
Subtag: lso
|
||||
Description: Laos Sign Language
|
||||
Added: 2009-07-29
|
||||
@ -43041,6 +43154,13 @@ Preferred-Value: lst
|
||||
Prefix: sgn
|
||||
%%
|
||||
Type: extlang
|
||||
Subtag: lsv
|
||||
Description: Sivia Sign Language
|
||||
Added: 2019-04-16
|
||||
Preferred-Value: lsv
|
||||
Prefix: sgn
|
||||
%%
|
||||
Type: extlang
|
||||
Subtag: lsy
|
||||
Description: Mauritian Sign Language
|
||||
Added: 2010-03-11
|
||||
@ -43966,6 +44086,11 @@ Description: Cherokee
|
||||
Added: 2005-10-16
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Chrs
|
||||
Description: Chorasmian
|
||||
Added: 2019-09-11
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Cirt
|
||||
Description: Cirth
|
||||
Added: 2005-10-16
|
||||
@ -44002,6 +44127,11 @@ Description: Nagari
|
||||
Added: 2005-10-16
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Diak
|
||||
Description: Dives Akuru
|
||||
Added: 2019-09-11
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Dogr
|
||||
Description: Dogra
|
||||
Added: 2017-01-13
|
||||
@ -44839,6 +44969,11 @@ Description: Sumero-Akkadian cuneiform
|
||||
Added: 2005-10-16
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Yezi
|
||||
Description: Yezidi
|
||||
Added: 2019-09-11
|
||||
%%
|
||||
Type: script
|
||||
Subtag: Yiii
|
||||
Description: Yi
|
||||
Added: 2005-10-16
|
||||
@ -45683,7 +45818,7 @@ Added: 2005-10-16
|
||||
%%
|
||||
Type: region
|
||||
Subtag: MK
|
||||
Description: The Former Yugoslav Republic of Macedonia
|
||||
Description: North Macedonia
|
||||
Added: 2005-10-16
|
||||
%%
|
||||
Type: region
|
||||
|
@ -79,20 +79,19 @@ endif
|
||||
# Define external dependencies
|
||||
|
||||
# Latest that could be made to work.
|
||||
GCC_VER := 8.2.0
|
||||
ifeq ($(GCC_VER), 8.2.0)
|
||||
gcc_ver := gcc-8.2.0
|
||||
binutils_ver := binutils-2.30
|
||||
ccache_ver := ccache-3.5.1a
|
||||
CCACHE_DIRNAME := ccache-3.5.1
|
||||
GCC_VER := 8.3.0
|
||||
ifeq ($(GCC_VER), 8.3.0)
|
||||
gcc_ver := gcc-8.3.0
|
||||
binutils_ver := binutils-2.32
|
||||
ccache_ver := 3.7.3
|
||||
mpfr_ver := mpfr-3.1.5
|
||||
gmp_ver := gmp-6.1.2
|
||||
mpc_ver := mpc-1.0.3
|
||||
gdb_ver := gdb-8.2.1
|
||||
gdb_ver := gdb-8.3
|
||||
else ifeq ($(GCC_VER), 7.3.0)
|
||||
gcc_ver := gcc-7.3.0
|
||||
binutils_ver := binutils-2.30
|
||||
ccache_ver := ccache-3.3.6
|
||||
ccache_ver := 3.3.6
|
||||
mpfr_ver := mpfr-3.1.5
|
||||
gmp_ver := gmp-6.1.2
|
||||
mpc_ver := mpc-1.0.3
|
||||
@ -100,7 +99,7 @@ else ifeq ($(GCC_VER), 7.3.0)
|
||||
else ifeq ($(GCC_VER), 4.9.2)
|
||||
gcc_ver := gcc-4.9.2
|
||||
binutils_ver := binutils-2.25
|
||||
ccache_ver := ccache-3.2.1
|
||||
ccache_ver := 3.2.1
|
||||
mpfr_ver := mpfr-3.0.1
|
||||
gmp_ver := gmp-4.3.2
|
||||
mpc_ver := mpc-1.0.1
|
||||
@ -111,7 +110,7 @@ endif
|
||||
|
||||
GCC := http://ftp.gnu.org/pub/gnu/gcc/$(gcc_ver)/$(gcc_ver).tar.xz
|
||||
BINUTILS := http://ftp.gnu.org/pub/gnu/binutils/$(binutils_ver).tar.xz
|
||||
CCACHE := https://samba.org/ftp/ccache/$(ccache_ver).tar.xz
|
||||
CCACHE := https://github.com/ccache/ccache/releases/download/v$(ccache_ver)/ccache-$(ccache_ver).tar.xz
|
||||
MPFR := https://www.mpfr.org/${mpfr_ver}/${mpfr_ver}.tar.bz2
|
||||
GMP := http://ftp.gnu.org/pub/gnu/gmp/${gmp_ver}.tar.bz2
|
||||
MPC := http://ftp.gnu.org/pub/gnu/mpc/${mpc_ver}.tar.gz
|
||||
|
@ -32,10 +32,7 @@ VS_VERSION="2017"
|
||||
VS_VERSION_NUM_NODOT="150"
|
||||
VS_DLL_VERSION="140"
|
||||
SDK_VERSION="10"
|
||||
SDK_FULL_VERSION="10.0.16299.0"
|
||||
MSVC_DIR="Microsoft.VC141.CRT"
|
||||
MSVC_FULL_VERSION="14.12.25827"
|
||||
REDIST_FULL_VERSION="14.12.25810"
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)"
|
||||
BUILD_DIR="${SCRIPT_DIR}/../../build/devkit"
|
||||
|
@ -73,7 +73,7 @@ $(GENSRC_DIR)/module-info.java.extra: $(GENSRC_DIR)/_gensrc_proc_done
|
||||
($(CD) $(GENSRC_DIR)/META-INF/providers && \
|
||||
p=""; \
|
||||
impl=""; \
|
||||
for i in $$($(GREP) '^' * | $(SORT) -t ':' -k 2 | $(SED) 's/:.*//'); do \
|
||||
for i in $$($(NAWK) '$$0=FILENAME" "$$0' * | $(SORT) -k 2 | $(SED) 's/ .*//'); do \
|
||||
c=$$($(CAT) $$i | $(TR) -d '\n\r'); \
|
||||
if test x$$p != x$$c; then \
|
||||
if test x$$p != x; then \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 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
|
||||
@ -46,6 +46,7 @@ public class SBCS {
|
||||
String hisName = cs.hisName;
|
||||
String pkgName = cs.pkgName;
|
||||
boolean isASCII = cs.isASCII;
|
||||
boolean isLatin1Decodable = true;
|
||||
|
||||
StringBuilder b2cSB = new StringBuilder();
|
||||
StringBuilder b2cNRSB = new StringBuilder();
|
||||
@ -69,6 +70,9 @@ public class SBCS {
|
||||
c2bOff += 0x100;
|
||||
c2bIndex[e.cp>>8] = 1;
|
||||
}
|
||||
if (e.cp > 0xFF) {
|
||||
isLatin1Decodable = false;
|
||||
}
|
||||
}
|
||||
|
||||
Formatter fm = new Formatter(b2cSB);
|
||||
@ -178,6 +182,9 @@ public class SBCS {
|
||||
if (line.indexOf("$ASCIICOMPATIBLE$") != -1) {
|
||||
line = line.replace("$ASCIICOMPATIBLE$", isASCII ? "true" : "false");
|
||||
}
|
||||
if (line.indexOf("$LATIN1DECODABLE$") != -1) {
|
||||
line = line.replace("$LATIN1DECODABLE$", isLatin1Decodable ? "true" : "false");
|
||||
}
|
||||
if (line.indexOf("$B2CTABLE$") != -1) {
|
||||
line = line.replace("$B2CTABLE$", b2c);
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ if [ -z "$TOPDIR" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make sure all shell commands are executed with the C locale
|
||||
export LC_ALL=C
|
||||
|
||||
if [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
|
||||
FULLDUMP_CMD="$OTOOL -v -V -h -X -d"
|
||||
LDD_CMD="$OTOOL -L"
|
||||
@ -110,7 +113,7 @@ elif [ "$OPENJDK_TARGET_OS" = "windows" ]; then
|
||||
"
|
||||
fi
|
||||
elif [ "$OPENJDK_TARGET_OS" = "macosx" ]; then
|
||||
DIS_DIFF_FILTER="LANG=C $SED \
|
||||
DIS_DIFF_FILTER="$SED \
|
||||
-e 's/0x[0-9a-f]\{3,16\}/<HEXSTR>/g' -e 's/^[0-9a-f]\{12,20\}/<ADDR>/' \
|
||||
-e 's/-20[0-9][0-9]-[0-1][0-9]-[0-3][0-9]-[0-2][0-9]\{5\}/<DATE>/g' \
|
||||
-e 's/), built on .*/), <DATE>/' \
|
||||
@ -134,7 +137,7 @@ diff_text() {
|
||||
|
||||
if [[ "$THIS_FILE" = *"META-INF/MANIFEST.MF" ]]; then
|
||||
# Filter out date string, ant version and java version differences.
|
||||
TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
|
||||
TMP=$($DIFF $OTHER_FILE $THIS_FILE | \
|
||||
$GREP '^[<>]' | \
|
||||
$SED -e '/[<>] Ant-Version: Apache Ant .*/d' \
|
||||
-e '/[<>] Created-By: .* (Oracle [Corpatin)]*/d' \
|
||||
@ -142,7 +145,7 @@ diff_text() {
|
||||
-e '/[<>].*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d')
|
||||
fi
|
||||
if test "x$SUFFIX" = "xjava"; then
|
||||
TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
|
||||
TMP=$($DIFF $OTHER_FILE $THIS_FILE | \
|
||||
$GREP '^[<>]' | \
|
||||
$SED -e '/[<>] \* from.*\.idl/d' \
|
||||
-e '/[<>] .*[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}-b[0-9]\{2\}.*/d' \
|
||||
@ -197,7 +200,7 @@ diff_text() {
|
||||
fi
|
||||
if test "x$SUFFIX" = "xproperties"; then
|
||||
# Filter out date string differences.
|
||||
TMP=$(LC_ALL=C $DIFF $OTHER_FILE $THIS_FILE | \
|
||||
TMP=$($DIFF $OTHER_FILE $THIS_FILE | \
|
||||
$GREP '^[<>]' | \
|
||||
$SED -e '/[<>].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*/d')
|
||||
fi
|
||||
@ -207,7 +210,7 @@ diff_text() {
|
||||
-e 's/<font size=-1>/<font size=\"-1\">/g'"
|
||||
$CAT $THIS_FILE | eval "$HTML_FILTER" > $THIS_FILE.filtered
|
||||
$CAT $OTHER_FILE | eval "$HTML_FILTER" > $OTHER_FILE.filtered
|
||||
TMP=$(LC_ALL=C $DIFF $OTHER_FILE.filtered $THIS_FILE.filtered | \
|
||||
TMP=$($DIFF $OTHER_FILE.filtered $THIS_FILE.filtered | \
|
||||
$GREP '^[<>]' | \
|
||||
$SED -e '/[<>] <!-- Generated by javadoc .* on .* -->/d' \
|
||||
-e '/[<>] <meta name="date" content=".*">/d' )
|
||||
@ -554,11 +557,11 @@ compare_zip_file() {
|
||||
CONTENTS_DIFF_FILE=$WORK_DIR/$ZIP_FILE.diff
|
||||
# On solaris, there is no -q option.
|
||||
if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then
|
||||
LC_ALL=C $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \
|
||||
$DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \
|
||||
| $GREP -v -e "^<" -e "^>" -e "^Common subdirectories:" \
|
||||
> $CONTENTS_DIFF_FILE
|
||||
else
|
||||
LC_ALL=C $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE
|
||||
$DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE
|
||||
fi
|
||||
|
||||
ONLY_OTHER=$($GREP "^Only in $OTHER_UNZIPDIR" $CONTENTS_DIFF_FILE)
|
||||
@ -605,11 +608,11 @@ compare_zip_file() {
|
||||
if [ -n "$SHOW_DIFFS" ]; then
|
||||
for i in $(cat $WORK_DIR/$ZIP_FILE.difflist) ; do
|
||||
if [ -f "${OTHER_UNZIPDIR}/$i.javap" ]; then
|
||||
LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap
|
||||
$DIFF ${OTHER_UNZIPDIR}/$i.javap ${THIS_UNZIPDIR}/$i.javap
|
||||
elif [ -f "${OTHER_UNZIPDIR}/$i.cleaned" ]; then
|
||||
LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i
|
||||
$DIFF ${OTHER_UNZIPDIR}/$i.cleaned ${THIS_UNZIPDIR}/$i
|
||||
else
|
||||
LC_ALL=C $DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i
|
||||
$DIFF ${OTHER_UNZIPDIR}/$i ${THIS_UNZIPDIR}/$i
|
||||
fi
|
||||
done
|
||||
fi
|
||||
@ -642,7 +645,7 @@ compare_jmod_file() {
|
||||
$JMOD list $THIS_JMOD | sort > $THIS_JMOD_LIST
|
||||
$JMOD list $OTHER_JMOD | sort > $OTHER_JMOD_LIST
|
||||
JMOD_LIST_DIFF_FILE=$WORK_DIR/$JMOD_FILE.list.diff
|
||||
LC_ALL=C $DIFF $THIS_JMOD_LIST $OTHER_JMOD_LIST > $JMOD_LIST_DIFF_FILE
|
||||
$DIFF $THIS_JMOD_LIST $OTHER_JMOD_LIST > $JMOD_LIST_DIFF_FILE
|
||||
|
||||
ONLY_THIS=$($GREP "^<" $JMOD_LIST_DIFF_FILE)
|
||||
ONLY_OTHER=$($GREP "^>" $JMOD_LIST_DIFF_FILE)
|
||||
@ -924,7 +927,7 @@ compare_bin_file() {
|
||||
> $WORK_FILE_BASE.symbols.this
|
||||
fi
|
||||
|
||||
LC_ALL=C $DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff
|
||||
$DIFF $WORK_FILE_BASE.symbols.other $WORK_FILE_BASE.symbols.this > $WORK_FILE_BASE.symbols.diff
|
||||
if [ -s $WORK_FILE_BASE.symbols.diff ]; then
|
||||
SYM_MSG=" diff "
|
||||
if [[ "$ACCEPTED_SYM_DIFF" != *"$BIN_FILE"* ]]; then
|
||||
@ -964,9 +967,9 @@ compare_bin_file() {
|
||||
| $UNIQ > $WORK_FILE_BASE.deps.this.uniq)
|
||||
(cd $FILE_WORK_DIR && $RM -f $NAME)
|
||||
|
||||
LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this \
|
||||
$DIFF $WORK_FILE_BASE.deps.other $WORK_FILE_BASE.deps.this \
|
||||
> $WORK_FILE_BASE.deps.diff
|
||||
LC_ALL=C $DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq \
|
||||
$DIFF $WORK_FILE_BASE.deps.other.uniq $WORK_FILE_BASE.deps.this.uniq \
|
||||
> $WORK_FILE_BASE.deps.diff.uniq
|
||||
|
||||
if [ -s $WORK_FILE_BASE.deps.diff ]; then
|
||||
@ -1016,7 +1019,7 @@ compare_bin_file() {
|
||||
> $WORK_FILE_BASE.fulldump.this 2>&1 &
|
||||
wait
|
||||
|
||||
LC_ALL=C $DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this \
|
||||
$DIFF $WORK_FILE_BASE.fulldump.other $WORK_FILE_BASE.fulldump.this \
|
||||
> $WORK_FILE_BASE.fulldump.diff
|
||||
|
||||
if [ -s $WORK_FILE_BASE.fulldump.diff ]; then
|
||||
@ -1063,7 +1066,7 @@ compare_bin_file() {
|
||||
| eval "$this_DIS_DIFF_FILTER" > $WORK_FILE_BASE.dis.this 2>&1 &
|
||||
wait
|
||||
|
||||
LC_ALL=C $DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff
|
||||
$DIFF $WORK_FILE_BASE.dis.other $WORK_FILE_BASE.dis.this > $WORK_FILE_BASE.dis.diff
|
||||
|
||||
if [ -s $WORK_FILE_BASE.dis.diff ]; then
|
||||
DIS_DIFF_SIZE=$(ls -n $WORK_FILE_BASE.dis.diff | awk '{print $5}')
|
||||
|
@ -2513,17 +2513,8 @@ void Compile::reshape_address(AddPNode* addp) {
|
||||
__ INSN(REG, as_Register(BASE)); \
|
||||
}
|
||||
|
||||
typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
|
||||
typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
|
||||
typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
|
||||
MacroAssembler::SIMD_RegVariant T, const Address &adr);
|
||||
|
||||
// Used for all non-volatile memory accesses. The use of
|
||||
// $mem->opcode() to discover whether this pattern uses sign-extended
|
||||
// offsets is something of a kludge.
|
||||
static void loadStore(MacroAssembler masm, mem_insn insn,
|
||||
Register reg, int opcode,
|
||||
Register base, int index, int size, int disp)
|
||||
static Address mem2address(int opcode, Register base, int index, int size, int disp)
|
||||
{
|
||||
Address::extend scale;
|
||||
|
||||
@ -2542,16 +2533,34 @@ typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
(masm.*insn)(reg, Address(base, disp));
|
||||
return Address(base, disp);
|
||||
} else {
|
||||
assert(disp == 0, "unsupported address mode: disp = %d", disp);
|
||||
(masm.*insn)(reg, Address(base, as_Register(index), scale));
|
||||
return Address(base, as_Register(index), scale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
|
||||
typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr);
|
||||
typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
|
||||
typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
|
||||
MacroAssembler::SIMD_RegVariant T, const Address &adr);
|
||||
|
||||
// Used for all non-volatile memory accesses. The use of
|
||||
// $mem->opcode() to discover whether this pattern uses sign-extended
|
||||
// offsets is something of a kludge.
|
||||
static void loadStore(MacroAssembler masm, mem_insn insn,
|
||||
Register reg, int opcode,
|
||||
Register base, int index, int size, int disp)
|
||||
{
|
||||
Address addr = mem2address(opcode, base, index, size, disp);
|
||||
(masm.*insn)(reg, addr);
|
||||
}
|
||||
|
||||
static void loadStore(MacroAssembler masm, mem_float_insn insn,
|
||||
FloatRegister reg, int opcode,
|
||||
Register base, int index, int size, int disp)
|
||||
FloatRegister reg, int opcode,
|
||||
Register base, int index, int size, int disp)
|
||||
{
|
||||
Address::extend scale;
|
||||
|
||||
@ -2573,8 +2582,8 @@ typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
|
||||
}
|
||||
|
||||
static void loadStore(MacroAssembler masm, mem_vector_insn insn,
|
||||
FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
|
||||
int opcode, Register base, int index, int size, int disp)
|
||||
FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
|
||||
int opcode, Register base, int index, int size, int disp)
|
||||
{
|
||||
if (index == -1) {
|
||||
(masm.*insn)(reg, T, Address(base, disp));
|
||||
@ -3791,7 +3800,7 @@ frame %{
|
||||
static const int hi[Op_RegL + 1] = { // enum name
|
||||
0, // Op_Node
|
||||
0, // Op_Set
|
||||
OptoReg::Bad, // Op_RegN
|
||||
OptoReg::Bad, // Op_RegN
|
||||
OptoReg::Bad, // Op_RegI
|
||||
R0_H_num, // Op_RegP
|
||||
OptoReg::Bad, // Op_RegF
|
||||
@ -6923,7 +6932,7 @@ instruct loadRange(iRegINoSp dst, memory mem)
|
||||
instruct loadP(iRegPNoSp dst, memory mem)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(!needs_acquiring_load(n));
|
||||
predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0));
|
||||
|
||||
ins_cost(4 * INSN_COST);
|
||||
format %{ "ldr $dst, $mem\t# ptr" %}
|
||||
@ -7616,6 +7625,7 @@ instruct loadL_volatile(iRegLNoSp dst, /* sync_memory*/indirect mem)
|
||||
instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(n->as_Load()->barrier_data() == 0);
|
||||
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
format %{ "ldar $dst, $mem\t# ptr" %}
|
||||
@ -8552,6 +8562,7 @@ instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoS
|
||||
instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
effect(KILL cr);
|
||||
@ -8665,7 +8676,7 @@ instruct compareAndSwapLAcq(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegL
|
||||
|
||||
instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
|
||||
predicate(needs_acquiring_load_exclusive(n));
|
||||
predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
|
||||
@ -8796,6 +8807,7 @@ instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN ne
|
||||
%}
|
||||
|
||||
instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
effect(TEMP_DEF res, KILL cr);
|
||||
@ -8895,7 +8907,7 @@ instruct compareAndExchangeNAcq(iRegNNoSp res, indirect mem, iRegN oldval, iRegN
|
||||
%}
|
||||
|
||||
instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
predicate(needs_acquiring_load_exclusive(n));
|
||||
predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
effect(TEMP_DEF res, KILL cr);
|
||||
@ -8996,6 +9008,7 @@ instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN ne
|
||||
%}
|
||||
|
||||
instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
effect(KILL cr);
|
||||
@ -9103,8 +9116,8 @@ instruct weakCompareAndSwapNAcq(iRegINoSp res, indirect mem, iRegN oldval, iRegN
|
||||
%}
|
||||
|
||||
instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
predicate(needs_acquiring_load_exclusive(n));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
effect(KILL cr);
|
||||
format %{
|
||||
@ -9154,6 +9167,7 @@ instruct get_and_setN(indirect mem, iRegN newv, iRegINoSp prev) %{
|
||||
%}
|
||||
|
||||
instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
|
||||
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
format %{ "atomic_xchg $prev, $newv, [$mem]" %}
|
||||
@ -9197,7 +9211,7 @@ instruct get_and_setNAcq(indirect mem, iRegN newv, iRegINoSp prev) %{
|
||||
%}
|
||||
|
||||
instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
|
||||
predicate(needs_acquiring_load_exclusive(n));
|
||||
predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "oops/constMethod.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -162,16 +162,12 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
// Creation also verifies the object.
|
||||
NativeMovConstReg* method_holder
|
||||
= nativeMovConstReg_at(stub + NativeInstruction::instruction_size);
|
||||
#ifndef PRODUCT
|
||||
NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
|
||||
|
||||
// read the value once
|
||||
volatile intptr_t data = method_holder->data();
|
||||
assert(data == 0 || data == (intptr_t)callee(),
|
||||
"a) MT-unsafe modification of inline cache");
|
||||
assert(data == 0 || jump->jump_destination() == entry,
|
||||
"b) MT-unsafe modification of inline cache");
|
||||
#ifdef ASSERT
|
||||
NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
|
||||
verify_mt_safe(callee, entry, method_holder, jump);
|
||||
#endif
|
||||
|
||||
// Update stub.
|
||||
method_holder->set_data((intptr_t)callee());
|
||||
NativeGeneralJump::insert_unconditional(method_holder->next_instruction_address(), entry);
|
||||
@ -189,6 +185,10 @@ void CompiledDirectStaticCall::set_stub_to_clean(static_stub_Relocation* static_
|
||||
NativeMovConstReg* method_holder
|
||||
= nativeMovConstReg_at(stub + NativeInstruction::instruction_size);
|
||||
method_holder->set_data(0);
|
||||
if (!static_stub->is_aot()) {
|
||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
||||
jump->set_jump_destination((address)-1);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -24,22 +24,23 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "code/vmreg.inline.hpp"
|
||||
#include "gc/z/zBarrier.inline.hpp"
|
||||
#include "gc/z/zBarrierSet.hpp"
|
||||
#include "gc/z/zBarrierSetAssembler.hpp"
|
||||
#include "gc/z/zBarrierSetRuntime.hpp"
|
||||
#include "gc/z/zThreadLocalData.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#ifdef COMPILER1
|
||||
#include "c1/c1_LIRAssembler.hpp"
|
||||
#include "c1/c1_MacroAssembler.hpp"
|
||||
#include "gc/z/c1/zBarrierSetC1.hpp"
|
||||
#endif // COMPILER1
|
||||
|
||||
#include "gc/z/zThreadLocalData.hpp"
|
||||
|
||||
ZBarrierSetAssembler::ZBarrierSetAssembler() :
|
||||
_load_barrier_slow_stub(),
|
||||
_load_barrier_weak_slow_stub() {}
|
||||
#ifdef COMPILER2
|
||||
#include "gc/z/c2/zBarrierSetC2.hpp"
|
||||
#endif // COMPILER2
|
||||
|
||||
#ifdef PRODUCT
|
||||
#define BLOCK_COMMENT(str) /* nothing */
|
||||
@ -66,7 +67,7 @@ void ZBarrierSetAssembler::load_at(MacroAssembler* masm,
|
||||
assert_different_registers(rscratch1, rscratch2, src.base());
|
||||
assert_different_registers(rscratch1, rscratch2, dst);
|
||||
|
||||
RegSet savedRegs = RegSet::range(r0,r28) - RegSet::of(dst, rscratch1, rscratch2);
|
||||
RegSet savedRegs = RegSet::range(r0, r28) - RegSet::of(dst, rscratch1, rscratch2);
|
||||
|
||||
Label done;
|
||||
|
||||
@ -206,7 +207,8 @@ void ZBarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm,
|
||||
|
||||
// The Address offset is too large to direct load - -784. Our range is +127, -128.
|
||||
__ mov(tmp, (long int)(in_bytes(ZThreadLocalData::address_bad_mask_offset()) -
|
||||
in_bytes(JavaThread::jni_environment_offset())));
|
||||
in_bytes(JavaThread::jni_environment_offset())));
|
||||
|
||||
// Load address bad mask
|
||||
__ add(tmp, jni_env, tmp);
|
||||
__ ldr(tmp, Address(tmp));
|
||||
@ -294,12 +296,12 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler*
|
||||
__ prologue("zgc_load_barrier stub", false);
|
||||
|
||||
// We don't use push/pop_clobbered_registers() - we need to pull out the result from r0.
|
||||
for (int i = 0; i < 32; i +=2) {
|
||||
__ stpd(as_FloatRegister(i), as_FloatRegister(i+1), Address(__ pre(sp,-16)));
|
||||
for (int i = 0; i < 32; i += 2) {
|
||||
__ stpd(as_FloatRegister(i), as_FloatRegister(i + 1), Address(__ pre(sp,-16)));
|
||||
}
|
||||
|
||||
RegSet saveRegs = RegSet::range(r0,r28) - RegSet::of(r0);
|
||||
__ push(saveRegs, sp);
|
||||
const RegSet save_regs = RegSet::range(r1, r28);
|
||||
__ push(save_regs, sp);
|
||||
|
||||
// Setup arguments
|
||||
__ load_parameter(0, c_rarg0);
|
||||
@ -307,98 +309,161 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler*
|
||||
|
||||
__ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2);
|
||||
|
||||
__ pop(saveRegs, sp);
|
||||
__ pop(save_regs, sp);
|
||||
|
||||
for (int i = 30; i >0; i -=2) {
|
||||
__ ldpd(as_FloatRegister(i), as_FloatRegister(i+1), Address(__ post(sp, 16)));
|
||||
}
|
||||
for (int i = 30; i >= 0; i -= 2) {
|
||||
__ ldpd(as_FloatRegister(i), as_FloatRegister(i + 1), Address(__ post(sp, 16)));
|
||||
}
|
||||
|
||||
__ epilogue();
|
||||
}
|
||||
#endif // COMPILER1
|
||||
|
||||
#ifdef COMPILER2
|
||||
|
||||
OptoReg::Name ZBarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
|
||||
if (!OptoReg::is_reg(opto_reg)) {
|
||||
return OptoReg::Bad;
|
||||
}
|
||||
|
||||
const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
|
||||
if (vm_reg->is_FloatRegister()) {
|
||||
return opto_reg & ~1;
|
||||
}
|
||||
|
||||
return opto_reg;
|
||||
}
|
||||
|
||||
#undef __
|
||||
#define __ cgen->assembler()->
|
||||
#define __ _masm->
|
||||
|
||||
// Generates a register specific stub for calling
|
||||
// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
|
||||
// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
|
||||
//
|
||||
// The raddr register serves as both input and output for this stub. When the stub is
|
||||
// called the raddr register contains the object field address (oop*) where the bad oop
|
||||
// was loaded from, which caused the slow path to be taken. On return from the stub the
|
||||
// raddr register contains the good/healed oop returned from
|
||||
// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
|
||||
// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
|
||||
static address generate_load_barrier_stub(StubCodeGenerator* cgen, Register raddr, DecoratorSet decorators) {
|
||||
// Don't generate stub for invalid registers
|
||||
if (raddr == zr || raddr == r29 || raddr == r30) {
|
||||
return NULL;
|
||||
class ZSaveLiveRegisters {
|
||||
private:
|
||||
MacroAssembler* const _masm;
|
||||
RegSet _gp_regs;
|
||||
RegSet _fp_regs;
|
||||
|
||||
public:
|
||||
void initialize(ZLoadBarrierStubC2* stub) {
|
||||
// Create mask of live registers
|
||||
RegMask live = stub->live();
|
||||
|
||||
// Record registers that needs to be saved/restored
|
||||
while (live.is_NotEmpty()) {
|
||||
const OptoReg::Name opto_reg = live.find_first_elem();
|
||||
live.Remove(opto_reg);
|
||||
if (OptoReg::is_reg(opto_reg)) {
|
||||
const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
|
||||
if (vm_reg->is_Register()) {
|
||||
_gp_regs += RegSet::of(vm_reg->as_Register());
|
||||
} else if (vm_reg->is_FloatRegister()) {
|
||||
_fp_regs += RegSet::of((Register)vm_reg->as_FloatRegister());
|
||||
} else {
|
||||
fatal("Unknown register type");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove C-ABI SOE registers, scratch regs and _ref register that will be updated
|
||||
_gp_regs -= RegSet::range(r19, r30) + RegSet::of(r8, r9, stub->ref());
|
||||
}
|
||||
|
||||
// Create stub name
|
||||
char name[64];
|
||||
const bool weak = (decorators & ON_WEAK_OOP_REF) != 0;
|
||||
os::snprintf(name, sizeof(name), "zgc_load_barrier%s_stub_%s", weak ? "_weak" : "", raddr->name());
|
||||
ZSaveLiveRegisters(MacroAssembler* masm, ZLoadBarrierStubC2* stub) :
|
||||
_masm(masm),
|
||||
_gp_regs(),
|
||||
_fp_regs() {
|
||||
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(cgen, "StubRoutines", os::strdup(name, mtCode));
|
||||
address start = __ pc();
|
||||
// Figure out what registers to save/restore
|
||||
initialize(stub);
|
||||
|
||||
// Save live registers
|
||||
RegSet savedRegs = RegSet::range(r0,r18) - RegSet::of(raddr);
|
||||
|
||||
__ enter();
|
||||
__ push(savedRegs, sp);
|
||||
|
||||
// Setup arguments
|
||||
if (raddr != c_rarg1) {
|
||||
__ mov(c_rarg1, raddr);
|
||||
// Save registers
|
||||
__ push(_gp_regs, sp);
|
||||
__ push_fp(_fp_regs, sp);
|
||||
}
|
||||
|
||||
__ ldr(c_rarg0, Address(raddr));
|
||||
~ZSaveLiveRegisters() {
|
||||
// Restore registers
|
||||
__ pop_fp(_fp_regs, sp);
|
||||
__ pop(_gp_regs, sp);
|
||||
}
|
||||
};
|
||||
|
||||
// Call barrier function
|
||||
__ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), c_rarg0, c_rarg1);
|
||||
#undef __
|
||||
#define __ _masm->
|
||||
|
||||
// Move result returned in r0 to raddr, if needed
|
||||
if (raddr != r0) {
|
||||
__ mov(raddr, r0);
|
||||
class ZSetupArguments {
|
||||
private:
|
||||
MacroAssembler* const _masm;
|
||||
const Register _ref;
|
||||
const Address _ref_addr;
|
||||
|
||||
public:
|
||||
ZSetupArguments(MacroAssembler* masm, ZLoadBarrierStubC2* stub) :
|
||||
_masm(masm),
|
||||
_ref(stub->ref()),
|
||||
_ref_addr(stub->ref_addr()) {
|
||||
|
||||
// Setup arguments
|
||||
if (_ref_addr.base() == noreg) {
|
||||
// No self healing
|
||||
if (_ref != c_rarg0) {
|
||||
__ mov(c_rarg0, _ref);
|
||||
}
|
||||
__ mov(c_rarg1, 0);
|
||||
} else {
|
||||
// Self healing
|
||||
if (_ref == c_rarg0) {
|
||||
// _ref is already at correct place
|
||||
__ lea(c_rarg1, _ref_addr);
|
||||
} else if (_ref != c_rarg1) {
|
||||
// _ref is in wrong place, but not in c_rarg1, so fix it first
|
||||
__ lea(c_rarg1, _ref_addr);
|
||||
__ mov(c_rarg0, _ref);
|
||||
} else if (_ref_addr.base() != c_rarg0 && _ref_addr.index() != c_rarg0) {
|
||||
assert(_ref == c_rarg1, "Mov ref first, vacating c_rarg0");
|
||||
__ mov(c_rarg0, _ref);
|
||||
__ lea(c_rarg1, _ref_addr);
|
||||
} else {
|
||||
assert(_ref == c_rarg1, "Need to vacate c_rarg1 and _ref_addr is using c_rarg0");
|
||||
if (_ref_addr.base() == c_rarg0 || _ref_addr.index() == c_rarg0) {
|
||||
__ mov(rscratch2, c_rarg1);
|
||||
__ lea(c_rarg1, _ref_addr);
|
||||
__ mov(c_rarg0, rscratch2);
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__ pop(savedRegs, sp);
|
||||
__ leave();
|
||||
__ ret(lr);
|
||||
~ZSetupArguments() {
|
||||
// Transfer result
|
||||
if (_ref != r0) {
|
||||
__ mov(_ref, r0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return start;
|
||||
#undef __
|
||||
#define __ masm->
|
||||
|
||||
void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, ZLoadBarrierStubC2* stub) const {
|
||||
BLOCK_COMMENT("ZLoadBarrierStubC2");
|
||||
|
||||
// Stub entry
|
||||
__ bind(*stub->entry());
|
||||
|
||||
{
|
||||
ZSaveLiveRegisters save_live_registers(masm, stub);
|
||||
ZSetupArguments setup_arguments(masm, stub);
|
||||
__ mov(rscratch1, stub->slow_path());
|
||||
__ blr(rscratch1);
|
||||
}
|
||||
|
||||
// Stub exit
|
||||
__ b(*stub->continuation());
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
static void barrier_stubs_init_inner(const char* label, const DecoratorSet decorators, address* stub) {
|
||||
const int nregs = 28; // Exclude FP, XZR, SP from calculation.
|
||||
const int code_size = nregs * 254; // Rough estimate of code size
|
||||
|
||||
ResourceMark rm;
|
||||
|
||||
CodeBuffer buf(BufferBlob::create(label, code_size));
|
||||
StubCodeGenerator cgen(&buf);
|
||||
|
||||
for (int i = 0; i < nregs; i++) {
|
||||
const Register reg = as_Register(i);
|
||||
stub[i] = generate_load_barrier_stub(&cgen, reg, decorators);
|
||||
}
|
||||
}
|
||||
|
||||
void ZBarrierSetAssembler::barrier_stubs_init() {
|
||||
barrier_stubs_init_inner("zgc_load_barrier_stubs", ON_STRONG_OOP_REF, _load_barrier_slow_stub);
|
||||
barrier_stubs_init_inner("zgc_load_barrier_weak_stubs", ON_WEAK_OOP_REF, _load_barrier_weak_slow_stub);
|
||||
}
|
||||
|
||||
address ZBarrierSetAssembler::load_barrier_slow_stub(Register reg) {
|
||||
return _load_barrier_slow_stub[reg->encoding()];
|
||||
}
|
||||
|
||||
address ZBarrierSetAssembler::load_barrier_weak_slow_stub(Register reg) {
|
||||
return _load_barrier_weak_slow_stub[reg->encoding()];
|
||||
}
|
||||
#endif // COMPILER2
|
||||
|
@ -24,6 +24,12 @@
|
||||
#ifndef CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP
|
||||
#define CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP
|
||||
|
||||
#include "code/vmreg.hpp"
|
||||
#include "oops/accessDecorators.hpp"
|
||||
#ifdef COMPILER2
|
||||
#include "opto/optoreg.hpp"
|
||||
#endif // COMPILER2
|
||||
|
||||
#ifdef COMPILER1
|
||||
class LIR_Assembler;
|
||||
class LIR_OprDesc;
|
||||
@ -32,14 +38,13 @@ class StubAssembler;
|
||||
class ZLoadBarrierStubC1;
|
||||
#endif // COMPILER1
|
||||
|
||||
#ifdef COMPILER2
|
||||
class Node;
|
||||
class ZLoadBarrierStubC2;
|
||||
#endif // COMPILER2
|
||||
|
||||
class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase {
|
||||
private:
|
||||
address _load_barrier_slow_stub[RegisterImpl::number_of_registers];
|
||||
address _load_barrier_weak_slow_stub[RegisterImpl::number_of_registers];
|
||||
|
||||
public:
|
||||
ZBarrierSetAssembler();
|
||||
|
||||
virtual void load_at(MacroAssembler* masm,
|
||||
DecoratorSet decorators,
|
||||
BasicType type,
|
||||
@ -83,10 +88,13 @@ public:
|
||||
DecoratorSet decorators) const;
|
||||
#endif // COMPILER1
|
||||
|
||||
virtual void barrier_stubs_init();
|
||||
#ifdef COMPILER2
|
||||
OptoReg::Name refine_register(const Node* node,
|
||||
OptoReg::Name opto_reg);
|
||||
|
||||
address load_barrier_slow_stub(Register reg);
|
||||
address load_barrier_weak_slow_stub(Register reg);
|
||||
void generate_c2_load_barrier_stub(MacroAssembler* masm,
|
||||
ZLoadBarrierStubC2* stub) const;
|
||||
#endif // COMPILER2
|
||||
};
|
||||
|
||||
#endif // CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP
|
||||
|
@ -24,155 +24,244 @@
|
||||
source_hpp %{
|
||||
|
||||
#include "gc/z/c2/zBarrierSetC2.hpp"
|
||||
#include "gc/z/zThreadLocalData.hpp"
|
||||
|
||||
%}
|
||||
|
||||
source %{
|
||||
|
||||
#include "gc/z/zBarrierSetAssembler.hpp"
|
||||
static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
|
||||
ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, weak);
|
||||
__ ldr(tmp, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(tmp, tmp, ref);
|
||||
__ cbnz(tmp, *stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
static void z_load_barrier_slow_reg(MacroAssembler& _masm, Register dst,
|
||||
Register base, int index, int scale,
|
||||
int disp, bool weak) {
|
||||
const address stub = weak ? ZBarrierSet::assembler()->load_barrier_weak_slow_stub(dst)
|
||||
: ZBarrierSet::assembler()->load_barrier_slow_stub(dst);
|
||||
|
||||
if (index == -1) {
|
||||
if (disp != 0) {
|
||||
__ lea(dst, Address(base, disp));
|
||||
} else {
|
||||
__ mov(dst, base);
|
||||
}
|
||||
} else {
|
||||
Register index_reg = as_Register(index);
|
||||
if (disp == 0) {
|
||||
__ lea(dst, Address(base, index_reg, Address::lsl(scale)));
|
||||
} else {
|
||||
__ lea(dst, Address(base, disp));
|
||||
__ lea(dst, Address(dst, index_reg, Address::lsl(scale)));
|
||||
}
|
||||
}
|
||||
|
||||
__ far_call(RuntimeAddress(stub));
|
||||
static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) {
|
||||
ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, false /* weak */);
|
||||
__ b(*stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
//
|
||||
// Execute ZGC load barrier (strong) slow path
|
||||
//
|
||||
instruct loadBarrierSlowReg(iRegP dst, memory src, rFlagsReg cr,
|
||||
vRegD_V0 v0, vRegD_V1 v1, vRegD_V2 v2, vRegD_V3 v3, vRegD_V4 v4,
|
||||
vRegD_V5 v5, vRegD_V6 v6, vRegD_V7 v7, vRegD_V8 v8, vRegD_V9 v9,
|
||||
vRegD_V10 v10, vRegD_V11 v11, vRegD_V12 v12, vRegD_V13 v13, vRegD_V14 v14,
|
||||
vRegD_V15 v15, vRegD_V16 v16, vRegD_V17 v17, vRegD_V18 v18, vRegD_V19 v19,
|
||||
vRegD_V20 v20, vRegD_V21 v21, vRegD_V22 v22, vRegD_V23 v23, vRegD_V24 v24,
|
||||
vRegD_V25 v25, vRegD_V26 v26, vRegD_V27 v27, vRegD_V28 v28, vRegD_V29 v29,
|
||||
vRegD_V30 v30, vRegD_V31 v31) %{
|
||||
match(Set dst (LoadBarrierSlowReg src dst));
|
||||
predicate(!n->as_LoadBarrierSlowReg()->is_weak());
|
||||
// Load Pointer
|
||||
instruct zLoadP(iRegPNoSp dst, memory mem, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierStrong));
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
||||
effect(KILL cr,
|
||||
KILL v0, KILL v1, KILL v2, KILL v3, KILL v4, KILL v5, KILL v6, KILL v7,
|
||||
KILL v8, KILL v9, KILL v10, KILL v11, KILL v12, KILL v13, KILL v14,
|
||||
KILL v15, KILL v16, KILL v17, KILL v18, KILL v19, KILL v20, KILL v21,
|
||||
KILL v22, KILL v23, KILL v24, KILL v25, KILL v26, KILL v27, KILL v28,
|
||||
KILL v29, KILL v30, KILL v31);
|
||||
ins_cost(4 * INSN_COST);
|
||||
|
||||
format %{ "lea $dst, $src\n\t"
|
||||
"call #ZLoadBarrierSlowPath" %}
|
||||
format %{ "ldr $dst, $mem" %}
|
||||
|
||||
ins_encode %{
|
||||
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$base$$Register,
|
||||
$src$$index, $src$$scale, $src$$disp, false);
|
||||
const Address ref_addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
|
||||
__ ldr($dst$$Register, ref_addr);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
z_load_barrier(_masm, this, ref_addr, $dst$$Register, rscratch2 /* tmp */, false /* weak */);
|
||||
}
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
|
||||
ins_pipe(iload_reg_mem);
|
||||
%}
|
||||
|
||||
//
|
||||
// Execute ZGC load barrier (weak) slow path
|
||||
//
|
||||
instruct loadBarrierWeakSlowReg(iRegP dst, memory src, rFlagsReg cr,
|
||||
vRegD_V0 v0, vRegD_V1 v1, vRegD_V2 v2, vRegD_V3 v3, vRegD_V4 v4,
|
||||
vRegD_V5 v5, vRegD_V6 v6, vRegD_V7 v7, vRegD_V8 v8, vRegD_V9 v9,
|
||||
vRegD_V10 v10, vRegD_V11 v11, vRegD_V12 v12, vRegD_V13 v13, vRegD_V14 v14,
|
||||
vRegD_V15 v15, vRegD_V16 v16, vRegD_V17 v17, vRegD_V18 v18, vRegD_V19 v19,
|
||||
vRegD_V20 v20, vRegD_V21 v21, vRegD_V22 v22, vRegD_V23 v23, vRegD_V24 v24,
|
||||
vRegD_V25 v25, vRegD_V26 v26, vRegD_V27 v27, vRegD_V28 v28, vRegD_V29 v29,
|
||||
vRegD_V30 v30, vRegD_V31 v31) %{
|
||||
match(Set dst (LoadBarrierSlowReg src dst));
|
||||
predicate(n->as_LoadBarrierSlowReg()->is_weak());
|
||||
// Load Weak Pointer
|
||||
instruct zLoadWeakP(iRegPNoSp dst, memory mem, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierWeak));
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
||||
effect(KILL cr,
|
||||
KILL v0, KILL v1, KILL v2, KILL v3, KILL v4, KILL v5, KILL v6, KILL v7,
|
||||
KILL v8, KILL v9, KILL v10, KILL v11, KILL v12, KILL v13, KILL v14,
|
||||
KILL v15, KILL v16, KILL v17, KILL v18, KILL v19, KILL v20, KILL v21,
|
||||
KILL v22, KILL v23, KILL v24, KILL v25, KILL v26, KILL v27, KILL v28,
|
||||
KILL v29, KILL v30, KILL v31);
|
||||
ins_cost(4 * INSN_COST);
|
||||
|
||||
format %{ "lea $dst, $src\n\t"
|
||||
"call #ZLoadBarrierSlowPath" %}
|
||||
format %{ "ldr $dst, $mem" %}
|
||||
|
||||
ins_encode %{
|
||||
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$base$$Register,
|
||||
$src$$index, $src$$scale, $src$$disp, true);
|
||||
const Address ref_addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
|
||||
__ ldr($dst$$Register, ref_addr);
|
||||
z_load_barrier(_masm, this, ref_addr, $dst$$Register, rscratch2 /* tmp */, true /* weak */);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
|
||||
ins_pipe(iload_reg_mem);
|
||||
%}
|
||||
|
||||
// Load Pointer Volatile
|
||||
instruct zLoadPVolatile(iRegPNoSp dst, indirect mem /* sync_memory */, rFlagsReg cr)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(UseZGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() == ZLoadBarrierStrong);
|
||||
effect(TEMP dst, KILL cr);
|
||||
|
||||
// Specialized versions of compareAndExchangeP that adds a keepalive that is consumed
|
||||
// but doesn't affect output.
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
|
||||
format %{ "ldar $dst, $mem\t" %}
|
||||
|
||||
ins_encode %{
|
||||
__ ldar($dst$$Register, $mem$$Register);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
z_load_barrier(_masm, this, Address($mem$$Register), $dst$$Register, rscratch2 /* tmp */, false /* weak */);
|
||||
}
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
|
||||
effect(KILL cr, TEMP_DEF res);
|
||||
|
||||
instruct z_compareAndExchangeP(iRegPNoSp res, indirect mem,
|
||||
iRegP oldval, iRegP newval, iRegP keepalive,
|
||||
rFlagsReg cr) %{
|
||||
match(Set res (ZCompareAndExchangeP (Binary mem keepalive) (Binary oldval newval)));
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "cmpxchg $mem, $oldval, $newval\n\t"
|
||||
"cset $res, EQ" %}
|
||||
|
||||
ins_encode %{
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
|
||||
false /* acquire */, true /* release */, false /* weak */, rscratch2);
|
||||
__ cset($res$$Register, Assembler::EQ);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
Label good;
|
||||
__ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(rscratch1, rscratch1, rscratch2);
|
||||
__ cbz(rscratch1, good);
|
||||
z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
|
||||
false /* acquire */, true /* release */, false /* weak */, rscratch2);
|
||||
__ cset($res$$Register, Assembler::EQ);
|
||||
__ bind(good);
|
||||
}
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong));
|
||||
effect(KILL cr, TEMP_DEF res);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "cmpxchg $mem, $oldval, $newval\n\t"
|
||||
"cset $res, EQ" %}
|
||||
|
||||
ins_encode %{
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
|
||||
true /* acquire */, true /* release */, false /* weak */, rscratch2);
|
||||
__ cset($res$$Register, Assembler::EQ);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
Label good;
|
||||
__ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(rscratch1, rscratch1, rscratch2);
|
||||
__ cbz(rscratch1, good);
|
||||
z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */ );
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
|
||||
true /* acquire */, true /* release */, false /* weak */, rscratch2);
|
||||
__ cset($res$$Register, Assembler::EQ);
|
||||
__ bind(good);
|
||||
}
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
|
||||
effect(TEMP_DEF res, KILL cr);
|
||||
format %{
|
||||
"cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
|
||||
%}
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "cmpxchg $res = $mem, $oldval, $newval" %}
|
||||
|
||||
ins_encode %{
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
|
||||
Assembler::xword, /*acquire*/ false, /*release*/ true,
|
||||
/*weak*/ false, $res$$Register);
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
|
||||
false /* acquire */, true /* release */, false /* weak */, $res$$Register);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
Label good;
|
||||
__ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(rscratch1, rscratch1, $res$$Register);
|
||||
__ cbz(rscratch1, good);
|
||||
z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
|
||||
false /* acquire */, true /* release */, false /* weak */, $res$$Register);
|
||||
__ bind(good);
|
||||
}
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct z_compareAndSwapP(iRegINoSp res,
|
||||
indirect mem,
|
||||
iRegP oldval, iRegP newval, iRegP keepalive,
|
||||
rFlagsReg cr) %{
|
||||
|
||||
match(Set res (ZCompareAndSwapP (Binary mem keepalive) (Binary oldval newval)));
|
||||
match(Set res (ZWeakCompareAndSwapP (Binary mem keepalive) (Binary oldval newval)));
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
effect(KILL cr);
|
||||
|
||||
format %{
|
||||
"cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
|
||||
"cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
|
||||
%}
|
||||
|
||||
ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
|
||||
aarch64_enc_cset_eq(res));
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
|
||||
instruct z_get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev,
|
||||
iRegP keepalive) %{
|
||||
match(Set prev (ZGetAndSetP mem (Binary newv keepalive)));
|
||||
instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
|
||||
match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
|
||||
effect(TEMP_DEF res, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "cmpxchg $res = $mem, $oldval, $newval" %}
|
||||
|
||||
ins_encode %{
|
||||
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
|
||||
true /* acquire */, true /* release */, false /* weak */, $res$$Register);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
Label good;
|
||||
__ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
|
||||
__ andr(rscratch1, rscratch1, $res$$Register);
|
||||
__ cbz(rscratch1, good);
|
||||
z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
|
||||
__ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
|
||||
true /* acquire */, true /* release */, false /* weak */, $res$$Register);
|
||||
__ bind(good);
|
||||
}
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_slow);
|
||||
%}
|
||||
|
||||
instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
|
||||
ins_cost(2 * VOLATILE_REF_COST);
|
||||
|
||||
format %{ "atomic_xchg $prev, $newv, [$mem]" %}
|
||||
|
||||
ins_encode %{
|
||||
__ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
|
||||
__ atomic_xchg($prev$$Register, $newv$$Register, $mem$$Register);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, rscratch2 /* tmp */, false /* weak */);
|
||||
}
|
||||
%}
|
||||
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
||||
instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
|
||||
match(Set prev (GetAndSetP mem newv));
|
||||
predicate(UseZGC && needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong));
|
||||
effect(TEMP_DEF prev, KILL cr);
|
||||
|
||||
ins_cost(VOLATILE_REF_COST);
|
||||
|
||||
format %{ "atomic_xchg_acq $prev, $newv, [$mem]" %}
|
||||
|
||||
ins_encode %{
|
||||
__ atomic_xchgal($prev$$Register, $newv$$Register, $mem$$Register);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, rscratch2 /* tmp */, false /* weak */);
|
||||
}
|
||||
%}
|
||||
ins_pipe(pipe_serial);
|
||||
%}
|
||||
|
@ -2132,6 +2132,65 @@ int MacroAssembler::pop(unsigned int bitset, Register stack) {
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Push lots of registers in the bit set supplied. Don't push sp.
|
||||
// Return the number of words pushed
|
||||
int MacroAssembler::push_fp(unsigned int bitset, Register stack) {
|
||||
int words_pushed = 0;
|
||||
|
||||
// Scan bitset to accumulate register pairs
|
||||
unsigned char regs[32];
|
||||
int count = 0;
|
||||
for (int reg = 0; reg <= 31; reg++) {
|
||||
if (1 & bitset)
|
||||
regs[count++] = reg;
|
||||
bitset >>= 1;
|
||||
}
|
||||
regs[count++] = zr->encoding_nocheck();
|
||||
count &= ~1; // Only push an even number of regs
|
||||
|
||||
// Always pushing full 128 bit registers.
|
||||
if (count) {
|
||||
stpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(pre(stack, -count * wordSize * 2)));
|
||||
words_pushed += 2;
|
||||
}
|
||||
for (int i = 2; i < count; i += 2) {
|
||||
stpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
|
||||
words_pushed += 2;
|
||||
}
|
||||
|
||||
assert(words_pushed == count, "oops, pushed != count");
|
||||
return count;
|
||||
}
|
||||
|
||||
int MacroAssembler::pop_fp(unsigned int bitset, Register stack) {
|
||||
int words_pushed = 0;
|
||||
|
||||
// Scan bitset to accumulate register pairs
|
||||
unsigned char regs[32];
|
||||
int count = 0;
|
||||
for (int reg = 0; reg <= 31; reg++) {
|
||||
if (1 & bitset)
|
||||
regs[count++] = reg;
|
||||
bitset >>= 1;
|
||||
}
|
||||
regs[count++] = zr->encoding_nocheck();
|
||||
count &= ~1;
|
||||
|
||||
for (int i = 2; i < count; i += 2) {
|
||||
ldpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
|
||||
words_pushed += 2;
|
||||
}
|
||||
if (count) {
|
||||
ldpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(post(stack, count * wordSize * 2)));
|
||||
words_pushed += 2;
|
||||
}
|
||||
|
||||
assert(words_pushed == count, "oops, pushed != count");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void MacroAssembler::verify_heapbase(const char* msg) {
|
||||
#if 0
|
||||
|
@ -442,12 +442,18 @@ private:
|
||||
int push(unsigned int bitset, Register stack);
|
||||
int pop(unsigned int bitset, Register stack);
|
||||
|
||||
int push_fp(unsigned int bitset, Register stack);
|
||||
int pop_fp(unsigned int bitset, Register stack);
|
||||
|
||||
void mov(Register dst, Address a);
|
||||
|
||||
public:
|
||||
void push(RegSet regs, Register stack) { if (regs.bits()) push(regs.bits(), stack); }
|
||||
void pop(RegSet regs, Register stack) { if (regs.bits()) pop(regs.bits(), stack); }
|
||||
|
||||
void push_fp(RegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); }
|
||||
void pop_fp(RegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); }
|
||||
|
||||
// Push and pop everything that might be clobbered by a native
|
||||
// runtime call except rscratch1 and rscratch2. (They are always
|
||||
// scratch, so we don't have to protect them.) Only save the lower
|
||||
|
@ -332,9 +332,14 @@ address NativeJump::jump_destination() const {
|
||||
|
||||
// We use jump to self as the unresolved address which the inline
|
||||
// cache code (and relocs) know about
|
||||
// As a special case we also use sequence movptr(r,0); br(r);
|
||||
// i.e. jump to 0 when we need leave space for a wide immediate
|
||||
// load
|
||||
|
||||
// return -1 if jump to self
|
||||
dest = (dest == (address) this) ? (address) -1 : dest;
|
||||
// return -1 if jump to self or to 0
|
||||
if ((dest == (address)this) || dest == 0) {
|
||||
dest = (address) -1;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
@ -356,9 +361,13 @@ address NativeGeneralJump::jump_destination() const {
|
||||
|
||||
// We use jump to self as the unresolved address which the inline
|
||||
// cache code (and relocs) know about
|
||||
// As a special case we also use jump to 0 when first generating
|
||||
// a general jump
|
||||
|
||||
// return -1 if jump to self
|
||||
dest = (dest == (address) this) ? (address) -1 : dest;
|
||||
// return -1 if jump to self or to 0
|
||||
if ((dest == (address)this) || dest == 0) {
|
||||
dest = (address) -1;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
RegSet &operator-=(const RegSet aSet) {
|
||||
*this = *this - aSet;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static RegSet of(Register r1) {
|
||||
return RegSet(r1);
|
||||
}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/vframeArray.hpp"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "interpreter/bytecode.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "oops/constMethod.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -115,16 +115,7 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
// Creation also verifies the object.
|
||||
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
|
||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
||||
|
||||
#ifdef ASSERT
|
||||
// read the value once
|
||||
volatile intptr_t data = method_holder->data();
|
||||
volatile address destination = jump->jump_destination();
|
||||
assert(data == 0 || data == (intptr_t)callee(),
|
||||
"a) MT-unsafe modification of inline cache");
|
||||
assert(destination == (address)-1 || destination == entry,
|
||||
"b) MT-unsafe modification of inline cache");
|
||||
#endif
|
||||
verify_mt_safe(callee, entry, method_holder, jump);
|
||||
|
||||
// Update stub.
|
||||
method_holder->set_data((intptr_t)callee());
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/vframeArray.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "oops/constMethod.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -178,15 +178,7 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub);
|
||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
||||
|
||||
#ifdef ASSERT
|
||||
// read the value once
|
||||
volatile intptr_t data = method_holder->data();
|
||||
volatile address destination = jump->jump_destination();
|
||||
assert(data == 0 || data == (intptr_t)callee(),
|
||||
"a) MT-unsafe modification of inline cache");
|
||||
assert(destination == (address)-1 || destination == entry,
|
||||
"b) MT-unsafe modification of inline cache");
|
||||
#endif
|
||||
verify_mt_safe(callee, entry, method_holder, jump);
|
||||
|
||||
// Update stub.
|
||||
method_holder->set_data((intptr_t)callee());
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "nativeInst_ppc.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/biasedLocking.hpp"
|
||||
#include "runtime/icache.hpp"
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "interpreter/interp_masm.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/vframeArray.hpp"
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "interpreter/templateInterpreter.hpp"
|
||||
#include "interpreter/templateTable.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/klassVtable.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "vmreg_ppc.inline.hpp"
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "oops/constMethod.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -104,19 +104,7 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
// Creation also verifies the object.
|
||||
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + NativeCall::get_IC_pos_in_java_to_interp_stub());
|
||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
||||
|
||||
#ifdef ASSERT
|
||||
// A generated lambda form might be deleted from the Lambdaform
|
||||
// cache in MethodTypeForm. If a jit compiled lambdaform method
|
||||
// becomes not entrant and the cache access returns null, the new
|
||||
// resolve will lead to a new generated LambdaForm.
|
||||
volatile intptr_t data = method_holder->data();
|
||||
volatile address destination = jump->jump_destination();
|
||||
assert(data == 0 || data == (intptr_t)callee() || callee->is_compiled_lambda_form(),
|
||||
"a) MT-unsafe modification of inline cache");
|
||||
assert(destination == (address)-1 || destination == entry,
|
||||
"b) MT-unsafe modification of inline cache");
|
||||
#endif
|
||||
verify_mt_safe(callee, entry, method_holder, jump);
|
||||
|
||||
// Update stub.
|
||||
method_holder->set_data((intptr_t)callee(), relocInfo::metadata_type);
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "interpreter/interp_masm.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "registerSaver_s390.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/klassVtable.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "vmreg_s390.inline.hpp"
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "oops/constMethod.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -104,16 +104,7 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
// Creation also verifies the object.
|
||||
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
|
||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
||||
|
||||
#ifdef ASSERT
|
||||
// read the value once
|
||||
volatile intptr_t data = method_holder->data();
|
||||
volatile address destination = jump->jump_destination();
|
||||
assert(data == 0 || data == (intptr_t)callee(),
|
||||
"a) MT-unsafe modification of inline cache");
|
||||
assert(destination == (address)-1 || destination == entry,
|
||||
"b) MT-unsafe modification of inline cache");
|
||||
#endif
|
||||
verify_mt_safe(callee, entry, method_holder, jump);
|
||||
|
||||
// Update stub.
|
||||
method_holder->set_data((intptr_t)callee());
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/vframeArray.hpp"
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "ci/ciMethod.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -157,16 +157,7 @@ void CompiledDirectStaticCall::set_to_interpreted(const methodHandle& callee, ad
|
||||
// Creation also verifies the object.
|
||||
NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
|
||||
NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
|
||||
|
||||
#ifdef ASSERT
|
||||
Method* old_method = reinterpret_cast<Method*>(method_holder->data());
|
||||
address destination = jump->jump_destination();
|
||||
assert(old_method == NULL || old_method == callee() ||
|
||||
!old_method->method_holder()->is_loader_alive(),
|
||||
"a) MT-unsafe modification of inline cache");
|
||||
assert(destination == (address)-1 || destination == entry,
|
||||
"b) MT-unsafe modification of inline cache");
|
||||
#endif
|
||||
verify_mt_safe(callee, entry, method_holder, jump);
|
||||
|
||||
// Update stub.
|
||||
method_holder->set_data((intptr_t)callee());
|
||||
|
@ -23,20 +23,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/z/zArguments.hpp"
|
||||
#include "runtime/globals.hpp"
|
||||
#include "runtime/globals_extension.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
|
||||
void ZArguments::initialize_platform() {
|
||||
#ifdef COMPILER2
|
||||
// The C2 barrier slow path expects vector registers to be least
|
||||
// 16 bytes wide, which is the minimum width available on all
|
||||
// x86-64 systems. However, the user could have speficied a lower
|
||||
// number on the command-line, in which case we print a warning
|
||||
// and raise it to 16.
|
||||
if (MaxVectorSize < 16) {
|
||||
warning("ZGC requires MaxVectorSize to be at least 16");
|
||||
FLAG_SET_DEFAULT(MaxVectorSize, 16);
|
||||
}
|
||||
#endif
|
||||
// Does nothing
|
||||
}
|
||||
|
@ -24,22 +24,22 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.inline.hpp"
|
||||
#include "code/codeBlob.hpp"
|
||||
#include "code/vmreg.inline.hpp"
|
||||
#include "gc/z/zBarrier.inline.hpp"
|
||||
#include "gc/z/zBarrierSet.hpp"
|
||||
#include "gc/z/zBarrierSetAssembler.hpp"
|
||||
#include "gc/z/zBarrierSetRuntime.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/stubCodeGenerator.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#ifdef COMPILER1
|
||||
#include "c1/c1_LIRAssembler.hpp"
|
||||
#include "c1/c1_MacroAssembler.hpp"
|
||||
#include "gc/z/c1/zBarrierSetC1.hpp"
|
||||
#endif // COMPILER1
|
||||
|
||||
ZBarrierSetAssembler::ZBarrierSetAssembler() :
|
||||
_load_barrier_slow_stub(),
|
||||
_load_barrier_weak_slow_stub() {}
|
||||
#ifdef COMPILER2
|
||||
#include "gc/z/c2/zBarrierSetC2.hpp"
|
||||
#endif // COMPILER2
|
||||
|
||||
#ifdef PRODUCT
|
||||
#define BLOCK_COMMENT(str) /* nothing */
|
||||
@ -344,137 +344,327 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler*
|
||||
|
||||
#endif // COMPILER1
|
||||
|
||||
#ifdef COMPILER2
|
||||
|
||||
OptoReg::Name ZBarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
|
||||
if (!OptoReg::is_reg(opto_reg)) {
|
||||
return OptoReg::Bad;
|
||||
}
|
||||
|
||||
const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
|
||||
if (vm_reg->is_XMMRegister()) {
|
||||
opto_reg &= ~15;
|
||||
switch (node->ideal_reg()) {
|
||||
case Op_VecX:
|
||||
opto_reg |= 2;
|
||||
break;
|
||||
case Op_VecY:
|
||||
opto_reg |= 4;
|
||||
break;
|
||||
case Op_VecZ:
|
||||
opto_reg |= 8;
|
||||
break;
|
||||
default:
|
||||
opto_reg |= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return opto_reg;
|
||||
}
|
||||
|
||||
// We use the vec_spill_helper from the x86.ad file to avoid reinventing this wheel
|
||||
extern int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
|
||||
int stack_offset, int reg, uint ireg, outputStream* st);
|
||||
|
||||
#undef __
|
||||
#define __ cgen->assembler()->
|
||||
#define __ _masm->
|
||||
|
||||
// Generates a register specific stub for calling
|
||||
// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
|
||||
// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
|
||||
//
|
||||
// The raddr register serves as both input and output for this stub. When the stub is
|
||||
// called the raddr register contains the object field address (oop*) where the bad oop
|
||||
// was loaded from, which caused the slow path to be taken. On return from the stub the
|
||||
// raddr register contains the good/healed oop returned from
|
||||
// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
|
||||
// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
|
||||
static address generate_load_barrier_stub(StubCodeGenerator* cgen, Register raddr, DecoratorSet decorators) {
|
||||
// Don't generate stub for invalid registers
|
||||
if (raddr == rsp || raddr == r15) {
|
||||
return NULL;
|
||||
class ZSaveLiveRegisters {
|
||||
private:
|
||||
struct XMMRegisterData {
|
||||
XMMRegister _reg;
|
||||
int _size;
|
||||
|
||||
// Used by GrowableArray::find()
|
||||
bool operator == (const XMMRegisterData& other) {
|
||||
return _reg == other._reg;
|
||||
}
|
||||
};
|
||||
|
||||
MacroAssembler* const _masm;
|
||||
GrowableArray<Register> _gp_registers;
|
||||
GrowableArray<XMMRegisterData> _xmm_registers;
|
||||
int _spill_size;
|
||||
int _spill_offset;
|
||||
|
||||
static int xmm_compare_register_size(XMMRegisterData* left, XMMRegisterData* right) {
|
||||
if (left->_size == right->_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (left->_size < right->_size) ? -1 : 1;
|
||||
}
|
||||
|
||||
// Create stub name
|
||||
char name[64];
|
||||
const bool weak = (decorators & ON_WEAK_OOP_REF) != 0;
|
||||
os::snprintf(name, sizeof(name), "zgc_load_barrier%s_stub_%s", weak ? "_weak" : "", raddr->name());
|
||||
|
||||
__ align(CodeEntryAlignment);
|
||||
StubCodeMark mark(cgen, "StubRoutines", os::strdup(name, mtCode));
|
||||
address start = __ pc();
|
||||
|
||||
// Save live registers
|
||||
if (raddr != rax) {
|
||||
__ push(rax);
|
||||
}
|
||||
if (raddr != rcx) {
|
||||
__ push(rcx);
|
||||
}
|
||||
if (raddr != rdx) {
|
||||
__ push(rdx);
|
||||
}
|
||||
if (raddr != rsi) {
|
||||
__ push(rsi);
|
||||
}
|
||||
if (raddr != rdi) {
|
||||
__ push(rdi);
|
||||
}
|
||||
if (raddr != r8) {
|
||||
__ push(r8);
|
||||
}
|
||||
if (raddr != r9) {
|
||||
__ push(r9);
|
||||
}
|
||||
if (raddr != r10) {
|
||||
__ push(r10);
|
||||
}
|
||||
if (raddr != r11) {
|
||||
__ push(r11);
|
||||
static int xmm_slot_size(OptoReg::Name opto_reg) {
|
||||
// The low order 4 bytes denote what size of the XMM register is live
|
||||
return (opto_reg & 15) << 3;
|
||||
}
|
||||
|
||||
// Setup arguments
|
||||
if (raddr != c_rarg1) {
|
||||
__ movq(c_rarg1, raddr);
|
||||
}
|
||||
__ movq(c_rarg0, Address(raddr, 0));
|
||||
|
||||
// Call barrier function
|
||||
__ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), c_rarg0, c_rarg1);
|
||||
|
||||
// Move result returned in rax to raddr, if needed
|
||||
if (raddr != rax) {
|
||||
__ movq(raddr, rax);
|
||||
static uint xmm_ideal_reg_for_size(int reg_size) {
|
||||
switch (reg_size) {
|
||||
case 8:
|
||||
return Op_VecD;
|
||||
case 16:
|
||||
return Op_VecX;
|
||||
case 32:
|
||||
return Op_VecY;
|
||||
case 64:
|
||||
return Op_VecZ;
|
||||
default:
|
||||
fatal("Invalid register size %d", reg_size);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore saved registers
|
||||
if (raddr != r11) {
|
||||
__ pop(r11);
|
||||
}
|
||||
if (raddr != r10) {
|
||||
__ pop(r10);
|
||||
}
|
||||
if (raddr != r9) {
|
||||
__ pop(r9);
|
||||
}
|
||||
if (raddr != r8) {
|
||||
__ pop(r8);
|
||||
}
|
||||
if (raddr != rdi) {
|
||||
__ pop(rdi);
|
||||
}
|
||||
if (raddr != rsi) {
|
||||
__ pop(rsi);
|
||||
}
|
||||
if (raddr != rdx) {
|
||||
__ pop(rdx);
|
||||
}
|
||||
if (raddr != rcx) {
|
||||
__ pop(rcx);
|
||||
}
|
||||
if (raddr != rax) {
|
||||
__ pop(rax);
|
||||
bool xmm_needs_vzeroupper() const {
|
||||
return _xmm_registers.is_nonempty() && _xmm_registers.at(0)._size > 16;
|
||||
}
|
||||
|
||||
__ ret(0);
|
||||
void xmm_register_save(const XMMRegisterData& reg_data) {
|
||||
const OptoReg::Name opto_reg = OptoReg::as_OptoReg(reg_data._reg->as_VMReg());
|
||||
const uint ideal_reg = xmm_ideal_reg_for_size(reg_data._size);
|
||||
_spill_offset -= reg_data._size;
|
||||
vec_spill_helper(__ code(), false /* do_size */, false /* is_load */, _spill_offset, opto_reg, ideal_reg, tty);
|
||||
}
|
||||
|
||||
return start;
|
||||
void xmm_register_restore(const XMMRegisterData& reg_data) {
|
||||
const OptoReg::Name opto_reg = OptoReg::as_OptoReg(reg_data._reg->as_VMReg());
|
||||
const uint ideal_reg = xmm_ideal_reg_for_size(reg_data._size);
|
||||
vec_spill_helper(__ code(), false /* do_size */, true /* is_load */, _spill_offset, opto_reg, ideal_reg, tty);
|
||||
_spill_offset += reg_data._size;
|
||||
}
|
||||
|
||||
void gp_register_save(Register reg) {
|
||||
_spill_offset -= 8;
|
||||
__ movq(Address(rsp, _spill_offset), reg);
|
||||
}
|
||||
|
||||
void gp_register_restore(Register reg) {
|
||||
__ movq(reg, Address(rsp, _spill_offset));
|
||||
_spill_offset += 8;
|
||||
}
|
||||
|
||||
void initialize(ZLoadBarrierStubC2* stub) {
|
||||
// Create mask of caller saved registers that need to
|
||||
// be saved/restored if live
|
||||
RegMask caller_saved;
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(rax->as_VMReg()));
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(rcx->as_VMReg()));
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(rdx->as_VMReg()));
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(rsi->as_VMReg()));
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(rdi->as_VMReg()));
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(r8->as_VMReg()));
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(r9->as_VMReg()));
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(r10->as_VMReg()));
|
||||
caller_saved.Insert(OptoReg::as_OptoReg(r11->as_VMReg()));
|
||||
caller_saved.Remove(OptoReg::as_OptoReg(stub->ref()->as_VMReg()));
|
||||
|
||||
// Create mask of live registers
|
||||
RegMask live = stub->live();
|
||||
if (stub->tmp() != noreg) {
|
||||
live.Insert(OptoReg::as_OptoReg(stub->tmp()->as_VMReg()));
|
||||
}
|
||||
|
||||
int gp_spill_size = 0;
|
||||
int xmm_spill_size = 0;
|
||||
|
||||
// Record registers that needs to be saved/restored
|
||||
while (live.is_NotEmpty()) {
|
||||
const OptoReg::Name opto_reg = live.find_first_elem();
|
||||
const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
|
||||
|
||||
live.Remove(opto_reg);
|
||||
|
||||
if (vm_reg->is_Register()) {
|
||||
if (caller_saved.Member(opto_reg)) {
|
||||
_gp_registers.append(vm_reg->as_Register());
|
||||
gp_spill_size += 8;
|
||||
}
|
||||
} else if (vm_reg->is_XMMRegister()) {
|
||||
// We encode in the low order 4 bits of the opto_reg, how large part of the register is live
|
||||
const VMReg vm_reg_base = OptoReg::as_VMReg(opto_reg & ~15);
|
||||
const int reg_size = xmm_slot_size(opto_reg);
|
||||
const XMMRegisterData reg_data = { vm_reg_base->as_XMMRegister(), reg_size };
|
||||
const int reg_index = _xmm_registers.find(reg_data);
|
||||
if (reg_index == -1) {
|
||||
// Not previously appended
|
||||
_xmm_registers.append(reg_data);
|
||||
xmm_spill_size += reg_size;
|
||||
} else {
|
||||
// Previously appended, update size
|
||||
const int reg_size_prev = _xmm_registers.at(reg_index)._size;
|
||||
if (reg_size > reg_size_prev) {
|
||||
_xmm_registers.at_put(reg_index, reg_data);
|
||||
xmm_spill_size += reg_size - reg_size_prev;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fatal("Unexpected register type");
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by size, largest first
|
||||
_xmm_registers.sort(xmm_compare_register_size);
|
||||
|
||||
// Stack pointer must be 16 bytes aligned for the call
|
||||
_spill_offset = _spill_size = align_up(xmm_spill_size + gp_spill_size, 16);
|
||||
}
|
||||
|
||||
public:
|
||||
ZSaveLiveRegisters(MacroAssembler* masm, ZLoadBarrierStubC2* stub) :
|
||||
_masm(masm),
|
||||
_gp_registers(),
|
||||
_xmm_registers(),
|
||||
_spill_size(0),
|
||||
_spill_offset(0) {
|
||||
|
||||
//
|
||||
// Stack layout after registers have been spilled:
|
||||
//
|
||||
// | ... | original rsp, 16 bytes aligned
|
||||
// ------------------
|
||||
// | zmm0 high |
|
||||
// | ... |
|
||||
// | zmm0 low | 16 bytes aligned
|
||||
// | ... |
|
||||
// | ymm1 high |
|
||||
// | ... |
|
||||
// | ymm1 low | 16 bytes aligned
|
||||
// | ... |
|
||||
// | xmmN high |
|
||||
// | ... |
|
||||
// | xmmN low | 8 bytes aligned
|
||||
// | reg0 | 8 bytes aligned
|
||||
// | reg1 |
|
||||
// | ... |
|
||||
// | regN | new rsp, if 16 bytes aligned
|
||||
// | <padding> | else new rsp, 16 bytes aligned
|
||||
// ------------------
|
||||
//
|
||||
|
||||
// Figure out what registers to save/restore
|
||||
initialize(stub);
|
||||
|
||||
// Allocate stack space
|
||||
if (_spill_size > 0) {
|
||||
__ subptr(rsp, _spill_size);
|
||||
}
|
||||
|
||||
// Save XMM/YMM/ZMM registers
|
||||
for (int i = 0; i < _xmm_registers.length(); i++) {
|
||||
xmm_register_save(_xmm_registers.at(i));
|
||||
}
|
||||
|
||||
if (xmm_needs_vzeroupper()) {
|
||||
__ vzeroupper();
|
||||
}
|
||||
|
||||
// Save general purpose registers
|
||||
for (int i = 0; i < _gp_registers.length(); i++) {
|
||||
gp_register_save(_gp_registers.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
~ZSaveLiveRegisters() {
|
||||
// Restore general purpose registers
|
||||
for (int i = _gp_registers.length() - 1; i >= 0; i--) {
|
||||
gp_register_restore(_gp_registers.at(i));
|
||||
}
|
||||
|
||||
__ vzeroupper();
|
||||
|
||||
// Restore XMM/YMM/ZMM registers
|
||||
for (int i = _xmm_registers.length() - 1; i >= 0; i--) {
|
||||
xmm_register_restore(_xmm_registers.at(i));
|
||||
}
|
||||
|
||||
// Free stack space
|
||||
if (_spill_size > 0) {
|
||||
__ addptr(rsp, _spill_size);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ZSetupArguments {
|
||||
private:
|
||||
MacroAssembler* const _masm;
|
||||
const Register _ref;
|
||||
const Address _ref_addr;
|
||||
|
||||
public:
|
||||
ZSetupArguments(MacroAssembler* masm, ZLoadBarrierStubC2* stub) :
|
||||
_masm(masm),
|
||||
_ref(stub->ref()),
|
||||
_ref_addr(stub->ref_addr()) {
|
||||
|
||||
// Setup arguments
|
||||
if (_ref_addr.base() == noreg) {
|
||||
// No self healing
|
||||
if (_ref != c_rarg0) {
|
||||
__ movq(c_rarg0, _ref);
|
||||
}
|
||||
__ xorq(c_rarg1, c_rarg1);
|
||||
} else {
|
||||
// Self healing
|
||||
if (_ref == c_rarg0) {
|
||||
__ lea(c_rarg1, _ref_addr);
|
||||
} else if (_ref != c_rarg1) {
|
||||
__ lea(c_rarg1, _ref_addr);
|
||||
__ movq(c_rarg0, _ref);
|
||||
} else if (_ref_addr.base() != c_rarg0 && _ref_addr.index() != c_rarg0) {
|
||||
__ movq(c_rarg0, _ref);
|
||||
__ lea(c_rarg1, _ref_addr);
|
||||
} else {
|
||||
__ xchgq(c_rarg0, c_rarg1);
|
||||
if (_ref_addr.base() == c_rarg0) {
|
||||
__ lea(c_rarg1, Address(c_rarg1, _ref_addr.index(), _ref_addr.scale(), _ref_addr.disp()));
|
||||
} else if (_ref_addr.index() == c_rarg0) {
|
||||
__ lea(c_rarg1, Address(_ref_addr.base(), c_rarg1, _ref_addr.scale(), _ref_addr.disp()));
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~ZSetupArguments() {
|
||||
// Transfer result
|
||||
if (_ref != rax) {
|
||||
__ movq(_ref, rax);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#undef __
|
||||
#define __ masm->
|
||||
|
||||
void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, ZLoadBarrierStubC2* stub) const {
|
||||
BLOCK_COMMENT("ZLoadBarrierStubC2");
|
||||
|
||||
// Stub entry
|
||||
__ bind(*stub->entry());
|
||||
|
||||
{
|
||||
ZSaveLiveRegisters save_live_registers(masm, stub);
|
||||
ZSetupArguments setup_arguments(masm, stub);
|
||||
__ call(RuntimeAddress(stub->slow_path()));
|
||||
}
|
||||
|
||||
// Stub exit
|
||||
__ jmp(*stub->continuation());
|
||||
}
|
||||
|
||||
#undef __
|
||||
|
||||
static void barrier_stubs_init_inner(const char* label, const DecoratorSet decorators, address* stub) {
|
||||
const int nregs = RegisterImpl::number_of_registers;
|
||||
const int code_size = nregs * 128; // Rough estimate of code size
|
||||
|
||||
ResourceMark rm;
|
||||
|
||||
CodeBuffer buf(BufferBlob::create(label, code_size));
|
||||
StubCodeGenerator cgen(&buf);
|
||||
|
||||
for (int i = 0; i < nregs; i++) {
|
||||
const Register reg = as_Register(i);
|
||||
stub[i] = generate_load_barrier_stub(&cgen, reg, decorators);
|
||||
}
|
||||
}
|
||||
|
||||
void ZBarrierSetAssembler::barrier_stubs_init() {
|
||||
barrier_stubs_init_inner("zgc_load_barrier_stubs", ON_STRONG_OOP_REF, _load_barrier_slow_stub);
|
||||
barrier_stubs_init_inner("zgc_load_barrier_weak_stubs", ON_WEAK_OOP_REF, _load_barrier_weak_slow_stub);
|
||||
}
|
||||
|
||||
address ZBarrierSetAssembler::load_barrier_slow_stub(Register reg) {
|
||||
return _load_barrier_slow_stub[reg->encoding()];
|
||||
}
|
||||
|
||||
address ZBarrierSetAssembler::load_barrier_weak_slow_stub(Register reg) {
|
||||
return _load_barrier_weak_slow_stub[reg->encoding()];
|
||||
}
|
||||
#endif // COMPILER2
|
||||
|
@ -24,6 +24,14 @@
|
||||
#ifndef CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
|
||||
#define CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
|
||||
|
||||
#include "code/vmreg.hpp"
|
||||
#include "oops/accessDecorators.hpp"
|
||||
#ifdef COMPILER2
|
||||
#include "opto/optoreg.hpp"
|
||||
#endif // COMPILER2
|
||||
|
||||
class MacroAssembler;
|
||||
|
||||
#ifdef COMPILER1
|
||||
class LIR_Assembler;
|
||||
class LIR_OprDesc;
|
||||
@ -32,14 +40,13 @@ class StubAssembler;
|
||||
class ZLoadBarrierStubC1;
|
||||
#endif // COMPILER1
|
||||
|
||||
#ifdef COMPILER2
|
||||
class Node;
|
||||
class ZLoadBarrierStubC2;
|
||||
#endif // COMPILER2
|
||||
|
||||
class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase {
|
||||
private:
|
||||
address _load_barrier_slow_stub[RegisterImpl::number_of_registers];
|
||||
address _load_barrier_weak_slow_stub[RegisterImpl::number_of_registers];
|
||||
|
||||
public:
|
||||
ZBarrierSetAssembler();
|
||||
|
||||
virtual void load_at(MacroAssembler* masm,
|
||||
DecoratorSet decorators,
|
||||
BasicType type,
|
||||
@ -82,10 +89,13 @@ public:
|
||||
DecoratorSet decorators) const;
|
||||
#endif // COMPILER1
|
||||
|
||||
virtual void barrier_stubs_init();
|
||||
#ifdef COMPILER2
|
||||
OptoReg::Name refine_register(const Node* node,
|
||||
OptoReg::Name opto_reg);
|
||||
|
||||
address load_barrier_slow_stub(Register reg);
|
||||
address load_barrier_weak_slow_stub(Register reg);
|
||||
void generate_c2_load_barrier_stub(MacroAssembler* masm,
|
||||
ZLoadBarrierStubC2* stub) const;
|
||||
#endif // COMPILER2
|
||||
};
|
||||
|
||||
#endif // CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
|
||||
|
@ -24,190 +24,144 @@
|
||||
source_hpp %{
|
||||
|
||||
#include "gc/z/c2/zBarrierSetC2.hpp"
|
||||
#include "gc/z/zThreadLocalData.hpp"
|
||||
|
||||
%}
|
||||
|
||||
source %{
|
||||
|
||||
#include "gc/z/zBarrierSetAssembler.hpp"
|
||||
static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
|
||||
ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, weak);
|
||||
__ testptr(ref, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
|
||||
__ jcc(Assembler::notZero, *stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
static void z_load_barrier_slow_reg(MacroAssembler& _masm, Register dst, Address src, bool weak) {
|
||||
assert(dst != rsp, "Invalid register");
|
||||
assert(dst != r15, "Invalid register");
|
||||
|
||||
const address stub = weak ? ZBarrierSet::assembler()->load_barrier_weak_slow_stub(dst)
|
||||
: ZBarrierSet::assembler()->load_barrier_slow_stub(dst);
|
||||
__ lea(dst, src);
|
||||
__ call(RuntimeAddress(stub));
|
||||
static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) {
|
||||
ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, false /* weak */);
|
||||
__ jmp(*stub->entry());
|
||||
__ bind(*stub->continuation());
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
// For XMM and YMM enabled processors
|
||||
instruct zLoadBarrierSlowRegXmmAndYmm(rRegP dst, memory src, rFlagsReg cr,
|
||||
rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
|
||||
rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
|
||||
rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
|
||||
rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
|
||||
match(Set dst (LoadBarrierSlowReg src dst));
|
||||
predicate(UseAVX <= 2 && !n->as_LoadBarrierSlowReg()->is_weak());
|
||||
// Load Pointer
|
||||
instruct zLoadP(rRegP dst, memory mem, rFlagsReg cr)
|
||||
%{
|
||||
predicate(UseZGC && n->as_Load()->barrier_data() == ZLoadBarrierStrong);
|
||||
match(Set dst (LoadP mem));
|
||||
effect(KILL cr, TEMP dst);
|
||||
|
||||
effect(KILL cr,
|
||||
KILL x0, KILL x1, KILL x2, KILL x3,
|
||||
KILL x4, KILL x5, KILL x6, KILL x7,
|
||||
KILL x8, KILL x9, KILL x10, KILL x11,
|
||||
KILL x12, KILL x13, KILL x14, KILL x15);
|
||||
ins_cost(125);
|
||||
|
||||
format %{ "lea $dst, $src\n\t"
|
||||
"call #ZLoadBarrierSlowPath" %}
|
||||
format %{ "movq $dst, $mem" %}
|
||||
|
||||
ins_encode %{
|
||||
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, false /* weak */);
|
||||
__ movptr($dst$$Register, $mem$$Address);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
z_load_barrier(_masm, this, $mem$$Address, $dst$$Register, noreg /* tmp */, false /* weak */);
|
||||
}
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// For ZMM enabled processors
|
||||
instruct zLoadBarrierSlowRegZmm(rRegP dst, memory src, rFlagsReg cr,
|
||||
rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
|
||||
rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
|
||||
rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
|
||||
rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
|
||||
rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
|
||||
rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
|
||||
rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
|
||||
rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
|
||||
// Load Weak Pointer
|
||||
instruct zLoadWeakP(rRegP dst, memory mem, rFlagsReg cr)
|
||||
%{
|
||||
predicate(UseZGC && n->as_Load()->barrier_data() == ZLoadBarrierWeak);
|
||||
match(Set dst (LoadP mem));
|
||||
effect(KILL cr, TEMP dst);
|
||||
|
||||
match(Set dst (LoadBarrierSlowReg src dst));
|
||||
predicate(UseAVX == 3 && !n->as_LoadBarrierSlowReg()->is_weak());
|
||||
ins_cost(125);
|
||||
|
||||
effect(KILL cr,
|
||||
KILL x0, KILL x1, KILL x2, KILL x3,
|
||||
KILL x4, KILL x5, KILL x6, KILL x7,
|
||||
KILL x8, KILL x9, KILL x10, KILL x11,
|
||||
KILL x12, KILL x13, KILL x14, KILL x15,
|
||||
KILL x16, KILL x17, KILL x18, KILL x19,
|
||||
KILL x20, KILL x21, KILL x22, KILL x23,
|
||||
KILL x24, KILL x25, KILL x26, KILL x27,
|
||||
KILL x28, KILL x29, KILL x30, KILL x31);
|
||||
|
||||
format %{ "lea $dst, $src\n\t"
|
||||
"call #ZLoadBarrierSlowPath" %}
|
||||
format %{ "movq $dst, $mem" %}
|
||||
|
||||
ins_encode %{
|
||||
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, false /* weak */);
|
||||
__ movptr($dst$$Register, $mem$$Address);
|
||||
z_load_barrier(_masm, this, $mem$$Address, $dst$$Register, noreg /* tmp */, true /* weak */);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
|
||||
ins_pipe(ialu_reg_mem);
|
||||
%}
|
||||
|
||||
// For XMM and YMM enabled processors
|
||||
instruct zLoadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory src, rFlagsReg cr,
|
||||
rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
|
||||
rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
|
||||
rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
|
||||
rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
|
||||
match(Set dst (LoadBarrierSlowReg src dst));
|
||||
predicate(UseAVX <= 2 && n->as_LoadBarrierSlowReg()->is_weak());
|
||||
instruct zCompareAndExchangeP(memory mem, rax_RegP oldval, rRegP newval, rRegP tmp, rFlagsReg cr) %{
|
||||
match(Set oldval (CompareAndExchangeP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
|
||||
effect(KILL cr, TEMP tmp);
|
||||
|
||||
effect(KILL cr,
|
||||
KILL x0, KILL x1, KILL x2, KILL x3,
|
||||
KILL x4, KILL x5, KILL x6, KILL x7,
|
||||
KILL x8, KILL x9, KILL x10, KILL x11,
|
||||
KILL x12, KILL x13, KILL x14, KILL x15);
|
||||
|
||||
format %{ "lea $dst, $src\n\t"
|
||||
"call #ZLoadBarrierSlowPath" %}
|
||||
format %{ "lock\n\t"
|
||||
"cmpxchgq $newval, $mem" %}
|
||||
|
||||
ins_encode %{
|
||||
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, true /* weak */);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
__ movptr($tmp$$Register, $oldval$$Register);
|
||||
}
|
||||
__ lock();
|
||||
__ cmpxchgptr($newval$$Register, $mem$$Address);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
Label good;
|
||||
__ testptr($oldval$$Register, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
|
||||
__ jcc(Assembler::zero, good);
|
||||
z_load_barrier_slow_path(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register);
|
||||
__ movptr($oldval$$Register, $tmp$$Register);
|
||||
__ lock();
|
||||
__ cmpxchgptr($newval$$Register, $mem$$Address);
|
||||
__ bind(good);
|
||||
}
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
|
||||
ins_pipe(pipe_cmpxchg);
|
||||
%}
|
||||
|
||||
// For ZMM enabled processors
|
||||
instruct zLoadBarrierWeakSlowRegZmm(rRegP dst, memory src, rFlagsReg cr,
|
||||
rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
|
||||
rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
|
||||
rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
|
||||
rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
|
||||
rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
|
||||
rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
|
||||
rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
|
||||
rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
|
||||
instruct zCompareAndSwapP(rRegI res, memory mem, rRegP newval, rRegP tmp, rFlagsReg cr, rax_RegP oldval) %{
|
||||
match(Set res (CompareAndSwapP mem (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
|
||||
predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
|
||||
effect(KILL cr, KILL oldval, TEMP tmp);
|
||||
|
||||
match(Set dst (LoadBarrierSlowReg src dst));
|
||||
predicate(UseAVX == 3 && n->as_LoadBarrierSlowReg()->is_weak());
|
||||
|
||||
effect(KILL cr,
|
||||
KILL x0, KILL x1, KILL x2, KILL x3,
|
||||
KILL x4, KILL x5, KILL x6, KILL x7,
|
||||
KILL x8, KILL x9, KILL x10, KILL x11,
|
||||
KILL x12, KILL x13, KILL x14, KILL x15,
|
||||
KILL x16, KILL x17, KILL x18, KILL x19,
|
||||
KILL x20, KILL x21, KILL x22, KILL x23,
|
||||
KILL x24, KILL x25, KILL x26, KILL x27,
|
||||
KILL x28, KILL x29, KILL x30, KILL x31);
|
||||
|
||||
format %{ "lea $dst, $src\n\t"
|
||||
"call #ZLoadBarrierSlowPath" %}
|
||||
format %{ "lock\n\t"
|
||||
"cmpxchgq $newval, $mem\n\t"
|
||||
"sete $res\n\t"
|
||||
"movzbl $res, $res" %}
|
||||
|
||||
ins_encode %{
|
||||
z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, true /* weak */);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
__ movptr($tmp$$Register, $oldval$$Register);
|
||||
}
|
||||
__ lock();
|
||||
__ cmpxchgptr($newval$$Register, $mem$$Address);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
Label good;
|
||||
__ testptr($oldval$$Register, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
|
||||
__ jcc(Assembler::zero, good);
|
||||
z_load_barrier_slow_path(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register);
|
||||
__ movptr($oldval$$Register, $tmp$$Register);
|
||||
__ lock();
|
||||
__ cmpxchgptr($newval$$Register, $mem$$Address);
|
||||
__ bind(good);
|
||||
__ cmpptr($tmp$$Register, $oldval$$Register);
|
||||
}
|
||||
__ setb(Assembler::equal, $res$$Register);
|
||||
__ movzbl($res$$Register, $res$$Register);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
|
||||
ins_pipe(pipe_cmpxchg);
|
||||
%}
|
||||
|
||||
// Specialized versions of compareAndExchangeP that adds a keepalive that is consumed
|
||||
// but doesn't affect output.
|
||||
instruct zXChgP(memory mem, rRegP newval, rFlagsReg cr) %{
|
||||
match(Set newval (GetAndSetP mem newval));
|
||||
predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
|
||||
effect(KILL cr);
|
||||
|
||||
instruct z_compareAndExchangeP(
|
||||
memory mem_ptr,
|
||||
rax_RegP oldval, rRegP newval, rRegP keepalive,
|
||||
rFlagsReg cr) %{
|
||||
predicate(VM_Version::supports_cx8());
|
||||
match(Set oldval (ZCompareAndExchangeP (Binary mem_ptr keepalive) (Binary oldval newval)));
|
||||
effect(KILL cr);
|
||||
format %{ "xchgq $newval, $mem" %}
|
||||
|
||||
format %{ "cmpxchgq $mem_ptr,$newval\t# "
|
||||
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
|
||||
opcode(0x0F, 0xB1);
|
||||
ins_encode(lock_prefix,
|
||||
REX_reg_mem_wide(newval, mem_ptr),
|
||||
OpcP, OpcS,
|
||||
reg_mem(newval, mem_ptr) // lock cmpxchg
|
||||
);
|
||||
ins_pipe( pipe_cmpxchg );
|
||||
%}
|
||||
|
||||
instruct z_compareAndSwapP(rRegI res,
|
||||
memory mem_ptr,
|
||||
rax_RegP oldval, rRegP newval, rRegP keepalive,
|
||||
rFlagsReg cr) %{
|
||||
predicate(VM_Version::supports_cx8());
|
||||
match(Set res (ZCompareAndSwapP (Binary mem_ptr keepalive) (Binary oldval newval)));
|
||||
match(Set res (ZWeakCompareAndSwapP (Binary mem_ptr keepalive) (Binary oldval newval)));
|
||||
effect(KILL cr, KILL oldval);
|
||||
|
||||
format %{ "cmpxchgq $mem_ptr,$newval\t# "
|
||||
"If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
|
||||
"sete $res\n\t"
|
||||
"movzbl $res, $res" %}
|
||||
opcode(0x0F, 0xB1);
|
||||
ins_encode(lock_prefix,
|
||||
REX_reg_mem_wide(newval, mem_ptr),
|
||||
OpcP, OpcS,
|
||||
reg_mem(newval, mem_ptr),
|
||||
REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
|
||||
REX_reg_breg(res, res), // movzbl
|
||||
Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
|
||||
ins_pipe( pipe_cmpxchg );
|
||||
%}
|
||||
|
||||
instruct z_xchgP( memory mem, rRegP newval, rRegP keepalive) %{
|
||||
match(Set newval (ZGetAndSetP mem (Binary newval keepalive)));
|
||||
format %{ "XCHGQ $newval,[$mem]" %}
|
||||
ins_encode %{
|
||||
__ xchgq($newval$$Register, $mem$$Address);
|
||||
__ xchgptr($newval$$Register, $mem$$Address);
|
||||
if (barrier_data() != ZLoadBarrierElided) {
|
||||
z_load_barrier(_masm, this, Address(noreg, 0), $newval$$Register, noreg /* tmp */, false /* weak */);
|
||||
}
|
||||
%}
|
||||
ins_pipe( pipe_cmpxchg );
|
||||
|
||||
ins_pipe(pipe_cmpxchg);
|
||||
%}
|
||||
|
@ -824,11 +824,13 @@ static void pass_arg3(MacroAssembler* masm, Register arg) {
|
||||
}
|
||||
|
||||
void MacroAssembler::stop(const char* msg) {
|
||||
address rip = pc();
|
||||
pusha(); // get regs on stack
|
||||
if (ShowMessageBoxOnError) {
|
||||
address rip = pc();
|
||||
pusha(); // get regs on stack
|
||||
lea(c_rarg1, InternalAddress(rip));
|
||||
movq(c_rarg2, rsp); // pass pointer to regs array
|
||||
}
|
||||
lea(c_rarg0, ExternalAddress((address) msg));
|
||||
lea(c_rarg1, InternalAddress(rip));
|
||||
movq(c_rarg2, rsp); // pass pointer to regs array
|
||||
andq(rsp, -16); // align stack as required by ABI
|
||||
call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64)));
|
||||
hlt();
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/vframeArray.hpp"
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/compiledICHolder.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/safepointMechanism.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/vframeArray.hpp"
|
||||
|
@ -1097,138 +1097,6 @@ reg_class vectorz_reg_legacy(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0
|
||||
reg_class_dynamic vectorz_reg(vectorz_reg_evex, vectorz_reg_legacy, %{ VM_Version::supports_evex() %} );
|
||||
reg_class_dynamic vectorz_reg_vl(vectorz_reg_evex, vectorz_reg_legacy, %{ VM_Version::supports_evex() && VM_Version::supports_avx512vl() %} );
|
||||
|
||||
reg_class xmm0_reg(XMM0, XMM0b, XMM0c, XMM0d);
|
||||
reg_class ymm0_reg(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0g, XMM0h);
|
||||
reg_class zmm0_reg(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0g, XMM0h, XMM0i, XMM0j, XMM0k, XMM0l, XMM0m, XMM0n, XMM0o, XMM0p);
|
||||
|
||||
reg_class xmm1_reg(XMM1, XMM1b, XMM1c, XMM1d);
|
||||
reg_class ymm1_reg(XMM1, XMM1b, XMM1c, XMM1d, XMM1e, XMM1f, XMM1g, XMM1h);
|
||||
reg_class zmm1_reg(XMM1, XMM1b, XMM1c, XMM1d, XMM1e, XMM1f, XMM1g, XMM1h, XMM1i, XMM1j, XMM1k, XMM1l, XMM1m, XMM1n, XMM1o, XMM1p);
|
||||
|
||||
reg_class xmm2_reg(XMM2, XMM2b, XMM2c, XMM2d);
|
||||
reg_class ymm2_reg(XMM2, XMM2b, XMM2c, XMM2d, XMM2e, XMM2f, XMM2g, XMM2h);
|
||||
reg_class zmm2_reg(XMM2, XMM2b, XMM2c, XMM2d, XMM2e, XMM2f, XMM2g, XMM2h, XMM2i, XMM2j, XMM2k, XMM2l, XMM2m, XMM2n, XMM2o, XMM2p);
|
||||
|
||||
reg_class xmm3_reg(XMM3, XMM3b, XMM3c, XMM3d);
|
||||
reg_class ymm3_reg(XMM3, XMM3b, XMM3c, XMM3d, XMM3e, XMM3f, XMM3g, XMM3h);
|
||||
reg_class zmm3_reg(XMM3, XMM3b, XMM3c, XMM3d, XMM3e, XMM3f, XMM3g, XMM3h, XMM3i, XMM3j, XMM3k, XMM3l, XMM3m, XMM3n, XMM3o, XMM3p);
|
||||
|
||||
reg_class xmm4_reg(XMM4, XMM4b, XMM4c, XMM4d);
|
||||
reg_class ymm4_reg(XMM4, XMM4b, XMM4c, XMM4d, XMM4e, XMM4f, XMM4g, XMM4h);
|
||||
reg_class zmm4_reg(XMM4, XMM4b, XMM4c, XMM4d, XMM4e, XMM4f, XMM4g, XMM4h, XMM4i, XMM4j, XMM4k, XMM4l, XMM4m, XMM4n, XMM4o, XMM4p);
|
||||
|
||||
reg_class xmm5_reg(XMM5, XMM5b, XMM5c, XMM5d);
|
||||
reg_class ymm5_reg(XMM5, XMM5b, XMM5c, XMM5d, XMM5e, XMM5f, XMM5g, XMM5h);
|
||||
reg_class zmm5_reg(XMM5, XMM5b, XMM5c, XMM5d, XMM5e, XMM5f, XMM5g, XMM5h, XMM5i, XMM5j, XMM5k, XMM5l, XMM5m, XMM5n, XMM5o, XMM5p);
|
||||
|
||||
reg_class xmm6_reg(XMM6, XMM6b, XMM6c, XMM6d);
|
||||
reg_class ymm6_reg(XMM6, XMM6b, XMM6c, XMM6d, XMM6e, XMM6f, XMM6g, XMM6h);
|
||||
reg_class zmm6_reg(XMM6, XMM6b, XMM6c, XMM6d, XMM6e, XMM6f, XMM6g, XMM6h, XMM6i, XMM6j, XMM6k, XMM6l, XMM6m, XMM6n, XMM6o, XMM6p);
|
||||
|
||||
reg_class xmm7_reg(XMM7, XMM7b, XMM7c, XMM7d);
|
||||
reg_class ymm7_reg(XMM7, XMM7b, XMM7c, XMM7d, XMM7e, XMM7f, XMM7g, XMM7h);
|
||||
reg_class zmm7_reg(XMM7, XMM7b, XMM7c, XMM7d, XMM7e, XMM7f, XMM7g, XMM7h, XMM7i, XMM7j, XMM7k, XMM7l, XMM7m, XMM7n, XMM7o, XMM7p);
|
||||
|
||||
#ifdef _LP64
|
||||
|
||||
reg_class xmm8_reg(XMM8, XMM8b, XMM8c, XMM8d);
|
||||
reg_class ymm8_reg(XMM8, XMM8b, XMM8c, XMM8d, XMM8e, XMM8f, XMM8g, XMM8h);
|
||||
reg_class zmm8_reg(XMM8, XMM8b, XMM8c, XMM8d, XMM8e, XMM8f, XMM8g, XMM8h, XMM8i, XMM8j, XMM8k, XMM8l, XMM8m, XMM8n, XMM8o, XMM8p);
|
||||
|
||||
reg_class xmm9_reg(XMM9, XMM9b, XMM9c, XMM9d);
|
||||
reg_class ymm9_reg(XMM9, XMM9b, XMM9c, XMM9d, XMM9e, XMM9f, XMM9g, XMM9h);
|
||||
reg_class zmm9_reg(XMM9, XMM9b, XMM9c, XMM9d, XMM9e, XMM9f, XMM9g, XMM9h, XMM9i, XMM9j, XMM9k, XMM9l, XMM9m, XMM9n, XMM9o, XMM9p);
|
||||
|
||||
reg_class xmm10_reg(XMM10, XMM10b, XMM10c, XMM10d);
|
||||
reg_class ymm10_reg(XMM10, XMM10b, XMM10c, XMM10d, XMM10e, XMM10f, XMM10g, XMM10h);
|
||||
reg_class zmm10_reg(XMM10, XMM10b, XMM10c, XMM10d, XMM10e, XMM10f, XMM10g, XMM10h, XMM10i, XMM10j, XMM10k, XMM10l, XMM10m, XMM10n, XMM10o, XMM10p);
|
||||
|
||||
reg_class xmm11_reg(XMM11, XMM11b, XMM11c, XMM11d);
|
||||
reg_class ymm11_reg(XMM11, XMM11b, XMM11c, XMM11d, XMM11e, XMM11f, XMM11g, XMM11h);
|
||||
reg_class zmm11_reg(XMM11, XMM11b, XMM11c, XMM11d, XMM11e, XMM11f, XMM11g, XMM11h, XMM11i, XMM11j, XMM11k, XMM11l, XMM11m, XMM11n, XMM11o, XMM11p);
|
||||
|
||||
reg_class xmm12_reg(XMM12, XMM12b, XMM12c, XMM12d);
|
||||
reg_class ymm12_reg(XMM12, XMM12b, XMM12c, XMM12d, XMM12e, XMM12f, XMM12g, XMM12h);
|
||||
reg_class zmm12_reg(XMM12, XMM12b, XMM12c, XMM12d, XMM12e, XMM12f, XMM12g, XMM12h, XMM12i, XMM12j, XMM12k, XMM12l, XMM12m, XMM12n, XMM12o, XMM12p);
|
||||
|
||||
reg_class xmm13_reg(XMM13, XMM13b, XMM13c, XMM13d);
|
||||
reg_class ymm13_reg(XMM13, XMM13b, XMM13c, XMM13d, XMM13e, XMM13f, XMM13g, XMM13h);
|
||||
reg_class zmm13_reg(XMM13, XMM13b, XMM13c, XMM13d, XMM13e, XMM13f, XMM13g, XMM13h, XMM13i, XMM13j, XMM13k, XMM13l, XMM13m, XMM13n, XMM13o, XMM13p);
|
||||
|
||||
reg_class xmm14_reg(XMM14, XMM14b, XMM14c, XMM14d);
|
||||
reg_class ymm14_reg(XMM14, XMM14b, XMM14c, XMM14d, XMM14e, XMM14f, XMM14g, XMM14h);
|
||||
reg_class zmm14_reg(XMM14, XMM14b, XMM14c, XMM14d, XMM14e, XMM14f, XMM14g, XMM14h, XMM14i, XMM14j, XMM14k, XMM14l, XMM14m, XMM14n, XMM14o, XMM14p);
|
||||
|
||||
reg_class xmm15_reg(XMM15, XMM15b, XMM15c, XMM15d);
|
||||
reg_class ymm15_reg(XMM15, XMM15b, XMM15c, XMM15d, XMM15e, XMM15f, XMM15g, XMM15h);
|
||||
reg_class zmm15_reg(XMM15, XMM15b, XMM15c, XMM15d, XMM15e, XMM15f, XMM15g, XMM15h, XMM15i, XMM15j, XMM15k, XMM15l, XMM15m, XMM15n, XMM15o, XMM15p);
|
||||
|
||||
reg_class xmm16_reg(XMM16, XMM16b, XMM16c, XMM16d);
|
||||
reg_class ymm16_reg(XMM16, XMM16b, XMM16c, XMM16d, XMM16e, XMM16f, XMM16g, XMM16h);
|
||||
reg_class zmm16_reg(XMM16, XMM16b, XMM16c, XMM16d, XMM16e, XMM16f, XMM16g, XMM16h, XMM16i, XMM16j, XMM16k, XMM16l, XMM16m, XMM16n, XMM16o, XMM16p);
|
||||
|
||||
reg_class xmm17_reg(XMM17, XMM17b, XMM17c, XMM17d);
|
||||
reg_class ymm17_reg(XMM17, XMM17b, XMM17c, XMM17d, XMM17e, XMM17f, XMM17g, XMM17h);
|
||||
reg_class zmm17_reg(XMM17, XMM17b, XMM17c, XMM17d, XMM17e, XMM17f, XMM17g, XMM17h, XMM17i, XMM17j, XMM17k, XMM17l, XMM17m, XMM17n, XMM17o, XMM17p);
|
||||
|
||||
reg_class xmm18_reg(XMM18, XMM18b, XMM18c, XMM18d);
|
||||
reg_class ymm18_reg(XMM18, XMM18b, XMM18c, XMM18d, XMM18e, XMM18f, XMM18g, XMM18h);
|
||||
reg_class zmm18_reg(XMM18, XMM18b, XMM18c, XMM18d, XMM18e, XMM18f, XMM18g, XMM18h, XMM18i, XMM18j, XMM18k, XMM18l, XMM18m, XMM18n, XMM18o, XMM18p);
|
||||
|
||||
reg_class xmm19_reg(XMM19, XMM19b, XMM19c, XMM19d);
|
||||
reg_class ymm19_reg(XMM19, XMM19b, XMM19c, XMM19d, XMM19e, XMM19f, XMM19g, XMM19h);
|
||||
reg_class zmm19_reg(XMM19, XMM19b, XMM19c, XMM19d, XMM19e, XMM19f, XMM19g, XMM19h, XMM19i, XMM19j, XMM19k, XMM19l, XMM19m, XMM19n, XMM19o, XMM19p);
|
||||
|
||||
reg_class xmm20_reg(XMM20, XMM20b, XMM20c, XMM20d);
|
||||
reg_class ymm20_reg(XMM20, XMM20b, XMM20c, XMM20d, XMM20e, XMM20f, XMM20g, XMM20h);
|
||||
reg_class zmm20_reg(XMM20, XMM20b, XMM20c, XMM20d, XMM20e, XMM20f, XMM20g, XMM20h, XMM20i, XMM20j, XMM20k, XMM20l, XMM20m, XMM20n, XMM20o, XMM20p);
|
||||
|
||||
reg_class xmm21_reg(XMM21, XMM21b, XMM21c, XMM21d);
|
||||
reg_class ymm21_reg(XMM21, XMM21b, XMM21c, XMM21d, XMM21e, XMM21f, XMM21g, XMM21h);
|
||||
reg_class zmm21_reg(XMM21, XMM21b, XMM21c, XMM21d, XMM21e, XMM21f, XMM21g, XMM21h, XMM21i, XMM21j, XMM21k, XMM21l, XMM21m, XMM21n, XMM21o, XMM21p);
|
||||
|
||||
reg_class xmm22_reg(XMM22, XMM22b, XMM22c, XMM22d);
|
||||
reg_class ymm22_reg(XMM22, XMM22b, XMM22c, XMM22d, XMM22e, XMM22f, XMM22g, XMM22h);
|
||||
reg_class zmm22_reg(XMM22, XMM22b, XMM22c, XMM22d, XMM22e, XMM22f, XMM22g, XMM22h, XMM22i, XMM22j, XMM22k, XMM22l, XMM22m, XMM22n, XMM22o, XMM22p);
|
||||
|
||||
reg_class xmm23_reg(XMM23, XMM23b, XMM23c, XMM23d);
|
||||
reg_class ymm23_reg(XMM23, XMM23b, XMM23c, XMM23d, XMM23e, XMM23f, XMM23g, XMM23h);
|
||||
reg_class zmm23_reg(XMM23, XMM23b, XMM23c, XMM23d, XMM23e, XMM23f, XMM23g, XMM23h, XMM23i, XMM23j, XMM23k, XMM23l, XMM23m, XMM23n, XMM23o, XMM23p);
|
||||
|
||||
reg_class xmm24_reg(XMM24, XMM24b, XMM24c, XMM24d);
|
||||
reg_class ymm24_reg(XMM24, XMM24b, XMM24c, XMM24d, XMM24e, XMM24f, XMM24g, XMM24h);
|
||||
reg_class zmm24_reg(XMM24, XMM24b, XMM24c, XMM24d, XMM24e, XMM24f, XMM24g, XMM24h, XMM24i, XMM24j, XMM24k, XMM24l, XMM24m, XMM24n, XMM24o, XMM24p);
|
||||
|
||||
reg_class xmm25_reg(XMM25, XMM25b, XMM25c, XMM25d);
|
||||
reg_class ymm25_reg(XMM25, XMM25b, XMM25c, XMM25d, XMM25e, XMM25f, XMM25g, XMM25h);
|
||||
reg_class zmm25_reg(XMM25, XMM25b, XMM25c, XMM25d, XMM25e, XMM25f, XMM25g, XMM25h, XMM25i, XMM25j, XMM25k, XMM25l, XMM25m, XMM25n, XMM25o, XMM25p);
|
||||
|
||||
reg_class xmm26_reg(XMM26, XMM26b, XMM26c, XMM26d);
|
||||
reg_class ymm26_reg(XMM26, XMM26b, XMM26c, XMM26d, XMM26e, XMM26f, XMM26g, XMM26h);
|
||||
reg_class zmm26_reg(XMM26, XMM26b, XMM26c, XMM26d, XMM26e, XMM26f, XMM26g, XMM26h, XMM26i, XMM26j, XMM26k, XMM26l, XMM26m, XMM26n, XMM26o, XMM26p);
|
||||
|
||||
reg_class xmm27_reg(XMM27, XMM27b, XMM27c, XMM27d);
|
||||
reg_class ymm27_reg(XMM27, XMM27b, XMM27c, XMM27d, XMM27e, XMM27f, XMM27g, XMM27h);
|
||||
reg_class zmm27_reg(XMM27, XMM27b, XMM27c, XMM27d, XMM27e, XMM27f, XMM27g, XMM27h, XMM27i, XMM27j, XMM27k, XMM27l, XMM27m, XMM27n, XMM27o, XMM27p);
|
||||
|
||||
reg_class xmm28_reg(XMM28, XMM28b, XMM28c, XMM28d);
|
||||
reg_class ymm28_reg(XMM28, XMM28b, XMM28c, XMM28d, XMM28e, XMM28f, XMM28g, XMM28h);
|
||||
reg_class zmm28_reg(XMM28, XMM28b, XMM28c, XMM28d, XMM28e, XMM28f, XMM28g, XMM28h, XMM28i, XMM28j, XMM28k, XMM28l, XMM28m, XMM28n, XMM28o, XMM28p);
|
||||
|
||||
reg_class xmm29_reg(XMM29, XMM29b, XMM29c, XMM29d);
|
||||
reg_class ymm29_reg(XMM29, XMM29b, XMM29c, XMM29d, XMM29e, XMM29f, XMM29g, XMM29h);
|
||||
reg_class zmm29_reg(XMM29, XMM29b, XMM29c, XMM29d, XMM29e, XMM29f, XMM29g, XMM29h, XMM29i, XMM29j, XMM29k, XMM29l, XMM29m, XMM29n, XMM29o, XMM29p);
|
||||
|
||||
reg_class xmm30_reg(XMM30, XMM30b, XMM30c, XMM30d);
|
||||
reg_class ymm30_reg(XMM30, XMM30b, XMM30c, XMM30d, XMM30e, XMM30f, XMM30g, XMM30h);
|
||||
reg_class zmm30_reg(XMM30, XMM30b, XMM30c, XMM30d, XMM30e, XMM30f, XMM30g, XMM30h, XMM30i, XMM30j, XMM30k, XMM30l, XMM30m, XMM30n, XMM30o, XMM30p);
|
||||
|
||||
reg_class xmm31_reg(XMM31, XMM31b, XMM31c, XMM31d);
|
||||
reg_class ymm31_reg(XMM31, XMM31b, XMM31c, XMM31d, XMM31e, XMM31f, XMM31g, XMM31h);
|
||||
reg_class zmm31_reg(XMM31, XMM31b, XMM31c, XMM31d, XMM31e, XMM31f, XMM31g, XMM31h, XMM31i, XMM31j, XMM31k, XMM31l, XMM31m, XMM31n, XMM31o, XMM31p);
|
||||
|
||||
#endif
|
||||
|
||||
%}
|
||||
|
||||
|
||||
@ -1800,8 +1668,8 @@ static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo
|
||||
return (UseAVX > 2) ? 6 : 4;
|
||||
}
|
||||
|
||||
static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
|
||||
int stack_offset, int reg, uint ireg, outputStream* st) {
|
||||
int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
|
||||
int stack_offset, int reg, uint ireg, outputStream* st) {
|
||||
// In 64-bit VM size calculation is very complex. Emitting instructions
|
||||
// into scratch buffer is used to get size in 64-bit VM.
|
||||
LP64_ONLY( assert(!do_size, "this method calculates size only for 32-bit VM"); )
|
||||
|
@ -1058,8 +1058,8 @@ static enum RC rc_class(OptoReg::Name reg)
|
||||
static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
|
||||
int src_hi, int dst_hi, uint ireg, outputStream* st);
|
||||
|
||||
static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
|
||||
int stack_offset, int reg, uint ireg, outputStream* st);
|
||||
int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
|
||||
int stack_offset, int reg, uint ireg, outputStream* st);
|
||||
|
||||
static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
|
||||
int dst_offset, uint ireg, outputStream* st) {
|
||||
@ -4260,200 +4260,6 @@ operand cmpOpUCF2() %{
|
||||
%}
|
||||
%}
|
||||
|
||||
// Operands for bound floating pointer register arguments
|
||||
operand rxmm0() %{
|
||||
constraint(ALLOC_IN_RC(xmm0_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm1() %{
|
||||
constraint(ALLOC_IN_RC(xmm1_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm2() %{
|
||||
constraint(ALLOC_IN_RC(xmm2_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm3() %{
|
||||
constraint(ALLOC_IN_RC(xmm3_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm4() %{
|
||||
constraint(ALLOC_IN_RC(xmm4_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm5() %{
|
||||
constraint(ALLOC_IN_RC(xmm5_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm6() %{
|
||||
constraint(ALLOC_IN_RC(xmm6_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm7() %{
|
||||
constraint(ALLOC_IN_RC(xmm7_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm8() %{
|
||||
constraint(ALLOC_IN_RC(xmm8_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm9() %{
|
||||
constraint(ALLOC_IN_RC(xmm9_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm10() %{
|
||||
constraint(ALLOC_IN_RC(xmm10_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm11() %{
|
||||
constraint(ALLOC_IN_RC(xmm11_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm12() %{
|
||||
constraint(ALLOC_IN_RC(xmm12_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm13() %{
|
||||
constraint(ALLOC_IN_RC(xmm13_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm14() %{
|
||||
constraint(ALLOC_IN_RC(xmm14_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm15() %{
|
||||
constraint(ALLOC_IN_RC(xmm15_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm16() %{
|
||||
constraint(ALLOC_IN_RC(xmm16_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm17() %{
|
||||
constraint(ALLOC_IN_RC(xmm17_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm18() %{
|
||||
constraint(ALLOC_IN_RC(xmm18_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm19() %{
|
||||
constraint(ALLOC_IN_RC(xmm19_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm20() %{
|
||||
constraint(ALLOC_IN_RC(xmm20_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm21() %{
|
||||
constraint(ALLOC_IN_RC(xmm21_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm22() %{
|
||||
constraint(ALLOC_IN_RC(xmm22_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm23() %{
|
||||
constraint(ALLOC_IN_RC(xmm23_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm24() %{
|
||||
constraint(ALLOC_IN_RC(xmm24_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm25() %{
|
||||
constraint(ALLOC_IN_RC(xmm25_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm26() %{
|
||||
constraint(ALLOC_IN_RC(xmm26_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm27() %{
|
||||
constraint(ALLOC_IN_RC(xmm27_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm28() %{
|
||||
constraint(ALLOC_IN_RC(xmm28_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm29() %{
|
||||
constraint(ALLOC_IN_RC(xmm29_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm30() %{
|
||||
constraint(ALLOC_IN_RC(xmm30_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
operand rxmm31() %{
|
||||
constraint(ALLOC_IN_RC(xmm31_reg));
|
||||
match(VecX);
|
||||
format%{%}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
//----------OPERAND CLASSES----------------------------------------------------
|
||||
// Operand Classes are groups of operands that are used as to simplify
|
||||
// instruction definitions by not requiring the AD writer to specify separate
|
||||
@ -5346,6 +5152,7 @@ instruct loadRange(rRegI dst, memory mem)
|
||||
instruct loadP(rRegP dst, memory mem)
|
||||
%{
|
||||
match(Set dst (LoadP mem));
|
||||
predicate(n->as_Load()->barrier_data() == 0);
|
||||
|
||||
ins_cost(125); // XXX
|
||||
format %{ "movq $dst, $mem\t# ptr" %}
|
||||
@ -7794,6 +7601,7 @@ instruct storePConditional(memory heap_top_ptr,
|
||||
rax_RegP oldval, rRegP newval,
|
||||
rFlagsReg cr)
|
||||
%{
|
||||
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||
match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
|
||||
|
||||
format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
|
||||
@ -7845,7 +7653,7 @@ instruct compareAndSwapP(rRegI res,
|
||||
rax_RegP oldval, rRegP newval,
|
||||
rFlagsReg cr)
|
||||
%{
|
||||
predicate(VM_Version::supports_cx8());
|
||||
predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0);
|
||||
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
|
||||
match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
|
||||
effect(KILL cr, KILL oldval);
|
||||
@ -8087,7 +7895,7 @@ instruct compareAndExchangeP(
|
||||
rax_RegP oldval, rRegP newval,
|
||||
rFlagsReg cr)
|
||||
%{
|
||||
predicate(VM_Version::supports_cx8());
|
||||
predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0);
|
||||
match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
|
||||
effect(KILL cr);
|
||||
|
||||
@ -8232,6 +8040,7 @@ instruct xchgL( memory mem, rRegL newval) %{
|
||||
|
||||
instruct xchgP( memory mem, rRegP newval) %{
|
||||
match(Set newval (GetAndSetP mem newval));
|
||||
predicate(n->as_LoadStore()->barrier_data() == 0);
|
||||
format %{ "XCHGQ $newval,[$mem]" %}
|
||||
ins_encode %{
|
||||
__ xchgq($newval$$Register, $mem$$Address);
|
||||
@ -11974,6 +11783,7 @@ instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
|
||||
instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
|
||||
%{
|
||||
match(Set cr (CmpP op1 (LoadP op2)));
|
||||
predicate(n->in(2)->as_Load()->barrier_data() == 0);
|
||||
|
||||
ins_cost(500); // XXX
|
||||
format %{ "cmpq $op1, $op2\t# ptr" %}
|
||||
@ -11999,7 +11809,8 @@ instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
|
||||
// and raw pointers have no anti-dependencies.
|
||||
instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
|
||||
%{
|
||||
predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none);
|
||||
predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none &&
|
||||
n->in(2)->as_Load()->barrier_data() == 0);
|
||||
match(Set cr (CmpP op1 (LoadP op2)));
|
||||
|
||||
format %{ "cmpq $op1, $op2\t# raw ptr" %}
|
||||
@ -12024,7 +11835,8 @@ instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
|
||||
// any compare to a zero should be eq/neq.
|
||||
instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
|
||||
%{
|
||||
predicate(!UseCompressedOops || (CompressedOops::base() != NULL));
|
||||
predicate((!UseCompressedOops || (CompressedOops::base() != NULL)) &&
|
||||
n->in(1)->as_Load()->barrier_data() == 0);
|
||||
match(Set cr (CmpP (LoadP op) zero));
|
||||
|
||||
ins_cost(500); // XXX
|
||||
@ -12037,7 +11849,9 @@ instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
|
||||
|
||||
instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
|
||||
%{
|
||||
predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
|
||||
predicate(UseCompressedOops && (CompressedOops::base() == NULL) &&
|
||||
(CompressedKlassPointers::base() == NULL) &&
|
||||
n->in(1)->as_Load()->barrier_data() == 0);
|
||||
match(Set cr (CmpP (LoadP mem) zero));
|
||||
|
||||
format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
|
||||
|
@ -132,18 +132,6 @@ extern "C" int getargs(procsinfo*, int, char*, int);
|
||||
#define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
|
||||
|
||||
// excerpts from systemcfg.h that might be missing on older os levels
|
||||
#ifndef PV_5_Compat
|
||||
#define PV_5_Compat 0x0F8000 /* Power PC 5 */
|
||||
#endif
|
||||
#ifndef PV_6
|
||||
#define PV_6 0x100000 /* Power PC 6 */
|
||||
#endif
|
||||
#ifndef PV_6_1
|
||||
#define PV_6_1 0x100001 /* Power PC 6 DD1.x */
|
||||
#endif
|
||||
#ifndef PV_6_Compat
|
||||
#define PV_6_Compat 0x108000 /* Power PC 6 */
|
||||
#endif
|
||||
#ifndef PV_7
|
||||
#define PV_7 0x200000 /* Power PC 7 */
|
||||
#endif
|
||||
@ -156,6 +144,13 @@ extern "C" int getargs(procsinfo*, int, char*, int);
|
||||
#ifndef PV_8_Compat
|
||||
#define PV_8_Compat 0x308000 /* Power PC 8 */
|
||||
#endif
|
||||
#ifndef PV_9
|
||||
#define PV_9 0x400000 /* Power PC 9 */
|
||||
#endif
|
||||
#ifndef PV_9_Compat
|
||||
#define PV_9_Compat 0x408000 /* Power PC 9 */
|
||||
#endif
|
||||
|
||||
|
||||
static address resolve_function_descriptor_to_code_pointer(address p);
|
||||
|
||||
@ -1386,15 +1381,7 @@ void os::print_os_info_brief(outputStream* st) {
|
||||
void os::print_os_info(outputStream* st) {
|
||||
st->print("OS:");
|
||||
|
||||
st->print("uname:");
|
||||
struct utsname name;
|
||||
uname(&name);
|
||||
st->print(name.sysname); st->print(" ");
|
||||
st->print(name.nodename); st->print(" ");
|
||||
st->print(name.release); st->print(" ");
|
||||
st->print(name.version); st->print(" ");
|
||||
st->print(name.machine);
|
||||
st->cr();
|
||||
os::Posix::print_uname_info(st);
|
||||
|
||||
uint32_t ver = os::Aix::os_version();
|
||||
st->print_cr("AIX kernel version %u.%u.%u.%u",
|
||||
@ -1402,16 +1389,12 @@ void os::print_os_info(outputStream* st) {
|
||||
|
||||
os::Posix::print_rlimit_info(st);
|
||||
|
||||
os::Posix::print_load_average(st);
|
||||
|
||||
// _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.
|
||||
long tmax = sysconf(_SC_THREAD_THREADS_MAX);
|
||||
st->print_cr("maximum #threads within a process:%ld", tmax);
|
||||
|
||||
// load average
|
||||
st->print("load average:");
|
||||
double loadavg[3] = {-1.L, -1.L, -1.L};
|
||||
os::loadavg(loadavg, 3);
|
||||
st->print_cr("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
|
||||
|
||||
// print wpar info
|
||||
libperfstat::wparinfo_t wi;
|
||||
if (libperfstat::get_wparinfo(&wi)) {
|
||||
@ -1504,6 +1487,9 @@ void os::print_memory_info(outputStream* st) {
|
||||
void os::get_summary_cpu_info(char* buf, size_t buflen) {
|
||||
// read _system_configuration.version
|
||||
switch (_system_configuration.version) {
|
||||
case PV_9:
|
||||
strncpy(buf, "Power PC 9", buflen);
|
||||
break;
|
||||
case PV_8:
|
||||
strncpy(buf, "Power PC 8", buflen);
|
||||
break;
|
||||
@ -1537,6 +1523,9 @@ void os::get_summary_cpu_info(char* buf, size_t buflen) {
|
||||
case PV_8_Compat:
|
||||
strncpy(buf, "PV_8_Compat", buflen);
|
||||
break;
|
||||
case PV_9_Compat:
|
||||
strncpy(buf, "PV_9_Compat", buflen);
|
||||
break;
|
||||
default:
|
||||
strncpy(buf, "unknown", buflen);
|
||||
}
|
||||
@ -2767,7 +2756,7 @@ static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
|
||||
os::SuspendResume::State state = osthread->sr.suspended();
|
||||
if (state == os::SuspendResume::SR_SUSPENDED) {
|
||||
sigset_t suspend_set; // signals for sigsuspend()
|
||||
|
||||
sigemptyset(&suspend_set);
|
||||
// get current set of blocked signals and unblock resume signal
|
||||
pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
|
||||
sigdelset(&suspend_set, SR_signum);
|
||||
@ -3053,6 +3042,7 @@ static bool call_chained_handler(struct sigaction *actp, int sig,
|
||||
|
||||
// try to honor the signal mask
|
||||
sigset_t oset;
|
||||
sigemptyset(&oset);
|
||||
pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
|
||||
|
||||
// call into the chained handler
|
||||
@ -3063,7 +3053,7 @@ static bool call_chained_handler(struct sigaction *actp, int sig,
|
||||
}
|
||||
|
||||
// restore the signal mask
|
||||
pthread_sigmask(SIG_SETMASK, &oset, 0);
|
||||
pthread_sigmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
// Tell jvm's signal handler the signal is taken care of.
|
||||
return true;
|
||||
@ -4020,7 +4010,7 @@ int os::loadavg(double values[], int nelem) {
|
||||
void os::pause() {
|
||||
char filename[MAX_PATH];
|
||||
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
|
||||
jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
|
||||
jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
|
||||
} else {
|
||||
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
|
||||
}
|
||||
|
@ -3671,7 +3671,7 @@ int os::loadavg(double loadavg[], int nelem) {
|
||||
void os::pause() {
|
||||
char filename[MAX_PATH];
|
||||
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
|
||||
jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
|
||||
jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
|
||||
} else {
|
||||
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
|
||||
}
|
||||
|
@ -373,8 +373,12 @@ struct tm* os::gmtime_pd(const time_t* clock, struct tm* res) {
|
||||
void os::Posix::print_load_average(outputStream* st) {
|
||||
st->print("load average:");
|
||||
double loadavg[3];
|
||||
os::loadavg(loadavg, 3);
|
||||
st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
|
||||
int res = os::loadavg(loadavg, 3);
|
||||
if (res != -1) {
|
||||
st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
|
||||
} else {
|
||||
st->print(" Unavailable");
|
||||
}
|
||||
st->cr();
|
||||
}
|
||||
|
||||
|
@ -4428,7 +4428,7 @@ bool os::pd_unmap_memory(char* addr, size_t bytes) {
|
||||
void os::pause() {
|
||||
char filename[MAX_PATH];
|
||||
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
|
||||
jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
|
||||
jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
|
||||
} else {
|
||||
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
|
||||
}
|
||||
|
@ -4975,7 +4975,7 @@ bool os::pd_unmap_memory(char* addr, size_t bytes) {
|
||||
void os::pause() {
|
||||
char filename[MAX_PATH];
|
||||
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
|
||||
jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
|
||||
jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
|
||||
} else {
|
||||
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
|
||||
}
|
||||
|
@ -773,11 +773,6 @@ bool InstructForm::captures_bottom_type(FormDict &globals) const {
|
||||
!strcmp(_matrule->_rChild->_opType,"CheckCastPP") ||
|
||||
!strcmp(_matrule->_rChild->_opType,"GetAndSetP") ||
|
||||
!strcmp(_matrule->_rChild->_opType,"GetAndSetN") ||
|
||||
#if INCLUDE_ZGC
|
||||
!strcmp(_matrule->_rChild->_opType,"ZGetAndSetP") ||
|
||||
!strcmp(_matrule->_rChild->_opType,"ZCompareAndExchangeP") ||
|
||||
!strcmp(_matrule->_rChild->_opType,"LoadBarrierSlowReg") ||
|
||||
#endif
|
||||
#if INCLUDE_SHENANDOAHGC
|
||||
!strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") ||
|
||||
!strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN") ||
|
||||
@ -3510,9 +3505,6 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
|
||||
"StoreCM",
|
||||
"GetAndSetB", "GetAndSetS", "GetAndAddI", "GetAndSetI", "GetAndSetP",
|
||||
"GetAndAddB", "GetAndAddS", "GetAndAddL", "GetAndSetL", "GetAndSetN",
|
||||
#if INCLUDE_ZGC
|
||||
"ZGetAndSetP", "ZCompareAndSwapP", "ZCompareAndExchangeP", "ZWeakCompareAndSwapP",
|
||||
#endif
|
||||
"ClearArray"
|
||||
};
|
||||
int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/compressedOops.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/method.inline.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "compiler/compilerOracle.hpp"
|
||||
#include "gc/shared/cardTableBarrierSet.hpp"
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/method.inline.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
|
@ -33,13 +33,13 @@
|
||||
#include "ci/ciKlass.hpp"
|
||||
#include "ci/ciMemberName.hpp"
|
||||
#include "ci/ciUtilities.inline.hpp"
|
||||
#include "compiler/compilationPolicy.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "interpreter/bytecode.hpp"
|
||||
#include "jfr/jfrEvents.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "runtime/vm_version.hpp"
|
||||
#include "utilities/bitMap.inline.hpp"
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "ci/ciUtilities.hpp"
|
||||
#include "gc/shared/barrierSet.hpp"
|
||||
#include "gc/shared/c1/barrierSetC1.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "code/pcDesc.hpp"
|
||||
#include "code/scopeDesc.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "compiler/compilationPolicy.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "gc/shared/barrierSet.hpp"
|
||||
#include "gc/shared/c1/barrierSetC1.hpp"
|
||||
@ -55,7 +56,6 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/biasedLocking.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "runtime/fieldDescriptor.inline.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
|
@ -238,6 +238,7 @@ void ciEnv::cache_jvmti_state() {
|
||||
_jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables();
|
||||
_jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions();
|
||||
_jvmti_can_pop_frame = JvmtiExport::can_pop_frame();
|
||||
_jvmti_can_get_owned_monitor_info = JvmtiExport::can_get_owned_monitor_info();
|
||||
}
|
||||
|
||||
bool ciEnv::jvmti_state_changed() const {
|
||||
@ -262,6 +263,10 @@ bool ciEnv::jvmti_state_changed() const {
|
||||
JvmtiExport::can_pop_frame()) {
|
||||
return true;
|
||||
}
|
||||
if (!_jvmti_can_get_owned_monitor_info &&
|
||||
JvmtiExport::can_get_owned_monitor_info()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ private:
|
||||
bool _jvmti_can_access_local_variables;
|
||||
bool _jvmti_can_post_on_exceptions;
|
||||
bool _jvmti_can_pop_frame;
|
||||
bool _jvmti_can_get_owned_monitor_info; // includes can_get_owned_monitor_stack_depth_info
|
||||
|
||||
// Cache DTrace flags
|
||||
bool _dtrace_extended_probes;
|
||||
@ -347,6 +348,7 @@ public:
|
||||
}
|
||||
bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; }
|
||||
bool jvmti_can_post_on_exceptions() const { return _jvmti_can_post_on_exceptions; }
|
||||
bool jvmti_can_get_owned_monitor_info() const { return _jvmti_can_get_owned_monitor_info; }
|
||||
|
||||
// Cache DTrace flags
|
||||
void cache_dtrace_flags();
|
||||
|
@ -57,7 +57,6 @@
|
||||
#include "oops/symbol.hpp"
|
||||
#include "prims/jvm_misc.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
|
@ -237,6 +237,8 @@ class ClassLoader: AllStatic {
|
||||
CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})
|
||||
CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;})
|
||||
|
||||
static bool has_bootclasspath_append() { return _first_append_entry != NULL; }
|
||||
|
||||
protected:
|
||||
// Initialization:
|
||||
// - setup the boot loader's system class path
|
||||
|
@ -377,20 +377,24 @@ Handle java_lang_String::create_from_platform_dependent_str(const char* str, TRA
|
||||
|
||||
if (_to_java_string_fn == NULL) {
|
||||
void *lib_handle = os::native_java_library();
|
||||
_to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "NewStringPlatform"));
|
||||
_to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "JNU_NewStringPlatform"));
|
||||
if (_to_java_string_fn == NULL) {
|
||||
fatal("NewStringPlatform missing");
|
||||
}
|
||||
}
|
||||
|
||||
jstring js = NULL;
|
||||
{ JavaThread* thread = (JavaThread*)THREAD;
|
||||
assert(thread->is_Java_thread(), "must be java thread");
|
||||
{
|
||||
assert(THREAD->is_Java_thread(), "must be java thread");
|
||||
JavaThread* thread = (JavaThread*)THREAD;
|
||||
HandleMark hm(thread);
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
js = (_to_java_string_fn)(thread->jni_environment(), str);
|
||||
}
|
||||
return Handle(THREAD, JNIHandles::resolve(js));
|
||||
|
||||
Handle native_platform_string(THREAD, JNIHandles::resolve(js));
|
||||
JNIHandles::destroy_local(js); // destroy local JNIHandle.
|
||||
return native_platform_string;
|
||||
}
|
||||
|
||||
// Converts a Java String to a native C string that can be used for
|
||||
|
@ -1205,10 +1205,8 @@ bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||
TempNewSymbol pkg_name = NULL;
|
||||
PackageEntry* pkg_entry = NULL;
|
||||
ModuleEntry* mod_entry = NULL;
|
||||
const char* pkg_string = NULL;
|
||||
pkg_name = InstanceKlass::package_from_name(class_name, CHECK_false);
|
||||
if (pkg_name != NULL) {
|
||||
pkg_string = pkg_name->as_C_string();
|
||||
if (loader_data != NULL) {
|
||||
pkg_entry = loader_data->packages()->lookup_only(pkg_name);
|
||||
}
|
||||
@ -1245,7 +1243,7 @@ bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||
// 3. or, the class is from an unamed module
|
||||
if (!ent->is_modules_image() && ik->is_shared_boot_class()) {
|
||||
// the class is from the -Xbootclasspath/a
|
||||
if (pkg_string == NULL ||
|
||||
if (pkg_name == NULL ||
|
||||
pkg_entry == NULL ||
|
||||
pkg_entry->in_unnamed_module()) {
|
||||
assert(mod_entry == NULL ||
|
||||
@ -1257,8 +1255,7 @@ bool SystemDictionary::is_shared_class_visible(Symbol* class_name,
|
||||
return false;
|
||||
} else {
|
||||
bool res = SystemDictionaryShared::is_shared_class_visible_for_classloader(
|
||||
ik, class_loader, pkg_string, pkg_name,
|
||||
pkg_entry, mod_entry, CHECK_(false));
|
||||
ik, class_loader, pkg_name, pkg_entry, mod_entry, CHECK_(false));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@ -1432,6 +1429,11 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle
|
||||
// a named package within the unnamed module. In all cases,
|
||||
// limit visibility to search for the class only in the boot
|
||||
// loader's append path.
|
||||
if (!ClassLoader::has_bootclasspath_append()) {
|
||||
// If there is no bootclasspath append entry, no need to continue
|
||||
// searching.
|
||||
return NULL;
|
||||
}
|
||||
search_only_bootloader_append = true;
|
||||
}
|
||||
}
|
||||
|
@ -657,7 +657,6 @@ bool SystemDictionaryShared::is_sharing_possible(ClassLoaderData* loader_data) {
|
||||
bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
|
||||
InstanceKlass* ik,
|
||||
Handle class_loader,
|
||||
const char* pkg_string,
|
||||
Symbol* pkg_name,
|
||||
PackageEntry* pkg_entry,
|
||||
ModuleEntry* mod_entry,
|
||||
@ -684,7 +683,7 @@ bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
|
||||
}
|
||||
} else if (SystemDictionary::is_system_class_loader(class_loader())) {
|
||||
assert(ent != NULL, "shared class for system loader should have valid SharedClassPathEntry");
|
||||
if (pkg_string == NULL) {
|
||||
if (pkg_name == NULL) {
|
||||
// The archived class is in the unnamed package. Currently, the boot image
|
||||
// does not contain any class in the unnamed package.
|
||||
assert(!ent->is_modules_image(), "Class in the unnamed package must be from the classpath");
|
||||
@ -906,14 +905,9 @@ InstanceKlass* SystemDictionaryShared::lookup_from_stream(Symbol* class_name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const RunTimeSharedClassInfo* record = find_record(&_unregistered_dictionary, class_name);
|
||||
const RunTimeSharedClassInfo* record = find_record(&_unregistered_dictionary, &_dynamic_unregistered_dictionary, class_name);
|
||||
if (record == NULL) {
|
||||
if (DynamicArchive::is_mapped()) {
|
||||
record = find_record(&_dynamic_unregistered_dictionary, class_name);
|
||||
}
|
||||
if (record == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int clsfile_size = cfs->length();
|
||||
@ -1413,29 +1407,34 @@ void SystemDictionaryShared::serialize_dictionary_headers(SerializeClosure* soc,
|
||||
}
|
||||
|
||||
const RunTimeSharedClassInfo*
|
||||
SystemDictionaryShared::find_record(RunTimeSharedDictionary* dict, Symbol* name) {
|
||||
if (UseSharedSpaces) {
|
||||
unsigned int hash = primitive_hash<Symbol*>(name);
|
||||
return dict->lookup(name, hash, 0);
|
||||
} else {
|
||||
SystemDictionaryShared::find_record(RunTimeSharedDictionary* static_dict, RunTimeSharedDictionary* dynamic_dict, Symbol* name) {
|
||||
if (!UseSharedSpaces || !name->is_shared()) {
|
||||
// The names of all shared classes must also be a shared Symbol.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int hash = primitive_hash<Symbol*>(name);
|
||||
const RunTimeSharedClassInfo* record = NULL;
|
||||
if (!MetaspaceShared::is_shared_dynamic(name)) {
|
||||
// The names of all shared classes in the static dict must also be in the
|
||||
// static archive
|
||||
record = static_dict->lookup(name, hash, 0);
|
||||
}
|
||||
|
||||
if (record == NULL && DynamicArchive::is_mapped()) {
|
||||
record = dynamic_dict->lookup(name, hash, 0);
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
InstanceKlass* SystemDictionaryShared::find_builtin_class(Symbol* name) {
|
||||
const RunTimeSharedClassInfo* record = find_record(&_builtin_dictionary, name);
|
||||
if (record) {
|
||||
const RunTimeSharedClassInfo* record = find_record(&_builtin_dictionary, &_dynamic_builtin_dictionary, name);
|
||||
if (record != NULL) {
|
||||
return record->_klass;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (DynamicArchive::is_mapped()) {
|
||||
record = find_record(&_dynamic_builtin_dictionary, name);
|
||||
if (record) {
|
||||
return record->_klass;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SystemDictionaryShared::update_shared_entry(InstanceKlass* k, int id) {
|
||||
|
@ -223,7 +223,9 @@ private:
|
||||
public:
|
||||
static InstanceKlass* find_builtin_class(Symbol* class_name);
|
||||
|
||||
static const RunTimeSharedClassInfo* find_record(RunTimeSharedDictionary* dict, Symbol* name);
|
||||
static const RunTimeSharedClassInfo* find_record(RunTimeSharedDictionary* static_dict,
|
||||
RunTimeSharedDictionary* dynamic_dict,
|
||||
Symbol* name);
|
||||
|
||||
static bool has_platform_or_app_classes();
|
||||
|
||||
@ -240,7 +242,6 @@ public:
|
||||
static bool is_sharing_possible(ClassLoaderData* loader_data);
|
||||
static bool is_shared_class_visible_for_classloader(InstanceKlass* ik,
|
||||
Handle class_loader,
|
||||
const char* pkg_string,
|
||||
Symbol* pkg_name,
|
||||
PackageEntry* pkg_entry,
|
||||
ModuleEntry* mod_entry,
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "classfile/verificationType.hpp"
|
||||
#include "classfile/verifier.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
|
||||
VerificationType VerificationType::from_tag(u1 tag) {
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "code/pcDesc.hpp"
|
||||
#include "compiler/compilationPolicy.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "jfr/jfrEvents.hpp"
|
||||
#include "logging/log.hpp"
|
||||
@ -46,7 +47,6 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/verifyOopClosure.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/icache.hpp"
|
||||
|
@ -741,4 +741,22 @@ void CompiledDirectStaticCall::print() {
|
||||
tty->cr();
|
||||
}
|
||||
|
||||
void CompiledDirectStaticCall::verify_mt_safe(const methodHandle& callee, address entry,
|
||||
NativeMovConstReg* method_holder,
|
||||
NativeJump* jump) {
|
||||
// A generated lambda form might be deleted from the Lambdaform
|
||||
// cache in MethodTypeForm. If a jit compiled lambdaform method
|
||||
// becomes not entrant and the cache access returns null, the new
|
||||
// resolve will lead to a new generated LambdaForm.
|
||||
Method* old_method = reinterpret_cast<Method*>(method_holder->data());
|
||||
assert(old_method == NULL || old_method == callee() ||
|
||||
callee->is_compiled_lambda_form() ||
|
||||
!old_method->method_holder()->is_loader_alive() ||
|
||||
old_method->is_old(), // may be race patching deoptimized nmethod due to redefinition.
|
||||
"a) MT-unsafe modification of inline cache");
|
||||
|
||||
address destination = jump->jump_destination();
|
||||
assert(destination == (address)-1 || destination == entry,
|
||||
"b) MT-unsafe modification of inline cache");
|
||||
}
|
||||
#endif // !PRODUCT
|
||||
|
@ -402,6 +402,9 @@ private:
|
||||
|
||||
// Also used by CompiledIC
|
||||
void set_to_interpreted(const methodHandle& callee, address entry);
|
||||
void verify_mt_safe(const methodHandle& callee, address entry,
|
||||
NativeMovConstReg* method_holder,
|
||||
NativeJump* jump) PRODUCT_RETURN;
|
||||
#if INCLUDE_AOT
|
||||
void set_to_far(const methodHandle& callee, address entry);
|
||||
#endif
|
||||
|
@ -27,18 +27,18 @@
|
||||
#include "code/compiledIC.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "code/scopeDesc.hpp"
|
||||
#include "compiler/compilationPolicy.hpp"
|
||||
#include "compiler/tieredThresholdPolicy.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/methodData.hpp"
|
||||
#include "oops/method.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/nativeLookup.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "runtime/frame.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "runtime/tieredThresholdPolicy.hpp"
|
||||
#include "runtime/vframe.hpp"
|
||||
#include "runtime/vmOperations.hpp"
|
||||
#include "utilities/events.hpp"
|
@ -22,8 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_RUNTIME_COMPILATIONPOLICY_HPP
|
||||
#define SHARE_RUNTIME_COMPILATIONPOLICY_HPP
|
||||
#ifndef SHARE_COMPILER_COMPILATIONPOLICY_HPP
|
||||
#define SHARE_COMPILER_COMPILATIONPOLICY_HPP
|
||||
|
||||
#include "code/nmethod.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
@ -110,4 +110,4 @@ class SimpleCompPolicy : public CompilationPolicy {
|
||||
};
|
||||
|
||||
|
||||
#endif // SHARE_RUNTIME_COMPILATIONPOLICY_HPP
|
||||
#endif // SHARE_COMPILER_COMPILATIONPOLICY_HPP
|
@ -30,6 +30,7 @@
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/codeHeapState.hpp"
|
||||
#include "code/dependencyContext.hpp"
|
||||
#include "compiler/compilationPolicy.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/compileLog.hpp"
|
||||
#include "compiler/compilerOracle.hpp"
|
||||
@ -48,7 +49,6 @@
|
||||
#include "prims/whitebox.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/interfaceSupport.inline.hpp"
|
||||
|
@ -66,8 +66,7 @@ NOT_PRODUCT(cflags(TraceOptoOutput, bool, TraceOptoOutput, TraceOptoOutput))
|
||||
cflags(VectorizeDebug, uintx, 0, VectorizeDebug) \
|
||||
cflags(CloneMapDebug, bool, false, CloneMapDebug) \
|
||||
cflags(IGVPrintLevel, intx, PrintIdealGraphLevel, IGVPrintLevel) \
|
||||
cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit) \
|
||||
ZGC_ONLY(cflags(ZTraceLoadBarriers, bool, false, ZTraceLoadBarriers))
|
||||
cflags(MaxNodeLimit, intx, MaxNodeLimit, MaxNodeLimit)
|
||||
#else
|
||||
#define compilerdirectives_c2_flags(cflags)
|
||||
#endif
|
||||
|
@ -48,29 +48,25 @@
|
||||
|
||||
// OopMapStream
|
||||
|
||||
OopMapStream::OopMapStream(OopMap* oop_map, int oop_types_mask) {
|
||||
OopMapStream::OopMapStream(OopMap* oop_map) {
|
||||
_stream = new CompressedReadStream(oop_map->write_stream()->buffer());
|
||||
_mask = oop_types_mask;
|
||||
_size = oop_map->omv_count();
|
||||
_position = 0;
|
||||
_valid_omv = false;
|
||||
}
|
||||
|
||||
OopMapStream::OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask) {
|
||||
OopMapStream::OopMapStream(const ImmutableOopMap* oop_map) {
|
||||
_stream = new CompressedReadStream(oop_map->data_addr());
|
||||
_mask = oop_types_mask;
|
||||
_size = oop_map->count();
|
||||
_position = 0;
|
||||
_valid_omv = false;
|
||||
}
|
||||
|
||||
void OopMapStream::find_next() {
|
||||
while(_position++ < _size) {
|
||||
if (_position++ < _size) {
|
||||
_omv.read_from(_stream);
|
||||
if(((int)_omv.type() & _mask) > 0) {
|
||||
_valid_omv = true;
|
||||
return;
|
||||
}
|
||||
_valid_omv = true;
|
||||
return;
|
||||
}
|
||||
_valid_omv = false;
|
||||
}
|
||||
@ -140,16 +136,7 @@ void OopMap::set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional) {
|
||||
assert( _locs_used[reg->value()] == OopMapValue::unused_value, "cannot insert twice" );
|
||||
debug_only( _locs_used[reg->value()] = x; )
|
||||
|
||||
OopMapValue o(reg, x);
|
||||
|
||||
if(x == OopMapValue::callee_saved_value) {
|
||||
// This can never be a stack location, so we don't need to transform it.
|
||||
assert(optional->is_reg(), "Trying to callee save a stack location");
|
||||
o.set_content_reg(optional);
|
||||
} else if(x == OopMapValue::derived_oop_value) {
|
||||
o.set_content_reg(optional);
|
||||
}
|
||||
|
||||
OopMapValue o(reg, x, optional);
|
||||
o.write_on(write_stream());
|
||||
increment_count();
|
||||
}
|
||||
@ -160,11 +147,6 @@ void OopMap::set_oop(VMReg reg) {
|
||||
}
|
||||
|
||||
|
||||
void OopMap::set_value(VMReg reg) {
|
||||
// At this time, we don't need value entries in our OopMap.
|
||||
}
|
||||
|
||||
|
||||
void OopMap::set_narrowoop(VMReg reg) {
|
||||
set_xxx(reg, OopMapValue::narrowoop_value, VMRegImpl::Bad());
|
||||
}
|
||||
@ -328,7 +310,7 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
|
||||
// changed before derived pointer offset has been collected)
|
||||
OopMapValue omv;
|
||||
{
|
||||
OopMapStream oms(map,OopMapValue::derived_oop_value);
|
||||
OopMapStream oms(map);
|
||||
if (!oms.is_done()) {
|
||||
#ifndef TIERED
|
||||
COMPILER1_PRESENT(ShouldNotReachHere();)
|
||||
@ -340,27 +322,28 @@ void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
|
||||
#endif // !TIERED
|
||||
do {
|
||||
omv = oms.current();
|
||||
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
|
||||
guarantee(loc != NULL, "missing saved register");
|
||||
oop *derived_loc = loc;
|
||||
oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
|
||||
// Ignore NULL oops and decoded NULL narrow oops which
|
||||
// equal to CompressedOops::base() when a narrow oop
|
||||
// implicit null check is used in compiled code.
|
||||
// The narrow_oop_base could be NULL or be the address
|
||||
// of the page below heap depending on compressed oops mode.
|
||||
if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
|
||||
derived_oop_fn(base_loc, derived_loc);
|
||||
if (omv.type() == OopMapValue::derived_oop_value) {
|
||||
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
|
||||
guarantee(loc != NULL, "missing saved register");
|
||||
oop *derived_loc = loc;
|
||||
oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
|
||||
// Ignore NULL oops and decoded NULL narrow oops which
|
||||
// equal to CompressedOops::base() when a narrow oop
|
||||
// implicit null check is used in compiled code.
|
||||
// The narrow_oop_base could be NULL or be the address
|
||||
// of the page below heap depending on compressed oops mode.
|
||||
if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
|
||||
derived_oop_fn(base_loc, derived_loc);
|
||||
}
|
||||
}
|
||||
oms.next();
|
||||
} while (!oms.is_done());
|
||||
}
|
||||
}
|
||||
|
||||
// We want coop and oop oop_types
|
||||
int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
|
||||
{
|
||||
for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
|
||||
// We want coop and oop oop_types
|
||||
for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
|
||||
omv = oms.current();
|
||||
oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
|
||||
// It should be an error if no location can be found for a
|
||||
@ -436,12 +419,14 @@ void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
|
||||
assert(map != NULL, "no ptr map found");
|
||||
DEBUG_ONLY(int nof_callee = 0;)
|
||||
|
||||
for (OopMapStream oms(map, OopMapValue::callee_saved_value); !oms.is_done(); oms.next()) {
|
||||
for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
|
||||
OopMapValue omv = oms.current();
|
||||
VMReg reg = omv.content_reg();
|
||||
oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
|
||||
reg_map->set_location(reg, (address) loc);
|
||||
DEBUG_ONLY(nof_callee++;)
|
||||
if (omv.type() == OopMapValue::callee_saved_value) {
|
||||
VMReg reg = omv.content_reg();
|
||||
oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
|
||||
reg_map->set_location(reg, (address) loc);
|
||||
DEBUG_ONLY(nof_callee++;)
|
||||
}
|
||||
}
|
||||
|
||||
// Check that runtime stubs save all callee-saved registers
|
||||
@ -452,25 +437,6 @@ void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
|
||||
#endif // COMPILER2
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Non-Product code
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
bool ImmutableOopMap::has_derived_pointer() const {
|
||||
#if !defined(TIERED) && !INCLUDE_JVMCI
|
||||
COMPILER1_PRESENT(return false);
|
||||
#endif // !TIERED
|
||||
#if COMPILER2_OR_JVMCI
|
||||
OopMapStream oms(this,OopMapValue::derived_oop_value);
|
||||
return oms.is_done();
|
||||
#else
|
||||
return false;
|
||||
#endif // COMPILER2_OR_JVMCI
|
||||
}
|
||||
|
||||
#endif //PRODUCT
|
||||
|
||||
// Printing code is present in product build for -XX:+PrintAssembly.
|
||||
|
||||
static
|
||||
|
@ -53,7 +53,7 @@ private:
|
||||
|
||||
public:
|
||||
// Constants
|
||||
enum { type_bits = 4,
|
||||
enum { type_bits = 2,
|
||||
register_bits = BitsPerShort - type_bits };
|
||||
|
||||
enum { type_shift = 0,
|
||||
@ -64,19 +64,41 @@ public:
|
||||
register_mask = right_n_bits(register_bits),
|
||||
register_mask_in_place = register_mask << register_shift };
|
||||
|
||||
enum oop_types { // must fit in type_bits
|
||||
unused_value =0, // powers of 2, for masking OopMapStream
|
||||
oop_value = 1,
|
||||
narrowoop_value = 2,
|
||||
callee_saved_value = 4,
|
||||
derived_oop_value= 8 };
|
||||
enum oop_types {
|
||||
oop_value,
|
||||
narrowoop_value,
|
||||
callee_saved_value,
|
||||
derived_oop_value,
|
||||
unused_value = -1 // Only used as a sentinel value
|
||||
};
|
||||
|
||||
// Constructors
|
||||
OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
|
||||
OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg, t); set_content_reg(VMRegImpl::Bad()); }
|
||||
OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg, t); set_content_reg(reg2); }
|
||||
OopMapValue (CompressedReadStream* stream) { read_from(stream); }
|
||||
OopMapValue (VMReg reg, oop_types t, VMReg reg2) {
|
||||
set_reg_type(reg, t);
|
||||
set_content_reg(reg2);
|
||||
}
|
||||
|
||||
private:
|
||||
void set_reg_type(VMReg p, oop_types t) {
|
||||
set_value((p->value() << register_shift) | t);
|
||||
assert(reg() == p, "sanity check" );
|
||||
assert(type() == t, "sanity check" );
|
||||
}
|
||||
|
||||
void set_content_reg(VMReg r) {
|
||||
if (is_callee_saved()) {
|
||||
// This can never be a stack location, so we don't need to transform it.
|
||||
assert(r->is_reg(), "Trying to callee save a stack location");
|
||||
} else if (is_derived_oop()) {
|
||||
assert (r->is_valid(), "must have a valid VMReg");
|
||||
} else {
|
||||
assert (!r->is_valid(), "valid VMReg not allowed");
|
||||
}
|
||||
_content_reg = r->value();
|
||||
}
|
||||
|
||||
public:
|
||||
// Archiving
|
||||
void write_on(CompressedWriteStream* stream) {
|
||||
stream->write_int(value());
|
||||
@ -94,15 +116,10 @@ public:
|
||||
|
||||
// Querying
|
||||
bool is_oop() { return mask_bits(value(), type_mask_in_place) == oop_value; }
|
||||
bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
|
||||
bool is_narrowoop() { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
|
||||
bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
|
||||
bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
|
||||
|
||||
void set_oop() { set_value((value() & register_mask_in_place) | oop_value); }
|
||||
void set_narrowoop() { set_value((value() & register_mask_in_place) | narrowoop_value); }
|
||||
void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); }
|
||||
void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); }
|
||||
|
||||
VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
|
||||
oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); }
|
||||
|
||||
@ -110,15 +127,7 @@ public:
|
||||
return (p->value() == (p->value() & register_mask));
|
||||
}
|
||||
|
||||
void set_reg_type(VMReg p, oop_types t) {
|
||||
set_value((p->value() << register_shift) | t);
|
||||
assert(reg() == p, "sanity check" );
|
||||
assert(type() == t, "sanity check" );
|
||||
}
|
||||
|
||||
|
||||
VMReg content_reg() const { return VMRegImpl::as_VMReg(_content_reg, true); }
|
||||
void set_content_reg(VMReg r) { _content_reg = r->value(); }
|
||||
|
||||
// Physical location queries
|
||||
bool is_register_loc() { return reg()->is_reg(); }
|
||||
@ -156,6 +165,8 @@ class OopMap: public ResourceObj {
|
||||
enum DeepCopyToken { _deep_copy_token };
|
||||
OopMap(DeepCopyToken, OopMap* source); // used only by deep_copy
|
||||
|
||||
void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
|
||||
|
||||
public:
|
||||
OopMap(int frame_size, int arg_count);
|
||||
|
||||
@ -173,19 +184,14 @@ class OopMap: public ResourceObj {
|
||||
// frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
|
||||
// slots to hold 4-byte values like ints and floats in the LP64 build.
|
||||
void set_oop ( VMReg local);
|
||||
void set_value( VMReg local);
|
||||
void set_narrowoop(VMReg local);
|
||||
void set_dead ( VMReg local);
|
||||
void set_callee_saved( VMReg local, VMReg caller_machine_register );
|
||||
void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
|
||||
void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
|
||||
|
||||
int heap_size() const;
|
||||
void copy_data_to(address addr) const;
|
||||
OopMap* deep_copy();
|
||||
|
||||
bool has_derived_pointer() const PRODUCT_RETURN0;
|
||||
|
||||
bool legal_vm_reg_name(VMReg local) {
|
||||
return OopMapValue::legal_vm_reg_name(local);
|
||||
}
|
||||
@ -269,7 +275,6 @@ private:
|
||||
public:
|
||||
ImmutableOopMap(const OopMap* oopmap);
|
||||
|
||||
bool has_derived_pointer() const PRODUCT_RETURN0;
|
||||
int count() const { return _count; }
|
||||
#ifdef ASSERT
|
||||
int nr_of_bytes() const; // this is an expensive operation, only used in debug builds
|
||||
@ -334,7 +339,6 @@ public:
|
||||
class OopMapStream : public StackObj {
|
||||
private:
|
||||
CompressedReadStream* _stream;
|
||||
int _mask;
|
||||
int _size;
|
||||
int _position;
|
||||
bool _valid_omv;
|
||||
@ -342,8 +346,8 @@ class OopMapStream : public StackObj {
|
||||
void find_next();
|
||||
|
||||
public:
|
||||
OopMapStream(OopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
|
||||
OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
|
||||
OopMapStream(OopMap* oop_map);
|
||||
OopMapStream(const ImmutableOopMap* oop_map);
|
||||
bool is_done() { if(!_valid_omv) { find_next(); } return !_valid_omv; }
|
||||
void next() { find_next(); }
|
||||
OopMapValue current() { return _omv; }
|
||||
|
@ -25,12 +25,12 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/compilerOracle.hpp"
|
||||
#include "compiler/tieredThresholdPolicy.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "runtime/safepointVerifiers.hpp"
|
||||
#include "runtime/tieredThresholdPolicy.hpp"
|
||||
#include "code/scopeDesc.hpp"
|
||||
#include "oops/method.inline.hpp"
|
||||
#if INCLUDE_JVMCI
|
@ -22,12 +22,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_RUNTIME_TIEREDTHRESHOLDPOLICY_HPP
|
||||
#define SHARE_RUNTIME_TIEREDTHRESHOLDPOLICY_HPP
|
||||
#ifndef SHARE_COMPILER_TIEREDTHRESHOLDPOLICY_HPP
|
||||
#define SHARE_COMPILER_TIEREDTHRESHOLDPOLICY_HPP
|
||||
|
||||
#include "code/nmethod.hpp"
|
||||
#include "compiler/compilationPolicy.hpp"
|
||||
#include "oops/methodData.hpp"
|
||||
#include "runtime/compilationPolicy.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#ifdef TIERED
|
||||
@ -275,4 +275,4 @@ public:
|
||||
|
||||
#endif // TIERED
|
||||
|
||||
#endif // SHARE_RUNTIME_TIEREDTHRESHOLDPOLICY_HPP
|
||||
#endif // SHARE_COMPILER_TIEREDTHRESHOLDPOLICY_HPP
|
@ -78,6 +78,8 @@ G1Analytics::G1Analytics(const G1Predictions* predictor) :
|
||||
_alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
|
||||
_prev_collection_pause_end_ms(0.0),
|
||||
_rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
|
||||
_concurrent_refine_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
|
||||
_logged_cards_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
|
||||
_cost_per_logged_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
|
||||
_cost_scan_hcc_seq(new TruncatedSeq(TruncatedSeqLength)),
|
||||
_young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
|
||||
@ -102,6 +104,10 @@ G1Analytics::G1Analytics(const G1Predictions* predictor) :
|
||||
int index = MIN2(ParallelGCThreads - 1, 7u);
|
||||
|
||||
_rs_length_diff_seq->add(rs_length_diff_defaults[index]);
|
||||
// Start with inverse of maximum STW cost.
|
||||
_concurrent_refine_rate_ms_seq->add(1/cost_per_logged_card_ms_defaults[0]);
|
||||
// Some applications have very low rates for logging cards.
|
||||
_logged_cards_rate_ms_seq->add(0.0);
|
||||
_cost_per_logged_card_ms_seq->add(cost_per_logged_card_ms_defaults[index]);
|
||||
_cost_scan_hcc_seq->add(0.0);
|
||||
_young_cards_per_entry_ratio_seq->add(young_cards_per_entry_ratio_defaults[index]);
|
||||
@ -159,6 +165,14 @@ void G1Analytics::compute_pause_time_ratio(double interval_ms, double pause_time
|
||||
(pause_time_ms * _recent_prev_end_times_for_all_gcs_sec->num()) / interval_ms;
|
||||
}
|
||||
|
||||
void G1Analytics::report_concurrent_refine_rate_ms(double cards_per_ms) {
|
||||
_concurrent_refine_rate_ms_seq->add(cards_per_ms);
|
||||
}
|
||||
|
||||
void G1Analytics::report_logged_cards_rate_ms(double cards_per_ms) {
|
||||
_logged_cards_rate_ms_seq->add(cards_per_ms);
|
||||
}
|
||||
|
||||
void G1Analytics::report_cost_per_logged_card_ms(double cost_per_logged_card_ms) {
|
||||
_cost_per_logged_card_ms_seq->add(cost_per_logged_card_ms);
|
||||
}
|
||||
@ -223,6 +237,14 @@ double G1Analytics::predict_alloc_rate_ms() const {
|
||||
return get_new_prediction(_alloc_rate_ms_seq);
|
||||
}
|
||||
|
||||
double G1Analytics::predict_concurrent_refine_rate_ms() const {
|
||||
return get_new_prediction(_concurrent_refine_rate_ms_seq);
|
||||
}
|
||||
|
||||
double G1Analytics::predict_logged_cards_rate_ms() const {
|
||||
return get_new_prediction(_logged_cards_rate_ms_seq);
|
||||
}
|
||||
|
||||
double G1Analytics::predict_cost_per_logged_card_ms() const {
|
||||
return get_new_prediction(_cost_per_logged_card_ms_seq);
|
||||
}
|
||||
|
@ -46,6 +46,8 @@ class G1Analytics: public CHeapObj<mtGC> {
|
||||
double _prev_collection_pause_end_ms;
|
||||
|
||||
TruncatedSeq* _rs_length_diff_seq;
|
||||
TruncatedSeq* _concurrent_refine_rate_ms_seq;
|
||||
TruncatedSeq* _logged_cards_rate_ms_seq;
|
||||
TruncatedSeq* _cost_per_logged_card_ms_seq;
|
||||
TruncatedSeq* _cost_scan_hcc_seq;
|
||||
TruncatedSeq* _young_cards_per_entry_ratio_seq;
|
||||
@ -99,6 +101,8 @@ public:
|
||||
void report_concurrent_mark_remark_times_ms(double ms);
|
||||
void report_concurrent_mark_cleanup_times_ms(double ms);
|
||||
void report_alloc_rate_ms(double alloc_rate);
|
||||
void report_concurrent_refine_rate_ms(double cards_per_ms);
|
||||
void report_logged_cards_rate_ms(double cards_per_ms);
|
||||
void report_cost_per_logged_card_ms(double cost_per_logged_card_ms);
|
||||
void report_cost_scan_hcc(double cost_scan_hcc);
|
||||
void report_cost_per_remset_card_ms(double cost_per_remset_card_ms, bool for_young_gc);
|
||||
@ -116,6 +120,8 @@ public:
|
||||
double predict_alloc_rate_ms() const;
|
||||
int num_alloc_rate_ms() const;
|
||||
|
||||
double predict_concurrent_refine_rate_ms() const;
|
||||
double predict_logged_cards_rate_ms() const;
|
||||
double predict_cost_per_logged_card_ms() const;
|
||||
|
||||
double predict_scan_hcc_ms() const;
|
||||
|
@ -409,7 +409,7 @@ double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1Survi
|
||||
guarantee(target_pause_time_ms > 0.0,
|
||||
"target_pause_time_ms = %1.6lf should be positive", target_pause_time_ms);
|
||||
|
||||
size_t pending_cards = _policy->pending_cards();
|
||||
size_t pending_cards = _policy->pending_cards_at_gc_start();
|
||||
double base_time_ms = _policy->predict_base_elapsed_time_ms(pending_cards);
|
||||
double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
|
||||
|
||||
|
@ -412,6 +412,22 @@ void G1ConcurrentRefine::adjust(double logged_cards_scan_time,
|
||||
dcqs.notify_if_necessary();
|
||||
}
|
||||
|
||||
G1ConcurrentRefine::RefinementStats G1ConcurrentRefine::total_refinement_stats() const {
|
||||
struct CollectData : public ThreadClosure {
|
||||
Tickspan _total_time;
|
||||
size_t _total_cards;
|
||||
CollectData() : _total_time(), _total_cards(0) {}
|
||||
virtual void do_thread(Thread* t) {
|
||||
G1ConcurrentRefineThread* crt = static_cast<G1ConcurrentRefineThread*>(t);
|
||||
_total_time += crt->total_refinement_time();
|
||||
_total_cards += crt->total_refined_cards();
|
||||
}
|
||||
} collector;
|
||||
// Cast away const so we can call non-modifying closure on threads.
|
||||
const_cast<G1ConcurrentRefine*>(this)->threads_do(&collector);
|
||||
return RefinementStats(collector._total_time, collector._total_cards);
|
||||
}
|
||||
|
||||
size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
|
||||
Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
|
||||
return activation_level(thresholds);
|
||||
@ -432,7 +448,8 @@ void G1ConcurrentRefine::maybe_activate_more_threads(uint worker_id, size_t num_
|
||||
}
|
||||
}
|
||||
|
||||
bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
|
||||
bool G1ConcurrentRefine::do_refinement_step(uint worker_id,
|
||||
size_t* total_refined_cards) {
|
||||
G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
|
||||
|
||||
size_t curr_cards = dcqs.num_cards();
|
||||
@ -448,5 +465,6 @@ bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
|
||||
|
||||
// Process the next buffer, if there are enough left.
|
||||
return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
|
||||
deactivation_threshold(worker_id));
|
||||
deactivation_threshold(worker_id),
|
||||
total_refined_cards);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/ticks.hpp"
|
||||
|
||||
// Forward decl
|
||||
class G1ConcurrentRefine;
|
||||
@ -118,11 +119,22 @@ public:
|
||||
// Adjust refinement thresholds based on work done during the pause and the goal time.
|
||||
void adjust(double logged_cards_scan_time, size_t processed_logged_cards, double goal_ms);
|
||||
|
||||
struct RefinementStats {
|
||||
Tickspan _time;
|
||||
size_t _cards;
|
||||
RefinementStats(Tickspan time, size_t cards) : _time(time), _cards(cards) {}
|
||||
};
|
||||
|
||||
RefinementStats total_refinement_stats() const;
|
||||
|
||||
// Cards in the dirty card queue set.
|
||||
size_t activation_threshold(uint worker_id) const;
|
||||
size_t deactivation_threshold(uint worker_id) const;
|
||||
// Perform a single refinement step. Called by the refinement threads when woken up.
|
||||
bool do_refinement_step(uint worker_id);
|
||||
|
||||
// Perform a single refinement step; called by the refinement
|
||||
// threads. Returns true if there was refinement work available.
|
||||
// Increments *total_refined_cards.
|
||||
bool do_refinement_step(uint worker_id, size_t* total_refined_cards);
|
||||
|
||||
// Iterate over all concurrent refinement threads applying the given closure.
|
||||
void threads_do(ThreadClosure *tc);
|
||||
|
@ -37,6 +37,8 @@ G1ConcurrentRefineThread::G1ConcurrentRefineThread(G1ConcurrentRefine* cr, uint
|
||||
ConcurrentGCThread(),
|
||||
_vtime_start(0.0),
|
||||
_vtime_accum(0.0),
|
||||
_total_refinement_time(),
|
||||
_total_refined_cards(0),
|
||||
_worker_id(worker_id),
|
||||
_active(false),
|
||||
_monitor(NULL),
|
||||
@ -101,11 +103,12 @@ void G1ConcurrentRefineThread::run_service() {
|
||||
break;
|
||||
}
|
||||
|
||||
size_t buffers_processed = 0;
|
||||
log_debug(gc, refine)("Activated worker %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
|
||||
_worker_id, _cr->activation_threshold(_worker_id),
|
||||
G1BarrierSet::dirty_card_queue_set().num_cards());
|
||||
|
||||
size_t start_total_refined_cards = _total_refined_cards; // For logging.
|
||||
|
||||
{
|
||||
SuspendibleThreadSetJoiner sts_join;
|
||||
|
||||
@ -115,20 +118,22 @@ void G1ConcurrentRefineThread::run_service() {
|
||||
continue; // Re-check for termination after yield delay.
|
||||
}
|
||||
|
||||
if (!_cr->do_refinement_step(_worker_id)) {
|
||||
break;
|
||||
Ticks start_time = Ticks::now();
|
||||
if (!_cr->do_refinement_step(_worker_id, &_total_refined_cards)) {
|
||||
break; // No cards to process.
|
||||
}
|
||||
++buffers_processed;
|
||||
_total_refinement_time += (Ticks::now() - start_time);
|
||||
}
|
||||
}
|
||||
|
||||
deactivate();
|
||||
log_debug(gc, refine)("Deactivated worker %d, off threshold: " SIZE_FORMAT
|
||||
", current: " SIZE_FORMAT ", buffers processed: "
|
||||
SIZE_FORMAT,
|
||||
", current: " SIZE_FORMAT ", refined cards: "
|
||||
SIZE_FORMAT ", total refined cards: " SIZE_FORMAT,
|
||||
_worker_id, _cr->deactivation_threshold(_worker_id),
|
||||
G1BarrierSet::dirty_card_queue_set().num_cards(),
|
||||
buffers_processed);
|
||||
_total_refined_cards - start_total_refined_cards,
|
||||
_total_refined_cards);
|
||||
|
||||
if (os::supports_vtime()) {
|
||||
_vtime_accum = (os::elapsedVTime() - _vtime_start);
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define SHARE_GC_G1_G1CONCURRENTREFINETHREAD_HPP
|
||||
|
||||
#include "gc/shared/concurrentGCThread.hpp"
|
||||
#include "utilities/ticks.hpp"
|
||||
|
||||
// Forward Decl.
|
||||
class G1ConcurrentRefine;
|
||||
@ -38,6 +39,10 @@ class G1ConcurrentRefineThread: public ConcurrentGCThread {
|
||||
|
||||
double _vtime_start; // Initial virtual time.
|
||||
double _vtime_accum; // Accumulated virtual time.
|
||||
|
||||
Tickspan _total_refinement_time;
|
||||
size_t _total_refined_cards;
|
||||
|
||||
uint _worker_id;
|
||||
|
||||
bool _active;
|
||||
@ -61,6 +66,9 @@ public:
|
||||
// Activate this thread.
|
||||
void activate();
|
||||
|
||||
Tickspan total_refinement_time() const { return _total_refinement_time; }
|
||||
size_t total_refined_cards() const { return _total_refined_cards; }
|
||||
|
||||
// Total virtual time so far.
|
||||
double vtime_accum() { return _vtime_accum; }
|
||||
};
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/flags/flagSetting.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "runtime/thread.inline.hpp"
|
||||
#include "runtime/threadSMR.hpp"
|
||||
@ -62,6 +63,9 @@ void G1DirtyCardQueue::handle_completed_buffer() {
|
||||
}
|
||||
}
|
||||
|
||||
// Assumed to be zero by concurrent threads.
|
||||
static uint par_ids_start() { return 0; }
|
||||
|
||||
G1DirtyCardQueueSet::G1DirtyCardQueueSet(Monitor* cbl_mon,
|
||||
BufferNode::Allocator* allocator) :
|
||||
PtrQueueSet(allocator),
|
||||
@ -73,15 +77,16 @@ G1DirtyCardQueueSet::G1DirtyCardQueueSet(Monitor* cbl_mon,
|
||||
_process_completed_buffers(false),
|
||||
_max_cards(MaxCardsUnlimited),
|
||||
_max_cards_padding(0),
|
||||
_free_ids(0, num_par_ids()),
|
||||
_processed_buffers_mut(0),
|
||||
_processed_buffers_rs_thread(0)
|
||||
_free_ids(par_ids_start(), num_par_ids()),
|
||||
_mutator_refined_cards_counters(NEW_C_HEAP_ARRAY(size_t, num_par_ids(), mtGC))
|
||||
{
|
||||
::memset(_mutator_refined_cards_counters, 0, num_par_ids() * sizeof(size_t));
|
||||
_all_active = true;
|
||||
}
|
||||
|
||||
G1DirtyCardQueueSet::~G1DirtyCardQueueSet() {
|
||||
abandon_completed_buffers();
|
||||
FREE_C_HEAP_ARRAY(size_t, _mutator_refined_cards_counters);
|
||||
}
|
||||
|
||||
// Determines how many mutator threads can process the buffers in parallel.
|
||||
@ -89,6 +94,14 @@ uint G1DirtyCardQueueSet::num_par_ids() {
|
||||
return (uint)os::initial_active_processor_count();
|
||||
}
|
||||
|
||||
size_t G1DirtyCardQueueSet::total_mutator_refined_cards() const {
|
||||
size_t sum = 0;
|
||||
for (uint i = 0; i < num_par_ids(); ++i) {
|
||||
sum += _mutator_refined_cards_counters[i];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
void G1DirtyCardQueueSet::handle_zero_index_for_thread(Thread* t) {
|
||||
G1ThreadLocalData::dirty_card_queue(t).handle_zero_index();
|
||||
}
|
||||
@ -213,7 +226,9 @@ G1BufferNodeList G1DirtyCardQueueSet::take_all_completed_buffers() {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool G1DirtyCardQueueSet::refine_buffer(BufferNode* node, uint worker_id) {
|
||||
bool G1DirtyCardQueueSet::refine_buffer(BufferNode* node,
|
||||
uint worker_id,
|
||||
size_t* total_refined_cards) {
|
||||
G1RemSet* rem_set = G1CollectedHeap::heap()->rem_set();
|
||||
size_t size = buffer_size();
|
||||
void** buffer = BufferNode::make_buffer_from_node(node);
|
||||
@ -223,6 +238,7 @@ bool G1DirtyCardQueueSet::refine_buffer(BufferNode* node, uint worker_id) {
|
||||
CardTable::CardValue* cp = static_cast<CardTable::CardValue*>(buffer[i]);
|
||||
rem_set->refine_card_concurrently(cp, worker_id);
|
||||
}
|
||||
*total_refined_cards += (i - node->index());
|
||||
node->set_index(i);
|
||||
return i == size;
|
||||
}
|
||||
@ -260,25 +276,27 @@ bool G1DirtyCardQueueSet::process_or_enqueue_completed_buffer(BufferNode* node)
|
||||
|
||||
bool G1DirtyCardQueueSet::mut_process_buffer(BufferNode* node) {
|
||||
uint worker_id = _free_ids.claim_par_id(); // temporarily claim an id
|
||||
bool result = refine_buffer(node, worker_id);
|
||||
uint counter_index = worker_id - par_ids_start();
|
||||
size_t* counter = &_mutator_refined_cards_counters[counter_index];
|
||||
bool result = refine_buffer(node, worker_id, counter);
|
||||
_free_ids.release_par_id(worker_id); // release the id
|
||||
|
||||
if (result) {
|
||||
assert_fully_consumed(node, buffer_size());
|
||||
Atomic::inc(&_processed_buffers_mut);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool G1DirtyCardQueueSet::refine_completed_buffer_concurrently(uint worker_id, size_t stop_at) {
|
||||
bool G1DirtyCardQueueSet::refine_completed_buffer_concurrently(uint worker_id,
|
||||
size_t stop_at,
|
||||
size_t* total_refined_cards) {
|
||||
BufferNode* node = get_completed_buffer(stop_at);
|
||||
if (node == NULL) {
|
||||
return false;
|
||||
} else if (refine_buffer(node, worker_id)) {
|
||||
} else if (refine_buffer(node, worker_id, total_refined_cards)) {
|
||||
assert_fully_consumed(node, buffer_size());
|
||||
// Done with fully processed buffer.
|
||||
deallocate_buffer(node);
|
||||
Atomic::inc(&_processed_buffers_rs_thread);
|
||||
return true;
|
||||
} else {
|
||||
// Return partially processed buffer to the queue.
|
||||
|
@ -78,14 +78,15 @@ class G1DirtyCardQueueSet: public PtrQueueSet {
|
||||
|
||||
void abandon_completed_buffers();
|
||||
|
||||
// Refine the cards in "node" from it's index to buffer_size.
|
||||
// Refine the cards in "node" from its index to buffer_size.
|
||||
// Stops processing if SuspendibleThreadSet::should_yield() is true.
|
||||
// Returns true if the entire buffer was processed, false if there
|
||||
// is a pending yield request. The node's index is updated to exclude
|
||||
// the processed elements, e.g. up to the element before processing
|
||||
// stopped, or one past the last element if the entire buffer was
|
||||
// processed.
|
||||
bool refine_buffer(BufferNode* node, uint worker_id);
|
||||
// processed. Increments *total_refined_cards by the number of cards
|
||||
// processed and removed from the buffer.
|
||||
bool refine_buffer(BufferNode* node, uint worker_id, size_t* total_refined_cards);
|
||||
|
||||
bool mut_process_buffer(BufferNode* node);
|
||||
|
||||
@ -97,10 +98,9 @@ class G1DirtyCardQueueSet: public PtrQueueSet {
|
||||
|
||||
G1FreeIdSet _free_ids;
|
||||
|
||||
// The number of completed buffers processed by mutator and rs thread,
|
||||
// respectively.
|
||||
jint _processed_buffers_mut;
|
||||
jint _processed_buffers_rs_thread;
|
||||
// Array of cumulative dirty cards refined by mutator threads.
|
||||
// Array has an entry per id in _free_ids.
|
||||
size_t* _mutator_refined_cards_counters;
|
||||
|
||||
public:
|
||||
G1DirtyCardQueueSet(Monitor* cbl_mon, BufferNode::Allocator* allocator);
|
||||
@ -158,7 +158,12 @@ public:
|
||||
// Stops processing a buffer if SuspendibleThreadSet::should_yield(),
|
||||
// returning the incompletely processed buffer to the completed buffer
|
||||
// list, for later processing of the remainder.
|
||||
bool refine_completed_buffer_concurrently(uint worker_id, size_t stop_at);
|
||||
//
|
||||
// Increments *total_refined_cards by the number of cards processed and
|
||||
// removed from the buffer.
|
||||
bool refine_completed_buffer_concurrently(uint worker_id,
|
||||
size_t stop_at,
|
||||
size_t* total_refined_cards);
|
||||
|
||||
// If a full collection is happening, reset partial logs, and release
|
||||
// completed ones: the full collection will make them all irrelevant.
|
||||
@ -181,13 +186,8 @@ public:
|
||||
return _max_cards_padding;
|
||||
}
|
||||
|
||||
jint processed_buffers_mut() {
|
||||
return _processed_buffers_mut;
|
||||
}
|
||||
jint processed_buffers_rs_thread() {
|
||||
return _processed_buffers_rs_thread;
|
||||
}
|
||||
|
||||
// Total dirty cards refined by mutator threads.
|
||||
size_t total_mutator_refined_cards() const;
|
||||
};
|
||||
|
||||
inline G1DirtyCardQueueSet* G1DirtyCardQueue::dirty_card_qset() const {
|
||||
|
@ -70,7 +70,11 @@ G1Policy::G1Policy(STWGCTimer* gc_timer) :
|
||||
_free_regions_at_end_of_collection(0),
|
||||
_max_rs_length(0),
|
||||
_rs_length_prediction(0),
|
||||
_pending_cards(0),
|
||||
_pending_cards_at_gc_start(0),
|
||||
_pending_cards_at_prev_gc_end(0),
|
||||
_total_mutator_refined_cards(0),
|
||||
_total_concurrent_refined_cards(0),
|
||||
_total_concurrent_refinement_time(),
|
||||
_bytes_allocated_in_old_since_last_gc(0),
|
||||
_initial_mark_to_mixed(),
|
||||
_collection_set(NULL),
|
||||
@ -442,6 +446,7 @@ void G1Policy::record_full_collection_start() {
|
||||
collector_state()->set_in_young_only_phase(false);
|
||||
collector_state()->set_in_full_gc(true);
|
||||
_collection_set->clear_candidates();
|
||||
record_concurrent_refinement_data(true /* is_full_collection */);
|
||||
}
|
||||
|
||||
void G1Policy::record_full_collection_end() {
|
||||
@ -472,12 +477,67 @@ void G1Policy::record_full_collection_end() {
|
||||
_survivor_surv_rate_group->reset();
|
||||
update_young_list_max_and_target_length();
|
||||
update_rs_length_prediction();
|
||||
_pending_cards_at_prev_gc_end = _g1h->pending_card_num();
|
||||
|
||||
_bytes_allocated_in_old_since_last_gc = 0;
|
||||
|
||||
record_pause(FullGC, _full_collection_start_sec, end_sec);
|
||||
}
|
||||
|
||||
void G1Policy::record_concurrent_refinement_data(bool is_full_collection) {
|
||||
_pending_cards_at_gc_start = _g1h->pending_card_num();
|
||||
|
||||
// Record info about concurrent refinement thread processing.
|
||||
G1ConcurrentRefine* cr = _g1h->concurrent_refine();
|
||||
G1ConcurrentRefine::RefinementStats cr_stats = cr->total_refinement_stats();
|
||||
|
||||
Tickspan cr_time = cr_stats._time - _total_concurrent_refinement_time;
|
||||
_total_concurrent_refinement_time = cr_stats._time;
|
||||
|
||||
size_t cr_cards = cr_stats._cards - _total_concurrent_refined_cards;
|
||||
_total_concurrent_refined_cards = cr_stats._cards;
|
||||
|
||||
// Don't update rate if full collection. We could be in an implicit full
|
||||
// collection after a non-full collection failure, in which case there
|
||||
// wasn't any mutator/cr-thread activity since last recording. And if
|
||||
// we're in an explicit full collection, the time since the last GC can
|
||||
// be arbitrarily short, so not a very good sample. Similarly, don't
|
||||
// update the rate if the current sample is empty or time is zero.
|
||||
if (!is_full_collection && (cr_cards > 0) && (cr_time > Tickspan())) {
|
||||
double rate = cr_cards / (cr_time.seconds() * MILLIUNITS);
|
||||
_analytics->report_concurrent_refine_rate_ms(rate);
|
||||
}
|
||||
|
||||
// Record info about mutator thread processing.
|
||||
G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
|
||||
size_t mut_total_cards = dcqs.total_mutator_refined_cards();
|
||||
size_t mut_cards = mut_total_cards - _total_mutator_refined_cards;
|
||||
_total_mutator_refined_cards = mut_total_cards;
|
||||
|
||||
// Record mutator's card logging rate.
|
||||
// Don't update if full collection; see above.
|
||||
if (!is_full_collection) {
|
||||
size_t total_cards = _pending_cards_at_gc_start + cr_cards + mut_cards;
|
||||
assert(_pending_cards_at_prev_gc_end <= total_cards,
|
||||
"untracked cards: last pending: " SIZE_FORMAT
|
||||
", pending: " SIZE_FORMAT ", conc refine: " SIZE_FORMAT
|
||||
", mut refine:" SIZE_FORMAT,
|
||||
_pending_cards_at_prev_gc_end, _pending_cards_at_gc_start,
|
||||
cr_cards, mut_cards);
|
||||
size_t logged_cards = total_cards - _pending_cards_at_prev_gc_end;
|
||||
double logging_start_time = _analytics->prev_collection_pause_end_ms();
|
||||
double logging_end_time = Ticks::now().seconds() * MILLIUNITS;
|
||||
double logging_time = logging_end_time - logging_start_time;
|
||||
// Unlike above for conc-refine rate, here we should not require a
|
||||
// non-empty sample, since an application could go some time with only
|
||||
// young-gen or filtered out writes. But we'll ignore unusually short
|
||||
// sample periods, as they may just pollute the predictions.
|
||||
if (logging_time > 1.0) { // Require > 1ms sample time.
|
||||
_analytics->report_logged_cards_rate_ms(logged_cards / logging_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G1Policy::record_collection_pause_start(double start_time_sec) {
|
||||
// We only need to do this here as the policy will only be applied
|
||||
// to the GC we're about to start. so, no point is calculating this
|
||||
@ -490,7 +550,8 @@ void G1Policy::record_collection_pause_start(double start_time_sec) {
|
||||
assert_used_and_recalculate_used_equal(_g1h);
|
||||
|
||||
phase_times()->record_cur_collection_start_sec(start_time_sec);
|
||||
_pending_cards = _g1h->pending_card_num();
|
||||
|
||||
record_concurrent_refinement_data(false /* is_full_collection */);
|
||||
|
||||
_collection_set->reset_bytes_used_before();
|
||||
_bytes_copied_during_gc = 0;
|
||||
@ -744,7 +805,7 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, size_t heap_use
|
||||
// after the mixed gc phase.
|
||||
// During mixed gc we do not use them for young gen sizing.
|
||||
if (this_pause_was_young_only) {
|
||||
_analytics->report_pending_cards((double) _pending_cards);
|
||||
_analytics->report_pending_cards((double) _pending_cards_at_gc_start);
|
||||
_analytics->report_rs_length((double) _max_rs_length);
|
||||
}
|
||||
}
|
||||
@ -798,6 +859,7 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, size_t heap_use
|
||||
scan_logged_cards_time_goal_ms -= scan_hcc_time_ms;
|
||||
}
|
||||
|
||||
_pending_cards_at_prev_gc_end = _g1h->pending_card_num();
|
||||
double const logged_cards_time = logged_cards_processing_time();
|
||||
|
||||
log_debug(gc, ergo, refine)("Concurrent refinement times: Logged Cards Scan time goal: %1.2fms Logged Cards Scan time: %1.2fms HCC time: %1.2fms",
|
||||
|
@ -100,7 +100,11 @@ class G1Policy: public CHeapObj<mtGC> {
|
||||
|
||||
size_t _rs_length_prediction;
|
||||
|
||||
size_t _pending_cards;
|
||||
size_t _pending_cards_at_gc_start;
|
||||
size_t _pending_cards_at_prev_gc_end;
|
||||
size_t _total_mutator_refined_cards;
|
||||
size_t _total_concurrent_refined_cards;
|
||||
Tickspan _total_concurrent_refinement_time;
|
||||
|
||||
// The amount of allocated bytes in old gen during the last mutator and the following
|
||||
// young GC phase.
|
||||
@ -244,7 +248,15 @@ private:
|
||||
uint base_free_regions, double target_pause_time_ms) const;
|
||||
|
||||
public:
|
||||
size_t pending_cards() const { return _pending_cards; }
|
||||
size_t pending_cards_at_gc_start() const { return _pending_cards_at_gc_start; }
|
||||
|
||||
size_t total_concurrent_refined_cards() const {
|
||||
return _total_concurrent_refined_cards;
|
||||
}
|
||||
|
||||
size_t total_mutator_refined_cards() const {
|
||||
return _total_mutator_refined_cards;
|
||||
}
|
||||
|
||||
// Calculate the minimum number of old regions we'll add to the CSet
|
||||
// during a mixed GC.
|
||||
@ -283,6 +295,9 @@ private:
|
||||
void record_pause(PauseKind kind, double start, double end);
|
||||
// Indicate that we aborted marking before doing any mixed GCs.
|
||||
void abort_time_to_mixed_tracking();
|
||||
|
||||
void record_concurrent_refinement_data(bool is_full_collection);
|
||||
|
||||
public:
|
||||
|
||||
G1Policy(STWGCTimer* gc_timer);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user