Merge
This commit is contained in:
commit
091b0c95c3
2
.hgtags
2
.hgtags
@ -650,3 +650,5 @@ a32f58c6b8be81877411767de7ba9c4cf087c1b5 jdk-15+31
|
||||
143e258f64af490010eb7e0bacc1cfaeceff0993 jdk-16+5
|
||||
2dad000726b8d5db9f3df647fb4949d88f269dd4 jdk-15+32
|
||||
4a8fd81d64bafa523cddb45f82805536edace106 jdk-16+6
|
||||
6b65f4e7a975628df51ef755b02642075390041d jdk-15+33
|
||||
c3a4a7ea7c304cabdacdc31741eb94c51351668d jdk-16+7
|
||||
|
@ -283,7 +283,7 @@
|
||||
<p>The JDK is currently known to be able to compile with at least version 9.2 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>
|
||||
<p>The minimum accepted version of clang is 3.5. Older versions will not be accepted by <code>configure</code>.</p>
|
||||
<p>To use clang instead of gcc on Linux, use <code>--with-toolchain-type=clang</code>.</p>
|
||||
<h3 id="apple-xcode">Apple Xcode</h3>
|
||||
<p>The oldest supported version of Xcode is 8.</p>
|
||||
@ -292,9 +292,8 @@
|
||||
<p>It is advisable to keep an older version of Xcode for building the JDK when updating Xcode. This <a href="http://iosdevelopertips.com/xcode/install-multiple-versions-of-xcode.html">blog page</a> has good suggestions on managing multiple Xcode versions. To use a specific version of Xcode, use <code>xcode-select -s</code> before running <code>configure</code>, or use <code>--with-toolchain-path</code> to point to the version of Xcode to use, e.g. <code>configure --with-toolchain-path=/Applications/Xcode8.app/Contents/Developer/usr/bin</code></p>
|
||||
<p>If you have recently (inadvertently) updated your OS and/or Xcode version, and the JDK can no longer be built, please see the section on <a href="#problems-with-the-build-environment">Problems with the Build Environment</a>, and <a href="#getting-help">Getting Help</a> to find out if there are any recent, non-merged patches available for this update.</p>
|
||||
<h3 id="microsoft-visual-studio">Microsoft Visual Studio</h3>
|
||||
<p>The minimum accepted version of Visual Studio is 2010. Older versions will not be accepted by <code>configure</code>. The maximum accepted version of Visual Studio is 2019. Versions older than 2017 are unlikely to continue working for long.</p>
|
||||
<p>If you have multiple versions of Visual Studio installed, <code>configure</code> will by default pick the latest. You can request a specific version to be used by setting <code>--with-toolchain-version</code>, e.g. <code>--with-toolchain-version=2015</code>.</p>
|
||||
<p>If you get <code>LINK: fatal error LNK1123: failure during conversion to COFF: file invalid</code> when building using Visual Studio 2010, you have encountered <a href="http://support.microsoft.com/kb/2757355">KB2757355</a>, a bug triggered by a specific installation order. However, the solution suggested by the KB article does not always resolve the problem. See <a href="https://stackoverflow.com/questions/10888391">this stackoverflow discussion</a> for other suggestions.</p>
|
||||
<p>The minimum accepted version of Visual Studio is 2017. Older versions will not be accepted by <code>configure</code> and will not work. The maximum accepted version of Visual Studio is 2019.</p>
|
||||
<p>If you have multiple versions of Visual Studio installed, <code>configure</code> will by default pick the latest. You can request a specific version to be used by setting <code>--with-toolchain-version</code>, e.g. <code>--with-toolchain-version=2017</code>.</p>
|
||||
<h3 id="ibm-xl-cc">IBM XL C/C++</h3>
|
||||
<p>Please consult the AIX section of the <a href="https://wiki.openjdk.java.net/display/Build/Supported+Build+Platforms">Supported Build Platforms</a> OpenJDK Build Wiki page for details about which versions of XLC are supported.</p>
|
||||
<h2 id="boot-jdk-requirements">Boot JDK Requirements</h2>
|
||||
|
@ -323,7 +323,7 @@ In general, any version between these two should be usable.
|
||||
|
||||
### clang
|
||||
|
||||
The minimum accepted version of clang is 3.2. Older versions will not be
|
||||
The minimum accepted version of clang is 3.5. Older versions will not be
|
||||
accepted by `configure`.
|
||||
|
||||
To use clang instead of gcc on Linux, use `--with-toolchain-type=clang`.
|
||||
@ -355,20 +355,13 @@ available for this update.
|
||||
|
||||
### Microsoft Visual Studio
|
||||
|
||||
The minimum accepted version of Visual Studio is 2010. Older versions will not
|
||||
be accepted by `configure`. The maximum accepted version of Visual Studio is
|
||||
2019. Versions older than 2017 are unlikely to continue working for long.
|
||||
The minimum accepted version of Visual Studio is 2017. Older versions will not
|
||||
be accepted by `configure` and will not work. The maximum accepted
|
||||
version of Visual Studio is 2019.
|
||||
|
||||
If you have multiple versions of Visual Studio installed, `configure` will by
|
||||
default pick the latest. You can request a specific version to be used by
|
||||
setting `--with-toolchain-version`, e.g. `--with-toolchain-version=2015`.
|
||||
|
||||
If you get `LINK: fatal error LNK1123: failure during conversion to COFF: file
|
||||
invalid` when building using Visual Studio 2010, you have encountered
|
||||
[KB2757355](http://support.microsoft.com/kb/2757355), a bug triggered by a
|
||||
specific installation order. However, the solution suggested by the KB article
|
||||
does not always resolve the problem. See [this stackoverflow discussion](
|
||||
https://stackoverflow.com/questions/10888391) for other suggestions.
|
||||
setting `--with-toolchain-version`, e.g. `--with-toolchain-version=2017`.
|
||||
|
||||
### IBM XL C/C++
|
||||
|
||||
|
@ -512,6 +512,18 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER],
|
||||
fi
|
||||
TOOLCHAIN_CFLAGS_JDK_CONLY="$LANGSTD_CFLAGS $TOOLCHAIN_CFLAGS_JDK_CONLY"
|
||||
|
||||
# CXXFLAGS C++ language level for all of JDK, including Hotspot.
|
||||
if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang || test "x$TOOLCHAIN_TYPE" = xxlc; then
|
||||
LANGSTD_CXXFLAGS="-std=c++14"
|
||||
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||
LANGSTD_CXXFLAGS="-std:c++14"
|
||||
else
|
||||
AC_MSG_ERROR([Don't know how to enable C++14 for this toolchain])
|
||||
fi
|
||||
TOOLCHAIN_CFLAGS_JDK_CXXONLY="$TOOLCHAIN_CFLAGS_JDK_CXXONLY $LANGSTD_CXXFLAGS"
|
||||
TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM $LANGSTD_CXXFLAGS"
|
||||
ADLC_LANGSTD_CXXFLAGS="$LANGSTD_CXXFLAGS"
|
||||
|
||||
# CFLAGS WARNINGS STUFF
|
||||
# Set JVM_CFLAGS warning handling
|
||||
if test "x$TOOLCHAIN_TYPE" = xgcc; then
|
||||
@ -694,13 +706,6 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
|
||||
$1_CFLAGS_CPU_JDK="${$1_CFLAGS_CPU_JDK} -fno-omit-frame-pointer"
|
||||
fi
|
||||
|
||||
$1_CXXSTD_CXXFLAG="-std=gnu++98"
|
||||
FLAGS_CXX_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${$1_CXXSTD_CXXFLAG}],
|
||||
PREFIX: $3, IF_FALSE: [$1_CXXSTD_CXXFLAG=""])
|
||||
$1_TOOLCHAIN_CFLAGS_JDK_CXXONLY="${$1_CXXSTD_CXXFLAG}"
|
||||
$1_TOOLCHAIN_CFLAGS_JVM="${$1_TOOLCHAIN_CFLAGS_JVM} ${$1_CXXSTD_CXXFLAG}"
|
||||
$2ADLC_CXXFLAG="${$1_CXXSTD_CXXFLAG}"
|
||||
|
||||
elif test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
if test "x$FLAGS_OS" = xlinux; then
|
||||
# ppc test not really needed for clang
|
||||
@ -795,7 +800,7 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
|
||||
AC_SUBST($2CFLAGS_JDKEXE)
|
||||
AC_SUBST($2CXXFLAGS_JDKLIB)
|
||||
AC_SUBST($2CXXFLAGS_JDKEXE)
|
||||
AC_SUBST($2ADLC_CXXFLAG)
|
||||
AC_SUBST($2ADLC_LANGSTD_CXXFLAGS)
|
||||
|
||||
COMPILER_FP_CONTRACT_OFF_FLAG="-ffp-contract=off"
|
||||
# Check that the compiler supports -ffp-contract=off flag
|
||||
|
@ -53,6 +53,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS],
|
||||
|
||||
LDFLAGS_TESTEXE="${TARGET_LDFLAGS_JDK_LIBPATH}"
|
||||
AC_SUBST(LDFLAGS_TESTEXE)
|
||||
AC_SUBST(ADLC_LDFLAGS)
|
||||
])
|
||||
|
||||
################################################################################
|
||||
|
@ -70,6 +70,7 @@ AC_DEFUN_ONCE([LIB_SETUP_STD_LIBS],
|
||||
else
|
||||
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
|
||||
JVM_LDFLAGS="$JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
|
||||
ADLC_LDFLAGS="$ADLC_LDFLAGS $STATIC_STDCXX_FLAGS"
|
||||
# Ideally, we should test stdc++ for the BUILD toolchain separately. For now
|
||||
# just use the same setting as for the TARGET toolchain.
|
||||
OPENJDK_BUILD_JVM_LDFLAGS="$OPENJDK_BUILD_JVM_LDFLAGS $STATIC_STDCXX_FLAGS"
|
||||
|
@ -476,7 +476,8 @@ DISABLED_WARNINGS_CXX := @DISABLED_WARNINGS_CXX@
|
||||
WARNINGS_AS_ERRORS := @WARNINGS_AS_ERRORS@
|
||||
|
||||
CFLAGS_CCACHE:=@CFLAGS_CCACHE@
|
||||
ADLC_CXXFLAG=@ADLC_CXXFLAG@
|
||||
ADLC_LANGSTD_CXXFLAGS=@ADLC_LANGSTD_CXXFLAGS@
|
||||
ADLC_LDFLAGS=@ADLC_LDFLAGS@
|
||||
|
||||
# Tools that potentially need to be cross compilation aware.
|
||||
CC:=@FIXPATH@ @CCACHE@ @ICECC@ @CC@
|
||||
|
@ -50,9 +50,9 @@ TOOLCHAIN_DESCRIPTION_microsoft="Microsoft Visual Studio"
|
||||
TOOLCHAIN_DESCRIPTION_xlc="IBM XL C/C++"
|
||||
|
||||
# Minimum supported versions, empty means unspecified
|
||||
TOOLCHAIN_MINIMUM_VERSION_clang="3.2"
|
||||
TOOLCHAIN_MINIMUM_VERSION_clang="3.5"
|
||||
TOOLCHAIN_MINIMUM_VERSION_gcc="5.0"
|
||||
TOOLCHAIN_MINIMUM_VERSION_microsoft="16.00.30319.01" # VS2010
|
||||
TOOLCHAIN_MINIMUM_VERSION_microsoft="19.10.0.0" # VS2017
|
||||
TOOLCHAIN_MINIMUM_VERSION_xlc=""
|
||||
|
||||
# Minimum supported linker versions, empty means unspecified
|
||||
|
@ -25,55 +25,7 @@
|
||||
|
||||
################################################################################
|
||||
# The order of these defines the priority by which we try to find them.
|
||||
VALID_VS_VERSIONS="2019 2017 2013 2015 2012 2010"
|
||||
|
||||
VS_DESCRIPTION_2010="Microsoft Visual Studio 2010"
|
||||
VS_VERSION_INTERNAL_2010=100
|
||||
VS_MSVCR_2010=msvcr100.dll
|
||||
# We don't use msvcp on Visual Studio 2010
|
||||
#VS_MSVCP_2010=msvcp100.dll
|
||||
VS_ENVVAR_2010="VS100COMNTOOLS"
|
||||
VS_VS_INSTALLDIR_2010="Microsoft Visual Studio 10.0"
|
||||
VS_SDK_INSTALLDIR_2010="Microsoft SDKs/Windows/v7.1"
|
||||
VS_VS_PLATFORM_NAME_2010="v100"
|
||||
VS_SDK_PLATFORM_NAME_2010="Windows7.1SDK"
|
||||
VS_SUPPORTED_2010=false
|
||||
|
||||
VS_DESCRIPTION_2012="Microsoft Visual Studio 2012"
|
||||
VS_VERSION_INTERNAL_2012=110
|
||||
VS_MSVCR_2012=msvcr110.dll
|
||||
VS_MSVCP_2012=msvcp110.dll
|
||||
VS_ENVVAR_2012="VS110COMNTOOLS"
|
||||
VS_VS_INSTALLDIR_2012="Microsoft Visual Studio 11.0"
|
||||
VS_SDK_INSTALLDIR_2012=
|
||||
VS_VS_PLATFORM_NAME_2012="v110"
|
||||
VS_SDK_PLATFORM_NAME_2012=
|
||||
VS_SUPPORTED_2012=false
|
||||
|
||||
VS_DESCRIPTION_2013="Microsoft Visual Studio 2013"
|
||||
VS_VERSION_INTERNAL_2013=120
|
||||
VS_MSVCR_2013=msvcr120.dll
|
||||
VS_MSVCP_2013=msvcp120.dll
|
||||
VS_ENVVAR_2013="VS120COMNTOOLS"
|
||||
VS_VS_INSTALLDIR_2013="Microsoft Visual Studio 12.0"
|
||||
VS_SDK_INSTALLDIR_2013=
|
||||
VS_VS_PLATFORM_NAME_2013="v120"
|
||||
VS_SDK_PLATFORM_NAME_2013=
|
||||
VS_SUPPORTED_2013=false
|
||||
|
||||
VS_DESCRIPTION_2015="Microsoft Visual Studio 2015"
|
||||
VS_VERSION_INTERNAL_2015=140
|
||||
VS_MSVCR_2015=vcruntime140.dll
|
||||
VS_MSVCP_2015=msvcp140.dll
|
||||
VS_ENVVAR_2015="VS140COMNTOOLS"
|
||||
VS_VS_INSTALLDIR_2015="Microsoft Visual Studio 14.0"
|
||||
VS_SDK_INSTALLDIR_2015=
|
||||
VS_VS_PLATFORM_NAME_2015="v140"
|
||||
VS_SDK_PLATFORM_NAME_2015=
|
||||
# The vcvars of 2015 breaks if 2017 is also installed. Work around this by
|
||||
# explicitly specifying Windows Kit 8.1 to be used.
|
||||
VS_ENV_ARGS_2015="8.1"
|
||||
VS_SUPPORTED_2015=false
|
||||
VALID_VS_VERSIONS="2019 2017"
|
||||
|
||||
VS_DESCRIPTION_2017="Microsoft Visual Studio 2017"
|
||||
VS_VERSION_INTERNAL_2017=141
|
||||
|
@ -37,18 +37,18 @@ ifeq ($(call check-jvm-feature, compiler2), true)
|
||||
ifeq ($(call isBuildOs, linux), true)
|
||||
ADLC_CFLAGS := -fno-exceptions -DLINUX
|
||||
else ifeq ($(call isBuildOs, aix), true)
|
||||
ADLC_LDFLAGS := -q64
|
||||
ADLC_LDFLAGS += -q64
|
||||
ADLC_CFLAGS := -qnortti -qeh -q64 -DAIX
|
||||
else ifeq ($(call isBuildOs, windows), true)
|
||||
ADLC_LDFLAGS := -nologo
|
||||
ADLC_LDFLAGS += -nologo
|
||||
ADLC_CFLAGS := -nologo -EHsc
|
||||
# NOTE: The old build also have -D_CRT_SECURE_NO_DEPRECATE but it doesn't
|
||||
# seem needed any more.
|
||||
ADLC_CFLAGS_WARNINGS := -W3 -D_CRT_SECURE_NO_WARNINGS
|
||||
endif
|
||||
|
||||
# Set the C++ standard if supported
|
||||
ADLC_CFLAGS += $(ADLC_CXXFLAG)
|
||||
# Set the C++ standard
|
||||
ADLC_CFLAGS += $(ADLC_LANGSTD_CXXFLAG)
|
||||
|
||||
# NOTE: The old build didn't set -DASSERT for windows but it doesn't seem to
|
||||
# hurt.
|
||||
|
@ -95,7 +95,8 @@ DISABLED_WARNINGS_clang := tautological-compare \
|
||||
|
||||
DISABLED_WARNINGS_xlc := tautological-compare shift-negative-value
|
||||
|
||||
DISABLED_WARNINGS_microsoft := 4100 4127 4201 4244 4291 4351 4511 4512 4514 4996
|
||||
DISABLED_WARNINGS_microsoft := 4100 4127 4201 4244 4291 4351 \
|
||||
4511 4512 4514 4624 4996
|
||||
|
||||
################################################################################
|
||||
# Platform specific setup
|
||||
|
@ -66,6 +66,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBSA, \
|
||||
CXXFLAGS := $(CXXFLAGS_JDKLIB) $(SA_CFLAGS) $(SA_CXXFLAGS), \
|
||||
EXTRA_SRC := $(LIBSA_EXTRA_SRC), \
|
||||
LDFLAGS := $(LDFLAGS_JDKLIB), \
|
||||
LIBS := $(LIBCXX), \
|
||||
LIBS_linux := $(LIBDL), \
|
||||
LIBS_macosx := -framework Foundation -framework JavaNativeFoundation \
|
||||
-framework JavaRuntimeSupport -framework Security -framework CoreFoundation, \
|
||||
|
@ -1099,7 +1099,7 @@ source %{
|
||||
|
||||
// r27 is not allocatable when compressed oops is on and heapbase is not
|
||||
// zero, compressed klass pointers doesn't use r27 after JDK-8234794
|
||||
if (UseCompressedOops && CompressedOops::ptrs_base() != NULL) {
|
||||
if (UseCompressedOops && (CompressedOops::ptrs_base() != NULL || UseAOT)) {
|
||||
_NO_SPECIAL_REG32_mask.Remove(OptoReg::as_OptoReg(r27->as_VMReg()));
|
||||
_NO_SPECIAL_REG_mask.SUBTRACT(_HEAPBASE_REG_mask);
|
||||
_NO_SPECIAL_PTR_REG_mask.SUBTRACT(_HEAPBASE_REG_mask);
|
||||
@ -4053,6 +4053,18 @@ operand immI_bitmask()
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
operand immL_positive_bitmaskI()
|
||||
%{
|
||||
predicate((n->get_long() != 0)
|
||||
&& ((julong)n->get_long() < 0x80000000ULL)
|
||||
&& is_power_of_2(n->get_long() + 1));
|
||||
match(ConL);
|
||||
|
||||
op_cost(0);
|
||||
format %{ %}
|
||||
interface(CONST_INTER);
|
||||
%}
|
||||
|
||||
// Scale values for scaled offset addressing modes (up to long but not quad)
|
||||
operand immIScale()
|
||||
%{
|
||||
@ -10150,7 +10162,7 @@ instruct lshift_ext(iRegLNoSp dst, iRegIorL2I src, immI scale, rFlagsReg cr) %{
|
||||
ins_encode %{
|
||||
__ sbfiz(as_Register($dst$$reg),
|
||||
as_Register($src$$reg),
|
||||
$scale$$constant & 63, MIN(32, (-$scale$$constant) & 63));
|
||||
$scale$$constant & 63, MIN2(32, (int)((-$scale$$constant) & 63)));
|
||||
%}
|
||||
|
||||
ins_pipe(ialu_reg_shift);
|
||||
@ -12149,6 +12161,50 @@ instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
// This pattern is automatically generated from aarch64_ad.m4
|
||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
||||
|
||||
// We can use ubfiz when masking by a positive number and then left shifting the result.
|
||||
// We know that the mask is positive because immI_bitmask guarantees it.
|
||||
instruct ubfizwIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
|
||||
%{
|
||||
match(Set dst (ConvI2L (LShiftI (AndI src mask) lshift)));
|
||||
predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(1)->in(2)->get_int() & 31)) <= 31);
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfizw $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant & 31;
|
||||
intptr_t mask = $mask$$constant;
|
||||
int width = exact_log2(mask+1);
|
||||
__ ubfizw(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
// This pattern is automatically generated from aarch64_ad.m4
|
||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
||||
|
||||
// We can use ubfiz when masking by a positive number and then left shifting the result.
|
||||
// We know that the mask is positive because immL_bitmask guarantees it.
|
||||
instruct ubfizLConvL2I(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
|
||||
%{
|
||||
match(Set dst (ConvL2I (LShiftL (AndL src mask) lshift)));
|
||||
predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(1)->in(2)->get_int() & 63)) <= 31);
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant & 63;
|
||||
intptr_t mask = $mask$$constant;
|
||||
int width = exact_log2_long(mask+1);
|
||||
__ ubfiz(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
|
||||
// This pattern is automatically generated from aarch64_ad.m4
|
||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
||||
@ -12171,6 +12227,42 @@ instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
// This pattern is automatically generated from aarch64_ad.m4
|
||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
||||
|
||||
// If there is a convert L to I block between and AndL and a LShiftI, we can also match ubfiz
|
||||
instruct ubfizLConvL2Ix(iRegINoSp dst, iRegL src, immI lshift, immL_positive_bitmaskI mask)
|
||||
%{
|
||||
match(Set dst (LShiftI (ConvL2I (AndL src mask)) lshift));
|
||||
predicate((exact_log2_long(n->in(1)->in(1)->in(2)->get_long() + 1) + (n->in(2)->get_int() & 31)) <= 31);
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant & 31;
|
||||
intptr_t mask = $mask$$constant;
|
||||
int width = exact_log2(mask+1);
|
||||
__ ubfiz(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
// This pattern is automatically generated from aarch64_ad.m4
|
||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
||||
|
||||
// Can skip int2long conversions after AND with small bitmask
|
||||
instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk)
|
||||
%{
|
||||
match(Set dst (ConvI2L (AndI src msk)));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %}
|
||||
ins_encode %{
|
||||
__ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1));
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
|
||||
// Rotations
|
||||
// This pattern is automatically generated from aarch64_ad.m4
|
||||
|
@ -237,39 +237,45 @@ define(`UBFIZ_INSN', `// This pattern is automatically generated from aarch64_ad
|
||||
|
||||
// We can use ubfiz when masking by a positive number and then left shifting the result.
|
||||
// We know that the mask is positive because imm$1_bitmask guarantees it.
|
||||
instruct $2$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift, imm$1_bitmask mask)
|
||||
instruct $3$1$8(iReg$2NoSp dst, iReg$1`'ORL2I($1) src, immI lshift, $7 mask)
|
||||
%{
|
||||
match(Set dst (LShift$1 (And$1 src mask) lshift));
|
||||
predicate((exact_log2$5(n->in(1)->in(2)->get_$4() + 1) + (n->in(2)->get_int() & $3)) <= ($3 + 1));
|
||||
ifelse($8,,
|
||||
match(Set dst (LShift$1 (And$1 src mask) lshift));,
|
||||
match(Set dst ($8 (LShift$1 (And$1 src mask) lshift)));)
|
||||
ifelse($8,,
|
||||
predicate(($6(n->in(1)->in(2)->get_$5() + 1) + (n->in(2)->get_int() & $4)) <= ($4 + 1));,
|
||||
predicate(($6(n->in(1)->in(1)->in(2)->get_$5() + 1) + (n->in(1)->in(2)->get_int() & $4)) <= 31);)
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "$2 $dst, $src, $lshift, $mask" %}
|
||||
format %{ "$3 $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant & $3;
|
||||
int lshift = $lshift$$constant & $4;
|
||||
intptr_t mask = $mask$$constant;
|
||||
int width = exact_log2$5(mask+1);
|
||||
__ $2(as_Register($dst$$reg),
|
||||
int width = $6(mask+1);
|
||||
__ $3(as_Register($dst$$reg),
|
||||
as_Register($src$$reg), lshift, width);
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
')
|
||||
UBFIZ_INSN(I, ubfizw, 31, int)
|
||||
UBFIZ_INSN(L, ubfiz, 63, long, _long)
|
||||
UBFIZ_INSN(I, I, ubfizw, 31, int, exact_log2, immI_bitmask)
|
||||
UBFIZ_INSN(L, L, ubfiz, 63, long, exact_log2_long, immL_bitmask)
|
||||
UBFIZ_INSN(I, L, ubfizw, 31, int, exact_log2, immI_bitmask, ConvI2L)
|
||||
UBFIZ_INSN(L, I, ubfiz, 63, long, exact_log2_long, immL_positive_bitmaskI, ConvL2I)
|
||||
|
||||
// This pattern is automatically generated from aarch64_ad.m4
|
||||
define(`BFX1_INSN', `// This pattern is automatically generated from aarch64_ad.m4
|
||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
||||
|
||||
// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
|
||||
instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
|
||||
// If there is a convert $1 to $2 block between and And$1 and a LShift$2, we can also match ubfiz
|
||||
instruct ubfiz$1Conv$3$9(iReg$2NoSp dst, iReg$1`'ORL2I($1) src, immI lshift, $8 mask)
|
||||
%{
|
||||
match(Set dst (LShiftL (ConvI2L (AndI src mask)) lshift));
|
||||
predicate((exact_log2(n->in(1)->in(1)->in(2)->get_int() + 1) + (n->in(2)->get_int() & 63)) <= (63 + 1));
|
||||
match(Set dst (LShift$2 (Conv$3 (And$1 src mask)) lshift));
|
||||
predicate(($4(n->in(1)->in(1)->in(2)->$5() + 1) + (n->in(2)->get_int() & $6)) <= $7);
|
||||
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfiz $dst, $src, $lshift, $mask" %}
|
||||
ins_encode %{
|
||||
int lshift = $lshift$$constant & 63;
|
||||
int lshift = $lshift$$constant & $6;
|
||||
intptr_t mask = $mask$$constant;
|
||||
int width = exact_log2(mask+1);
|
||||
__ ubfiz(as_Register($dst$$reg),
|
||||
@ -277,6 +283,23 @@ instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
')dnl
|
||||
BFX1_INSN(I, L, I2L, exact_log2, get_int, 63, (63 + 1), immI_bitmask)
|
||||
BFX1_INSN(L, I, L2I, exact_log2_long, get_long, 31, 31, immL_positive_bitmaskI, x)
|
||||
// This pattern is automatically generated from aarch64_ad.m4
|
||||
// DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
|
||||
|
||||
// Can skip int2long conversions after AND with small bitmask
|
||||
instruct ubfizIConvI2LAndI(iRegLNoSp dst, iRegI src, immI_bitmask msk)
|
||||
%{
|
||||
match(Set dst (ConvI2L (AndI src msk)));
|
||||
ins_cost(INSN_COST);
|
||||
format %{ "ubfiz $dst, $src, 0, exact_log2($msk + 1) " %}
|
||||
ins_encode %{
|
||||
__ ubfiz(as_Register($dst$$reg), as_Register($src$$reg), 0, exact_log2($msk$$constant + 1));
|
||||
%}
|
||||
ins_pipe(ialu_reg_shift);
|
||||
%}
|
||||
|
||||
|
||||
// Rotations dnl
|
||||
|
@ -1517,7 +1517,7 @@ void Address::lea(MacroAssembler *as, Register r) const {
|
||||
break;
|
||||
}
|
||||
case base_plus_offset_reg: {
|
||||
__ add(r, _base, _index, _ext.op(), MAX(_ext.shift(), 0));
|
||||
__ add(r, _base, _index, _ext.op(), MAX2(_ext.shift(), 0));
|
||||
break;
|
||||
}
|
||||
case literal: {
|
||||
|
@ -2284,7 +2284,6 @@ void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
|
||||
assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point");
|
||||
|
||||
int elem_size = type2aelembytes(basic_type);
|
||||
int shift_amount;
|
||||
int scale = exact_log2(elem_size);
|
||||
|
||||
Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());
|
||||
|
@ -658,10 +658,10 @@ intptr_t* frame::real_fp() const {
|
||||
p[frame::name##_offset], #name); \
|
||||
}
|
||||
|
||||
static __thread uintptr_t nextfp;
|
||||
static __thread uintptr_t nextpc;
|
||||
static __thread uintptr_t nextsp;
|
||||
static __thread RegisterMap *reg_map;
|
||||
static THREAD_LOCAL uintptr_t nextfp;
|
||||
static THREAD_LOCAL uintptr_t nextpc;
|
||||
static THREAD_LOCAL uintptr_t nextsp;
|
||||
static THREAD_LOCAL RegisterMap *reg_map;
|
||||
|
||||
static void printbc(Method *m, intptr_t bcx) {
|
||||
const char *name;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -67,8 +67,6 @@ 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);
|
||||
|
||||
Label done;
|
||||
|
||||
// Load bad mask into scratch register.
|
||||
@ -82,37 +80,21 @@ void ZBarrierSetAssembler::load_at(MacroAssembler* masm,
|
||||
|
||||
__ enter();
|
||||
|
||||
__ push(savedRegs, sp);
|
||||
__ push_call_clobbered_registers_except(RegSet::of(dst));
|
||||
|
||||
if (c_rarg0 != dst) {
|
||||
__ mov(c_rarg0, dst);
|
||||
}
|
||||
__ mov(c_rarg1, rscratch2);
|
||||
|
||||
int step = 4 * wordSize;
|
||||
__ mov(rscratch2, -step);
|
||||
__ sub(sp, sp, step);
|
||||
|
||||
for (int i = 28; i >= 4; i -= 4) {
|
||||
__ st1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
|
||||
as_FloatRegister(i+3), __ T1D, Address(__ post(sp, rscratch2)));
|
||||
}
|
||||
__ st1(as_FloatRegister(0), as_FloatRegister(1), as_FloatRegister(2),
|
||||
as_FloatRegister(3), __ T1D, Address(sp));
|
||||
|
||||
__ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2);
|
||||
|
||||
for (int i = 0; i <= 28; i += 4) {
|
||||
__ ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
|
||||
as_FloatRegister(i+3), __ T1D, Address(__ post(sp, step)));
|
||||
}
|
||||
|
||||
// Make sure dst has the return value.
|
||||
if (dst != r0) {
|
||||
__ mov(dst, r0);
|
||||
}
|
||||
|
||||
__ pop(savedRegs, sp);
|
||||
__ pop_call_clobbered_registers_except(RegSet::of(dst));
|
||||
__ leave();
|
||||
|
||||
__ bind(done);
|
||||
@ -170,7 +152,7 @@ void ZBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm,
|
||||
|
||||
assert_different_registers(src, count, rscratch1);
|
||||
|
||||
__ pusha();
|
||||
__ push(saved_regs, sp);
|
||||
|
||||
if (count == c_rarg0) {
|
||||
if (src == c_rarg1) {
|
||||
@ -189,7 +171,8 @@ void ZBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm,
|
||||
|
||||
__ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_array_addr(), 2);
|
||||
|
||||
__ popa();
|
||||
__ pop(saved_regs, sp);
|
||||
|
||||
BLOCK_COMMENT("} ZBarrierSetAssembler::arraycopy_prologue");
|
||||
}
|
||||
|
||||
@ -295,13 +278,7 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler*
|
||||
DecoratorSet decorators) const {
|
||||
__ 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)));
|
||||
}
|
||||
|
||||
const RegSet save_regs = RegSet::range(r1, r28);
|
||||
__ push(save_regs, sp);
|
||||
__ push_call_clobbered_registers_except(RegSet::of(r0));
|
||||
|
||||
// Setup arguments
|
||||
__ load_parameter(0, c_rarg0);
|
||||
@ -309,11 +286,7 @@ void ZBarrierSetAssembler::generate_c1_load_barrier_runtime_stub(StubAssembler*
|
||||
|
||||
__ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2);
|
||||
|
||||
__ pop(save_regs, sp);
|
||||
|
||||
for (int i = 30; i >= 0; i -= 2) {
|
||||
__ ldpd(as_FloatRegister(i), as_FloatRegister(i + 1), Address(__ post(sp, 16)));
|
||||
}
|
||||
__ pop_call_clobbered_registers_except(RegSet::of(r0));
|
||||
|
||||
__ epilogue();
|
||||
}
|
||||
|
@ -2626,9 +2626,9 @@ void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[])
|
||||
fatal("DEBUG MESSAGE: %s", msg);
|
||||
}
|
||||
|
||||
void MacroAssembler::push_call_clobbered_registers() {
|
||||
void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) {
|
||||
int step = 4 * wordSize;
|
||||
push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
|
||||
push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2) - exclude, sp);
|
||||
sub(sp, sp, step);
|
||||
mov(rscratch1, -step);
|
||||
// Push v0-v7, v16-v31.
|
||||
@ -2641,14 +2641,14 @@ void MacroAssembler::push_call_clobbered_registers() {
|
||||
as_FloatRegister(3), T1D, Address(sp));
|
||||
}
|
||||
|
||||
void MacroAssembler::pop_call_clobbered_registers() {
|
||||
void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) {
|
||||
for (int i = 0; i < 32; i += 4) {
|
||||
if (i <= v7->encoding() || i >= v16->encoding())
|
||||
ld1(as_FloatRegister(i), as_FloatRegister(i+1), as_FloatRegister(i+2),
|
||||
as_FloatRegister(i+3), T1D, Address(post(sp, 4 * wordSize)));
|
||||
}
|
||||
|
||||
pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
|
||||
pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2) - exclude, sp);
|
||||
}
|
||||
|
||||
void MacroAssembler::push_CPU_state(bool save_vectors) {
|
||||
|
@ -477,9 +477,18 @@ public:
|
||||
// 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
|
||||
// 64 bits of each vector register.
|
||||
void push_call_clobbered_registers();
|
||||
void pop_call_clobbered_registers();
|
||||
// 64 bits of each vector register. Additonal registers can be excluded
|
||||
// in a passed RegSet.
|
||||
void push_call_clobbered_registers_except(RegSet exclude);
|
||||
void pop_call_clobbered_registers_except(RegSet exclude);
|
||||
|
||||
void push_call_clobbered_registers() {
|
||||
push_call_clobbered_registers_except(RegSet());
|
||||
}
|
||||
void pop_call_clobbered_registers() {
|
||||
pop_call_clobbered_registers_except(RegSet());
|
||||
}
|
||||
|
||||
|
||||
// now mov instructions for loading absolute addresses and 32 or
|
||||
// 64 bit integers
|
||||
|
@ -697,7 +697,6 @@ class StubGenerator: public StubCodeGenerator {
|
||||
int unit = wordSize * direction;
|
||||
int bias = (UseSIMDForMemoryOps ? 4:2) * wordSize;
|
||||
|
||||
int offset;
|
||||
const Register t0 = r3, t1 = r4, t2 = r5, t3 = r6,
|
||||
t4 = r7, t5 = r10, t6 = r11, t7 = r12;
|
||||
const Register stride = r13;
|
||||
@ -4061,7 +4060,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
FloatRegister vtmpZ = v0, vtmp = v1, vtmp3 = v2;
|
||||
RegSet spilled_regs = RegSet::of(tmp3, tmp4);
|
||||
|
||||
int prefetchLoopExitCondition = MAX(64, SoftwarePrefetchHintDistance/2);
|
||||
int prefetchLoopExitCondition = MAX2(64, SoftwarePrefetchHintDistance/2);
|
||||
|
||||
__ eor(vtmpZ, __ T16B, vtmpZ, vtmpZ);
|
||||
// cnt2 == amount of characters left to compare
|
||||
@ -4219,7 +4218,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
DIFF_LAST_POSITION, DIFF_LAST_POSITION2;
|
||||
// exit from large loop when less than 64 bytes left to read or we're about
|
||||
// to prefetch memory behind array border
|
||||
int largeLoopExitCondition = MAX(64, SoftwarePrefetchHintDistance)/(isLL ? 1 : 2);
|
||||
int largeLoopExitCondition = MAX2(64, SoftwarePrefetchHintDistance)/(isLL ? 1 : 2);
|
||||
// cnt1/cnt2 contains amount of characters to compare. cnt1 can be re-used
|
||||
// update cnt2 counter with already loaded 8 bytes
|
||||
__ sub(cnt2, cnt2, wordSize/(isLL ? 1 : 2));
|
||||
@ -4645,7 +4644,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
address entry = __ pc();
|
||||
Label LOOP, LOOP_START, LOOP_PRFM, LOOP_PRFM_START, DONE;
|
||||
Register src = r0, dst = r1, len = r2, octetCounter = r3;
|
||||
const int large_loop_threshold = MAX(64, SoftwarePrefetchHintDistance)/8 + 4;
|
||||
const int large_loop_threshold = MAX2(64, SoftwarePrefetchHintDistance)/8 + 4;
|
||||
|
||||
// do one more 8-byte read to have address 16-byte aligned in most cases
|
||||
// also use single store instruction
|
||||
|
@ -413,6 +413,7 @@ void TemplateTable::fast_aldc(bool wide)
|
||||
// Stash null_sentinel address to get its value later
|
||||
__ movptr(rarg, (uintptr_t)Universe::the_null_sentinel_addr());
|
||||
__ ldr(tmp, Address(rarg));
|
||||
__ resolve_oop_handle(tmp);
|
||||
__ cmpoop(result, tmp);
|
||||
__ br(Assembler::NE, notNull);
|
||||
__ mov(result, 0); // NULL object reference
|
||||
|
@ -462,6 +462,7 @@ void TemplateTable::fast_aldc(bool wide) {
|
||||
// Stash null_sentinel address to get its value later
|
||||
__ mov_slow(rarg, (uintptr_t)Universe::the_null_sentinel_addr());
|
||||
__ ldr(tmp, Address(rarg));
|
||||
__ resolve_oop_handle(tmp);
|
||||
__ cmp(result, tmp);
|
||||
__ b(notNull, ne);
|
||||
__ mov(result, 0); // NULL object reference
|
||||
|
@ -317,9 +317,10 @@ void TemplateTable::fast_aldc(bool wide) {
|
||||
__ get_cache_index_at_bcp(Rscratch, 1, index_size); // Load index.
|
||||
__ load_resolved_reference_at_index(R17_tos, Rscratch, &is_null);
|
||||
|
||||
// Convert null sentinel to NULL.
|
||||
// Convert null sentinel to NULL
|
||||
int simm16_rest = __ load_const_optimized(Rscratch, Universe::the_null_sentinel_addr(), R0, true);
|
||||
__ ld(Rscratch, simm16_rest, Rscratch);
|
||||
__ resolve_oop_handle(Rscratch);
|
||||
__ cmpld(CCR0, R17_tos, Rscratch);
|
||||
if (VM_Version::has_isel()) {
|
||||
__ isel_0(R17_tos, CCR0, Assembler::equal);
|
||||
|
@ -466,6 +466,7 @@ void TemplateTable::fast_aldc(bool wide) {
|
||||
|
||||
// Convert null sentinel to NULL.
|
||||
__ load_const_optimized(Z_R1_scratch, (intptr_t)Universe::the_null_sentinel_addr());
|
||||
__ resolve_oop_handle(Z_R1_scratch);
|
||||
__ z_cg(Z_tos, Address(Z_R1_scratch));
|
||||
__ z_brne(L_resolved);
|
||||
__ clear_reg(Z_tos);
|
||||
|
@ -448,6 +448,7 @@ void TemplateTable::fast_aldc(bool wide) {
|
||||
Label notNull;
|
||||
ExternalAddress null_sentinel((address)Universe::the_null_sentinel_addr());
|
||||
__ movptr(tmp, null_sentinel);
|
||||
__ resolve_oop_handle(tmp);
|
||||
__ cmpoop(tmp, result);
|
||||
__ jccb(Assembler::notEqual, notNull);
|
||||
__ xorptr(result, result); // NULL object reference
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "aot/aotCompiledMethod.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "metaprogramming/integralConstant.hpp"
|
||||
#include "metaprogramming/isRegisteredEnum.hpp"
|
||||
#include "oops/metadata.hpp"
|
||||
#include "oops/method.hpp"
|
||||
|
||||
@ -37,8 +36,6 @@ enum CodeState {
|
||||
invalid = 2 // AOT code is invalidated because dependencies failed
|
||||
};
|
||||
|
||||
template<> struct IsRegisteredEnum<CodeState> : public TrueType {};
|
||||
|
||||
typedef struct {
|
||||
AOTCompiledMethod* _aot;
|
||||
CodeState _state; // State change cases: not_set->in_use, not_set->invalid
|
||||
|
@ -195,6 +195,9 @@ class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
|
||||
oop method_type() const;
|
||||
void set_method_type(oop p);
|
||||
|
||||
// We need to clear the OopHandle because these hashtable entries are not constructed properly.
|
||||
void clear_method_type() { _method_type = OopHandle(); }
|
||||
|
||||
void free_entry();
|
||||
|
||||
SymbolPropertyEntry* next() const {
|
||||
@ -247,7 +250,7 @@ private:
|
||||
symbol->increment_refcount();
|
||||
entry->set_symbol_mode(symbol_mode);
|
||||
entry->set_method(NULL);
|
||||
entry->set_method_type(NULL);
|
||||
entry->clear_method_type();
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
@ -436,11 +436,11 @@ char* java_lang_String::as_platform_dependent_str(Handle java_string, TRAPS) {
|
||||
char *native_platform_string;
|
||||
{ JavaThread* thread = (JavaThread*)THREAD;
|
||||
assert(thread->is_Java_thread(), "must be java thread");
|
||||
JNIEnv *env = thread->jni_environment();
|
||||
jstring js = (jstring) JNIHandles::make_local(env, java_string());
|
||||
jstring js = (jstring) JNIHandles::make_local(thread, java_string());
|
||||
bool is_copy;
|
||||
HandleMark hm(thread);
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
JNIEnv *env = thread->jni_environment();
|
||||
native_platform_string = (_to_platform_string_fn)(env, js, &is_copy);
|
||||
assert(is_copy == JNI_TRUE, "is_copy value changed");
|
||||
JNIHandles::destroy_local(js);
|
||||
@ -895,7 +895,7 @@ void java_lang_Class::fixup_mirror(Klass* k, TRAPS) {
|
||||
assert(present, "Missing archived mirror for %s", k->external_name());
|
||||
return;
|
||||
} else {
|
||||
k->set_java_mirror_handle(OopHandle());
|
||||
k->clear_java_mirror_handle();
|
||||
k->clear_has_raw_archived_mirror();
|
||||
}
|
||||
}
|
||||
@ -1201,7 +1201,7 @@ oop java_lang_Class::archive_mirror(Klass* k, TRAPS) {
|
||||
ik->is_shared_app_class())) {
|
||||
// Archiving mirror for classes from non-builtin loaders is not
|
||||
// supported. Clear the _java_mirror within the archived class.
|
||||
k->set_java_mirror_handle(OopHandle());
|
||||
k->clear_java_mirror_handle();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -2844,10 +2844,10 @@ Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* h
|
||||
void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci, TRAPS) {
|
||||
// set Method* or mid/cpref
|
||||
HandleMark hm(THREAD);
|
||||
Handle mname(Thread::current(), stackFrame->obj_field(_memberName_offset));
|
||||
Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
|
||||
InstanceKlass* ik = method->method_holder();
|
||||
CallInfo info(method(), ik, CHECK);
|
||||
MethodHandles::init_method_MemberName(mname, info);
|
||||
MethodHandles::init_method_MemberName(mname, info, THREAD);
|
||||
// set bci
|
||||
java_lang_StackFrameInfo::set_bci(stackFrame(), bci);
|
||||
// method may be redefined; store the version
|
||||
|
@ -1903,8 +1903,7 @@ class CopySharedClassInfoToArchive : StackObj {
|
||||
bool _is_builtin;
|
||||
public:
|
||||
CopySharedClassInfoToArchive(CompactHashtableWriter* writer,
|
||||
bool is_builtin,
|
||||
bool is_static_archive)
|
||||
bool is_builtin)
|
||||
: _writer(writer), _is_builtin(is_builtin) {}
|
||||
|
||||
bool do_entry(InstanceKlass* k, DumpTimeSharedClassInfo& info) {
|
||||
@ -1953,12 +1952,11 @@ void SystemDictionaryShared::write_lambda_proxy_class_dictionary(LambdaProxyClas
|
||||
}
|
||||
|
||||
void SystemDictionaryShared::write_dictionary(RunTimeSharedDictionary* dictionary,
|
||||
bool is_builtin,
|
||||
bool is_static_archive) {
|
||||
bool is_builtin) {
|
||||
CompactHashtableStats stats;
|
||||
dictionary->reset();
|
||||
CompactHashtableWriter writer(_dumptime_table->count_of(is_builtin), &stats);
|
||||
CopySharedClassInfoToArchive copy(&writer, is_builtin, is_static_archive);
|
||||
CopySharedClassInfoToArchive copy(&writer, is_builtin);
|
||||
_dumptime_table->iterate(©);
|
||||
writer.dump(dictionary, is_builtin ? "builtin dictionary" : "unregistered dictionary");
|
||||
}
|
||||
|
@ -211,8 +211,7 @@ private:
|
||||
TRAPS);
|
||||
static DumpTimeSharedClassInfo* find_or_allocate_info_for(InstanceKlass* k);
|
||||
static void write_dictionary(RunTimeSharedDictionary* dictionary,
|
||||
bool is_builtin,
|
||||
bool is_static_archive = true);
|
||||
bool is_builtin);
|
||||
static void write_lambda_proxy_class_dictionary(LambdaProxyClassDictionary* dictionary);
|
||||
static bool is_jfr_event_class(InstanceKlass *k);
|
||||
static bool is_registered_lambda_proxy_class(InstanceKlass* ik);
|
||||
|
@ -296,7 +296,6 @@ bool Verifier::is_eligible_for_verification(InstanceKlass* klass, bool should_ve
|
||||
Symbol* Verifier::inference_verify(
|
||||
InstanceKlass* klass, char* message, size_t message_len, TRAPS) {
|
||||
JavaThread* thread = (JavaThread*)THREAD;
|
||||
JNIEnv *env = thread->jni_environment();
|
||||
|
||||
verify_byte_codes_fn_t verify_func = verify_byte_codes_fn();
|
||||
|
||||
@ -305,10 +304,10 @@ Symbol* Verifier::inference_verify(
|
||||
return vmSymbols::java_lang_VerifyError();
|
||||
}
|
||||
|
||||
ResourceMark rm(THREAD);
|
||||
ResourceMark rm(thread);
|
||||
log_info(verification)("Verifying class %s with old format", klass->external_name());
|
||||
|
||||
jclass cls = (jclass) JNIHandles::make_local(env, klass->java_mirror());
|
||||
jclass cls = (jclass) JNIHandles::make_local(thread, klass->java_mirror());
|
||||
jint result;
|
||||
|
||||
{
|
||||
@ -316,7 +315,7 @@ Symbol* Verifier::inference_verify(
|
||||
ThreadToNativeFromVM ttn(thread);
|
||||
// ThreadToNativeFromVM takes care of changing thread_state, so safepoint
|
||||
// code knows that we have left the VM
|
||||
|
||||
JNIEnv *env = thread->jni_environment();
|
||||
result = (*verify_func)(env, cls, message, (int)message_len, klass->major_version());
|
||||
}
|
||||
|
||||
|
@ -1655,7 +1655,7 @@ void CompileBroker::wait_for_completion(CompileTask* task) {
|
||||
bool free_task;
|
||||
#if INCLUDE_JVMCI
|
||||
AbstractCompiler* comp = compiler(task->comp_level());
|
||||
if (!UseJVMCINativeLibrary && comp->is_jvmci() && !task->should_wait_for_compilation()) {
|
||||
if (comp->is_jvmci() && !task->should_wait_for_compilation()) {
|
||||
// It may return before compilation is completed.
|
||||
free_task = wait_for_jvmci_completion((JVMCICompiler*) comp, task, thread);
|
||||
} else
|
||||
|
@ -68,9 +68,11 @@ G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h,
|
||||
// entries, since entry 0 keeps track of surviving bytes for non-young regions.
|
||||
// We also add a few elements at the beginning and at the end in
|
||||
// an attempt to eliminate cache contention
|
||||
size_t array_length = PADDING_ELEM_NUM + _surviving_words_length + PADDING_ELEM_NUM;
|
||||
const size_t padding_elem_num = (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t));
|
||||
size_t array_length = padding_elem_num + _surviving_words_length + padding_elem_num;
|
||||
|
||||
_surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
|
||||
_surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
|
||||
_surviving_young_words = _surviving_young_words_base + padding_elem_num;
|
||||
memset(_surviving_young_words, 0, _surviving_words_length * sizeof(size_t));
|
||||
|
||||
_plab_allocator = new G1PLABAllocator(_g1h->allocator());
|
||||
|
@ -81,8 +81,6 @@ class G1ParScanThreadState : public CHeapObj<mtGC> {
|
||||
// available for allocation.
|
||||
bool _old_gen_is_full;
|
||||
|
||||
#define PADDING_ELEM_NUM (DEFAULT_CACHE_LINE_SIZE / sizeof(size_t))
|
||||
|
||||
G1RedirtyCardsQueue& redirty_cards_queue() { return _rdcq; }
|
||||
G1CardTable* ct() { return _ct; }
|
||||
|
||||
|
@ -53,6 +53,7 @@ ShenandoahParallelWeakRootsCleaningTask<IsAlive, KeepAlive>::~ShenandoahParallel
|
||||
if (StringDedup::is_enabled()) {
|
||||
StringDedup::gc_epilogue();
|
||||
}
|
||||
_weak_processing_task.report_num_dead();
|
||||
}
|
||||
|
||||
template<typename IsAlive, typename KeepAlive>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -135,7 +135,6 @@ T* JfrDoublyLinkedList<T>::remove(T* const node) {
|
||||
prev->set_next(next);
|
||||
}
|
||||
--_count;
|
||||
assert(_count >= 0, "invariant");
|
||||
assert(!in_list(node), "still in list error");
|
||||
return node;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -83,7 +83,7 @@ class JfrBasicHashtable : public CHeapObj<mtTracing> {
|
||||
|
||||
size_t hash_to_index(uintptr_t full_hash) const {
|
||||
const uintptr_t h = full_hash % _table_size;
|
||||
assert(h >= 0 && h < _table_size, "Illegal hash value");
|
||||
assert(h < _table_size, "Illegal hash value");
|
||||
return (size_t)h;
|
||||
}
|
||||
size_t entry_size() const { return _entry_size; }
|
||||
|
@ -251,7 +251,7 @@ C2V_VMENTRY_NULL(jobject, getObjectAtAddress, (JNIEnv* env, jobject c2vm, jlong
|
||||
if (obj != NULL) {
|
||||
oopDesc::verify(obj);
|
||||
}
|
||||
return JNIHandles::make_local(obj);
|
||||
return JNIHandles::make_local(THREAD, obj);
|
||||
C2V_END
|
||||
|
||||
C2V_VMENTRY_NULL(jbyteArray, getBytecode, (JNIEnv* env, jobject, jobject jvmci_method))
|
||||
@ -1038,7 +1038,7 @@ C2V_VMENTRY_NULL(jobject, executeHotSpotNmethod, (JNIEnv* env, jobject, jobject
|
||||
if (jap.return_type() == T_VOID) {
|
||||
return NULL;
|
||||
} else if (is_reference_type(jap.return_type())) {
|
||||
return JNIHandles::make_local((oop) result.get_jobject());
|
||||
return JNIHandles::make_local(THREAD, (oop) result.get_jobject());
|
||||
} else {
|
||||
jvalue *value = (jvalue *) result.get_value_addr();
|
||||
// Narrow the value down if required (Important on big endian machines)
|
||||
@ -2314,7 +2314,7 @@ C2V_VMENTRY_NULL(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclas
|
||||
}
|
||||
|
||||
typeArrayOop info_oop = oopFactory::new_longArray(4, CHECK_0);
|
||||
jlongArray info = (jlongArray) JNIHandles::make_local(info_oop);
|
||||
jlongArray info = (jlongArray) JNIHandles::make_local(THREAD, info_oop);
|
||||
runtime->init_JavaVM_info(info, JVMCI_CHECK_0);
|
||||
return info;
|
||||
}
|
||||
@ -2565,7 +2565,7 @@ C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmc
|
||||
}
|
||||
fieldDescriptor fd(iklass, index);
|
||||
oop reflected = Reflection::new_field(&fd, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, reflected);
|
||||
return JNIHandles::make_local(THREAD, reflected);
|
||||
}
|
||||
|
||||
C2V_VMENTRY_NULL(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current))
|
||||
|
@ -672,6 +672,7 @@ void JVMCINMethodData::set_nmethod_mirror(nmethod* nm, oop new_mirror) {
|
||||
|
||||
// Since we've patched some oops in the nmethod,
|
||||
// (re)register it with the heap.
|
||||
MutexLocker ml(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
Universe::heap()->register_nmethod(nm);
|
||||
}
|
||||
|
||||
@ -800,7 +801,7 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm() {
|
||||
|
||||
JNI_CreateJavaVM = CAST_TO_FN_PTR(JNI_CreateJavaVM_t, os::dll_lookup(sl_handle, "JNI_CreateJavaVM"));
|
||||
if (JNI_CreateJavaVM == NULL) {
|
||||
vm_exit_during_initialization("Unable to find JNI_CreateJavaVM", sl_path);
|
||||
fatal("Unable to find JNI_CreateJavaVM in %s", sl_path);
|
||||
}
|
||||
|
||||
ResourceMark rm;
|
||||
@ -835,7 +836,7 @@ JNIEnv* JVMCIRuntime::init_shared_library_javavm() {
|
||||
JVMCI_event_1("created JavaVM[%ld]@" PTR_FORMAT " for JVMCI runtime %d", javaVM_id, p2i(javaVM), _id);
|
||||
return env;
|
||||
} else {
|
||||
vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), sl_path);
|
||||
fatal("JNI_CreateJavaVM failed with return value %d", result);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,23 +22,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "metaprogramming/integralConstant.hpp"
|
||||
#include "metaprogramming/isRegisteredEnum.hpp"
|
||||
#ifndef SHARE_MEMORY_ALLSTATIC_HPP
|
||||
#define SHARE_MEMORY_ALLSTATIC_HPP
|
||||
|
||||
#include "unittest.hpp"
|
||||
|
||||
struct IsRegisteredEnumTest : AllStatic {
|
||||
enum A { A_x, A_y, A_z };
|
||||
enum B { B_x, B_y, B_z };
|
||||
// Base class for classes used as namespaces. HotSpot style prefers
|
||||
// using classes for grouping. Deriving from this class indicates the
|
||||
// derived class is intended to be a namespace, with no instances ever
|
||||
// created.
|
||||
struct AllStatic {
|
||||
AllStatic() = delete;
|
||||
~AllStatic() = delete;
|
||||
};
|
||||
|
||||
typedef IsRegisteredEnumTest::A A;
|
||||
typedef IsRegisteredEnumTest::B B;
|
||||
|
||||
template<> struct IsRegisteredEnum<A> : public TrueType {};
|
||||
|
||||
STATIC_ASSERT(!IsRegisteredEnum<int>::value);
|
||||
STATIC_ASSERT(IsRegisteredEnum<A>::value);
|
||||
STATIC_ASSERT(!IsRegisteredEnum<B>::value);
|
||||
#endif // SHARE_MEMORY_ALLSTATIC_HPP
|
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_MEMORY_ALLOCATION_HPP
|
||||
#define SHARE_MEMORY_ALLOCATION_HPP
|
||||
|
||||
#include "memory/allStatic.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
@ -349,13 +350,6 @@ class MetaspaceObj {
|
||||
|
||||
class Arena;
|
||||
|
||||
class AllStatic {
|
||||
public:
|
||||
AllStatic() { ShouldNotCallThis(); }
|
||||
~AllStatic() { ShouldNotCallThis(); }
|
||||
};
|
||||
|
||||
|
||||
extern char* resource_allocate_bytes(size_t size,
|
||||
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
|
||||
extern char* resource_allocate_bytes(Thread* thread, size_t size,
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "oops/instanceRefKlass.hpp"
|
||||
#include "oops/objArrayOop.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/oopHandle.inline.hpp"
|
||||
#include "oops/typeArrayKlass.hpp"
|
||||
#include "prims/resolvedMethodTable.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
@ -106,35 +107,46 @@ PRIMITIVE_MIRRORS_DO(DEFINE_PRIMITIVE_MIRROR)
|
||||
Klass* Universe::_typeArrayKlassObjs[T_LONG+1] = { NULL /*, NULL...*/ };
|
||||
Klass* Universe::_objectArrayKlassObj = NULL;
|
||||
oop Universe::_mirrors[T_VOID+1] = { NULL /*, NULL...*/ };
|
||||
oop Universe::_main_thread_group = NULL;
|
||||
oop Universe::_system_thread_group = NULL;
|
||||
objArrayOop Universe::_the_empty_class_klass_array = NULL;
|
||||
|
||||
OopHandle Universe::_main_thread_group;
|
||||
OopHandle Universe::_system_thread_group;
|
||||
OopHandle Universe::_the_empty_class_array;
|
||||
OopHandle Universe::_the_null_string;
|
||||
OopHandle Universe::_the_min_jint_string;
|
||||
|
||||
OopHandle Universe::_the_null_sentinel;
|
||||
|
||||
// _out_of_memory_errors is an objArray
|
||||
enum OutOfMemoryInstance { _oom_java_heap,
|
||||
_oom_c_heap,
|
||||
_oom_metaspace,
|
||||
_oom_class_metaspace,
|
||||
_oom_array_size,
|
||||
_oom_gc_overhead_limit,
|
||||
_oom_realloc_objects,
|
||||
_oom_retry,
|
||||
_oom_count };
|
||||
|
||||
OopHandle Universe::_out_of_memory_errors;
|
||||
OopHandle Universe::_delayed_stack_overflow_error_message;
|
||||
OopHandle Universe::_preallocated_out_of_memory_error_array;
|
||||
volatile jint Universe::_preallocated_out_of_memory_error_avail_count = 0;
|
||||
|
||||
OopHandle Universe::_null_ptr_exception_instance;
|
||||
OopHandle Universe::_arithmetic_exception_instance;
|
||||
OopHandle Universe::_virtual_machine_error_instance;
|
||||
|
||||
oop Universe::_reference_pending_list = NULL;
|
||||
|
||||
Array<Klass*>* Universe::_the_array_interfaces_array = NULL;
|
||||
oop Universe::_the_null_sentinel = NULL;
|
||||
oop Universe::_the_null_string = NULL;
|
||||
oop Universe::_the_min_jint_string = NULL;
|
||||
LatestMethodCache* Universe::_finalizer_register_cache = NULL;
|
||||
LatestMethodCache* Universe::_loader_addClass_cache = NULL;
|
||||
LatestMethodCache* Universe::_throw_illegal_access_error_cache = NULL;
|
||||
LatestMethodCache* Universe::_throw_no_such_method_error_cache = NULL;
|
||||
LatestMethodCache* Universe::_do_stack_walk_cache = NULL;
|
||||
oop Universe::_out_of_memory_error_java_heap = NULL;
|
||||
oop Universe::_out_of_memory_error_metaspace = NULL;
|
||||
oop Universe::_out_of_memory_error_class_metaspace = NULL;
|
||||
oop Universe::_out_of_memory_error_array_size = NULL;
|
||||
oop Universe::_out_of_memory_error_gc_overhead_limit = NULL;
|
||||
oop Universe::_out_of_memory_error_realloc_objects = NULL;
|
||||
oop Universe::_out_of_memory_error_retry = NULL;
|
||||
oop Universe::_delayed_stack_overflow_error_message = NULL;
|
||||
objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL;
|
||||
volatile jint Universe::_preallocated_out_of_memory_error_avail_count = 0;
|
||||
|
||||
bool Universe::_verify_in_progress = false;
|
||||
long Universe::verify_flags = Universe::Verify_All;
|
||||
oop Universe::_null_ptr_exception_instance = NULL;
|
||||
oop Universe::_arithmetic_exception_instance = NULL;
|
||||
oop Universe::_virtual_machine_error_instance = NULL;
|
||||
oop Universe::_vm_exception = NULL;
|
||||
oop Universe::_reference_pending_list = NULL;
|
||||
|
||||
Array<int>* Universe::_the_empty_int_array = NULL;
|
||||
Array<u2>* Universe::_the_empty_short_array = NULL;
|
||||
@ -143,8 +155,8 @@ Array<InstanceKlass*>* Universe::_the_empty_instance_klass_array = NULL;
|
||||
Array<Method*>* Universe::_the_empty_method_array = NULL;
|
||||
|
||||
// These variables are guarded by FullGCALot_lock.
|
||||
debug_only(objArrayOop Universe::_fullgc_alot_dummy_array = NULL;)
|
||||
debug_only(int Universe::_fullgc_alot_dummy_next = 0;)
|
||||
debug_only(OopHandle Universe::_fullgc_alot_dummy_array;)
|
||||
debug_only(int Universe::_fullgc_alot_dummy_next = 0;)
|
||||
|
||||
// Heap
|
||||
int Universe::_verify_count = 0;
|
||||
@ -166,6 +178,25 @@ OopStorage* Universe::_vm_global = NULL;
|
||||
|
||||
CollectedHeap* Universe::_collectedHeap = NULL;
|
||||
|
||||
objArrayOop Universe::the_empty_class_array () {
|
||||
return (objArrayOop)_the_empty_class_array.resolve();
|
||||
}
|
||||
|
||||
oop Universe::main_thread_group() { return _main_thread_group.resolve(); }
|
||||
void Universe::set_main_thread_group(oop group) { _main_thread_group = OopHandle(vm_global(), group); }
|
||||
|
||||
oop Universe::system_thread_group() { return _system_thread_group.resolve(); }
|
||||
void Universe::set_system_thread_group(oop group) { _system_thread_group = OopHandle(vm_global(), group); }
|
||||
|
||||
oop Universe::the_null_string() { return _the_null_string.resolve(); }
|
||||
oop Universe::the_min_jint_string() { return _the_min_jint_string.resolve(); }
|
||||
|
||||
oop Universe::null_ptr_exception_instance() { return _null_ptr_exception_instance.resolve(); }
|
||||
oop Universe::arithmetic_exception_instance() { return _arithmetic_exception_instance.resolve(); }
|
||||
oop Universe::virtual_machine_error_instance() { return _virtual_machine_error_instance.resolve(); }
|
||||
|
||||
oop Universe::the_null_sentinel() { return _the_null_sentinel.resolve(); }
|
||||
|
||||
void Universe::basic_type_classes_do(void f(Klass*)) {
|
||||
for (int i = T_BOOLEAN; i < T_LONG+1; i++) {
|
||||
f(_typeArrayKlassObjs[i]);
|
||||
@ -185,31 +216,11 @@ void Universe::oops_do(OopClosure* f) {
|
||||
PRIMITIVE_MIRRORS_DO(DO_PRIMITIVE_MIRROR);
|
||||
|
||||
for (int i = T_BOOLEAN; i < T_VOID+1; i++) {
|
||||
f->do_oop((oop*) &_mirrors[i]);
|
||||
f->do_oop(&_mirrors[i]);
|
||||
}
|
||||
assert(_mirrors[0] == NULL && _mirrors[T_BOOLEAN - 1] == NULL, "checking");
|
||||
|
||||
f->do_oop((oop*)&_the_empty_class_klass_array);
|
||||
f->do_oop((oop*)&_the_null_sentinel);
|
||||
f->do_oop((oop*)&_the_null_string);
|
||||
f->do_oop((oop*)&_the_min_jint_string);
|
||||
f->do_oop((oop*)&_out_of_memory_error_java_heap);
|
||||
f->do_oop((oop*)&_out_of_memory_error_metaspace);
|
||||
f->do_oop((oop*)&_out_of_memory_error_class_metaspace);
|
||||
f->do_oop((oop*)&_out_of_memory_error_array_size);
|
||||
f->do_oop((oop*)&_out_of_memory_error_gc_overhead_limit);
|
||||
f->do_oop((oop*)&_out_of_memory_error_realloc_objects);
|
||||
f->do_oop((oop*)&_out_of_memory_error_retry);
|
||||
f->do_oop((oop*)&_delayed_stack_overflow_error_message);
|
||||
f->do_oop((oop*)&_preallocated_out_of_memory_error_array);
|
||||
f->do_oop((oop*)&_null_ptr_exception_instance);
|
||||
f->do_oop((oop*)&_arithmetic_exception_instance);
|
||||
f->do_oop((oop*)&_virtual_machine_error_instance);
|
||||
f->do_oop((oop*)&_main_thread_group);
|
||||
f->do_oop((oop*)&_system_thread_group);
|
||||
f->do_oop((oop*)&_vm_exception);
|
||||
f->do_oop((oop*)&_reference_pending_list);
|
||||
debug_only(f->do_oop((oop*)&_fullgc_alot_dummy_array);)
|
||||
f->do_oop(&_reference_pending_list);
|
||||
ThreadsSMRSupport::exiting_threads_oops_do(f);
|
||||
}
|
||||
|
||||
@ -331,10 +342,12 @@ void Universe::genesis(TRAPS) {
|
||||
|
||||
SystemDictionary::initialize(CHECK);
|
||||
|
||||
Klass* ok = SystemDictionary::Object_klass();
|
||||
// Create string constants
|
||||
oop s = StringTable::intern("null", CHECK);
|
||||
_the_null_string = OopHandle(vm_global(), s);
|
||||
s = StringTable::intern("-2147483648", CHECK);
|
||||
_the_min_jint_string = OopHandle(vm_global(), s);
|
||||
|
||||
_the_null_string = StringTable::intern("null", CHECK);
|
||||
_the_min_jint_string = StringTable::intern("-2147483648", CHECK);
|
||||
|
||||
#if INCLUDE_CDS
|
||||
if (UseSharedSpaces) {
|
||||
@ -363,7 +376,7 @@ void Universe::genesis(TRAPS) {
|
||||
|
||||
{
|
||||
Handle tns = java_lang_String::create_from_str("<null_sentinel>", CHECK);
|
||||
_the_null_sentinel = tns();
|
||||
_the_null_sentinel = OopHandle(vm_global(), tns());
|
||||
}
|
||||
|
||||
// Maybe this could be lifted up now that object array can be initialized
|
||||
@ -398,7 +411,6 @@ void Universe::genesis(TRAPS) {
|
||||
// But we can't allocate directly in the old generation,
|
||||
// so we allocate wherever, and hope that the first collection
|
||||
// moves these objects to the bottom of the old generation.
|
||||
// We can allocate directly in the permanent generation, so we do.
|
||||
int size = FullGCALotDummies * 2;
|
||||
|
||||
objArrayOop naked_array = oopFactory::new_objArray(SystemDictionary::Object_klass(), size, CHECK);
|
||||
@ -414,11 +426,11 @@ void Universe::genesis(TRAPS) {
|
||||
// If we had a race to here, the other dummy_array instances
|
||||
// and their elements just get dropped on the floor, which is fine.
|
||||
MutexLocker ml(THREAD, FullGCALot_lock);
|
||||
if (_fullgc_alot_dummy_array == NULL) {
|
||||
_fullgc_alot_dummy_array = dummy_array();
|
||||
if (_fullgc_alot_dummy_array.is_empty()) {
|
||||
_fullgc_alot_dummy_array = OopHandle(vm_global(), dummy_array());
|
||||
}
|
||||
}
|
||||
assert(i == _fullgc_alot_dummy_array->length(), "just checking");
|
||||
assert(i == ((objArrayOop)_fullgc_alot_dummy_array.resolve())->length(), "just checking");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -509,9 +521,9 @@ oop Universe::reference_pending_list() {
|
||||
return _reference_pending_list;
|
||||
}
|
||||
|
||||
void Universe::set_reference_pending_list(oop list) {
|
||||
void Universe::clear_reference_pending_list() {
|
||||
assert_pll_ownership();
|
||||
_reference_pending_list = list;
|
||||
_reference_pending_list = NULL;
|
||||
}
|
||||
|
||||
bool Universe::has_reference_pending_list() {
|
||||
@ -563,6 +575,45 @@ bool Universe::on_page_boundary(void* addr) {
|
||||
return is_aligned(addr, os::vm_page_size());
|
||||
}
|
||||
|
||||
// the array of preallocated errors with backtraces
|
||||
objArrayOop Universe::preallocated_out_of_memory_errors() {
|
||||
return (objArrayOop)_preallocated_out_of_memory_error_array.resolve();
|
||||
}
|
||||
|
||||
objArrayOop Universe::out_of_memory_errors() { return (objArrayOop)_out_of_memory_errors.resolve(); }
|
||||
|
||||
oop Universe::out_of_memory_error_java_heap() {
|
||||
return gen_out_of_memory_error(out_of_memory_errors()->obj_at(_oom_java_heap));
|
||||
}
|
||||
|
||||
oop Universe::out_of_memory_error_c_heap() {
|
||||
return gen_out_of_memory_error(out_of_memory_errors()->obj_at(_oom_c_heap));
|
||||
}
|
||||
|
||||
oop Universe::out_of_memory_error_metaspace() {
|
||||
return gen_out_of_memory_error(out_of_memory_errors()->obj_at(_oom_metaspace));
|
||||
}
|
||||
|
||||
oop Universe::out_of_memory_error_class_metaspace() {
|
||||
return gen_out_of_memory_error(out_of_memory_errors()->obj_at(_oom_class_metaspace));
|
||||
}
|
||||
|
||||
oop Universe::out_of_memory_error_array_size() {
|
||||
return gen_out_of_memory_error(out_of_memory_errors()->obj_at(_oom_array_size));
|
||||
}
|
||||
|
||||
oop Universe::out_of_memory_error_gc_overhead_limit() {
|
||||
return gen_out_of_memory_error(out_of_memory_errors()->obj_at(_oom_gc_overhead_limit));
|
||||
}
|
||||
|
||||
oop Universe::out_of_memory_error_realloc_objects() {
|
||||
return gen_out_of_memory_error(out_of_memory_errors()->obj_at(_oom_realloc_objects));
|
||||
}
|
||||
|
||||
// Throw default _out_of_memory_error_retry object as it will never propagate out of the VM
|
||||
oop Universe::out_of_memory_error_retry() { return out_of_memory_errors()->obj_at(_oom_retry); }
|
||||
oop Universe::delayed_stack_overflow_error_message() { return _delayed_stack_overflow_error_message.resolve(); }
|
||||
|
||||
|
||||
bool Universe::should_fill_in_stack_trace(Handle throwable) {
|
||||
// never attempt to fill in the stack trace of preallocated errors that do not have
|
||||
@ -570,13 +621,13 @@ bool Universe::should_fill_in_stack_trace(Handle throwable) {
|
||||
// preallocated errors with backtrace have been consumed. Also need to avoid
|
||||
// a potential loop which could happen if an out of memory occurs when attempting
|
||||
// to allocate the backtrace.
|
||||
return ((throwable() != Universe::_out_of_memory_error_java_heap) &&
|
||||
(throwable() != Universe::_out_of_memory_error_metaspace) &&
|
||||
(throwable() != Universe::_out_of_memory_error_class_metaspace) &&
|
||||
(throwable() != Universe::_out_of_memory_error_array_size) &&
|
||||
(throwable() != Universe::_out_of_memory_error_gc_overhead_limit) &&
|
||||
(throwable() != Universe::_out_of_memory_error_realloc_objects) &&
|
||||
(throwable() != Universe::_out_of_memory_error_retry));
|
||||
objArrayOop preallocated_oom = out_of_memory_errors();
|
||||
for (int i = 0; i < _oom_count; i++) {
|
||||
if (throwable() == preallocated_oom->obj_at(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -619,6 +670,57 @@ oop Universe::gen_out_of_memory_error(oop default_err) {
|
||||
}
|
||||
}
|
||||
|
||||
// Setup preallocated OutOfMemoryError errors
|
||||
void Universe::create_preallocated_out_of_memory_errors(TRAPS) {
|
||||
InstanceKlass* ik = SystemDictionary::OutOfMemoryError_klass();
|
||||
objArrayOop oa = oopFactory::new_objArray(ik, _oom_count, CHECK);
|
||||
objArrayHandle oom_array(THREAD, oa);
|
||||
|
||||
for (int i = 0; i < _oom_count; i++) {
|
||||
oop oom_obj = ik->allocate_instance(CHECK);
|
||||
oom_array->obj_at_put(i, oom_obj);
|
||||
}
|
||||
_out_of_memory_errors = OopHandle(vm_global(), oom_array());
|
||||
|
||||
Handle msg = java_lang_String::create_from_str("Java heap space", CHECK);
|
||||
java_lang_Throwable::set_message(oom_array->obj_at(_oom_java_heap), msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("C heap space", CHECK);
|
||||
java_lang_Throwable::set_message(oom_array->obj_at(_oom_c_heap), msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Metaspace", CHECK);
|
||||
java_lang_Throwable::set_message(oom_array->obj_at(_oom_metaspace), msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Compressed class space", CHECK);
|
||||
java_lang_Throwable::set_message(oom_array->obj_at(_oom_class_metaspace), msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK);
|
||||
java_lang_Throwable::set_message(oom_array->obj_at(_oom_array_size), msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("GC overhead limit exceeded", CHECK);
|
||||
java_lang_Throwable::set_message(oom_array->obj_at(_oom_gc_overhead_limit), msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Java heap space: failed reallocation of scalar replaced objects", CHECK);
|
||||
java_lang_Throwable::set_message(oom_array->obj_at(_oom_realloc_objects), msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Java heap space: failed retryable allocation", CHECK);
|
||||
java_lang_Throwable::set_message(oom_array->obj_at(_oom_retry), msg());
|
||||
|
||||
// Setup the array of errors that have preallocated backtrace
|
||||
int len = (StackTraceInThrowable) ? (int)PreallocatedOutOfMemoryErrorCount : 0;
|
||||
objArrayOop instance = oopFactory::new_objArray(ik, len, CHECK);
|
||||
_preallocated_out_of_memory_error_array = OopHandle(vm_global(), instance);
|
||||
objArrayHandle preallocated_oom_array(THREAD, instance);
|
||||
|
||||
for (int i=0; i<len; i++) {
|
||||
oop err = ik->allocate_instance(CHECK);
|
||||
Handle err_h(THREAD, err);
|
||||
java_lang_Throwable::allocate_backtrace(err_h, CHECK);
|
||||
preallocated_oom_array->obj_at_put(i, err_h());
|
||||
}
|
||||
_preallocated_out_of_memory_error_avail_count = (jint)len;
|
||||
}
|
||||
|
||||
intptr_t Universe::_non_oop_bits = 0;
|
||||
|
||||
void* Universe::non_oop_word() {
|
||||
@ -882,35 +984,33 @@ bool universe_post_init() {
|
||||
}
|
||||
|
||||
HandleMark hm(THREAD);
|
||||
// Setup preallocated empty java.lang.Class array
|
||||
Universe::_the_empty_class_klass_array = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_false);
|
||||
// Setup preallocated empty java.lang.Class array for Method reflection.
|
||||
|
||||
objArrayOop the_empty_class_array = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_false);
|
||||
Universe::_the_empty_class_array = OopHandle(Universe::vm_global(), the_empty_class_array);
|
||||
|
||||
// Setup preallocated OutOfMemoryError errors
|
||||
Klass* k = SystemDictionary::OutOfMemoryError_klass();
|
||||
InstanceKlass* ik = InstanceKlass::cast(k);
|
||||
Universe::_out_of_memory_error_java_heap = ik->allocate_instance(CHECK_false);
|
||||
Universe::_out_of_memory_error_metaspace = ik->allocate_instance(CHECK_false);
|
||||
Universe::_out_of_memory_error_class_metaspace = ik->allocate_instance(CHECK_false);
|
||||
Universe::_out_of_memory_error_array_size = ik->allocate_instance(CHECK_false);
|
||||
Universe::_out_of_memory_error_gc_overhead_limit =
|
||||
ik->allocate_instance(CHECK_false);
|
||||
Universe::_out_of_memory_error_realloc_objects = ik->allocate_instance(CHECK_false);
|
||||
Universe::_out_of_memory_error_retry = ik->allocate_instance(CHECK_false);
|
||||
Universe::create_preallocated_out_of_memory_errors(CHECK_false);
|
||||
|
||||
oop instance;
|
||||
// Setup preallocated cause message for delayed StackOverflowError
|
||||
if (StackReservedPages > 0) {
|
||||
Universe::_delayed_stack_overflow_error_message =
|
||||
java_lang_String::create_oop_from_str("Delayed StackOverflowError due to ReservedStackAccess annotated method", CHECK_false);
|
||||
instance = java_lang_String::create_oop_from_str("Delayed StackOverflowError due to ReservedStackAccess annotated method", CHECK_false);
|
||||
Universe::_delayed_stack_overflow_error_message = OopHandle(Universe::vm_global(), instance);
|
||||
}
|
||||
|
||||
// Setup preallocated NullPointerException
|
||||
// (this is currently used for a cheap & dirty solution in compiler exception handling)
|
||||
k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_NullPointerException(), true, CHECK_false);
|
||||
Universe::_null_ptr_exception_instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
|
||||
Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_NullPointerException(), true, CHECK_false);
|
||||
instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
|
||||
Universe::_null_ptr_exception_instance = OopHandle(Universe::vm_global(), instance);
|
||||
|
||||
// Setup preallocated ArithmeticException
|
||||
// (this is currently used for a cheap & dirty solution in compiler exception handling)
|
||||
k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ArithmeticException(), true, CHECK_false);
|
||||
Universe::_arithmetic_exception_instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
|
||||
instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
|
||||
Universe::_arithmetic_exception_instance = OopHandle(Universe::vm_global(), instance);
|
||||
|
||||
// Virtual Machine Error for when we get into a situation we can't resolve
|
||||
k = SystemDictionary::VirtualMachineError_klass();
|
||||
bool linked = InstanceKlass::cast(k)->link_class_or_fail(CHECK_false);
|
||||
@ -918,48 +1018,11 @@ bool universe_post_init() {
|
||||
tty->print_cr("Unable to link/verify VirtualMachineError class");
|
||||
return false; // initialization failed
|
||||
}
|
||||
Universe::_virtual_machine_error_instance =
|
||||
InstanceKlass::cast(k)->allocate_instance(CHECK_false);
|
||||
instance = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
|
||||
Universe::_virtual_machine_error_instance = OopHandle(Universe::vm_global(), instance);
|
||||
|
||||
Universe::_vm_exception = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
|
||||
|
||||
Handle msg = java_lang_String::create_from_str("Java heap space", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_java_heap, msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Metaspace", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_metaspace, msg());
|
||||
msg = java_lang_String::create_from_str("Compressed class space", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_class_metaspace, msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Requested array size exceeds VM limit", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_array_size, msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("GC overhead limit exceeded", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_gc_overhead_limit, msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Java heap space: failed reallocation of scalar replaced objects", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_realloc_objects, msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("Java heap space: failed retryable allocation", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_out_of_memory_error_retry, msg());
|
||||
|
||||
msg = java_lang_String::create_from_str("/ by zero", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::_arithmetic_exception_instance, msg());
|
||||
|
||||
// Setup the array of errors that have preallocated backtrace
|
||||
k = Universe::_out_of_memory_error_java_heap->klass();
|
||||
assert(k->name() == vmSymbols::java_lang_OutOfMemoryError(), "should be out of memory error");
|
||||
ik = InstanceKlass::cast(k);
|
||||
|
||||
int len = (StackTraceInThrowable) ? (int)PreallocatedOutOfMemoryErrorCount : 0;
|
||||
Universe::_preallocated_out_of_memory_error_array = oopFactory::new_objArray(ik, len, CHECK_false);
|
||||
for (int i=0; i<len; i++) {
|
||||
oop err = ik->allocate_instance(CHECK_false);
|
||||
Handle err_h = Handle(THREAD, err);
|
||||
java_lang_Throwable::allocate_backtrace(err_h, CHECK_false);
|
||||
Universe::preallocated_out_of_memory_errors()->obj_at_put(i, err_h());
|
||||
}
|
||||
Universe::_preallocated_out_of_memory_error_avail_count = (jint)len;
|
||||
Handle msg = java_lang_String::create_from_str("/ by zero", CHECK_false);
|
||||
java_lang_Throwable::set_message(Universe::arithmetic_exception_instance(), msg());
|
||||
|
||||
Universe::initialize_known_methods(CHECK_false);
|
||||
|
||||
@ -1225,18 +1288,16 @@ Method* LatestMethodCache::get_method() {
|
||||
// Release dummy object(s) at bottom of heap
|
||||
bool Universe::release_fullgc_alot_dummy() {
|
||||
MutexLocker ml(FullGCALot_lock);
|
||||
if (_fullgc_alot_dummy_array != NULL) {
|
||||
if (_fullgc_alot_dummy_next >= _fullgc_alot_dummy_array->length()) {
|
||||
objArrayOop fullgc_alot_dummy_array = (objArrayOop)_fullgc_alot_dummy_array.resolve();
|
||||
if (fullgc_alot_dummy_array != NULL) {
|
||||
if (_fullgc_alot_dummy_next >= fullgc_alot_dummy_array->length()) {
|
||||
// No more dummies to release, release entire array instead
|
||||
_fullgc_alot_dummy_array = NULL;
|
||||
_fullgc_alot_dummy_array.release(Universe::vm_global());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Release dummy at bottom of old generation
|
||||
_fullgc_alot_dummy_array->obj_at_put(_fullgc_alot_dummy_next++, NULL);
|
||||
|
||||
// Release dummy at bottom of permanent generation
|
||||
_fullgc_alot_dummy_array->obj_at_put(_fullgc_alot_dummy_next++, NULL);
|
||||
fullgc_alot_dummy_array->obj_at_put(_fullgc_alot_dummy_next++, NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "gc/shared/verifyOption.hpp"
|
||||
#include "oops/array.hpp"
|
||||
#include "oops/oopHandle.hpp"
|
||||
#include "runtime/handles.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
|
||||
@ -106,31 +107,27 @@ class Universe: AllStatic {
|
||||
static oop _short_mirror;
|
||||
static oop _void_mirror;
|
||||
|
||||
static oop _main_thread_group; // Reference to the main thread group object
|
||||
static oop _system_thread_group; // Reference to the system thread group object
|
||||
static OopHandle _main_thread_group; // Reference to the main thread group object
|
||||
static OopHandle _system_thread_group; // Reference to the system thread group object
|
||||
|
||||
static OopHandle _the_empty_class_array; // Canonicalized obj array of type java.lang.Class
|
||||
static OopHandle _the_null_string; // A cache of "null" as a Java string
|
||||
static OopHandle _the_min_jint_string; // A cache of "-2147483648" as a Java string
|
||||
|
||||
static OopHandle _the_null_sentinel; // A unique object pointer unused except as a sentinel for null.
|
||||
|
||||
// preallocated error objects (no backtrace)
|
||||
static OopHandle _out_of_memory_errors;
|
||||
|
||||
// preallocated cause message for delayed StackOverflowError
|
||||
static OopHandle _delayed_stack_overflow_error_message;
|
||||
|
||||
static objArrayOop _the_empty_class_klass_array; // Canonicalized obj array of type java.lang.Class
|
||||
static oop _the_null_sentinel; // A unique object pointer unused except as a sentinel for null.
|
||||
static oop _the_null_string; // A cache of "null" as a Java string
|
||||
static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string
|
||||
static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects
|
||||
static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector
|
||||
static LatestMethodCache* _throw_illegal_access_error_cache; // Unsafe.throwIllegalAccessError() method
|
||||
static LatestMethodCache* _throw_no_such_method_error_cache; // Unsafe.throwNoSuchMethodError() method
|
||||
static LatestMethodCache* _do_stack_walk_cache; // method for stack walker callback
|
||||
|
||||
// preallocated error objects (no backtrace)
|
||||
static oop _out_of_memory_error_java_heap;
|
||||
static oop _out_of_memory_error_metaspace;
|
||||
static oop _out_of_memory_error_class_metaspace;
|
||||
static oop _out_of_memory_error_array_size;
|
||||
static oop _out_of_memory_error_gc_overhead_limit;
|
||||
static oop _out_of_memory_error_realloc_objects;
|
||||
static oop _out_of_memory_error_retry;
|
||||
|
||||
// preallocated cause message for delayed StackOverflowError
|
||||
static oop _delayed_stack_overflow_error_message;
|
||||
|
||||
static Array<int>* _the_empty_int_array; // Canonicalized int array
|
||||
static Array<u2>* _the_empty_short_array; // Canonicalized short array
|
||||
static Array<Klass*>* _the_empty_klass_array; // Canonicalized klass array
|
||||
@ -140,17 +137,14 @@ class Universe: AllStatic {
|
||||
static Array<Klass*>* _the_array_interfaces_array;
|
||||
|
||||
// array of preallocated error objects with backtrace
|
||||
static objArrayOop _preallocated_out_of_memory_error_array;
|
||||
static OopHandle _preallocated_out_of_memory_error_array;
|
||||
|
||||
// number of preallocated error objects available for use
|
||||
static volatile jint _preallocated_out_of_memory_error_avail_count;
|
||||
|
||||
static oop _null_ptr_exception_instance; // preallocated exception object
|
||||
static oop _arithmetic_exception_instance; // preallocated exception object
|
||||
static oop _virtual_machine_error_instance; // preallocated exception object
|
||||
// The object used as an exception dummy when exceptions are thrown for
|
||||
// the vm thread.
|
||||
static oop _vm_exception;
|
||||
static OopHandle _null_ptr_exception_instance; // preallocated exception object
|
||||
static OopHandle _arithmetic_exception_instance; // preallocated exception object
|
||||
static OopHandle _virtual_machine_error_instance; // preallocated exception object
|
||||
|
||||
// References waiting to be transferred to the ReferenceHandler
|
||||
static oop _reference_pending_list;
|
||||
@ -161,8 +155,7 @@ class Universe: AllStatic {
|
||||
static intptr_t _non_oop_bits;
|
||||
|
||||
// array of dummy objects used with +FullGCAlot
|
||||
debug_only(static objArrayOop _fullgc_alot_dummy_array;)
|
||||
// index of next entry to clear
|
||||
debug_only(static OopHandle _fullgc_alot_dummy_array;)
|
||||
debug_only(static int _fullgc_alot_dummy_next;)
|
||||
|
||||
// Compiler/dispatch support
|
||||
@ -174,8 +167,9 @@ class Universe: AllStatic {
|
||||
static bool _fully_initialized; // true after universe_init and initialize_vtables called
|
||||
|
||||
// the array of preallocated errors with backtraces
|
||||
static objArrayOop preallocated_out_of_memory_errors() { return _preallocated_out_of_memory_error_array; }
|
||||
static objArrayOop preallocated_out_of_memory_errors();
|
||||
|
||||
static objArrayOop out_of_memory_errors();
|
||||
// generate an out of memory error; if possible using an error with preallocated backtrace;
|
||||
// otherwise return the given default error.
|
||||
static oop gen_out_of_memory_error(oop default_err);
|
||||
@ -265,17 +259,23 @@ class Universe: AllStatic {
|
||||
assert((uint)t < T_VOID+1, "range check");
|
||||
return check_mirror(_mirrors[t]);
|
||||
}
|
||||
static oop main_thread_group() { return _main_thread_group; }
|
||||
static void set_main_thread_group(oop group) { _main_thread_group = group;}
|
||||
static oop main_thread_group();
|
||||
static void set_main_thread_group(oop group);
|
||||
|
||||
static oop system_thread_group() { return _system_thread_group; }
|
||||
static void set_system_thread_group(oop group) { _system_thread_group = group;}
|
||||
static oop system_thread_group();
|
||||
static void set_system_thread_group(oop group);
|
||||
|
||||
static objArrayOop the_empty_class_klass_array () { return _the_empty_class_klass_array; }
|
||||
static Array<Klass*>* the_array_interfaces_array() { return _the_array_interfaces_array; }
|
||||
static oop the_null_string() { return _the_null_string; }
|
||||
static oop the_min_jint_string() { return _the_min_jint_string; }
|
||||
static objArrayOop the_empty_class_array ();
|
||||
|
||||
static oop the_null_string();
|
||||
static oop the_min_jint_string();
|
||||
|
||||
static oop null_ptr_exception_instance();
|
||||
static oop arithmetic_exception_instance();
|
||||
static oop virtual_machine_error_instance();
|
||||
static oop vm_exception() { return virtual_machine_error_instance(); }
|
||||
|
||||
static Array<Klass*>* the_array_interfaces_array() { return _the_array_interfaces_array; }
|
||||
static Method* finalizer_register_method() { return _finalizer_register_cache->get_method(); }
|
||||
static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); }
|
||||
|
||||
@ -284,16 +284,13 @@ class Universe: AllStatic {
|
||||
|
||||
static Method* do_stack_walk_method() { return _do_stack_walk_cache->get_method(); }
|
||||
|
||||
static oop the_null_sentinel() { return _the_null_sentinel; }
|
||||
static oop the_null_sentinel();
|
||||
static address the_null_sentinel_addr() { return (address) &_the_null_sentinel; }
|
||||
|
||||
// Function to initialize these
|
||||
static void initialize_known_methods(TRAPS);
|
||||
|
||||
static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; }
|
||||
static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; }
|
||||
static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; }
|
||||
static oop vm_exception() { return _vm_exception; }
|
||||
static void create_preallocated_out_of_memory_errors(TRAPS);
|
||||
|
||||
// Reference pending list manipulation. Access is protected by
|
||||
// Heap_lock. The getter, setter and predicate require the caller
|
||||
@ -302,7 +299,7 @@ class Universe: AllStatic {
|
||||
// Heap_lock, so requires the lock is locked, but not necessarily by
|
||||
// the current thread.
|
||||
static oop reference_pending_list();
|
||||
static void set_reference_pending_list(oop list);
|
||||
static void clear_reference_pending_list();
|
||||
static bool has_reference_pending_list();
|
||||
static oop swap_reference_pending_list(oop list);
|
||||
|
||||
@ -315,15 +312,17 @@ class Universe: AllStatic {
|
||||
// OutOfMemoryError support. Returns an error with the required message. The returned error
|
||||
// may or may not have a backtrace. If error has a backtrace then the stack trace is already
|
||||
// filled in.
|
||||
static oop out_of_memory_error_java_heap() { return gen_out_of_memory_error(_out_of_memory_error_java_heap); }
|
||||
static oop out_of_memory_error_metaspace() { return gen_out_of_memory_error(_out_of_memory_error_metaspace); }
|
||||
static oop out_of_memory_error_class_metaspace() { return gen_out_of_memory_error(_out_of_memory_error_class_metaspace); }
|
||||
static oop out_of_memory_error_array_size() { return gen_out_of_memory_error(_out_of_memory_error_array_size); }
|
||||
static oop out_of_memory_error_gc_overhead_limit() { return gen_out_of_memory_error(_out_of_memory_error_gc_overhead_limit); }
|
||||
static oop out_of_memory_error_realloc_objects() { return gen_out_of_memory_error(_out_of_memory_error_realloc_objects); }
|
||||
static oop out_of_memory_error_java_heap();
|
||||
static oop out_of_memory_error_c_heap();
|
||||
static oop out_of_memory_error_metaspace();
|
||||
static oop out_of_memory_error_class_metaspace();
|
||||
static oop out_of_memory_error_array_size();
|
||||
static oop out_of_memory_error_gc_overhead_limit();
|
||||
static oop out_of_memory_error_realloc_objects();
|
||||
|
||||
// Throw default _out_of_memory_error_retry object as it will never propagate out of the VM
|
||||
static oop out_of_memory_error_retry() { return _out_of_memory_error_retry; }
|
||||
static oop delayed_stack_overflow_error_message() { return _delayed_stack_overflow_error_message; }
|
||||
static oop out_of_memory_error_retry();
|
||||
static oop delayed_stack_overflow_error_message();
|
||||
|
||||
// The particular choice of collected heap.
|
||||
static CollectedHeap* heap() { return _collectedHeap; }
|
||||
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_METAPROGRAMMING_ISREGISTEREDENUM_HPP
|
||||
#define SHARE_METAPROGRAMMING_ISREGISTEREDENUM_HPP
|
||||
|
||||
#include "metaprogramming/integralConstant.hpp"
|
||||
|
||||
// Recognize registered enum types.
|
||||
// Registration is by specializing this trait.
|
||||
//
|
||||
// This is a manual stand-in for the C++11 std::is_enum<T> type trait.
|
||||
// It's a lot of work to implement is_enum portably in C++98, so this
|
||||
// manual approach is being taken for those enum types we need to
|
||||
// distinguish.
|
||||
template<typename T>
|
||||
struct IsRegisteredEnum : public FalseType {};
|
||||
|
||||
#endif // SHARE_METAPROGRAMMING_ISREGISTEREDENUM_HPP
|
@ -30,8 +30,8 @@
|
||||
#include "metaprogramming/integralConstant.hpp"
|
||||
#include "metaprogramming/isFloatingPoint.hpp"
|
||||
#include "metaprogramming/isIntegral.hpp"
|
||||
#include "metaprogramming/isRegisteredEnum.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include <type_traits>
|
||||
|
||||
class PrimitiveConversions : public AllStatic {
|
||||
public:
|
||||
@ -68,8 +68,8 @@ private:
|
||||
// Return an object of type T with the same value representation as x.
|
||||
//
|
||||
// T and U must be of the same size. It is expected that one of T and
|
||||
// U is an integral type, and the other is an integral type, a
|
||||
// (registered) enum type, or a floating point type
|
||||
// U is an integral type, and the other is an integral type, an enum type,
|
||||
// or a floating point type.
|
||||
//
|
||||
// This implementation uses the "union trick", which seems to be the
|
||||
// best of a bad set of options. Though technically undefined
|
||||
@ -122,7 +122,7 @@ template<typename T, typename U>
|
||||
struct PrimitiveConversions::Cast<
|
||||
T, U, true,
|
||||
typename EnableIf<IsIntegral<T>::value &&
|
||||
(IsRegisteredEnum<U>::value ||
|
||||
(std::is_enum<U>::value ||
|
||||
IsFloatingPoint<U>::value)>::type>
|
||||
{
|
||||
T operator()(U x) const { return cast_using_union<T>(x); }
|
||||
@ -133,7 +133,7 @@ template<typename T, typename U>
|
||||
struct PrimitiveConversions::Cast<
|
||||
T, U, true,
|
||||
typename EnableIf<IsIntegral<U>::value &&
|
||||
(IsRegisteredEnum<T>::value ||
|
||||
(std::is_enum<T>::value ||
|
||||
IsFloatingPoint<T>::value)>::type>
|
||||
{
|
||||
T operator()(U x) const { return cast_using_union<T>(x); }
|
||||
|
@ -53,7 +53,7 @@
|
||||
|
||||
void Klass::set_java_mirror(Handle m) {
|
||||
assert(!m.is_null(), "New mirror should never be null.");
|
||||
assert(_java_mirror.resolve() == NULL, "should only be used to initialize mirror");
|
||||
assert(_java_mirror.is_empty(), "should only be used to initialize mirror");
|
||||
_java_mirror = class_loader_data()->add_handle(m);
|
||||
}
|
||||
|
||||
@ -61,6 +61,10 @@ oop Klass::java_mirror_no_keepalive() const {
|
||||
return _java_mirror.peek();
|
||||
}
|
||||
|
||||
void Klass::replace_java_mirror(oop mirror) {
|
||||
_java_mirror.replace(mirror);
|
||||
}
|
||||
|
||||
bool Klass::is_cloneable() const {
|
||||
return _access_flags.is_cloneable_fast() ||
|
||||
is_subtype_of(SystemDictionary::Cloneable_klass());
|
||||
@ -195,10 +199,7 @@ void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word
|
||||
// which zeros out memory - calloc equivalent.
|
||||
// The constructor is also used from CppVtableCloner,
|
||||
// which doesn't zero out the memory before calling the constructor.
|
||||
// Need to set the _java_mirror field explicitly to not hit an assert that the field
|
||||
// should be NULL before setting it.
|
||||
Klass::Klass(KlassID id) : _id(id),
|
||||
_java_mirror(NULL),
|
||||
_prototype_header(markWord::prototype()),
|
||||
_shared_class_path_index(-1) {
|
||||
CDS_ONLY(_shared_class_flags = 0;)
|
||||
@ -555,7 +556,7 @@ void Klass::remove_java_mirror() {
|
||||
log_trace(cds, unshareable)("remove java_mirror: %s", external_name());
|
||||
}
|
||||
// Just null out the mirror. The class_loader_data() no longer exists.
|
||||
_java_mirror = OopHandle();
|
||||
clear_java_mirror_handle();
|
||||
}
|
||||
|
||||
void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
|
||||
@ -609,7 +610,7 @@ void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protec
|
||||
|
||||
// No archived mirror data
|
||||
log_debug(cds, mirror)("No archived mirror data for %s", external_name());
|
||||
_java_mirror = OopHandle();
|
||||
clear_java_mirror_handle();
|
||||
this->clear_has_raw_archived_mirror();
|
||||
}
|
||||
|
||||
|
@ -267,12 +267,11 @@ protected:
|
||||
void set_archived_java_mirror_raw(oop m) NOT_CDS_JAVA_HEAP_RETURN; // no GC barrier
|
||||
|
||||
// Temporary mirror switch used by RedefineClasses
|
||||
// Both mirrors are on the ClassLoaderData::_handles list already so no
|
||||
// barriers are needed.
|
||||
void set_java_mirror_handle(OopHandle mirror) { _java_mirror = mirror; }
|
||||
OopHandle java_mirror_handle() const {
|
||||
return _java_mirror;
|
||||
}
|
||||
void replace_java_mirror(oop mirror);
|
||||
|
||||
// Set java mirror OopHandle to NULL for CDS
|
||||
// This leaves the OopHandle in the CLD, but that's ok, you can't release them.
|
||||
void clear_java_mirror_handle() { _java_mirror = OopHandle(); }
|
||||
|
||||
// modifier flags
|
||||
jint modifier_flags() const { return _modifier_flags; }
|
||||
|
@ -805,7 +805,7 @@ bool Method::needs_clinit_barrier() const {
|
||||
objArrayHandle Method::resolved_checked_exceptions_impl(Method* method, TRAPS) {
|
||||
int length = method->checked_exceptions_length();
|
||||
if (length == 0) { // common case
|
||||
return objArrayHandle(THREAD, Universe::the_empty_class_klass_array());
|
||||
return objArrayHandle(THREAD, Universe::the_empty_class_array());
|
||||
} else {
|
||||
methodHandle h_this(THREAD, method);
|
||||
objArrayOop m_oop = oopFactory::new_objArray(SystemDictionary::Class_klass(), length, CHECK_(objArrayHandle()));
|
||||
|
@ -45,11 +45,25 @@ public:
|
||||
explicit OopHandle(oop* w) : _obj(w) {}
|
||||
OopHandle(OopStorage* storage, oop obj);
|
||||
|
||||
OopHandle(const OopHandle& copy) : _obj(copy._obj) {}
|
||||
|
||||
OopHandle& operator=(const OopHandle& copy) {
|
||||
// Allow "this" to be junk if copy is empty; needed by initialization of
|
||||
// raw memory in hashtables.
|
||||
assert(is_empty() || copy.is_empty(), "can only copy if empty");
|
||||
_obj = copy._obj;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline oop resolve() const;
|
||||
inline oop peek() const;
|
||||
|
||||
bool is_empty() const { return _obj == NULL; }
|
||||
|
||||
inline void release(OopStorage* storage);
|
||||
|
||||
inline void replace(oop obj);
|
||||
|
||||
// Used only for removing handle.
|
||||
oop* ptr_raw() const { return _obj; }
|
||||
};
|
||||
|
@ -54,4 +54,10 @@ inline void OopHandle::release(OopStorage* storage) {
|
||||
}
|
||||
}
|
||||
|
||||
inline void OopHandle::replace(oop obj) {
|
||||
oop* ptr = ptr_raw();
|
||||
assert(ptr != NULL, "should not use replace");
|
||||
NativeAccess<>::oop_store(ptr, obj);
|
||||
}
|
||||
|
||||
#endif // SHARE_OOPS_OOPHANDLE_INLINE_HPP
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -723,8 +723,7 @@ void ConnectionGraph::add_to_congraph_unsafe_access(Node* n, uint opcode, Unique
|
||||
if (adr_type->isa_oopptr()
|
||||
|| ((opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass)
|
||||
&& adr_type == TypeRawPtr::NOTNULL
|
||||
&& adr->in(AddPNode::Address)->is_Proj()
|
||||
&& adr->in(AddPNode::Address)->in(0)->is_Allocate())) {
|
||||
&& is_captured_store_address(adr))) {
|
||||
delayed_worklist->push(n); // Process it later.
|
||||
#ifdef ASSERT
|
||||
assert (adr->is_AddP(), "expecting an AddP");
|
||||
@ -771,8 +770,7 @@ bool ConnectionGraph::add_final_edges_unsafe_access(Node* n, uint opcode) {
|
||||
if (adr_type->isa_oopptr()
|
||||
|| ((opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass)
|
||||
&& adr_type == TypeRawPtr::NOTNULL
|
||||
&& adr->in(AddPNode::Address)->is_Proj()
|
||||
&& adr->in(AddPNode::Address)->in(0)->is_Allocate())) {
|
||||
&& is_captured_store_address(adr))) {
|
||||
// Point Address to Value
|
||||
PointsToNode* adr_ptn = ptnode_adr(adr->_idx);
|
||||
assert(adr_ptn != NULL &&
|
||||
@ -1584,8 +1582,7 @@ int ConnectionGraph::find_init_values(JavaObjectNode* pta, PointsToNode* init_va
|
||||
// Raw pointers are used for initializing stores so skip it
|
||||
// since it should be recorded already
|
||||
Node* base = get_addp_base(field->ideal_node());
|
||||
assert(adr_type->isa_rawptr() && base->is_Proj() &&
|
||||
(base->in(0) == alloc),"unexpected pointer type");
|
||||
assert(adr_type->isa_rawptr() && is_captured_store_address(field->ideal_node()), "unexpected pointer type");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
@ -1916,8 +1913,7 @@ void ConnectionGraph::optimize_ideal_graph(GrowableArray<Node*>& ptr_cmp_worklis
|
||||
Node *n = storestore_worklist.pop();
|
||||
MemBarStoreStoreNode *storestore = n ->as_MemBarStoreStore();
|
||||
Node *alloc = storestore->in(MemBarNode::Precedent)->in(0);
|
||||
assert (alloc->is_Allocate(), "storestore should point to AllocateNode");
|
||||
if (not_global_escape(alloc)) {
|
||||
if (alloc->is_Allocate() && not_global_escape(alloc)) {
|
||||
MemBarNode* mb = MemBarNode::make(C, Op_MemBarCPUOrder, Compile::AliasIdxBot);
|
||||
mb->init_req(TypeFunc::Memory, storestore->in(TypeFunc::Memory));
|
||||
mb->init_req(TypeFunc::Control, storestore->in(TypeFunc::Control));
|
||||
@ -2251,11 +2247,29 @@ bool FieldNode::has_base(JavaObjectNode* jobj) const {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ConnectionGraph::is_captured_store_address(Node* addp) {
|
||||
// Handle simple case first.
|
||||
assert(_igvn->type(addp)->isa_oopptr() == NULL, "should be raw access");
|
||||
if (addp->in(AddPNode::Address)->is_Proj() && addp->in(AddPNode::Address)->in(0)->is_Allocate()) {
|
||||
return true;
|
||||
} else if (addp->in(AddPNode::Address)->is_Phi()) {
|
||||
for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
|
||||
Node* addp_use = addp->fast_out(i);
|
||||
if (addp_use->is_Store()) {
|
||||
for (DUIterator_Fast jmax, j = addp_use->fast_outs(jmax); j < jmax; j++) {
|
||||
if (addp_use->fast_out(j)->is_Initialize()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ConnectionGraph::address_offset(Node* adr, PhaseTransform *phase) {
|
||||
const Type *adr_type = phase->type(adr);
|
||||
if (adr->is_AddP() && adr_type->isa_oopptr() == NULL &&
|
||||
adr->in(AddPNode::Address)->is_Proj() &&
|
||||
adr->in(AddPNode::Address)->in(0)->is_Allocate()) {
|
||||
if (adr->is_AddP() && adr_type->isa_oopptr() == NULL && is_captured_store_address(adr)) {
|
||||
// We are computing a raw address for a store captured by an Initialize
|
||||
// compute an appropriate address type. AddP cases #3 and #5 (see below).
|
||||
int offs = (int)phase->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
|
||||
@ -2358,7 +2372,7 @@ Node* ConnectionGraph::get_addp_base(Node *addp) {
|
||||
assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
|
||||
opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
|
||||
(uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
|
||||
(uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
|
||||
is_captured_store_address(addp), "sanity");
|
||||
}
|
||||
}
|
||||
return base;
|
||||
@ -2974,7 +2988,10 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist,
|
||||
continue;
|
||||
}
|
||||
if (!n->is_CheckCastPP()) { // not unique CheckCastPP.
|
||||
assert(!alloc->is_Allocate(), "allocation should have unique type");
|
||||
// we could reach here for allocate case if one init is associated with many allocs.
|
||||
if (alloc->is_Allocate()) {
|
||||
alloc->as_Allocate()->_is_scalar_replaceable = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -512,6 +512,7 @@ private:
|
||||
// offset of a field reference
|
||||
int address_offset(Node* adr, PhaseTransform *phase);
|
||||
|
||||
bool is_captured_store_address(Node* addp);
|
||||
|
||||
// Propagate unique types created for unescaped allocated objects
|
||||
// through the graph
|
||||
|
@ -1554,78 +1554,95 @@ jfloat Node::getf() const {
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
//------------------------------find------------------------------------------
|
||||
// Find a neighbor of this Node with the given _idx
|
||||
// If idx is negative, find its absolute value, following both _in and _out.
|
||||
static void find_recur(Compile* C, Node* &result, Node *n, int idx, bool only_ctrl,
|
||||
VectorSet* old_space, VectorSet* new_space ) {
|
||||
int node_idx = (idx >= 0) ? idx : -idx;
|
||||
if (NotANode(n)) return; // Gracefully handle NULL, -1, 0xabababab, etc.
|
||||
// Contained in new_space or old_space? Check old_arena first since it's mostly empty.
|
||||
VectorSet *v = C->old_arena()->contains(n) ? old_space : new_space;
|
||||
if( v->test(n->_idx) ) return;
|
||||
if( (int)n->_idx == node_idx
|
||||
debug_only(|| n->debug_idx() == node_idx) ) {
|
||||
if (result != NULL)
|
||||
tty->print("find: " INTPTR_FORMAT " and " INTPTR_FORMAT " both have idx==%d\n",
|
||||
(uintptr_t)result, (uintptr_t)n, node_idx);
|
||||
result = n;
|
||||
}
|
||||
v->set(n->_idx);
|
||||
for( uint i=0; i<n->len(); i++ ) {
|
||||
if( only_ctrl && !(n->is_Region()) && (n->Opcode() != Op_Root) && (i != TypeFunc::Control) ) continue;
|
||||
find_recur(C, result, n->in(i), idx, only_ctrl, old_space, new_space );
|
||||
}
|
||||
// Search along forward edges also:
|
||||
if (idx < 0 && !only_ctrl) {
|
||||
for( uint j=0; j<n->outcnt(); j++ ) {
|
||||
find_recur(C, result, n->raw_out(j), idx, only_ctrl, old_space, new_space );
|
||||
}
|
||||
}
|
||||
#ifdef ASSERT
|
||||
// Search along debug_orig edges last, checking for cycles
|
||||
Node* orig = n->debug_orig();
|
||||
if (orig != NULL) {
|
||||
do {
|
||||
if (NotANode(orig)) break;
|
||||
find_recur(C, result, orig, idx, only_ctrl, old_space, new_space );
|
||||
orig = orig->debug_orig();
|
||||
} while (orig != NULL && orig != n->debug_orig());
|
||||
}
|
||||
#endif //ASSERT
|
||||
}
|
||||
|
||||
// call this from debugger:
|
||||
Node* find_node(Node* n, int idx) {
|
||||
// Call this from debugger:
|
||||
Node* find_node(Node* n, const int idx) {
|
||||
return n->find(idx);
|
||||
}
|
||||
|
||||
// call this from debugger with root node as default:
|
||||
Node* find_node(int idx) {
|
||||
// Call this from debugger with root node as default:
|
||||
Node* find_node(const int idx) {
|
||||
return Compile::current()->root()->find(idx);
|
||||
}
|
||||
|
||||
//------------------------------find-------------------------------------------
|
||||
Node* Node::find(int idx) const {
|
||||
VectorSet old_space, new_space;
|
||||
Node* result = NULL;
|
||||
find_recur(Compile::current(), result, (Node*) this, idx, false, &old_space, &new_space);
|
||||
return result;
|
||||
// Call this from debugger:
|
||||
Node* find_ctrl(Node* n, const int idx) {
|
||||
return n->find_ctrl(idx);
|
||||
}
|
||||
|
||||
// Call this from debugger with root node as default:
|
||||
Node* find_ctrl(const int idx) {
|
||||
return Compile::current()->root()->find_ctrl(idx);
|
||||
}
|
||||
|
||||
//------------------------------find_ctrl--------------------------------------
|
||||
// Find an ancestor to this node in the control history with given _idx
|
||||
Node* Node::find_ctrl(int idx) const {
|
||||
VectorSet old_space, new_space;
|
||||
Node* Node::find_ctrl(int idx) {
|
||||
return find(idx, true);
|
||||
}
|
||||
|
||||
//------------------------------find-------------------------------------------
|
||||
// Tries to find the node with the index |idx| starting from this node. If idx is negative,
|
||||
// the search also includes forward (out) edges. Returns NULL if not found.
|
||||
// If only_ctrl is set, the search will only be done on control nodes. Returns NULL if
|
||||
// not found or if the node to be found is not a control node (search will not find it).
|
||||
Node* Node::find(const int idx, bool only_ctrl) {
|
||||
ResourceMark rm;
|
||||
VectorSet old_space;
|
||||
VectorSet new_space;
|
||||
Node_List worklist;
|
||||
Arena* old_arena = Compile::current()->old_arena();
|
||||
add_to_worklist(this, &worklist, old_arena, &old_space, &new_space);
|
||||
Node* result = NULL;
|
||||
find_recur(Compile::current(), result, (Node*)this, idx, true, &old_space, &new_space);
|
||||
int node_idx = (idx >= 0) ? idx : -idx;
|
||||
|
||||
for (uint list_index = 0; list_index < worklist.size(); list_index++) {
|
||||
Node* n = worklist[list_index];
|
||||
|
||||
if ((int)n->_idx == node_idx debug_only(|| n->debug_idx() == node_idx)) {
|
||||
if (result != NULL) {
|
||||
tty->print("find: " INTPTR_FORMAT " and " INTPTR_FORMAT " both have idx==%d\n",
|
||||
(uintptr_t)result, (uintptr_t)n, node_idx);
|
||||
}
|
||||
result = n;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < n->len(); i++) {
|
||||
if (!only_ctrl || n->is_Region() || (n->Opcode() == Op_Root) || (i == TypeFunc::Control)) {
|
||||
// If only_ctrl is set: Add regions, the root node, or control inputs only
|
||||
add_to_worklist(n->in(i), &worklist, old_arena, &old_space, &new_space);
|
||||
}
|
||||
}
|
||||
|
||||
// Also search along forward edges if idx is negative and the search is not done on control nodes only
|
||||
if (idx < 0 && !only_ctrl) {
|
||||
for (uint i = 0; i < n->outcnt(); i++) {
|
||||
add_to_worklist(n->raw_out(i), &worklist, old_arena, &old_space, &new_space);
|
||||
}
|
||||
}
|
||||
#ifdef ASSERT
|
||||
// Search along debug_orig edges last
|
||||
Node* orig = n->debug_orig();
|
||||
while (orig != NULL && add_to_worklist(orig, &worklist, old_arena, &old_space, &new_space)) {
|
||||
orig = orig->debug_orig();
|
||||
}
|
||||
#endif // ASSERT
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Node::add_to_worklist(Node* n, Node_List* worklist, Arena* old_arena, VectorSet* old_space, VectorSet* new_space) {
|
||||
if (NotANode(n)) {
|
||||
return false; // Gracefully handle NULL, -1, 0xabababab, etc.
|
||||
}
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
// Contained in new_space or old_space? Check old_arena first since it's mostly empty.
|
||||
VectorSet* v = old_arena->contains(n) ? old_space : new_space;
|
||||
if (!v->test_set(n->_idx)) {
|
||||
worklist->push(n);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------Name-------------------------------------------
|
||||
extern const char *NodeClassNames[];
|
||||
@ -2141,8 +2158,9 @@ void Node::verify_edges(Unique_Node_List &visited) {
|
||||
}
|
||||
assert( cnt == 0,"Mismatched edge count.");
|
||||
} else if (n == NULL) {
|
||||
assert(i >= req() || i == 0 || is_Region() || is_Phi() || is_ArrayCopy()
|
||||
|| (is_Unlock() && i == req()-1), "only region, phi, arraycopy or unlock nodes have null data edges");
|
||||
assert(i >= req() || i == 0 || is_Region() || is_Phi() || is_ArrayCopy() || (is_Unlock() && i == req()-1)
|
||||
|| (is_MemBar() && i == 5), // the precedence edge to a membar can be removed during macro node expansion
|
||||
"only region, phi, arraycopy, unlock or membar nodes have null data edges");
|
||||
} else {
|
||||
assert(n->is_top(), "sanity");
|
||||
// Nothing to check.
|
||||
@ -2226,7 +2244,7 @@ void Node::verify(Node* n, int verify_depth) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // not PRODUCT
|
||||
|
||||
//------------------------------walk-------------------------------------------
|
||||
// Graph walk, with both pre-order and post-order functions
|
||||
|
@ -1118,10 +1118,11 @@ private:
|
||||
void walk_(NFunc pre, NFunc post, void *env, VectorSet &visited);
|
||||
|
||||
//----------------- Printing, etc
|
||||
public:
|
||||
#ifndef PRODUCT
|
||||
Node* find(int idx) const; // Search the graph for the given idx.
|
||||
Node* find_ctrl(int idx) const; // Search control ancestors for the given idx.
|
||||
static bool add_to_worklist(Node* n, Node_List* worklist, Arena* old_arena, VectorSet* old_space, VectorSet* new_space);
|
||||
public:
|
||||
Node* find(int idx, bool only_ctrl = false); // Search the graph for the given idx.
|
||||
Node* find_ctrl(int idx); // Search control ancestors for the given idx.
|
||||
void dump() const { dump("\n"); } // Print this node.
|
||||
void dump(const char* suffix, bool mark = false, outputStream *st = tty) const; // Print this node.
|
||||
void dump(int depth) const; // Print this node, recursively to depth d
|
||||
|
@ -344,8 +344,7 @@ JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderR
|
||||
trace_class_resolution(k);
|
||||
}
|
||||
|
||||
cls = (jclass)JNIHandles::make_local(
|
||||
env, k->java_mirror());
|
||||
cls = (jclass)JNIHandles::make_local(THREAD, k->java_mirror());
|
||||
return cls;
|
||||
JNI_END
|
||||
|
||||
@ -501,7 +500,7 @@ JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID meth
|
||||
} else {
|
||||
reflection_method = Reflection::new_method(m, false, CHECK_NULL);
|
||||
}
|
||||
ret = JNIHandles::make_local(env, reflection_method);
|
||||
ret = JNIHandles::make_local(THREAD, reflection_method);
|
||||
return ret;
|
||||
JNI_END
|
||||
|
||||
@ -535,7 +534,7 @@ JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
|
||||
: k->super() ) );
|
||||
assert(super == super2,
|
||||
"java_super computation depends on interface, array, other super");
|
||||
obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());
|
||||
obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(THREAD, super->java_mirror());
|
||||
return obj;
|
||||
JNI_END
|
||||
|
||||
@ -623,7 +622,7 @@ JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))
|
||||
|
||||
jni_check_async_exceptions(thread);
|
||||
oop exception = thread->pending_exception();
|
||||
jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);
|
||||
jthrowable ret = (jthrowable) JNIHandles::make_local(THREAD, exception);
|
||||
|
||||
HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(ret);
|
||||
return ret;
|
||||
@ -754,7 +753,7 @@ JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))
|
||||
HOTSPOT_JNI_NEWGLOBALREF_ENTRY(env, ref);
|
||||
|
||||
Handle ref_handle(thread, JNIHandles::resolve(ref));
|
||||
jobject ret = JNIHandles::make_global(ref_handle);
|
||||
jobject ret = JNIHandles::make_global(ref_handle, AllocFailStrategy::RETURN_NULL);
|
||||
|
||||
HOTSPOT_JNI_NEWGLOBALREF_RETURN(ret);
|
||||
return ret;
|
||||
@ -798,7 +797,8 @@ JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
|
||||
|
||||
HOTSPOT_JNI_NEWLOCALREF_ENTRY(env, ref);
|
||||
|
||||
jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
|
||||
jobject ret = JNIHandles::make_local(THREAD, JNIHandles::resolve(ref),
|
||||
AllocFailStrategy::RETURN_NULL);
|
||||
|
||||
HOTSPOT_JNI_NEWLOCALREF_RETURN(ret);
|
||||
return ret;
|
||||
@ -976,7 +976,7 @@ static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver,
|
||||
|
||||
// Convert result
|
||||
if (is_reference_type(result->get_type())) {
|
||||
result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
|
||||
result->set_jobject(JNIHandles::make_local(THREAD, (oop) result->get_jobject()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1038,7 +1038,7 @@ static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receive
|
||||
|
||||
// Convert result
|
||||
if (is_reference_type(result->get_type())) {
|
||||
result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
|
||||
result->set_jobject(JNIHandles::make_local(THREAD, (oop) result->get_jobject()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1054,7 +1054,7 @@ JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
|
||||
DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
|
||||
|
||||
instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
|
||||
ret = JNIHandles::make_local(env, i);
|
||||
ret = JNIHandles::make_local(THREAD, i);
|
||||
return ret;
|
||||
JNI_END
|
||||
|
||||
@ -1070,7 +1070,7 @@ JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID,
|
||||
DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
|
||||
|
||||
instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
|
||||
obj = JNIHandles::make_local(env, i);
|
||||
obj = JNIHandles::make_local(THREAD, i);
|
||||
JavaValue jvalue(T_VOID);
|
||||
JNI_ArgumentPusherArray ap(methodID, args);
|
||||
jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
|
||||
@ -1090,7 +1090,7 @@ JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID,
|
||||
DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
|
||||
|
||||
instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
|
||||
obj = JNIHandles::make_local(env, i);
|
||||
obj = JNIHandles::make_local(THREAD, i);
|
||||
JavaValue jvalue(T_VOID);
|
||||
JNI_ArgumentPusherVaArg ap(methodID, args);
|
||||
jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
|
||||
@ -1110,7 +1110,7 @@ JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID,
|
||||
DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
|
||||
|
||||
instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(clazz), CHECK_NULL);
|
||||
obj = JNIHandles::make_local(env, i);
|
||||
obj = JNIHandles::make_local(THREAD, i);
|
||||
va_list args;
|
||||
va_start(args, methodID);
|
||||
JavaValue jvalue(T_VOID);
|
||||
@ -1128,7 +1128,7 @@ JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
|
||||
|
||||
Klass* k = JNIHandles::resolve_non_null(obj)->klass();
|
||||
jclass ret =
|
||||
(jclass) JNIHandles::make_local(env, k->java_mirror());
|
||||
(jclass) JNIHandles::make_local(THREAD, k->java_mirror());
|
||||
|
||||
HOTSPOT_JNI_GETOBJECTCLASS_RETURN(ret);
|
||||
return ret;
|
||||
@ -1910,7 +1910,7 @@ JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID
|
||||
o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
|
||||
}
|
||||
oop loaded_obj = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(o, offset);
|
||||
jobject ret = JNIHandles::make_local(env, loaded_obj);
|
||||
jobject ret = JNIHandles::make_local(THREAD, loaded_obj);
|
||||
HOTSPOT_JNI_GETOBJECTFIELD_RETURN(ret);
|
||||
return ret;
|
||||
JNI_END
|
||||
@ -2090,7 +2090,7 @@ JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldI
|
||||
}
|
||||
assert(found, "bad fieldID passed into jni_ToReflectedField");
|
||||
oop reflected = Reflection::new_field(&fd, CHECK_NULL);
|
||||
ret = JNIHandles::make_local(env, reflected);
|
||||
ret = JNIHandles::make_local(THREAD, reflected);
|
||||
return ret;
|
||||
JNI_END
|
||||
|
||||
@ -2150,7 +2150,7 @@ JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID
|
||||
if (JvmtiExport::should_post_field_access()) {
|
||||
JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
|
||||
}
|
||||
jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
|
||||
jobject ret = JNIHandles::make_local(THREAD, id->holder()->java_mirror()->obj_field(id->offset()));
|
||||
HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(ret);
|
||||
return ret;
|
||||
JNI_END
|
||||
@ -2277,7 +2277,7 @@ JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize l
|
||||
jstring ret = NULL;
|
||||
DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);
|
||||
oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);
|
||||
ret = (jstring) JNIHandles::make_local(env, string);
|
||||
ret = (jstring) JNIHandles::make_local(THREAD, string);
|
||||
return ret;
|
||||
JNI_END
|
||||
|
||||
@ -2353,7 +2353,7 @@ JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))
|
||||
DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);
|
||||
|
||||
oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL);
|
||||
ret = (jstring) JNIHandles::make_local(env, result);
|
||||
ret = (jstring) JNIHandles::make_local(THREAD, result);
|
||||
return ret;
|
||||
JNI_END
|
||||
|
||||
@ -2433,7 +2433,7 @@ JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass ele
|
||||
result->obj_at_put(index, initial_value);
|
||||
}
|
||||
}
|
||||
ret = (jobjectArray) JNIHandles::make_local(env, result);
|
||||
ret = (jobjectArray) JNIHandles::make_local(THREAD, result);
|
||||
return ret;
|
||||
JNI_END
|
||||
|
||||
@ -2447,7 +2447,7 @@ JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, js
|
||||
DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
|
||||
objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
|
||||
if (a->is_within_bounds(index)) {
|
||||
ret = JNIHandles::make_local(env, a->obj_at(index));
|
||||
ret = JNIHandles::make_local(THREAD, a->obj_at(index));
|
||||
return ret;
|
||||
} else {
|
||||
ResourceMark rm(THREAD);
|
||||
@ -2507,7 +2507,7 @@ JNI_ENTRY(Return, \
|
||||
DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
|
||||
\
|
||||
oop obj= oopFactory::Allocator(len, CHECK_NULL); \
|
||||
ret = (Return) JNIHandles::make_local(env, obj); \
|
||||
ret = (Return) JNIHandles::make_local(THREAD, obj); \
|
||||
return ret;\
|
||||
JNI_END
|
||||
|
||||
@ -3049,10 +3049,13 @@ JNI_END
|
||||
|
||||
JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
|
||||
JNIWrapper("jni_NewWeakGlobalRef");
|
||||
HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
|
||||
HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(env, ref);
|
||||
Handle ref_handle(thread, JNIHandles::resolve(ref));
|
||||
jweak ret = JNIHandles::make_weak_global(ref_handle);
|
||||
HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
|
||||
jweak ret = JNIHandles::make_weak_global(ref_handle, AllocFailStrategy::RETURN_NULL);
|
||||
if (ret == NULL) {
|
||||
THROW_OOP_(Universe::out_of_memory_error_c_heap(), NULL);
|
||||
}
|
||||
HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(ret);
|
||||
return ret;
|
||||
JNI_END
|
||||
|
||||
@ -3128,6 +3131,12 @@ static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) {
|
||||
directBufferClass = (jclass) env->NewGlobalRef(directBufferClass);
|
||||
directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass);
|
||||
|
||||
// Global refs will be NULL if out-of-memory (no exception is pending)
|
||||
if (bufferClass == NULL || directBufferClass == NULL || directByteBufferClass == NULL) {
|
||||
directBufferSupportInitializeFailed = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get needed field and method IDs
|
||||
directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V");
|
||||
if (env->ExceptionCheck()) {
|
||||
|
@ -141,7 +141,7 @@ static void trace_class_resolution_impl(Klass* to_class, TRAPS) {
|
||||
const char * source_file = NULL;
|
||||
const char * trace = "explicit";
|
||||
InstanceKlass* caller = NULL;
|
||||
JavaThread* jthread = JavaThread::current();
|
||||
JavaThread* jthread = (JavaThread*) THREAD;
|
||||
if (jthread->has_last_Java_frame()) {
|
||||
vframeStream vfst(jthread);
|
||||
|
||||
@ -447,7 +447,7 @@ JVM_ENTRY(jobjectArray, JVM_GetProperties(JNIEnv *env))
|
||||
}
|
||||
}
|
||||
|
||||
return (jobjectArray) JNIHandles::make_local(env, result_h());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result_h());
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -464,7 +464,7 @@ JVM_ENTRY(jstring, JVM_GetTemporaryDirectory(JNIEnv *env))
|
||||
HandleMark hm(THREAD);
|
||||
const char* temp_dir = os::get_temp_directory();
|
||||
Handle h = java_lang_String::create_from_platform_dependent_str(temp_dir, CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(env, h());
|
||||
return (jstring) JNIHandles::make_local(THREAD, h());
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -568,7 +568,7 @@ JVM_ENTRY(jstring, JVM_GetExtendedNPEMessage(JNIEnv *env, jthrowable throwable))
|
||||
bool ok = BytecodeUtils::get_NPE_message_at(&ss, method, bci);
|
||||
if (ok) {
|
||||
oop result = java_lang_String::create_oop_from_str(ss.base(), CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(env, result);
|
||||
return (jstring) JNIHandles::make_local(THREAD, result);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -622,7 +622,7 @@ JVM_ENTRY(jobject, JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mod
|
||||
|
||||
oop result = StackWalk::walk(stackStream_h, mode, skip_frames, frame_count,
|
||||
start_index, frames_array_h, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, result);
|
||||
return JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -630,7 +630,6 @@ JVM_ENTRY(jint, JVM_MoreStackWalk(JNIEnv *env, jobject stackStream, jlong mode,
|
||||
jint frame_count, jint start_index,
|
||||
jobjectArray frames))
|
||||
JVMWrapper("JVM_MoreStackWalk");
|
||||
JavaThread* jt = (JavaThread*) THREAD;
|
||||
|
||||
// frames array is a Class<?>[] array when only getting caller reference,
|
||||
// and a StackFrameInfo[] array (or derivative) otherwise. It should never
|
||||
@ -738,7 +737,7 @@ JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
|
||||
new_obj = Handle(THREAD, new_obj_oop);
|
||||
}
|
||||
|
||||
return JNIHandles::make_local(env, new_obj());
|
||||
return JNIHandles::make_local(THREAD, new_obj());
|
||||
JVM_END
|
||||
|
||||
// java.io.File ///////////////////////////////////////////////////////////////
|
||||
@ -784,7 +783,7 @@ JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env))
|
||||
default:
|
||||
if (!m->is_ignored_by_security_stack_walk()) {
|
||||
// We have reached the desired frame; return the holder class.
|
||||
return (jclass) JNIHandles::make_local(env, m->method_holder()->java_mirror());
|
||||
return (jclass) JNIHandles::make_local(THREAD, m->method_holder()->java_mirror());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -803,7 +802,7 @@ JVM_ENTRY(jclass, JVM_FindPrimitiveClass(JNIEnv* env, const char* utf))
|
||||
if (mirror == NULL) {
|
||||
THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf);
|
||||
} else {
|
||||
return (jclass) JNIHandles::make_local(env, mirror);
|
||||
return (jclass) JNIHandles::make_local(THREAD, mirror);
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -832,7 +831,7 @@ JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env,
|
||||
if (log_is_enabled(Debug, class, resolve)) {
|
||||
trace_class_resolution(k);
|
||||
}
|
||||
return (jclass) JNIHandles::make_local(env, k->java_mirror());
|
||||
return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
|
||||
JVM_END
|
||||
|
||||
// Find a class with this name in this loader, using the caller's protection domain.
|
||||
@ -920,7 +919,7 @@ static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) {
|
||||
}
|
||||
|
||||
// common code for JVM_DefineClass() and JVM_DefineClassWithSource()
|
||||
static jclass jvm_define_class_common(JNIEnv *env, const char *name,
|
||||
static jclass jvm_define_class_common(const char *name,
|
||||
jobject loader, const jbyte *buf,
|
||||
jsize len, jobject pd, const char *source,
|
||||
TRAPS) {
|
||||
@ -964,7 +963,7 @@ static jclass jvm_define_class_common(JNIEnv *env, const char *name,
|
||||
trace_class_resolution(k);
|
||||
}
|
||||
|
||||
return (jclass) JNIHandles::make_local(env, k->java_mirror());
|
||||
return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
|
||||
}
|
||||
|
||||
enum {
|
||||
@ -978,11 +977,10 @@ enum {
|
||||
* Define a class with the specified flags that indicates if it's a nestmate,
|
||||
* hidden, or strongly referenced from class loader.
|
||||
*/
|
||||
static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *name,
|
||||
static jclass jvm_lookup_define_class(jclass lookup, const char *name,
|
||||
const jbyte *buf, jsize len, jobject pd,
|
||||
jboolean init, int flags, jobject classData, TRAPS) {
|
||||
assert(THREAD->is_Java_thread(), "must be a JavaThread");
|
||||
JavaThread* jt = (JavaThread*) THREAD;
|
||||
ResourceMark rm(THREAD);
|
||||
|
||||
Klass* lookup_k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup));
|
||||
@ -1099,13 +1097,13 @@ static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *na
|
||||
ik->link_class(CHECK_NULL);
|
||||
}
|
||||
|
||||
return (jclass) JNIHandles::make_local(env, defined_k->java_mirror());
|
||||
return (jclass) JNIHandles::make_local(THREAD, defined_k->java_mirror());
|
||||
}
|
||||
|
||||
JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
|
||||
JVMWrapper("JVM_DefineClass");
|
||||
|
||||
return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
|
||||
return jvm_define_class_common(name, loader, buf, len, pd, NULL, THREAD);
|
||||
JVM_END
|
||||
|
||||
/*
|
||||
@ -1129,13 +1127,13 @@ JVM_ENTRY(jclass, JVM_LookupDefineClass(JNIEnv *env, jclass lookup, const char *
|
||||
|
||||
assert(buf != NULL, "buf must not be NULL");
|
||||
|
||||
return jvm_lookup_define_class(env, lookup, name, buf, len, pd, initialize, flags, classData, THREAD);
|
||||
return jvm_lookup_define_class(lookup, name, buf, len, pd, initialize, flags, classData, THREAD);
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))
|
||||
JVMWrapper("JVM_DefineClassWithSource");
|
||||
|
||||
return jvm_define_class_common(env, name, loader, buf, len, pd, source, THREAD);
|
||||
return jvm_define_class_common(name, loader, buf, len, pd, source, THREAD);
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name))
|
||||
@ -1151,10 +1149,10 @@ JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
|
||||
// Internalize the string, converting '.' to '/' in string.
|
||||
char* p = (char*)str;
|
||||
while (*p != '\0') {
|
||||
if (*p == '.') {
|
||||
*p = '/';
|
||||
}
|
||||
p++;
|
||||
if (*p == '.') {
|
||||
*p = '/';
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
const int str_len = (int)(p - str);
|
||||
@ -1187,7 +1185,7 @@ JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
|
||||
}
|
||||
#endif
|
||||
return (k == NULL) ? NULL :
|
||||
(jclass) JNIHandles::make_local(env, k->java_mirror());
|
||||
(jclass) JNIHandles::make_local(THREAD, k->java_mirror());
|
||||
JVM_END
|
||||
|
||||
// Module support //////////////////////////////////////////////////////////////////////////////
|
||||
@ -1233,7 +1231,7 @@ JVM_ENTRY(jstring, JVM_InitClassName(JNIEnv *env, jclass cls))
|
||||
HandleMark hm(THREAD);
|
||||
Handle java_class(THREAD, JNIHandles::resolve(cls));
|
||||
oop result = java_lang_Class::name(java_class, CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(env, result);
|
||||
return (jstring) JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -1246,7 +1244,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassInterfaces(JNIEnv *env, jclass cls))
|
||||
if (java_lang_Class::is_primitive(mirror)) {
|
||||
// Primitive objects does not have any interfaces
|
||||
objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);
|
||||
return (jobjectArray) JNIHandles::make_local(env, r);
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, r);
|
||||
}
|
||||
|
||||
Klass* klass = java_lang_Class::as_Klass(mirror);
|
||||
@ -1274,7 +1272,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassInterfaces(JNIEnv *env, jclass cls))
|
||||
result->obj_at_put(0, SystemDictionary::Cloneable_klass()->java_mirror());
|
||||
result->obj_at_put(1, SystemDictionary::Serializable_klass()->java_mirror());
|
||||
}
|
||||
return (jobjectArray) JNIHandles::make_local(env, result());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result());
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -1325,7 +1323,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))
|
||||
}
|
||||
|
||||
// return the copy
|
||||
return (jobjectArray) JNIHandles::make_local(env, signers_copy);
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, signers_copy);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -1355,7 +1353,7 @@ JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))
|
||||
}
|
||||
|
||||
oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls));
|
||||
return (jobject) JNIHandles::make_local(env, pd);
|
||||
return (jobject) JNIHandles::make_local(THREAD, pd);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -1363,7 +1361,7 @@ JVM_END
|
||||
JVM_ENTRY(jobject, JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls))
|
||||
JVMWrapper("JVM_GetInheritedAccessControlContext");
|
||||
oop result = java_lang_Thread::inherited_access_control_context(thread->threadObj());
|
||||
return JNIHandles::make_local(env, result);
|
||||
return JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
class RegisterArrayForGC {
|
||||
@ -1442,7 +1440,7 @@ JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))
|
||||
if (is_privileged && privileged_context.is_null()) return NULL;
|
||||
|
||||
oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, result);
|
||||
return JNIHandles::make_local(THREAD, result);
|
||||
}
|
||||
|
||||
// the resource area must be registered in case of a gc
|
||||
@ -1456,7 +1454,7 @@ JVM_ENTRY(jobject, JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls))
|
||||
|
||||
oop result = java_security_AccessControlContext::create(h_context, is_privileged, privileged_context, CHECK_NULL);
|
||||
|
||||
return JNIHandles::make_local(env, result);
|
||||
return JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -1498,7 +1496,7 @@ JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))
|
||||
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
|
||||
! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_instance_klass()) {
|
||||
oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);
|
||||
return (jobjectArray)JNIHandles::make_local(env, result);
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, result);
|
||||
}
|
||||
|
||||
InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));
|
||||
@ -1507,7 +1505,7 @@ JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))
|
||||
if (iter.length() == 0) {
|
||||
// Neither an inner nor outer class
|
||||
oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);
|
||||
return (jobjectArray)JNIHandles::make_local(env, result);
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, result);
|
||||
}
|
||||
|
||||
// find inner class info
|
||||
@ -1549,10 +1547,10 @@ JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))
|
||||
for(int i = 0; i < members; i++) {
|
||||
res->obj_at_put(i, result->obj_at(i));
|
||||
}
|
||||
return (jobjectArray)JNIHandles::make_local(env, res);
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, res);
|
||||
}
|
||||
|
||||
return (jobjectArray)JNIHandles::make_local(env, result());
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, result());
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -1570,7 +1568,7 @@ JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass))
|
||||
)->compute_enclosing_class(&inner_is_member, CHECK_NULL);
|
||||
if (outer_klass == NULL) return NULL; // already a top-level class
|
||||
if (!inner_is_member) return NULL; // a hidden or unsafe anonymous class (inside a method)
|
||||
return (jclass) JNIHandles::make_local(env, outer_klass->java_mirror());
|
||||
return (jclass) JNIHandles::make_local(THREAD, outer_klass->java_mirror());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -1588,7 +1586,7 @@ JVM_ENTRY(jstring, JVM_GetSimpleBinaryName(JNIEnv *env, jclass cls))
|
||||
constantPoolHandle i_cp(thread, k->constants());
|
||||
Symbol* name = i_cp->symbol_at(noff);
|
||||
Handle str = java_lang_String::create_from_symbol(name, CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(env, str());
|
||||
return (jstring) JNIHandles::make_local(THREAD, str());
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -1607,7 +1605,7 @@ JVM_ENTRY(jstring, JVM_GetClassSignature(JNIEnv *env, jclass cls))
|
||||
Symbol* sym = InstanceKlass::cast(k)->generic_signature();
|
||||
if (sym == NULL) return NULL;
|
||||
Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(env, str());
|
||||
return (jstring) JNIHandles::make_local(THREAD, str());
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -1623,7 +1621,7 @@ JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls))
|
||||
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
|
||||
if (k->is_instance_klass()) {
|
||||
typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->class_annotations(), CHECK_NULL);
|
||||
return (jbyteArray) JNIHandles::make_local(env, a);
|
||||
return (jbyteArray) JNIHandles::make_local(THREAD, a);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -1695,7 +1693,7 @@ JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls))
|
||||
AnnotationArray* type_annotations = InstanceKlass::cast(k)->class_type_annotations();
|
||||
if (type_annotations != NULL) {
|
||||
typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);
|
||||
return (jbyteArray) JNIHandles::make_local(env, a);
|
||||
return (jbyteArray) JNIHandles::make_local(THREAD, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1715,7 +1713,7 @@ JVM_ENTRY(jbyteArray, JVM_GetMethodTypeAnnotations(JNIEnv *env, jobject method))
|
||||
AnnotationArray* type_annotations = m->type_annotations();
|
||||
if (type_annotations != NULL) {
|
||||
typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);
|
||||
return (jbyteArray) JNIHandles::make_local(env, a);
|
||||
return (jbyteArray) JNIHandles::make_local(THREAD, a);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -1731,7 +1729,7 @@ JVM_ENTRY(jbyteArray, JVM_GetFieldTypeAnnotations(JNIEnv *env, jobject field))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(fd.type_annotations(), THREAD));
|
||||
return (jbyteArray) JNIHandles::make_local(THREAD, Annotations::make_java_array(fd.type_annotations(), THREAD));
|
||||
JVM_END
|
||||
|
||||
static void bounds_check(const constantPoolHandle& cp, jint index, TRAPS) {
|
||||
@ -1787,7 +1785,7 @@ JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
|
||||
flags, CHECK_NULL);
|
||||
result->obj_at_put(i, param);
|
||||
}
|
||||
return (jobjectArray)JNIHandles::make_local(env, result());
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, result());
|
||||
}
|
||||
}
|
||||
JVM_END
|
||||
@ -1804,7 +1802,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass,
|
||||
java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_array_klass()) {
|
||||
// Return empty array
|
||||
oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL);
|
||||
return (jobjectArray) JNIHandles::make_local(env, res);
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, res);
|
||||
}
|
||||
|
||||
InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));
|
||||
@ -1839,7 +1837,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass,
|
||||
}
|
||||
}
|
||||
assert(out_idx == num_fields, "just checking");
|
||||
return (jobjectArray) JNIHandles::make_local(env, result());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -1881,13 +1879,13 @@ JVM_ENTRY(jobjectArray, JVM_GetRecordComponents(JNIEnv* env, jclass ofClass))
|
||||
oop component_oop = java_lang_reflect_RecordComponent::create(ik, component, CHECK_NULL);
|
||||
components_h->obj_at_put(x, component_oop);
|
||||
}
|
||||
return (jobjectArray)JNIHandles::make_local(components_h());
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, components_h());
|
||||
}
|
||||
}
|
||||
|
||||
// Return empty array if ofClass is not a record.
|
||||
objArrayOop result = oopFactory::new_objArray(SystemDictionary::RecordComponent_klass(), 0, CHECK_NULL);
|
||||
return (jobjectArray)JNIHandles::make_local(env, result);
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, result);
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -1912,7 +1910,7 @@ static jobjectArray get_class_declared_methods_helper(
|
||||
|| java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_array_klass()) {
|
||||
// Return empty array
|
||||
oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL);
|
||||
return (jobjectArray) JNIHandles::make_local(env, res);
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, res);
|
||||
}
|
||||
|
||||
InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)));
|
||||
@ -1965,7 +1963,7 @@ static jobjectArray get_class_declared_methods_helper(
|
||||
}
|
||||
}
|
||||
|
||||
return (jobjectArray) JNIHandles::make_local(env, result());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result());
|
||||
}
|
||||
|
||||
JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly))
|
||||
@ -2147,7 +2145,7 @@ JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))
|
||||
InstanceKlass* k_h = InstanceKlass::cast(k);
|
||||
Handle jcp = reflect_ConstantPool::create(CHECK_NULL);
|
||||
reflect_ConstantPool::set_cp(jcp(), k_h->constants());
|
||||
return JNIHandles::make_local(jcp());
|
||||
return JNIHandles::make_local(THREAD, jcp());
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -2174,7 +2172,7 @@ JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject u
|
||||
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
|
||||
}
|
||||
Klass* k = cp->klass_at(index, CHECK_NULL);
|
||||
return (jclass) JNIHandles::make_local(k->java_mirror());
|
||||
return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -2189,7 +2187,7 @@ JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, j
|
||||
}
|
||||
Klass* k = ConstantPool::klass_at_if_loaded(cp, index);
|
||||
if (k == NULL) return NULL;
|
||||
return (jclass) JNIHandles::make_local(k->java_mirror());
|
||||
return (jclass) JNIHandles::make_local(THREAD, k->java_mirror());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -2219,7 +2217,7 @@ static jobject get_method_at_helper(const constantPoolHandle& cp, jint index, bo
|
||||
} else {
|
||||
method = Reflection::new_constructor(m, CHECK_NULL);
|
||||
}
|
||||
return JNIHandles::make_local(method);
|
||||
return JNIHandles::make_local(THREAD, method);
|
||||
}
|
||||
|
||||
JVM_ENTRY(jobject, JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject obj, jobject unused, jint index))
|
||||
@ -2266,7 +2264,7 @@ static jobject get_field_at_helper(constantPoolHandle cp, jint index, bool force
|
||||
THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class");
|
||||
}
|
||||
oop field = Reflection::new_field(&fd, CHECK_NULL);
|
||||
return JNIHandles::make_local(field);
|
||||
return JNIHandles::make_local(THREAD, field);
|
||||
}
|
||||
|
||||
JVM_ENTRY(jobject, JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject obj, jobject unusedl, jint index))
|
||||
@ -2313,7 +2311,7 @@ JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject
|
||||
dest->obj_at_put(1, str());
|
||||
str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);
|
||||
dest->obj_at_put(2, str());
|
||||
return (jobjectArray) JNIHandles::make_local(dest());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, dest());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -2363,7 +2361,7 @@ JVM_ENTRY(jobjectArray, JVM_ConstantPoolGetNameAndTypeRefInfoAt(JNIEnv *env, job
|
||||
dest->obj_at_put(0, str());
|
||||
str = java_lang_String::create_from_symbol(member_sig, CHECK_NULL);
|
||||
dest->obj_at_put(1, str());
|
||||
return (jobjectArray) JNIHandles::make_local(dest());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, dest());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -2429,7 +2427,7 @@ JVM_ENTRY(jstring, JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject obj, jobject
|
||||
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Wrong type at constant pool index");
|
||||
}
|
||||
oop str = cp->string_at(index, CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(str);
|
||||
return (jstring) JNIHandles::make_local(THREAD, str);
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -2445,7 +2443,7 @@ JVM_ENTRY(jstring, JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject obj, jobject u
|
||||
}
|
||||
Symbol* sym = cp->symbol_at(index);
|
||||
Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(str());
|
||||
return (jstring) JNIHandles::make_local(THREAD, str());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -2502,7 +2500,7 @@ JVM_ENTRY(jobject, JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused))
|
||||
JVMWrapper("JVM_AssertionStatusDirectives");
|
||||
JvmtiVMObjectAllocEventCollector oam;
|
||||
oop asd = JavaAssertions::createAssertionStatusDirectives(CHECK_NULL);
|
||||
return JNIHandles::make_local(env, asd);
|
||||
return JNIHandles::make_local(THREAD, asd);
|
||||
JVM_END
|
||||
|
||||
// Verification ////////////////////////////////////////////////////////////////////////////////
|
||||
@ -3284,8 +3282,8 @@ JVM_END
|
||||
JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
|
||||
JVMWrapper("JVM_CurrentThread");
|
||||
oop jthread = thread->threadObj();
|
||||
assert (thread != NULL, "no current thread!");
|
||||
return JNIHandles::make_local(env, jthread);
|
||||
assert(jthread != NULL, "no current thread!");
|
||||
return JNIHandles::make_local(THREAD, jthread);
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
|
||||
@ -3377,7 +3375,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env))
|
||||
result->obj_at_put(i, klass_array->at(i)->java_mirror());
|
||||
}
|
||||
|
||||
return (jobjectArray) JNIHandles::make_local(env, result);
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -3390,7 +3388,7 @@ JVM_ENTRY(jstring, JVM_GetSystemPackage(JNIEnv *env, jstring name))
|
||||
JvmtiVMObjectAllocEventCollector oam;
|
||||
char* str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
|
||||
oop result = ClassLoader::get_system_package(str, CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(result);
|
||||
return (jstring) JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -3398,7 +3396,7 @@ JVM_ENTRY(jobjectArray, JVM_GetSystemPackages(JNIEnv *env))
|
||||
JVMWrapper("JVM_GetSystemPackages");
|
||||
JvmtiVMObjectAllocEventCollector oam;
|
||||
objArrayOop result = ClassLoader::get_system_packages(CHECK_NULL);
|
||||
return (jobjectArray) JNIHandles::make_local(result);
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -3411,9 +3409,9 @@ JVM_ENTRY(jobject, JVM_GetAndClearReferencePendingList(JNIEnv* env))
|
||||
MonitorLocker ml(Heap_lock);
|
||||
oop ref = Universe::reference_pending_list();
|
||||
if (ref != NULL) {
|
||||
Universe::set_reference_pending_list(NULL);
|
||||
Universe::clear_reference_pending_list();
|
||||
}
|
||||
return JNIHandles::make_local(env, ref);
|
||||
return JNIHandles::make_local(THREAD, ref);
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(jboolean, JVM_HasReferencePendingList(JNIEnv* env))
|
||||
@ -3441,7 +3439,7 @@ JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env))
|
||||
vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection
|
||||
oop loader = vfst.method()->method_holder()->class_loader();
|
||||
if (loader != NULL && !SystemDictionary::is_platform_class_loader(loader)) {
|
||||
return JNIHandles::make_local(env, loader);
|
||||
return JNIHandles::make_local(THREAD, loader);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -3480,7 +3478,7 @@ JVM_ENTRY(jobject, JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index))
|
||||
jvalue value;
|
||||
BasicType type = Reflection::array_get(&value, a, index, CHECK_NULL);
|
||||
oop box = Reflection::box(&value, type, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, box);
|
||||
return JNIHandles::make_local(THREAD, box);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -3530,7 +3528,7 @@ JVM_ENTRY(jobject, JVM_NewArray(JNIEnv *env, jclass eltClass, jint length))
|
||||
JvmtiVMObjectAllocEventCollector oam;
|
||||
oop element_mirror = JNIHandles::resolve(eltClass);
|
||||
oop result = Reflection::reflect_new_array(element_mirror, length, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, result);
|
||||
return JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -3541,7 +3539,7 @@ JVM_ENTRY(jobject, JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim
|
||||
oop element_mirror = JNIHandles::resolve(eltClass);
|
||||
assert(dim_array->is_typeArray(), "just checking");
|
||||
oop result = Reflection::reflect_new_multi_array(element_mirror, typeArrayOop(dim_array), CHECK_NULL);
|
||||
return JNIHandles::make_local(env, result);
|
||||
return JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -3608,7 +3606,7 @@ JVM_ENTRY(jstring, JVM_InternString(JNIEnv *env, jstring str))
|
||||
if (str == NULL) return NULL;
|
||||
oop string = JNIHandles::resolve_non_null(str);
|
||||
oop result = StringTable::intern(string, CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(env, result);
|
||||
return (jstring) JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -3667,7 +3665,7 @@ jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,
|
||||
if (init && klass->is_instance_klass()) {
|
||||
klass->initialize(CHECK_NULL);
|
||||
}
|
||||
return (jclass) JNIHandles::make_local(env, klass->java_mirror());
|
||||
return (jclass) JNIHandles::make_local(THREAD, klass->java_mirror());
|
||||
}
|
||||
|
||||
|
||||
@ -3681,14 +3679,14 @@ JVM_ENTRY(jobject, JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jo
|
||||
Handle receiver(THREAD, JNIHandles::resolve(obj));
|
||||
objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));
|
||||
oop result = Reflection::invoke_method(method_handle(), receiver, args, CHECK_NULL);
|
||||
jobject res = JNIHandles::make_local(env, result);
|
||||
jobject res = JNIHandles::make_local(THREAD, result);
|
||||
if (JvmtiExport::should_post_vm_object_alloc()) {
|
||||
oop ret_type = java_lang_reflect_Method::return_type(method_handle());
|
||||
assert(ret_type != NULL, "sanity check: ret_type oop must not be NULL!");
|
||||
if (java_lang_Class::is_primitive(ret_type)) {
|
||||
// Only for primitive type vm allocates memory for java object.
|
||||
// See box() method.
|
||||
JvmtiExport::post_vm_object_alloc(JavaThread::current(), result);
|
||||
JvmtiExport::post_vm_object_alloc(thread, result);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
@ -3703,9 +3701,9 @@ JVM_ENTRY(jobject, JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjec
|
||||
oop constructor_mirror = JNIHandles::resolve(c);
|
||||
objArrayHandle args(THREAD, objArrayOop(JNIHandles::resolve(args0)));
|
||||
oop result = Reflection::invoke_constructor(constructor_mirror, args, CHECK_NULL);
|
||||
jobject res = JNIHandles::make_local(env, result);
|
||||
jobject res = JNIHandles::make_local(THREAD, result);
|
||||
if (JvmtiExport::should_post_vm_object_alloc()) {
|
||||
JvmtiExport::post_vm_object_alloc(JavaThread::current(), result);
|
||||
JvmtiExport::post_vm_object_alloc(thread, result);
|
||||
}
|
||||
return res;
|
||||
JVM_END
|
||||
@ -3818,7 +3816,7 @@ JVM_ENTRY(jclass, JVM_LookupLambdaProxyClassFromArchive(JNIEnv* env,
|
||||
jclass jcls = NULL;
|
||||
if (lambda_ik != NULL) {
|
||||
InstanceKlass* loaded_lambda = SystemDictionaryShared::prepare_shared_lambda_proxy_class(lambda_ik, caller_ik, initialize, THREAD);
|
||||
jcls = loaded_lambda == NULL ? NULL : (jclass) JNIHandles::make_local(env, loaded_lambda->java_mirror());
|
||||
jcls = loaded_lambda == NULL ? NULL : (jclass) JNIHandles::make_local(THREAD, loaded_lambda->java_mirror());
|
||||
}
|
||||
return jcls;
|
||||
#else
|
||||
@ -3876,7 +3874,7 @@ JVM_ENTRY(jobjectArray, JVM_GetAllThreads(JNIEnv *env, jclass dummy))
|
||||
threads_ah->obj_at_put(i, h());
|
||||
}
|
||||
|
||||
return (jobjectArray) JNIHandles::make_local(env, threads_ah());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, threads_ah());
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -3918,7 +3916,7 @@ JVM_ENTRY(jobjectArray, JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobject
|
||||
// The JavaThread references in thread_handle_array are validated
|
||||
// in VM_ThreadDump::doit().
|
||||
Handle stacktraces = ThreadService::dump_stack_traces(thread_handle_array, num_threads, CHECK_NULL);
|
||||
return (jobjectArray)JNIHandles::make_local(env, stacktraces());
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, stacktraces());
|
||||
|
||||
JVM_END
|
||||
|
||||
@ -3981,7 +3979,7 @@ JVM_ENTRY(jobjectArray, JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass))
|
||||
str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
|
||||
dest->obj_at_put(2, str());
|
||||
}
|
||||
return (jobjectArray) JNIHandles::make_local(dest());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, dest());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -4011,7 +4009,7 @@ JVM_ENTRY(jobjectArray, JVM_GetVmArguments(JNIEnv *env))
|
||||
Handle h = java_lang_String::create_from_platform_dependent_str(vm_args[i], CHECK_NULL);
|
||||
result_h->obj_at_put(index, h());
|
||||
}
|
||||
return (jobjectArray) JNIHandles::make_local(env, result_h());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result_h());
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY_NO_ENV(jint, JVM_FindSignal(const char *name))
|
||||
|
@ -724,13 +724,13 @@ JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread
|
||||
javaVFrame *jvf, GrowableArray<jvmtiMonitorStackDepthInfo*>* owned_monitors_list, jint stack_depth) {
|
||||
jvmtiError err = JVMTI_ERROR_NONE;
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
|
||||
GrowableArray<MonitorInfo*>* mons = jvf->monitors();
|
||||
if (mons->is_empty()) {
|
||||
return err; // this javaVFrame holds no monitors
|
||||
}
|
||||
|
||||
HandleMark hm;
|
||||
oop wait_obj = NULL;
|
||||
{
|
||||
// The ObjectMonitor* can't be async deflated since we are either
|
||||
@ -1005,7 +1005,6 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
|
||||
// as lightweight locks before inflating the monitor are not included.
|
||||
// We have to count the number of recursive monitor entries the hard way.
|
||||
// We pass a handle to survive any GCs along the way.
|
||||
ResourceMark rm(current_thread);
|
||||
ret.entry_count = count_locked_objects(owning_thread, hobj);
|
||||
}
|
||||
// implied else: entry_count == 0
|
||||
|
@ -1221,6 +1221,44 @@ bool VM_RedefineClasses::is_unresolved_class_mismatch(const constantPoolHandle&
|
||||
} // end is_unresolved_class_mismatch()
|
||||
|
||||
|
||||
// The bug 6214132 caused the verification to fail.
|
||||
// 1. What's done in RedefineClasses() before verification:
|
||||
// a) A reference to the class being redefined (_the_class) and a
|
||||
// reference to new version of the class (_scratch_class) are
|
||||
// saved here for use during the bytecode verification phase of
|
||||
// RedefineClasses.
|
||||
// b) The _java_mirror field from _the_class is copied to the
|
||||
// _java_mirror field in _scratch_class. This means that a jclass
|
||||
// returned for _the_class or _scratch_class will refer to the
|
||||
// same Java mirror. The verifier will see the "one true mirror"
|
||||
// for the class being verified.
|
||||
// 2. See comments in JvmtiThreadState for what is done during verification.
|
||||
|
||||
class RedefineVerifyMark : public StackObj {
|
||||
private:
|
||||
JvmtiThreadState* _state;
|
||||
Klass* _scratch_class;
|
||||
Handle _scratch_mirror;
|
||||
|
||||
public:
|
||||
|
||||
RedefineVerifyMark(Klass* the_class, Klass* scratch_class,
|
||||
JvmtiThreadState* state) : _state(state), _scratch_class(scratch_class)
|
||||
{
|
||||
_state->set_class_versions_map(the_class, scratch_class);
|
||||
_scratch_mirror = Handle(_state->get_thread(), _scratch_class->java_mirror());
|
||||
_scratch_class->replace_java_mirror(the_class->java_mirror());
|
||||
}
|
||||
|
||||
~RedefineVerifyMark() {
|
||||
// Restore the scratch class's mirror, so when scratch_class is removed
|
||||
// the correct mirror pointing to it can be cleared.
|
||||
_scratch_class->replace_java_mirror(_scratch_mirror());
|
||||
_state->clear_class_versions_map();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
|
||||
|
||||
// For consistency allocate memory using os::malloc wrapper.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -247,19 +247,8 @@ class JvmtiThreadState : public CHeapObj<mtInternal> {
|
||||
// RedefineClasses support
|
||||
// The bug 6214132 caused the verification to fail.
|
||||
//
|
||||
// Below is the detailed description of the fix approach taken:
|
||||
// 1. What's done in RedefineClasses() before verification:
|
||||
// a) A reference to the class being redefined (_the_class) and a
|
||||
// reference to new version of the class (_scratch_class) are
|
||||
// saved here for use during the bytecode verification phase of
|
||||
// RedefineClasses. See RedefineVerifyMark for how these fields
|
||||
// are managed.
|
||||
// b) The _java_mirror field from _the_class is copied to the
|
||||
// _java_mirror field in _scratch_class. This means that a jclass
|
||||
// returned for _the_class or _scratch_class will refer to the
|
||||
// same Java mirror. The verifier will see the "one true mirror"
|
||||
// for the class being verified.
|
||||
// 2. What is done at verification:
|
||||
// What is done at verification:
|
||||
// (This seems to only apply to the old verifier.)
|
||||
// When the verifier makes calls into the VM to ask questions about
|
||||
// the class being verified, it will pass the jclass to JVM_* functions.
|
||||
// The jclass is always pointing to the mirror of _the_class.
|
||||
@ -401,27 +390,4 @@ public:
|
||||
void run_nmethod_entry_barriers();
|
||||
};
|
||||
|
||||
class RedefineVerifyMark : public StackObj {
|
||||
private:
|
||||
JvmtiThreadState* _state;
|
||||
Klass* _scratch_class;
|
||||
OopHandle _scratch_mirror;
|
||||
|
||||
public:
|
||||
RedefineVerifyMark(Klass* the_class, Klass* scratch_class,
|
||||
JvmtiThreadState *state) : _state(state), _scratch_class(scratch_class)
|
||||
{
|
||||
_state->set_class_versions_map(the_class, scratch_class);
|
||||
_scratch_mirror = _scratch_class->java_mirror_handle();
|
||||
_scratch_class->set_java_mirror_handle(the_class->java_mirror_handle());
|
||||
}
|
||||
|
||||
~RedefineVerifyMark() {
|
||||
// Restore the scratch class's mirror, so when scratch_class is removed
|
||||
// the correct mirror pointing to it can be cleared.
|
||||
_scratch_class->set_java_mirror_handle(_scratch_mirror);
|
||||
_state->clear_class_versions_map();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHARE_PRIMS_JVMTITHREADSTATE_HPP
|
||||
|
@ -179,7 +179,6 @@ Handle MethodHandles::resolve_MemberName_type(Handle mname, Klass* caller, TRAPS
|
||||
oop MethodHandles::init_MemberName(Handle mname, Handle target, TRAPS) {
|
||||
// This method is used from java.lang.invoke.MemberName constructors.
|
||||
// It fills in the new MemberName from a java.lang.reflect.Member.
|
||||
Thread* thread = Thread::current();
|
||||
oop target_oop = target();
|
||||
Klass* target_klass = target_oop->klass();
|
||||
if (target_klass == SystemDictionary::reflect_Field_klass()) {
|
||||
@ -207,7 +206,7 @@ oop MethodHandles::init_MemberName(Handle mname, Handle target, TRAPS) {
|
||||
if (m == NULL || is_signature_polymorphic(m->intrinsic_id()))
|
||||
return NULL; // do not resolve unless there is a concrete signature
|
||||
CallInfo info(m, k, CHECK_NULL);
|
||||
return init_method_MemberName(mname, info);
|
||||
return init_method_MemberName(mname, info, THREAD);
|
||||
}
|
||||
} else if (target_klass == SystemDictionary::reflect_Constructor_klass()) {
|
||||
oop clazz = java_lang_reflect_Constructor::clazz(target_oop);
|
||||
@ -217,13 +216,13 @@ oop MethodHandles::init_MemberName(Handle mname, Handle target, TRAPS) {
|
||||
Method* m = InstanceKlass::cast(k)->method_with_idnum(slot);
|
||||
if (m == NULL) return NULL;
|
||||
CallInfo info(m, k, CHECK_NULL);
|
||||
return init_method_MemberName(mname, info);
|
||||
return init_method_MemberName(mname, info, THREAD);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
|
||||
oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info, TRAPS) {
|
||||
assert(info.resolved_appendix().is_null(), "only normal methods here");
|
||||
methodHandle m(Thread::current(), info.resolved_method());
|
||||
assert(m.not_null(), "null method handle");
|
||||
@ -789,7 +788,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller,
|
||||
THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
|
||||
}
|
||||
result.set_resolved_method_name(CHECK_(empty));
|
||||
oop mname2 = init_method_MemberName(mname, result);
|
||||
oop mname2 = init_method_MemberName(mname, result, THREAD);
|
||||
return Handle(THREAD, mname2);
|
||||
}
|
||||
case IS_CONSTRUCTOR:
|
||||
@ -812,7 +811,7 @@ Handle MethodHandles::resolve_MemberName(Handle mname, Klass* caller,
|
||||
}
|
||||
assert(result.is_statically_bound(), "");
|
||||
result.set_resolved_method_name(CHECK_(empty));
|
||||
oop mname2 = init_method_MemberName(mname, result);
|
||||
oop mname2 = init_method_MemberName(mname, result, THREAD);
|
||||
return Handle(THREAD, mname2);
|
||||
}
|
||||
case IS_FIELD:
|
||||
@ -922,8 +921,6 @@ int MethodHandles::find_MemberNames(Klass* k,
|
||||
int skip, objArrayHandle results, TRAPS) {
|
||||
// %%% take caller into account!
|
||||
|
||||
Thread* thread = Thread::current();
|
||||
|
||||
if (k == NULL || !k->is_instance_klass()) return -1;
|
||||
|
||||
int rfill = 0, rlimit = results->length(), rskip = skip;
|
||||
@ -960,7 +957,7 @@ int MethodHandles::find_MemberNames(Klass* k,
|
||||
if (rskip > 0) {
|
||||
--rskip;
|
||||
} else if (rfill < rlimit) {
|
||||
Handle result(thread, results->obj_at(rfill++));
|
||||
Handle result(THREAD, results->obj_at(rfill++));
|
||||
if (!java_lang_invoke_MemberName::is_instance(result()))
|
||||
return -99; // caller bug!
|
||||
oop saved = MethodHandles::init_field_MemberName(result, st.field_descriptor());
|
||||
@ -1011,11 +1008,11 @@ int MethodHandles::find_MemberNames(Klass* k,
|
||||
if (rskip > 0) {
|
||||
--rskip;
|
||||
} else if (rfill < rlimit) {
|
||||
Handle result(thread, results->obj_at(rfill++));
|
||||
Handle result(THREAD, results->obj_at(rfill++));
|
||||
if (!java_lang_invoke_MemberName::is_instance(result()))
|
||||
return -99; // caller bug!
|
||||
CallInfo info(m, NULL, CHECK_0);
|
||||
oop saved = MethodHandles::init_method_MemberName(result, info);
|
||||
oop saved = MethodHandles::init_method_MemberName(result, info, THREAD);
|
||||
if (saved != result())
|
||||
results->obj_at_put(rfill-1, saved); // show saved instance to user
|
||||
} else if (++overflow >= overflow_limit) {
|
||||
@ -1302,7 +1299,7 @@ JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname
|
||||
x = mname();
|
||||
}
|
||||
result->obj_at_put(1, x);
|
||||
return JNIHandles::make_local(env, result());
|
||||
return JNIHandles::make_local(THREAD, result());
|
||||
}
|
||||
JVM_END
|
||||
|
||||
@ -1550,7 +1547,7 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
|
||||
assert(SystemDictionary::MethodHandle_klass() != NULL, "should be present");
|
||||
|
||||
oop mirror = SystemDictionary::MethodHandle_klass()->java_mirror();
|
||||
jclass MH_class = (jclass) JNIHandles::make_local(env, mirror);
|
||||
jclass MH_class = (jclass) JNIHandles::make_local(THREAD, mirror);
|
||||
|
||||
{
|
||||
ThreadToNativeFromVM ttnfv(thread);
|
||||
|
@ -65,7 +65,7 @@ class MethodHandles: AllStatic {
|
||||
static void expand_MemberName(Handle mname, int suppress, TRAPS); // expand defc/name/type if missing
|
||||
static oop init_MemberName(Handle mname_h, Handle target_h, TRAPS); // compute vmtarget/vmindex from target
|
||||
static oop init_field_MemberName(Handle mname_h, fieldDescriptor& fd, bool is_setter = false);
|
||||
static oop init_method_MemberName(Handle mname_h, CallInfo& info);
|
||||
static oop init_method_MemberName(Handle mname_h, CallInfo& info, TRAPS);
|
||||
static int find_MemberNames(Klass* k, Symbol* name, Symbol* sig,
|
||||
int mflags, Klass* caller,
|
||||
int skip, objArrayHandle results, TRAPS);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -288,6 +288,9 @@ void LiveFrameStream::fill_live_stackframe(Handle stackFrame,
|
||||
const methodHandle& method, TRAPS) {
|
||||
fill_stackframe(stackFrame, method, CHECK);
|
||||
if (_jvf != NULL) {
|
||||
ResourceMark rm(THREAD);
|
||||
HandleMark hm(THREAD);
|
||||
|
||||
StackValueCollection* locals = _jvf->locals();
|
||||
StackValueCollection* expressions = _jvf->expressions();
|
||||
GrowableArray<MonitorInfo*>* monitors = _jvf->monitors();
|
||||
|
@ -265,7 +265,7 @@ UNSAFE_ENTRY(jobject, Unsafe_GetReference(JNIEnv *env, jobject unsafe, jobject o
|
||||
oop p = JNIHandles::resolve(obj);
|
||||
assert_field_offset_sane(p, offset);
|
||||
oop v = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);
|
||||
return JNIHandles::make_local(env, v);
|
||||
return JNIHandles::make_local(THREAD, v);
|
||||
} UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_PutReference(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
|
||||
@ -279,7 +279,7 @@ UNSAFE_ENTRY(jobject, Unsafe_GetReferenceVolatile(JNIEnv *env, jobject unsafe, j
|
||||
oop p = JNIHandles::resolve(obj);
|
||||
assert_field_offset_sane(p, offset);
|
||||
oop v = HeapAccess<MO_SEQ_CST | ON_UNKNOWN_OOP_REF>::oop_load_at(p, offset);
|
||||
return JNIHandles::make_local(env, v);
|
||||
return JNIHandles::make_local(THREAD, v);
|
||||
} UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_PutReferenceVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h)) {
|
||||
@ -291,7 +291,7 @@ UNSAFE_ENTRY(void, Unsafe_PutReferenceVolatile(JNIEnv *env, jobject unsafe, jobj
|
||||
|
||||
UNSAFE_ENTRY(jobject, Unsafe_GetUncompressedObject(JNIEnv *env, jobject unsafe, jlong addr)) {
|
||||
oop v = *(oop*) (address) addr;
|
||||
return JNIHandles::make_local(env, v);
|
||||
return JNIHandles::make_local(THREAD, v);
|
||||
} UNSAFE_END
|
||||
|
||||
#define DEFINE_GETSETOOP(java_type, Type) \
|
||||
@ -356,7 +356,7 @@ UNSAFE_LEAF(void, Unsafe_FullFence(JNIEnv *env, jobject unsafe)) {
|
||||
|
||||
UNSAFE_ENTRY(jobject, Unsafe_AllocateInstance(JNIEnv *env, jobject unsafe, jclass cls)) {
|
||||
instanceOop i = InstanceKlass::allocate_instance(JNIHandles::resolve_non_null(cls), CHECK_NULL);
|
||||
return JNIHandles::make_local(env, i);
|
||||
return JNIHandles::make_local(THREAD, i);
|
||||
} UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(jlong, Unsafe_AllocateMemory0(JNIEnv *env, jobject unsafe, jlong size)) {
|
||||
@ -565,7 +565,7 @@ UNSAFE_ENTRY(jobject, Unsafe_StaticFieldBase0(JNIEnv *env, jobject unsafe, jobje
|
||||
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
|
||||
}
|
||||
|
||||
return JNIHandles::make_local(env, mirror);
|
||||
return JNIHandles::make_local(THREAD, mirror);
|
||||
} UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(void, Unsafe_EnsureClassInitialized0(JNIEnv *env, jobject unsafe, jobject clazz)) {
|
||||
@ -881,7 +881,7 @@ UNSAFE_ENTRY(jclass, Unsafe_DefineAnonymousClass0(JNIEnv *env, jobject unsafe, j
|
||||
|
||||
InstanceKlass* anon_klass = Unsafe_DefineAnonymousClass_impl(env, host_class, data, cp_patches_jh, &temp_alloc, THREAD);
|
||||
if (anon_klass != NULL) {
|
||||
res_jh = JNIHandles::make_local(env, anon_klass->java_mirror());
|
||||
res_jh = JNIHandles::make_local(THREAD, anon_klass->java_mirror());
|
||||
}
|
||||
|
||||
// try/finally clause:
|
||||
@ -914,7 +914,7 @@ UNSAFE_ENTRY(jobject, Unsafe_CompareAndExchangeReference(JNIEnv *env, jobject un
|
||||
oop p = JNIHandles::resolve(obj);
|
||||
assert_field_offset_sane(p, offset);
|
||||
oop res = HeapAccess<ON_UNKNOWN_OOP_REF>::oop_atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x);
|
||||
return JNIHandles::make_local(env, res);
|
||||
return JNIHandles::make_local(THREAD, res);
|
||||
} UNSAFE_END
|
||||
|
||||
UNSAFE_ENTRY(jint, Unsafe_CompareAndExchangeInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
|
||||
|
@ -631,7 +631,7 @@ WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env))
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
MemoryUsage usage = g1h->get_auxiliary_data_memory_usage();
|
||||
Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, h());
|
||||
return JNIHandles::make_local(THREAD, h());
|
||||
}
|
||||
THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1AuxiliaryMemoryUsage: G1 GC is not enabled");
|
||||
WB_END
|
||||
@ -654,7 +654,7 @@ WB_ENTRY(jintArray, WB_G1MemoryNodeIds(JNIEnv* env, jobject o))
|
||||
for (int i = 0; i < num_node_ids; i++) {
|
||||
result->int_at_put(i, (jint)node_ids[i]);
|
||||
}
|
||||
return (jintArray) JNIHandles::make_local(env, result);
|
||||
return (jintArray) JNIHandles::make_local(THREAD, result);
|
||||
}
|
||||
THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1MemoryNodeIds: G1 GC is not enabled");
|
||||
WB_END
|
||||
@ -715,7 +715,7 @@ WB_ENTRY(jlongArray, WB_G1GetMixedGCInfo(JNIEnv* env, jobject o, jint liveness))
|
||||
result->long_at_put(0, rli.total_count());
|
||||
result->long_at_put(1, rli.total_memory());
|
||||
result->long_at_put(2, rli.total_memory_to_free());
|
||||
return (jlongArray) JNIHandles::make_local(env, result);
|
||||
return (jlongArray) JNIHandles::make_local(THREAD, result);
|
||||
WB_END
|
||||
|
||||
#endif // INCLUDE_G1GC
|
||||
@ -1678,12 +1678,11 @@ WB_ENTRY(jlong, WB_GetMethodData(JNIEnv* env, jobject wv, jobject method))
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o))
|
||||
return (jlong) Thread::current()->stack_size();
|
||||
return (jlong) thread->stack_size();
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jlong, WB_GetThreadRemainingStackSize(JNIEnv* env, jobject o))
|
||||
JavaThread* t = JavaThread::current();
|
||||
return (jlong) t->stack_available(os::current_stack_pointer()) - (jlong)JavaThread::stack_shadow_zone_size();
|
||||
return (jlong) thread->stack_available(os::current_stack_pointer()) - (jlong)JavaThread::stack_shadow_zone_size();
|
||||
WB_END
|
||||
|
||||
|
||||
@ -1790,7 +1789,7 @@ WB_ENTRY(void, WB_AssertSpecialLock(JNIEnv* env, jobject o, jboolean allowVMBloc
|
||||
|
||||
MutexLocker ml(new Mutex(Mutex::special, "SpecialTest_lock", allowVMBlock, sfpt_check_required), safepoint_check);
|
||||
// If the lock above succeeds, try to safepoint to test the NSV implied with this special lock.
|
||||
ThreadBlockInVM tbivm(JavaThread::current());
|
||||
ThreadBlockInVM tbivm(thread);
|
||||
WB_END
|
||||
|
||||
WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj))
|
||||
@ -1957,7 +1956,7 @@ WB_ENTRY(jobject, WB_GetResolvedReferences(JNIEnv* env, jobject wb, jclass clazz
|
||||
InstanceKlass *ik = InstanceKlass::cast(k);
|
||||
ConstantPool *cp = ik->constants();
|
||||
objArrayOop refs = cp->resolved_references();
|
||||
return (jobject)JNIHandles::make_local(env, refs);
|
||||
return (jobject)JNIHandles::make_local(THREAD, refs);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "utilities/align.hpp"
|
||||
#include "utilities/bytes.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include <type_traits>
|
||||
|
||||
enum atomic_memory_order {
|
||||
// The modes that align with C++11 are intended to
|
||||
@ -383,7 +384,7 @@ template<typename T, typename PlatformOp>
|
||||
struct Atomic::LoadImpl<
|
||||
T,
|
||||
PlatformOp,
|
||||
typename EnableIf<IsIntegral<T>::value || IsRegisteredEnum<T>::value || IsPointer<T>::value>::type>
|
||||
typename EnableIf<IsIntegral<T>::value || std::is_enum<T>::value || IsPointer<T>::value>::type>
|
||||
{
|
||||
T operator()(T const volatile* dest) const {
|
||||
// Forward to the platform handler for the size of T.
|
||||
@ -435,7 +436,7 @@ template<typename T, typename PlatformOp>
|
||||
struct Atomic::StoreImpl<
|
||||
T, T,
|
||||
PlatformOp,
|
||||
typename EnableIf<IsIntegral<T>::value || IsRegisteredEnum<T>::value>::type>
|
||||
typename EnableIf<IsIntegral<T>::value || std::is_enum<T>::value>::type>
|
||||
{
|
||||
void operator()(T volatile* dest, T new_value) const {
|
||||
// Forward to the platform handler for the size of T.
|
||||
@ -737,7 +738,7 @@ inline bool Atomic::replace_if_null(D* volatile* dest, T* value,
|
||||
template<typename T>
|
||||
struct Atomic::CmpxchgImpl<
|
||||
T, T, T,
|
||||
typename EnableIf<IsIntegral<T>::value || IsRegisteredEnum<T>::value>::type>
|
||||
typename EnableIf<IsIntegral<T>::value || std::is_enum<T>::value>::type>
|
||||
{
|
||||
T operator()(T volatile* dest, T compare_value, T exchange_value,
|
||||
atomic_memory_order order) const {
|
||||
@ -871,7 +872,7 @@ inline T Atomic::CmpxchgByteUsingInt::operator()(T volatile* dest,
|
||||
template<typename T>
|
||||
struct Atomic::XchgImpl<
|
||||
T, T,
|
||||
typename EnableIf<IsIntegral<T>::value || IsRegisteredEnum<T>::value>::type>
|
||||
typename EnableIf<IsIntegral<T>::value || std::is_enum<T>::value>::type>
|
||||
{
|
||||
T operator()(T volatile* dest, T exchange_value, atomic_memory_order order) const {
|
||||
// Forward to the platform handler for the size of T.
|
||||
|
@ -906,8 +906,10 @@ void BiasedLocking::preserve_marks() {
|
||||
_preserved_mark_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<markWord>(10, mtGC);
|
||||
_preserved_oop_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<Handle>(10, mtGC);
|
||||
|
||||
ResourceMark rm;
|
||||
Thread* cur = Thread::current();
|
||||
ResourceMark rm(cur);
|
||||
HandleMark hm(cur);
|
||||
|
||||
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
|
||||
if (thread->has_last_Java_frame()) {
|
||||
RegisterMap rm(thread);
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -218,6 +216,7 @@ static bool eliminate_allocations(JavaThread* thread, int exec_mode, CompiledMet
|
||||
}
|
||||
|
||||
static void eliminate_locks(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk, bool realloc_failures) {
|
||||
HandleMark hm;
|
||||
#ifndef PRODUCT
|
||||
bool first = true;
|
||||
#endif
|
||||
@ -1535,6 +1534,8 @@ void Deoptimization::revoke_from_deopt_handler(JavaThread* thread, frame fr, Reg
|
||||
if (!UseBiasedLocking) {
|
||||
return;
|
||||
}
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
|
||||
get_monitors_from_stack(objects_to_revoke, thread, fr, map);
|
||||
|
||||
|
@ -55,43 +55,21 @@ void jni_handles_init() {
|
||||
}
|
||||
|
||||
jobject JNIHandles::make_local(oop obj) {
|
||||
if (obj == NULL) {
|
||||
return NULL; // ignore null handles
|
||||
} else {
|
||||
Thread* thread = Thread::current();
|
||||
assert(oopDesc::is_oop(obj), "not an oop");
|
||||
assert(!current_thread_in_native(), "must not be in native");
|
||||
return thread->active_handles()->allocate_handle(obj);
|
||||
}
|
||||
return make_local(Thread::current(), obj);
|
||||
}
|
||||
|
||||
|
||||
// optimized versions
|
||||
|
||||
jobject JNIHandles::make_local(Thread* thread, oop obj) {
|
||||
// Used by NewLocalRef which requires NULL on out-of-memory
|
||||
jobject JNIHandles::make_local(Thread* thread, oop obj, AllocFailType alloc_failmode) {
|
||||
if (obj == NULL) {
|
||||
return NULL; // ignore null handles
|
||||
} else {
|
||||
assert(oopDesc::is_oop(obj), "not an oop");
|
||||
assert(thread->is_Java_thread(), "not a Java thread");
|
||||
assert(!current_thread_in_native(), "must not be in native");
|
||||
return thread->active_handles()->allocate_handle(obj);
|
||||
return thread->active_handles()->allocate_handle(obj, alloc_failmode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jobject JNIHandles::make_local(JNIEnv* env, oop obj) {
|
||||
if (obj == NULL) {
|
||||
return NULL; // ignore null handles
|
||||
} else {
|
||||
JavaThread* thread = JavaThread::thread_from_jni_environment(env);
|
||||
assert(oopDesc::is_oop(obj), "not an oop");
|
||||
assert(!current_thread_in_native(), "must not be in native");
|
||||
return thread->active_handles()->allocate_handle(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void report_handle_allocation_failure(AllocFailType alloc_failmode,
|
||||
const char* handle_kind) {
|
||||
if (alloc_failmode == AllocFailStrategy::EXIT_OOM) {
|
||||
@ -124,7 +102,6 @@ jobject JNIHandles::make_global(Handle obj, AllocFailType alloc_failmode) {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
jobject JNIHandles::make_weak_global(Handle obj, AllocFailType alloc_failmode) {
|
||||
assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
|
||||
assert(!current_thread_in_native(), "must not be in native");
|
||||
@ -365,7 +342,7 @@ void JNIHandleBlock::zap() {
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) {
|
||||
JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread, AllocFailType alloc_failmode) {
|
||||
assert(thread == NULL || thread == Thread::current(), "sanity check");
|
||||
JNIHandleBlock* block;
|
||||
// Check the thread-local free list for a block so we don't
|
||||
@ -383,7 +360,14 @@ JNIHandleBlock* JNIHandleBlock::allocate_block(Thread* thread) {
|
||||
Mutex::_no_safepoint_check_flag);
|
||||
if (_block_free_list == NULL) {
|
||||
// Allocate new block
|
||||
block = new JNIHandleBlock();
|
||||
if (alloc_failmode == AllocFailStrategy::RETURN_NULL) {
|
||||
block = new (std::nothrow) JNIHandleBlock();
|
||||
if (block == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
block = new JNIHandleBlock();
|
||||
}
|
||||
_blocks_allocated++;
|
||||
block->zap();
|
||||
#ifndef PRODUCT
|
||||
@ -483,7 +467,7 @@ void JNIHandleBlock::oops_do(OopClosure* f) {
|
||||
}
|
||||
|
||||
|
||||
jobject JNIHandleBlock::allocate_handle(oop obj) {
|
||||
jobject JNIHandleBlock::allocate_handle(oop obj, AllocFailType alloc_failmode) {
|
||||
assert(Universe::heap()->is_in(obj), "sanity check");
|
||||
if (_top == 0) {
|
||||
// This is the first allocation or the initial block got zapped when
|
||||
@ -531,7 +515,7 @@ jobject JNIHandleBlock::allocate_handle(oop obj) {
|
||||
if (_last->_next != NULL) {
|
||||
// update last and retry
|
||||
_last = _last->_next;
|
||||
return allocate_handle(obj);
|
||||
return allocate_handle(obj, alloc_failmode);
|
||||
}
|
||||
|
||||
// No space available, we have to rebuild free list or expand
|
||||
@ -542,12 +526,15 @@ jobject JNIHandleBlock::allocate_handle(oop obj) {
|
||||
Thread* thread = Thread::current();
|
||||
Handle obj_handle(thread, obj);
|
||||
// This can block, so we need to preserve obj across call.
|
||||
_last->_next = JNIHandleBlock::allocate_block(thread);
|
||||
_last->_next = JNIHandleBlock::allocate_block(thread, alloc_failmode);
|
||||
if (_last->_next == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
_last = _last->_next;
|
||||
_allocate_before_rebuild--;
|
||||
obj = obj_handle();
|
||||
}
|
||||
return allocate_handle(obj); // retry
|
||||
return allocate_handle(obj, alloc_failmode); // retry
|
||||
}
|
||||
|
||||
void JNIHandleBlock::rebuild_free_list() {
|
||||
|
@ -84,16 +84,18 @@ class JNIHandles : AllStatic {
|
||||
|
||||
// Local handles
|
||||
static jobject make_local(oop obj);
|
||||
static jobject make_local(JNIEnv* env, oop obj); // Fast version when env is known
|
||||
static jobject make_local(Thread* thread, oop obj); // Even faster version when current thread is known
|
||||
static jobject make_local(Thread* thread, oop obj, // Faster version when current thread is known
|
||||
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
|
||||
inline static void destroy_local(jobject handle);
|
||||
|
||||
// Global handles
|
||||
static jobject make_global(Handle obj, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
|
||||
static jobject make_global(Handle obj,
|
||||
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
|
||||
static void destroy_global(jobject handle);
|
||||
|
||||
// Weak global handles
|
||||
static jobject make_weak_global(Handle obj, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
|
||||
static jobject make_weak_global(Handle obj,
|
||||
AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
|
||||
static void destroy_weak_global(jobject handle);
|
||||
static bool is_global_weak_cleared(jweak handle); // Test jweak without resolution
|
||||
|
||||
@ -177,10 +179,10 @@ class JNIHandleBlock : public CHeapObj<mtInternal> {
|
||||
|
||||
public:
|
||||
// Handle allocation
|
||||
jobject allocate_handle(oop obj);
|
||||
jobject allocate_handle(oop obj, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
|
||||
|
||||
// Block allocation and block free list management
|
||||
static JNIHandleBlock* allocate_block(Thread* thread = NULL);
|
||||
static JNIHandleBlock* allocate_block(Thread* thread = NULL, AllocFailType alloc_failmode = AllocFailStrategy::EXIT_OOM);
|
||||
static void release_block(JNIHandleBlock* block, Thread* thread = NULL);
|
||||
|
||||
// JNI PushLocalFrame/PopLocalFrame support
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/padded.hpp"
|
||||
#include "metaprogramming/isRegisteredEnum.hpp"
|
||||
#include "oops/markWord.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/park.hpp"
|
||||
@ -378,7 +377,4 @@ class ObjectMonitor {
|
||||
void install_displaced_markword_in_object(const oop obj);
|
||||
};
|
||||
|
||||
// Register for atomic operations.
|
||||
template<> struct IsRegisteredEnum<ObjectMonitor::AllocationState> : public TrueType {};
|
||||
|
||||
#endif // SHARE_RUNTIME_OBJECTMONITOR_HPP
|
||||
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include "jvm.h"
|
||||
#include "jvmtifiles/jvmti.h"
|
||||
#include "metaprogramming/isRegisteredEnum.hpp"
|
||||
#include "metaprogramming/integralConstant.hpp"
|
||||
#include "utilities/exceptions.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
@ -972,10 +971,6 @@ class os: AllStatic {
|
||||
|
||||
};
|
||||
|
||||
#ifndef _WINDOWS
|
||||
template<> struct IsRegisteredEnum<os::SuspendResume::State> : public TrueType {};
|
||||
#endif // !_WINDOWS
|
||||
|
||||
// Note that "PAUSE" is almost always used with synchronization
|
||||
// so arguably we should provide Atomic::SpinPause() instead
|
||||
// of the global SpinPause() with C linkage.
|
||||
|
@ -812,8 +812,7 @@ oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_ac
|
||||
Handle return_type(THREAD, return_type_oop);
|
||||
|
||||
objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
|
||||
|
||||
if (exception_types.is_null()) return NULL;
|
||||
assert(!exception_types.is_null(), "cannot return null");
|
||||
|
||||
Symbol* method_name = method->name();
|
||||
oop name_oop = StringTable::intern(method_name, CHECK_NULL);
|
||||
@ -859,7 +858,7 @@ oop Reflection::new_constructor(const methodHandle& method, TRAPS) {
|
||||
if (parameter_types.is_null()) return NULL;
|
||||
|
||||
objArrayHandle exception_types = get_exception_types(method, CHECK_NULL);
|
||||
if (exception_types.is_null()) return NULL;
|
||||
assert(!exception_types.is_null(), "cannot return null");
|
||||
|
||||
const int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS;
|
||||
|
||||
|
@ -165,6 +165,7 @@ void javaVFrame::print_locked_object_class_name(outputStream* st, Handle obj, co
|
||||
void javaVFrame::print_lock_info_on(outputStream* st, int frame_count) {
|
||||
Thread* THREAD = Thread::current();
|
||||
ResourceMark rm(THREAD);
|
||||
HandleMark hm(THREAD);
|
||||
|
||||
// If this is the first frame and it is java.lang.Object.wait(...)
|
||||
// then print out the receiver. Locals are not always available,
|
||||
@ -447,6 +448,21 @@ void interpretedVFrame::set_locals(StackValueCollection* values) const {
|
||||
entryVFrame::entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread)
|
||||
: externalVFrame(fr, reg_map, thread) {}
|
||||
|
||||
MonitorInfo::MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced) {
|
||||
Thread* thread = Thread::current();
|
||||
if (!owner_is_scalar_replaced) {
|
||||
_owner = Handle(thread, owner);
|
||||
_owner_klass = Handle();
|
||||
} else {
|
||||
assert(eliminated, "monitor should be eliminated for scalar replaced object");
|
||||
_owner = Handle();
|
||||
_owner_klass = Handle(thread, owner);
|
||||
}
|
||||
_lock = lock;
|
||||
_eliminated = eliminated;
|
||||
_owner_is_scalar_replaced = owner_is_scalar_replaced;
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
void vframeStreamCommon::found_bad_method_frame() const {
|
||||
// 6379830 Cut point for an assertion that occasionally fires when
|
||||
@ -612,6 +628,8 @@ static void print_stack_values(const char* title, StackValueCollection* values)
|
||||
|
||||
void javaVFrame::print() {
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
|
||||
vframe::print();
|
||||
tty->print("\t");
|
||||
method()->print_value();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,6 +30,7 @@
|
||||
#include "code/location.hpp"
|
||||
#include "oops/oop.hpp"
|
||||
#include "runtime/frame.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/stackValue.hpp"
|
||||
#include "runtime/stackValueCollection.hpp"
|
||||
#include "utilities/growableArray.hpp"
|
||||
@ -241,34 +242,22 @@ class entryVFrame: public externalVFrame {
|
||||
// 2) the monitor lock
|
||||
class MonitorInfo : public ResourceObj {
|
||||
private:
|
||||
oop _owner; // the object owning the monitor
|
||||
Handle _owner; // the object owning the monitor
|
||||
BasicLock* _lock;
|
||||
oop _owner_klass; // klass (mirror) if owner was scalar replaced
|
||||
Handle _owner_klass; // klass (mirror) if owner was scalar replaced
|
||||
bool _eliminated;
|
||||
bool _owner_is_scalar_replaced;
|
||||
public:
|
||||
// Constructor
|
||||
MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced) {
|
||||
if (!owner_is_scalar_replaced) {
|
||||
_owner = owner;
|
||||
_owner_klass = NULL;
|
||||
} else {
|
||||
assert(eliminated, "monitor should be eliminated for scalar replaced object");
|
||||
_owner = NULL;
|
||||
_owner_klass = owner;
|
||||
}
|
||||
_lock = lock;
|
||||
_eliminated = eliminated;
|
||||
_owner_is_scalar_replaced = owner_is_scalar_replaced;
|
||||
}
|
||||
MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced);
|
||||
// Accessors
|
||||
oop owner() const {
|
||||
oop owner() const {
|
||||
assert(!_owner_is_scalar_replaced, "should not be called for scalar replaced object");
|
||||
return _owner;
|
||||
return _owner();
|
||||
}
|
||||
oop owner_klass() const {
|
||||
oop owner_klass() const {
|
||||
assert(_owner_is_scalar_replaced, "should not be called for not scalar replaced object");
|
||||
return _owner_klass;
|
||||
return _owner_klass();
|
||||
}
|
||||
BasicLock* lock() const { return _lock; }
|
||||
bool eliminated() const { return _eliminated; }
|
||||
|
@ -70,28 +70,32 @@ void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) {
|
||||
|
||||
int index;
|
||||
|
||||
// Get the monitors off-stack
|
||||
{
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
// Get the monitors off-stack
|
||||
|
||||
GrowableArray<MonitorInfo*>* list = vf->monitors();
|
||||
if (list->is_empty()) {
|
||||
_monitors = NULL;
|
||||
} else {
|
||||
GrowableArray<MonitorInfo*>* list = vf->monitors();
|
||||
if (list->is_empty()) {
|
||||
_monitors = NULL;
|
||||
} else {
|
||||
|
||||
// Allocate monitor chunk
|
||||
_monitors = new MonitorChunk(list->length());
|
||||
vf->thread()->add_monitor_chunk(_monitors);
|
||||
// Allocate monitor chunk
|
||||
_monitors = new MonitorChunk(list->length());
|
||||
vf->thread()->add_monitor_chunk(_monitors);
|
||||
|
||||
// Migrate the BasicLocks from the stack to the monitor chunk
|
||||
for (index = 0; index < list->length(); index++) {
|
||||
MonitorInfo* monitor = list->at(index);
|
||||
assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
|
||||
BasicObjectLock* dest = _monitors->at(index);
|
||||
if (monitor->owner_is_scalar_replaced()) {
|
||||
dest->set_obj(NULL);
|
||||
} else {
|
||||
assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
|
||||
dest->set_obj(monitor->owner());
|
||||
monitor->lock()->move_to(monitor->owner(), dest->lock());
|
||||
// Migrate the BasicLocks from the stack to the monitor chunk
|
||||
for (index = 0; index < list->length(); index++) {
|
||||
MonitorInfo* monitor = list->at(index);
|
||||
assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
|
||||
BasicObjectLock* dest = _monitors->at(index);
|
||||
if (monitor->owner_is_scalar_replaced()) {
|
||||
dest->set_obj(NULL);
|
||||
} else {
|
||||
assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
|
||||
dest->set_obj(monitor->owner());
|
||||
monitor->lock()->move_to(monitor->owner(), dest->lock());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -369,23 +369,7 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
|
||||
/************/ \
|
||||
/* Universe */ \
|
||||
/************/ \
|
||||
\
|
||||
static_field(Universe, _mirrors[0], oop) \
|
||||
static_field(Universe, _main_thread_group, oop) \
|
||||
static_field(Universe, _system_thread_group, oop) \
|
||||
static_field(Universe, _the_empty_class_klass_array, objArrayOop) \
|
||||
static_field(Universe, _null_ptr_exception_instance, oop) \
|
||||
static_field(Universe, _arithmetic_exception_instance, oop) \
|
||||
static_field(Universe, _vm_exception, oop) \
|
||||
static_field(Universe, _collectedHeap, CollectedHeap*) \
|
||||
static_field(Universe, _base_vtable_size, int) \
|
||||
static_field(Universe, _bootstrapping, bool) \
|
||||
static_field(Universe, _fully_initialized, bool) \
|
||||
static_field(Universe, _verify_count, int) \
|
||||
static_field(Universe, _verify_oop_mask, uintptr_t) \
|
||||
static_field(Universe, _verify_oop_bits, uintptr_t) \
|
||||
static_field(Universe, _non_oop_bits, intptr_t) \
|
||||
\
|
||||
/******************/ \
|
||||
/* CompressedOops */ \
|
||||
/******************/ \
|
||||
|
@ -26,7 +26,6 @@
|
||||
#define SHARE_SERVICES_ATTACHLISTENER_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "metaprogramming/isRegisteredEnum.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
@ -57,8 +56,6 @@ enum AttachListenerState {
|
||||
AL_INITIALIZED
|
||||
};
|
||||
|
||||
template<> struct IsRegisteredEnum<AttachListenerState> : public TrueType {};
|
||||
|
||||
class AttachListener: AllStatic {
|
||||
public:
|
||||
static void vm_start() NOT_SERVICES_RETURN;
|
||||
|
@ -508,7 +508,7 @@ JVM_ENTRY(jobjectArray, jmm_GetMemoryPools(JNIEnv* env, jobject obj))
|
||||
poolArray->obj_at_put(i, ph());
|
||||
}
|
||||
}
|
||||
return (jobjectArray) JNIHandles::make_local(env, poolArray());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, poolArray());
|
||||
JVM_END
|
||||
|
||||
// Returns an array of java/lang/management/MemoryManagerMXBean object
|
||||
@ -552,7 +552,7 @@ JVM_ENTRY(jobjectArray, jmm_GetMemoryManagers(JNIEnv* env, jobject obj))
|
||||
mgrArray->obj_at_put(i, ph());
|
||||
}
|
||||
}
|
||||
return (jobjectArray) JNIHandles::make_local(env, mgrArray());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, mgrArray());
|
||||
JVM_END
|
||||
|
||||
|
||||
@ -565,7 +565,7 @@ JVM_ENTRY(jobject, jmm_GetMemoryPoolUsage(JNIEnv* env, jobject obj))
|
||||
if (pool != NULL) {
|
||||
MemoryUsage usage = pool->get_memory_usage();
|
||||
Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, h());
|
||||
return JNIHandles::make_local(THREAD, h());
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -580,7 +580,7 @@ JVM_ENTRY(jobject, jmm_GetPeakMemoryPoolUsage(JNIEnv* env, jobject obj))
|
||||
if (pool != NULL) {
|
||||
MemoryUsage usage = pool->get_peak_memory_usage();
|
||||
Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, h());
|
||||
return JNIHandles::make_local(THREAD, h());
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -595,7 +595,7 @@ JVM_ENTRY(jobject, jmm_GetPoolCollectionUsage(JNIEnv* env, jobject obj))
|
||||
if (pool != NULL && pool->is_collected_pool()) {
|
||||
MemoryUsage usage = pool->get_last_collection_usage();
|
||||
Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, h());
|
||||
return JNIHandles::make_local(THREAD, h());
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@ -759,7 +759,7 @@ JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
|
||||
}
|
||||
|
||||
Handle obj = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
|
||||
return JNIHandles::make_local(env, obj());
|
||||
return JNIHandles::make_local(THREAD, obj());
|
||||
JVM_END
|
||||
|
||||
// Returns the boolean value of a given attribute.
|
||||
@ -1274,7 +1274,7 @@ JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboo
|
||||
result_h->obj_at_put(index, info_obj);
|
||||
}
|
||||
|
||||
return (jobjectArray) JNIHandles::make_local(env, result_h());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result_h());
|
||||
JVM_END
|
||||
|
||||
// Reset statistic. Return true if the requested statistic is reset.
|
||||
@ -1420,23 +1420,23 @@ JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
|
||||
for(int i = 0; i < num_entries; i++) {
|
||||
res->obj_at_put(i, flags_ah->obj_at(i));
|
||||
}
|
||||
return (jobjectArray)JNIHandles::make_local(env, res);
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, res);
|
||||
}
|
||||
|
||||
return (jobjectArray)JNIHandles::make_local(env, flags_ah());
|
||||
return (jobjectArray)JNIHandles::make_local(THREAD, flags_ah());
|
||||
JVM_END
|
||||
|
||||
// Utility function used by jmm_GetVMGlobals. Returns false if flag type
|
||||
// can't be determined, true otherwise. If false is returned, then *global
|
||||
// will be incomplete and invalid.
|
||||
bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, JVMFlag *flag, TRAPS) {
|
||||
bool add_global_entry(Handle name, jmmVMGlobal *global, JVMFlag *flag, TRAPS) {
|
||||
Handle flag_name;
|
||||
if (name() == NULL) {
|
||||
flag_name = java_lang_String::create_from_str(flag->_name, CHECK_false);
|
||||
} else {
|
||||
flag_name = name;
|
||||
}
|
||||
global->name = (jstring)JNIHandles::make_local(env, flag_name());
|
||||
global->name = (jstring)JNIHandles::make_local(THREAD, flag_name());
|
||||
|
||||
if (flag->is_bool()) {
|
||||
global->value.z = flag->get_bool() ? JNI_TRUE : JNI_FALSE;
|
||||
@ -1464,7 +1464,7 @@ bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, JVMFlag *fl
|
||||
global->type = JMM_VMGLOBAL_TYPE_JLONG;
|
||||
} else if (flag->is_ccstr()) {
|
||||
Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false);
|
||||
global->value.l = (jobject)JNIHandles::make_local(env, str());
|
||||
global->value.l = (jobject)JNIHandles::make_local(THREAD, str());
|
||||
global->type = JMM_VMGLOBAL_TYPE_JSTRING;
|
||||
} else {
|
||||
global->type = JMM_VMGLOBAL_TYPE_UNKNOWN;
|
||||
@ -1543,7 +1543,7 @@ JVM_ENTRY(jint, jmm_GetVMGlobals(JNIEnv *env,
|
||||
char* str = java_lang_String::as_utf8_string(s);
|
||||
JVMFlag* flag = JVMFlag::find_flag(str);
|
||||
if (flag != NULL &&
|
||||
add_global_entry(env, sh, &globals[i], flag, THREAD)) {
|
||||
add_global_entry(sh, &globals[i], flag, THREAD)) {
|
||||
num_entries++;
|
||||
} else {
|
||||
globals[i].name = NULL;
|
||||
@ -1565,7 +1565,7 @@ JVM_ENTRY(jint, jmm_GetVMGlobals(JNIEnv *env,
|
||||
}
|
||||
// Exclude the locked (diagnostic, experimental) flags
|
||||
if ((flag->is_unlocked() || flag->is_unlocker()) &&
|
||||
add_global_entry(env, null_h, &globals[num_entries], flag, THREAD)) {
|
||||
add_global_entry(null_h, &globals[num_entries], flag, THREAD)) {
|
||||
num_entries++;
|
||||
}
|
||||
}
|
||||
@ -1750,7 +1750,7 @@ static Handle find_deadlocks(bool object_monitors_only, TRAPS) {
|
||||
//
|
||||
JVM_ENTRY(jobjectArray, jmm_FindDeadlockedThreads(JNIEnv *env, jboolean object_monitors_only))
|
||||
Handle result = find_deadlocks(object_monitors_only != 0, CHECK_NULL);
|
||||
return (jobjectArray) JNIHandles::make_local(env, result());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result());
|
||||
JVM_END
|
||||
|
||||
// Finds cycles of threads that are deadlocked on monitor locks
|
||||
@ -1758,7 +1758,7 @@ JVM_END
|
||||
// Otherwise, returns NULL.
|
||||
JVM_ENTRY(jobjectArray, jmm_FindMonitorDeadlockedThreads(JNIEnv *env))
|
||||
Handle result = find_deadlocks(true, CHECK_NULL);
|
||||
return (jobjectArray) JNIHandles::make_local(env, result());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, result());
|
||||
JVM_END
|
||||
|
||||
// Gets the information about GC extension attributes including
|
||||
@ -1940,7 +1940,7 @@ JVM_ENTRY(jobjectArray, jmm_GetDiagnosticCommands(JNIEnv *env))
|
||||
oop cmd_name = java_lang_String::create_oop_from_str(dcmd_list->at(i), CHECK_NULL);
|
||||
cmd_array->obj_at_put(i, cmd_name);
|
||||
}
|
||||
return (jobjectArray) JNIHandles::make_local(env, cmd_array());
|
||||
return (jobjectArray) JNIHandles::make_local(THREAD, cmd_array());
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds,
|
||||
@ -2049,7 +2049,7 @@ JVM_ENTRY(jstring, jmm_ExecuteDiagnosticCommand(JNIEnv *env, jstring commandline
|
||||
bufferedStream output;
|
||||
DCmd::parse_and_execute(DCmd_Source_MBean, &output, cmdline, ' ', CHECK_NULL);
|
||||
oop result = java_lang_String::create_oop_from_str(output.as_string(), CHECK_NULL);
|
||||
return (jstring) JNIHandles::make_local(env, result);
|
||||
return (jstring) JNIHandles::make_local(THREAD, result);
|
||||
JVM_END
|
||||
|
||||
JVM_ENTRY(void, jmm_SetDiagnosticFrameworkNotificationEnabled(JNIEnv *env, jboolean enabled))
|
||||
|
@ -567,6 +567,7 @@ StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) {
|
||||
_locked_monitors = NULL;
|
||||
if (with_lock_info) {
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
GrowableArray<MonitorInfo*>* list = jvf->locked_monitors();
|
||||
int length = list->length();
|
||||
if (length > 0) {
|
||||
|
@ -1095,7 +1095,11 @@ template<class T> static void swap(T& a, T& b) {
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
#define ARRAY_SIZE(array) (sizeof(array)/sizeof((array)[0]))
|
||||
// array_size_impl is a function that takes a reference to T[N] and
|
||||
// returns a reference to char[N]. It is not ODR-used, so not defined.
|
||||
template<typename T, size_t N> char (&array_size_impl(T (&)[N]))[N];
|
||||
|
||||
#define ARRAY_SIZE(array) sizeof(array_size_impl(array))
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Sum and product which can never overflow: they wrap, just like the
|
||||
|
@ -36,6 +36,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -83,6 +84,9 @@ final class ProcessHandleImpl implements ProcessHandle {
|
||||
*/
|
||||
private static final Executor processReaperExecutor =
|
||||
doPrivileged((PrivilegedAction<Executor>) () -> {
|
||||
// Initialize ThreadLocalRandom now to avoid using the smaller stack
|
||||
// of the processReaper threads.
|
||||
ThreadLocalRandom.current();
|
||||
|
||||
ThreadGroup tg = Thread.currentThread().getThreadGroup();
|
||||
while (tg.getParent() != null) tg = tg.getParent();
|
||||
|
@ -43,7 +43,6 @@ import java.util.Optional;
|
||||
import java.util.Spliterator;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.Collectors;
|
||||
@ -1134,16 +1133,16 @@ public final class String
|
||||
/**
|
||||
* Compares this {@code String} to another {@code String}, ignoring case
|
||||
* considerations. Two strings are considered equal ignoring case if they
|
||||
* are of the same length and corresponding characters in the two strings
|
||||
* are equal ignoring case.
|
||||
* are of the same length and corresponding Unicode code points in the two
|
||||
* strings are equal ignoring case.
|
||||
*
|
||||
* <p> Two characters {@code c1} and {@code c2} are considered the same
|
||||
* <p> Two Unicode code points are considered the same
|
||||
* ignoring case if at least one of the following is true:
|
||||
* <ul>
|
||||
* <li> The two characters are the same (as compared by the
|
||||
* <li> The two Unicode code points are the same (as compared by the
|
||||
* {@code ==} operator)
|
||||
* <li> Calling {@code Character.toLowerCase(Character.toUpperCase(char))}
|
||||
* on each character produces the same result
|
||||
* <li> Calling {@code Character.toLowerCase(Character.toUpperCase(int))}
|
||||
* on each Unicode code point produces the same result
|
||||
* </ul>
|
||||
*
|
||||
* <p>Note that this method does <em>not</em> take locale into account, and
|
||||
@ -1158,6 +1157,7 @@ public final class String
|
||||
* false} otherwise
|
||||
*
|
||||
* @see #equals(Object)
|
||||
* @see #codePoints()
|
||||
*/
|
||||
public boolean equalsIgnoreCase(String anotherString) {
|
||||
return (this == anotherString) ? true
|
||||
@ -1224,7 +1224,8 @@ public final class String
|
||||
|
||||
/**
|
||||
* A Comparator that orders {@code String} objects as by
|
||||
* {@code compareToIgnoreCase}. This comparator is serializable.
|
||||
* {@link #compareToIgnoreCase(String) compareToIgnoreCase}.
|
||||
* This comparator is serializable.
|
||||
* <p>
|
||||
* Note that this Comparator does <em>not</em> take locale into account,
|
||||
* and will result in an unsatisfactory ordering for certain locales.
|
||||
@ -1261,10 +1262,10 @@ public final class String
|
||||
/**
|
||||
* Compares two strings lexicographically, ignoring case
|
||||
* differences. This method returns an integer whose sign is that of
|
||||
* calling {@code compareTo} with normalized versions of the strings
|
||||
* calling {@code compareTo} with case folded versions of the strings
|
||||
* where case differences have been eliminated by calling
|
||||
* {@code Character.toLowerCase(Character.toUpperCase(character))} on
|
||||
* each character.
|
||||
* {@code Character.toLowerCase(Character.toUpperCase(int))} on
|
||||
* each Unicode code point.
|
||||
* <p>
|
||||
* Note that this method does <em>not</em> take locale into account,
|
||||
* and will result in an unsatisfactory ordering for certain locales.
|
||||
@ -1275,6 +1276,7 @@ public final class String
|
||||
* specified String is greater than, equal to, or less
|
||||
* than this String, ignoring case considerations.
|
||||
* @see java.text.Collator
|
||||
* @see #codePoints()
|
||||
* @since 1.2
|
||||
*/
|
||||
public int compareToIgnoreCase(String str) {
|
||||
@ -1362,30 +1364,26 @@ public final class String
|
||||
* <p>
|
||||
* A substring of this {@code String} object is compared to a substring
|
||||
* of the argument {@code other}. The result is {@code true} if these
|
||||
* substrings represent character sequences that are the same, ignoring
|
||||
* case if and only if {@code ignoreCase} is true. The substring of
|
||||
* this {@code String} object to be compared begins at index
|
||||
* {@code toffset} and has length {@code len}. The substring of
|
||||
* {@code other} to be compared begins at index {@code ooffset} and
|
||||
* has length {@code len}. The result is {@code false} if and only if
|
||||
* at least one of the following is true:
|
||||
* <ul><li>{@code toffset} is negative.
|
||||
* <li>{@code ooffset} is negative.
|
||||
* <li>{@code toffset+len} is greater than the length of this
|
||||
* substrings represent Unicode code point sequences that are the same,
|
||||
* ignoring case if and only if {@code ignoreCase} is true.
|
||||
* The sequences {@code tsequence} and {@code osequence} are compared,
|
||||
* where {@code tsequence} is the sequence produced as if by calling
|
||||
* {@code this.substring(toffset, len).codePoints()} and {@code osequence}
|
||||
* is the sequence produced as if by calling
|
||||
* {@code other.substring(ooffset, len).codePoints()}.
|
||||
* The result is {@code true} if and only if all of the following
|
||||
* are true:
|
||||
* <ul><li>{@code toffset} is non-negative.
|
||||
* <li>{@code ooffset} is non-negative.
|
||||
* <li>{@code toffset+len} is less than or equal to the length of this
|
||||
* {@code String} object.
|
||||
* <li>{@code ooffset+len} is greater than the length of the other
|
||||
* <li>{@code ooffset+len} is less than or equal to the length of the other
|
||||
* argument.
|
||||
* <li>{@code ignoreCase} is {@code false} and there is some nonnegative
|
||||
* integer <i>k</i> less than {@code len} such that:
|
||||
* <blockquote><pre>
|
||||
* this.charAt(toffset+k) != other.charAt(ooffset+k)
|
||||
* </pre></blockquote>
|
||||
* <li>{@code ignoreCase} is {@code true} and there is some nonnegative
|
||||
* integer <i>k</i> less than {@code len} such that:
|
||||
* <blockquote><pre>
|
||||
* Character.toLowerCase(Character.toUpperCase(this.charAt(toffset+k))) !=
|
||||
* Character.toLowerCase(Character.toUpperCase(other.charAt(ooffset+k)))
|
||||
* </pre></blockquote>
|
||||
* <li>if {@code ignoreCase} is {@code false}, all pairs of corresponding Unicode
|
||||
* code points are equal integer values; or if {@code ignoreCase} is {@code true},
|
||||
* {@link Character#toLowerCase(int) Character.toLowerCase(}
|
||||
* {@link Character#toUpperCase(int)}{@code )} on all pairs of Unicode code points
|
||||
* results in equal integer values.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Note that this method does <em>not</em> take locale into account,
|
||||
@ -1400,12 +1398,14 @@ public final class String
|
||||
* @param other the string argument.
|
||||
* @param ooffset the starting offset of the subregion in the string
|
||||
* argument.
|
||||
* @param len the number of characters to compare.
|
||||
* @param len the number of characters (Unicode code units -
|
||||
* 16bit {@code char} value) to compare.
|
||||
* @return {@code true} if the specified subregion of this string
|
||||
* matches the specified subregion of the string argument;
|
||||
* {@code false} otherwise. Whether the matching is exact
|
||||
* or case insensitive depends on the {@code ignoreCase}
|
||||
* argument.
|
||||
* @see #codePoints()
|
||||
*/
|
||||
public boolean regionMatches(boolean ignoreCase, int toffset,
|
||||
String other, int ooffset, int len) {
|
||||
|
@ -319,25 +319,92 @@ final class StringUTF16 {
|
||||
}
|
||||
|
||||
public static int compareToCI(byte[] value, byte[] other) {
|
||||
int len1 = length(value);
|
||||
int len2 = length(other);
|
||||
int lim = Math.min(len1, len2);
|
||||
for (int k = 0; k < lim; k++) {
|
||||
char c1 = getChar(value, k);
|
||||
char c2 = getChar(other, k);
|
||||
if (c1 != c2) {
|
||||
c1 = Character.toUpperCase(c1);
|
||||
c2 = Character.toUpperCase(c2);
|
||||
if (c1 != c2) {
|
||||
c1 = Character.toLowerCase(c1);
|
||||
c2 = Character.toLowerCase(c2);
|
||||
if (c1 != c2) {
|
||||
return c1 - c2;
|
||||
}
|
||||
}
|
||||
return compareToCIImpl(value, 0, length(value), other, 0, length(other));
|
||||
}
|
||||
|
||||
private static int compareToCIImpl(byte[] value, int toffset, int tlen,
|
||||
byte[] other, int ooffset, int olen) {
|
||||
int tlast = toffset + tlen;
|
||||
int olast = ooffset + olen;
|
||||
assert toffset >= 0 && ooffset >= 0;
|
||||
assert tlast <= length(value);
|
||||
assert olast <= length(other);
|
||||
|
||||
for (int k1 = toffset, k2 = ooffset; k1 < tlast && k2 < olast; k1++, k2++) {
|
||||
int cp1 = (int)getChar(value, k1);
|
||||
int cp2 = (int)getChar(other, k2);
|
||||
|
||||
if (cp1 == cp2 || compareCodePointCI(cp1, cp2) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for supplementary characters case
|
||||
cp1 = codePointIncluding(value, cp1, k1, toffset, tlast);
|
||||
if (cp1 < 0) {
|
||||
k1++;
|
||||
cp1 -= cp1;
|
||||
}
|
||||
cp2 = codePointIncluding(other, cp2, k2, ooffset, olast);
|
||||
if (cp2 < 0) {
|
||||
k2++;
|
||||
cp2 -= cp2;
|
||||
}
|
||||
|
||||
int diff = compareCodePointCI(cp1, cp2);
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
return len1 - len2;
|
||||
return tlen - olen;
|
||||
}
|
||||
|
||||
// Case insensitive comparison of two code points
|
||||
private static int compareCodePointCI(int cp1, int cp2) {
|
||||
// try converting both characters to uppercase.
|
||||
// If the results match, then the comparison scan should
|
||||
// continue.
|
||||
cp1 = Character.toUpperCase(cp1);
|
||||
cp2 = Character.toUpperCase(cp2);
|
||||
if (cp1 != cp2) {
|
||||
// Unfortunately, conversion to uppercase does not work properly
|
||||
// for the Georgian alphabet, which has strange rules about case
|
||||
// conversion. So we need to make one last check before
|
||||
// exiting.
|
||||
cp1 = Character.toLowerCase(cp1);
|
||||
cp2 = Character.toLowerCase(cp2);
|
||||
if (cp1 != cp2) {
|
||||
return cp1 - cp2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Returns a code point from the code unit pointed by "index". If it is
|
||||
// not a surrogate or an unpaired surrogate, then the code unit is
|
||||
// returned as is. Otherwise, it is combined with the code unit before
|
||||
// or after, depending on the type of the surrogate at index, to make a
|
||||
// supplementary code point. The return value will be negated if the code
|
||||
// unit pointed by index is a high surrogate, and index + 1 is a low surrogate.
|
||||
private static int codePointIncluding(byte[] ba, int cp, int index, int start, int end) {
|
||||
// fast check
|
||||
if (!Character.isSurrogate((char)cp)) {
|
||||
return cp;
|
||||
}
|
||||
if (Character.isLowSurrogate((char)cp)) {
|
||||
if (index > start) {
|
||||
char c = getChar(ba, index - 1);
|
||||
if (Character.isHighSurrogate(c)) {
|
||||
return Character.toCodePoint(c, (char)cp);
|
||||
}
|
||||
}
|
||||
} else if (index + 1 < end) { // cp == high surrogate
|
||||
char c = getChar(ba, index + 1);
|
||||
if (Character.isLowSurrogate(c)) {
|
||||
// negate the code point
|
||||
return - Character.toCodePoint((char)cp, c);
|
||||
}
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
public static int compareToCI_Latin1(byte[] value, byte[] other) {
|
||||
@ -716,34 +783,7 @@ final class StringUTF16 {
|
||||
|
||||
public static boolean regionMatchesCI(byte[] value, int toffset,
|
||||
byte[] other, int ooffset, int len) {
|
||||
int last = toffset + len;
|
||||
assert toffset >= 0 && ooffset >= 0;
|
||||
assert ooffset + len <= length(other);
|
||||
assert last <= length(value);
|
||||
while (toffset < last) {
|
||||
char c1 = getChar(value, toffset++);
|
||||
char c2 = getChar(other, ooffset++);
|
||||
if (c1 == c2) {
|
||||
continue;
|
||||
}
|
||||
// try converting both characters to uppercase.
|
||||
// If the results match, then the comparison scan should
|
||||
// continue.
|
||||
char u1 = Character.toUpperCase(c1);
|
||||
char u2 = Character.toUpperCase(c2);
|
||||
if (u1 == u2) {
|
||||
continue;
|
||||
}
|
||||
// Unfortunately, conversion to uppercase does not work properly
|
||||
// for the Georgian alphabet, which has strange rules about case
|
||||
// conversion. So we need to make one last check before
|
||||
// exiting.
|
||||
if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return compareToCIImpl(value, toffset, len, other, ooffset, len) == 0;
|
||||
}
|
||||
|
||||
public static boolean regionMatchesCI_Latin1(byte[] value, int toffset,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -60,6 +60,11 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
public abstract class AlgorithmParameterGeneratorSpi {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public AlgorithmParameterGeneratorSpi() {}
|
||||
|
||||
/**
|
||||
* Initializes this parameter generator for a certain size
|
||||
* and source of randomness.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -50,6 +50,11 @@ import java.security.spec.InvalidParameterSpecException;
|
||||
|
||||
public abstract class AlgorithmParametersSpi {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public AlgorithmParametersSpi() {}
|
||||
|
||||
/**
|
||||
* Initializes this parameters object using the parameters
|
||||
* specified in {@code paramSpec}.
|
||||
|
@ -69,6 +69,11 @@ import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
public abstract class KeyFactorySpi {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public KeyFactorySpi() {}
|
||||
|
||||
/**
|
||||
* Generates a public key object from the provided key
|
||||
* specification (key material).
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -58,6 +58,11 @@ import java.security.spec.AlgorithmParameterSpec;
|
||||
|
||||
public abstract class KeyPairGeneratorSpi {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public KeyPairGeneratorSpi() {}
|
||||
|
||||
/**
|
||||
* Initializes the key pair generator for a certain keysize, using
|
||||
* the default parameter set.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -53,6 +53,11 @@ import javax.security.auth.callback.*;
|
||||
|
||||
public abstract class KeyStoreSpi {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public KeyStoreSpi() {}
|
||||
|
||||
/**
|
||||
* Returns the key associated with the given alias, using the given
|
||||
* password to recover it. The key must have been associated with
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -54,6 +54,11 @@ public abstract class MessageDigestSpi {
|
||||
// for re-use in engineUpdate(ByteBuffer input)
|
||||
private byte[] tempArray;
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public MessageDigestSpi() {}
|
||||
|
||||
/**
|
||||
* Returns the digest length in bytes.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -102,6 +102,11 @@ public abstract class PermissionCollection implements java.io.Serializable {
|
||||
// when set, add will throw an exception.
|
||||
private volatile boolean readOnly;
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public PermissionCollection() {}
|
||||
|
||||
/**
|
||||
* Adds a permission object to the current collection of permission objects.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -87,6 +87,11 @@ import sun.security.util.SecurityConstants;
|
||||
|
||||
public abstract class Policy {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public Policy() {}
|
||||
|
||||
/**
|
||||
* A read-only empty PermissionCollection instance.
|
||||
* @since 1.6
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -44,6 +44,11 @@ package java.security;
|
||||
|
||||
public abstract class PolicySpi {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public PolicySpi() {}
|
||||
|
||||
/**
|
||||
* Check whether the policy has granted a Permission to a ProtectionDomain.
|
||||
*
|
||||
|
@ -52,6 +52,11 @@ import sun.security.jca.JCAUtil;
|
||||
|
||||
public abstract class SignatureSpi {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public SignatureSpi() {}
|
||||
|
||||
/**
|
||||
* Application-specified source of randomness.
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -65,6 +65,11 @@ import java.security.NoSuchProviderException;
|
||||
|
||||
public abstract class CertificateFactorySpi {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public CertificateFactorySpi() {}
|
||||
|
||||
/**
|
||||
* Generates a certificate object and initializes it with
|
||||
* the data read from the input stream {@code inStream}.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -67,6 +67,11 @@ import sun.security.x509.X509CRLEntryImpl;
|
||||
|
||||
public abstract class X509CRLEntry implements X509Extension {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public X509CRLEntry() {}
|
||||
|
||||
/**
|
||||
* Compares this CRL entry for equality with the given
|
||||
* object. If the {@code other} object is an
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,7 +30,6 @@ import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import sun.nio.cs.ISO_8859_1;
|
||||
|
||||
@ -961,12 +960,15 @@ public class Base64 {
|
||||
|
||||
private final InputStream is;
|
||||
private final boolean isMIME;
|
||||
private final int[] base64; // base64 -> byte mapping
|
||||
private int bits = 0; // 24-bit buffer for decoding
|
||||
private int nextin = 18; // next available "off" in "bits" for input;
|
||||
// -> 18, 12, 6, 0
|
||||
private int nextout = -8; // next available "off" in "bits" for output;
|
||||
// -> 8, 0, -8 (no byte for output)
|
||||
private final int[] base64; // base64 -> byte mapping
|
||||
private int bits = 0; // 24-bit buffer for decoding
|
||||
|
||||
/* writing bit pos inside bits; one of 24 (left, msb), 18, 12, 6, 0 */
|
||||
private int wpos = 0;
|
||||
|
||||
/* reading bit pos inside bits: one of 24 (left, msb), 16, 8, 0 */
|
||||
private int rpos = 0;
|
||||
|
||||
private boolean eof = false;
|
||||
private boolean closed = false;
|
||||
|
||||
@ -983,107 +985,153 @@ public class Base64 {
|
||||
return read(sbBuf, 0, 1) == -1 ? -1 : sbBuf[0] & 0xff;
|
||||
}
|
||||
|
||||
private int eof(byte[] b, int off, int len, int oldOff)
|
||||
throws IOException
|
||||
{
|
||||
private int leftovers(byte[] b, int off, int pos, int limit) {
|
||||
eof = true;
|
||||
if (nextin != 18) {
|
||||
if (nextin == 12)
|
||||
throw new IOException("Base64 stream has one un-decoded dangling byte.");
|
||||
// treat ending xx/xxx without padding character legal.
|
||||
// same logic as v == '=' below
|
||||
b[off++] = (byte)(bits >> (16));
|
||||
if (nextin == 0) { // only one padding byte
|
||||
if (len == 1) { // no enough output space
|
||||
bits >>= 8; // shift to lowest byte
|
||||
nextout = 0;
|
||||
} else {
|
||||
b[off++] = (byte) (bits >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We use a loop here, as this method is executed only a few times.
|
||||
* Unrolling the loop would probably not contribute much here.
|
||||
*/
|
||||
while (rpos - 8 >= wpos && pos != limit) {
|
||||
rpos -= 8;
|
||||
b[pos++] = (byte) (bits >> rpos);
|
||||
}
|
||||
return off == oldOff ? -1 : off - oldOff;
|
||||
return pos - off != 0 || rpos - 8 >= wpos ? pos - off : -1;
|
||||
}
|
||||
|
||||
private int padding(byte[] b, int off, int len, int oldOff)
|
||||
throws IOException
|
||||
{
|
||||
// = shiftto==18 unnecessary padding
|
||||
// x= shiftto==12 dangling x, invalid unit
|
||||
// xx= shiftto==6 && missing last '='
|
||||
// xx=y or last is not '='
|
||||
if (nextin == 18 || nextin == 12 ||
|
||||
nextin == 6 && is.read() != '=') {
|
||||
throw new IOException("Illegal base64 ending sequence:" + nextin);
|
||||
private int eof(byte[] b, int off, int pos, int limit) throws IOException {
|
||||
/*
|
||||
* pos != limit
|
||||
*
|
||||
* wpos == 18: x dangling single x, invalid unit
|
||||
* accept ending xx or xxx without padding characters
|
||||
*/
|
||||
if (wpos == 18) {
|
||||
throw new IOException("Base64 stream has one un-decoded dangling byte.");
|
||||
}
|
||||
b[off++] = (byte)(bits >> (16));
|
||||
if (nextin == 0) { // only one padding byte
|
||||
if (len == 1) { // no enough output space
|
||||
bits >>= 8; // shift to lowest byte
|
||||
nextout = 0;
|
||||
} else {
|
||||
b[off++] = (byte) (bits >> 8);
|
||||
}
|
||||
rpos = 24;
|
||||
return leftovers(b, off, pos, limit);
|
||||
}
|
||||
|
||||
private int padding(byte[] b, int off, int pos, int limit) throws IOException {
|
||||
/*
|
||||
* pos != limit
|
||||
*
|
||||
* wpos == 24: = (unnecessary padding)
|
||||
* wpos == 18: x= (dangling single x, invalid unit)
|
||||
* wpos == 12 and missing last '=': xx= (invalid padding)
|
||||
* wpos == 12 and last is not '=': xx=x (invalid padding)
|
||||
*/
|
||||
if (wpos >= 18 || wpos == 12 && is.read() != '=') {
|
||||
throw new IOException("Illegal base64 ending sequence:" + wpos);
|
||||
}
|
||||
eof = true;
|
||||
return off - oldOff;
|
||||
rpos = 24;
|
||||
return leftovers(b, off, pos, limit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (closed)
|
||||
if (closed) {
|
||||
throw new IOException("Stream is closed");
|
||||
if (eof && nextout < 0) // eof and no leftover
|
||||
return -1;
|
||||
if (off < 0 || len < 0 || len > b.length - off)
|
||||
throw new IndexOutOfBoundsException();
|
||||
int oldOff = off;
|
||||
while (nextout >= 0) { // leftover output byte(s) in bits buf
|
||||
if (len == 0)
|
||||
return off - oldOff;
|
||||
b[off++] = (byte)(bits >> nextout);
|
||||
len--;
|
||||
nextout -= 8;
|
||||
}
|
||||
Objects.checkFromIndexSize(off, len, b.length);
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rather than keeping 2 running vars (e.g., off and len),
|
||||
* we only keep one (pos), while definitely fixing the boundaries
|
||||
* of the range [off, limit).
|
||||
* More specifically, each use of pos as an index in b meets
|
||||
* pos - off >= 0 & limit - pos > 0
|
||||
*
|
||||
* Note that limit can overflow to Integer.MIN_VALUE. However,
|
||||
* as long as comparisons with pos are as coded, there's no harm.
|
||||
*/
|
||||
int pos = off;
|
||||
final int limit = off + len;
|
||||
if (eof) {
|
||||
return leftovers(b, off, pos, limit);
|
||||
}
|
||||
|
||||
/*
|
||||
* Leftovers from previous invocation; here, wpos = 0.
|
||||
* There can be at most 2 leftover bytes (rpos <= 16).
|
||||
* Further, b has at least one free place.
|
||||
*
|
||||
* The logic could be coded as a loop, (as in method leftovers())
|
||||
* but the explicit "unrolling" makes it possible to generate
|
||||
* better byte extraction code.
|
||||
*/
|
||||
if (rpos == 16) {
|
||||
b[pos++] = (byte) (bits >> 8);
|
||||
rpos = 8;
|
||||
if (pos == limit) {
|
||||
return len;
|
||||
}
|
||||
}
|
||||
if (rpos == 8) {
|
||||
b[pos++] = (byte) bits;
|
||||
rpos = 0;
|
||||
if (pos == limit) {
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
bits = 0;
|
||||
while (len > 0) {
|
||||
int v = is.read();
|
||||
if (v == -1) {
|
||||
return eof(b, off, len, oldOff);
|
||||
wpos = 24;
|
||||
for (;;) {
|
||||
/* pos != limit & rpos == 0 */
|
||||
final int i = is.read();
|
||||
if (i < 0) {
|
||||
return eof(b, off, pos, limit);
|
||||
}
|
||||
if ((v = base64[v]) < 0) {
|
||||
if (v == -2) { // padding byte(s)
|
||||
return padding(b, off, len, oldOff);
|
||||
}
|
||||
final int v = base64[i];
|
||||
if (v < 0) {
|
||||
/*
|
||||
* i not in alphabet, thus
|
||||
* v == -2: i is '=', the padding
|
||||
* v == -1: i is something else, typically CR or LF
|
||||
*/
|
||||
if (v == -1) {
|
||||
if (!isMIME)
|
||||
throw new IOException("Illegal base64 character " +
|
||||
Integer.toString(v, 16));
|
||||
continue; // skip if for rfc2045
|
||||
if (isMIME) {
|
||||
continue;
|
||||
}
|
||||
throw new IOException("Illegal base64 character 0x" +
|
||||
Integer.toHexString(i));
|
||||
}
|
||||
// neve be here
|
||||
return padding(b, off, pos, limit);
|
||||
}
|
||||
bits |= (v << nextin);
|
||||
if (nextin == 0) {
|
||||
nextin = 18; // clear for next in
|
||||
b[off++] = (byte)(bits >> 16);
|
||||
if (len == 1) {
|
||||
nextout = 8; // 2 bytes left in bits
|
||||
break;
|
||||
}
|
||||
b[off++] = (byte)(bits >> 8);
|
||||
if (len == 2) {
|
||||
nextout = 0; // 1 byte left in bits
|
||||
break;
|
||||
}
|
||||
b[off++] = (byte)bits;
|
||||
len -= 3;
|
||||
wpos -= 6;
|
||||
bits |= v << wpos;
|
||||
if (wpos != 0) {
|
||||
continue;
|
||||
}
|
||||
if (limit - pos >= 3) {
|
||||
/* frequently taken fast path, no need to track rpos */
|
||||
b[pos++] = (byte) (bits >> 16);
|
||||
b[pos++] = (byte) (bits >> 8);
|
||||
b[pos++] = (byte) bits;
|
||||
bits = 0;
|
||||
} else {
|
||||
nextin -= 6;
|
||||
wpos = 24;
|
||||
if (pos == limit) {
|
||||
return len;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* b has either 1 or 2 free places */
|
||||
b[pos++] = (byte) (bits >> 16);
|
||||
if (pos == limit) {
|
||||
rpos = 16;
|
||||
return len;
|
||||
}
|
||||
b[pos++] = (byte) (bits >> 8);
|
||||
/* pos == limit, no need for an if */
|
||||
rpos = 8;
|
||||
return len;
|
||||
}
|
||||
return off - oldOff;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,6 +76,11 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class AbstractExecutorService implements ExecutorService {
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public AbstractExecutorService() {}
|
||||
|
||||
/**
|
||||
* Returns a {@code RunnableFuture} for the given runnable and default
|
||||
* value.
|
||||
|
@ -242,6 +242,11 @@ public abstract class ForkJoinTask<V> implements Future<V>, Serializable {
|
||||
private static final int SIGNAL = 1 << 16; // true if joiner waiting
|
||||
private static final int SMASK = 0xffff; // short bits for tags
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public ForkJoinTask() {}
|
||||
|
||||
static boolean isExceptionalStatus(int s) { // needed by subclasses
|
||||
return (s & THROWN) != 0;
|
||||
}
|
||||
|
@ -165,6 +165,11 @@ package java.util.concurrent;
|
||||
public abstract class RecursiveAction extends ForkJoinTask<Void> {
|
||||
private static final long serialVersionUID = 5232453952276485070L;
|
||||
|
||||
/**
|
||||
* Constructor for subclasses to call.
|
||||
*/
|
||||
public RecursiveAction() {}
|
||||
|
||||
/**
|
||||
* The main computation performed by this task.
|
||||
*/
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user