This commit is contained in:
Prasanta Sadhukhan 2020-07-25 12:48:29 +05:30
commit 091b0c95c3
175 changed files with 2282 additions and 1292 deletions

View File

@ -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

View File

@ -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>

View File

@ -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++

View File

@ -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

View File

@ -53,6 +53,7 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS],
LDFLAGS_TESTEXE="${TARGET_LDFLAGS_JDK_LIBPATH}"
AC_SUBST(LDFLAGS_TESTEXE)
AC_SUBST(ADLC_LDFLAGS)
])
################################################################################

View File

@ -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"

View File

@ -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@

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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, \

View File

@ -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

View File

@ -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

View File

@ -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: {

View File

@ -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());

View File

@ -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;

View File

@ -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();
}

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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(&copy);
writer.dump(dictionary, is_builtin ? "builtin dictionary" : "unregistered dictionary");
}

View File

@ -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);

View File

@ -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());
}

View File

@ -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

View File

@ -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());

View File

@ -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; }

View File

@ -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>

View File

@ -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;
}

View File

@ -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; }

View File

@ -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))

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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;
}

View File

@ -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; }

View File

@ -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

View File

@ -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); }

View File

@ -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();
}

View File

@ -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; }

View File

@ -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()));

View File

@ -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; }
};

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()) {

View File

@ -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))

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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)) {

View File

@ -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;
}

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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() {

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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();

View File

@ -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; }

View File

@ -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());
}
}
}
}

View File

@ -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 */ \
/******************/ \

View File

@ -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;

View File

@ -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))

View File

@ -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) {

View File

@ -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

View File

@ -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();

View File

@ -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) {

View File

@ -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,

View File

@ -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.

View File

@ -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}.

View File

@ -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).

View File

@ -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.

View File

@ -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

View File

@ -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.
*

View File

@ -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.
*

View File

@ -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

View File

@ -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.
*

View File

@ -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.
*/

View File

@ -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}.

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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