--- a/.hgtags-top-repo Thu Nov 12 18:27:55 2015 -0800
+++ b/.hgtags-top-repo Wed Jul 05 21:00:20 2017 +0200
@@ -334,3 +334,4 @@
895353113f382d24e623191fdab0e29a3ce34738 jdk9-b89
cf1dc4c035fb84693d4ae5ad818785cb4d1465d1 jdk9-b90
122142a185381ce5cea959bf13b923d8cc333628 jdk9-b91
+106c06398f7ab330eef9e335fbd3a5a8ead23b77 jdk9-b92
--- a/common/autoconf/configure.ac Thu Nov 12 18:27:55 2015 -0800
+++ b/common/autoconf/configure.ac Wed Jul 05 21:00:20 2017 +0200
@@ -155,6 +155,9 @@
#
###############################################################################
+# See if we are doing a complete static build or not
+JDKOPT_SETUP_STATIC_BUILD
+
# First determine the toolchain type (compiler family)
TOOLCHAIN_DETERMINE_TOOLCHAIN_TYPE
--- a/common/autoconf/flags.m4 Thu Nov 12 18:27:55 2015 -0800
+++ b/common/autoconf/flags.m4 Wed Jul 05 21:00:20 2017 +0200
@@ -221,7 +221,11 @@
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
# Linking is different on MacOSX
- SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+ if test "x$STATIC_BUILD" = xtrue; then
+ SHARED_LIBRARY_FLAGS ='-undefined dynamic_lookup'
+ else
+ SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+ fi
SET_EXECUTABLE_ORIGIN='-Xlinker -rpath -Xlinker @loader_path/.'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Xlinker -install_name -Xlinker @rpath/[$]1'
@@ -696,7 +700,9 @@
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
-I${JDK_TOPDIR}/src/java.base/share/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \
- -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include"
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \
+ -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
# The shared libraries are compiled using the picflag.
CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
--- a/common/autoconf/generated-configure.sh Thu Nov 12 18:27:55 2015 -0800
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 21:00:20 2017 +0200
@@ -803,6 +803,7 @@
SHARED_LIBRARY_SUFFIX
LIBRARY_PREFIX
TOOLCHAIN_TYPE
+STATIC_BUILD
BUILD_HOTSPOT
HOTSPOT_DIST
BUILD_OUTPUT
@@ -1074,6 +1075,7 @@
with_override_nashorn
with_override_jdk
with_import_hotspot
+enable_static_build
with_toolchain_type
with_extra_cflags
with_extra_cxxflags
@@ -1852,6 +1854,7 @@
run the Queens test after Hotspot build [disabled]
--enable-unlimited-crypto
Enable unlimited crypto policy [disabled]
+ --enable-static-build enable static library build [disabled]
--disable-warnings-as-errors
do not consider native warnings to be an error
[enabled]
@@ -3989,6 +3992,15 @@
#
+################################################################################
+#
+# Static build support. When enabled will generate static
+# libraries instead of shared libraries for all JDK libs.
+#
+
+
+
+
#
# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -29018,6 +29030,40 @@
#
###############################################################################
+# See if we are doing a complete static build or not
+
+ # Check whether --enable-static-build was given.
+if test "${enable_static_build+set}" = set; then :
+ enableval=$enable_static_build;
+fi
+
+ STATIC_BUILD=false
+ if test "x$enable_static_build" = "xyes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if static build is enabled" >&5
+$as_echo_n "checking if static build is enabled... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ if test "x$OPENJDK_TARGET_OS" != "xmacosx"; then
+ as_fn_error $? "--enable-static-build is only supported for macosx builds" "$LINENO" 5
+ fi
+ STATIC_BUILD_CFLAGS="-DSTATIC_BUILD=1"
+ LEGACY_EXTRA_CFLAGS="$LEGACY_EXTRA_CFLAGS $STATIC_BUILD_CFLAGS"
+ LEGACY_EXTRA_CXXFLAGS="$LEGACY_EXTRA_CXXFLAGS $STATIC_BUILD_CFLAGS"
+ CFLAGS_JDKLIB_EXTRA="$CFLAGS_JDKLIB_EXTRA $STATIC_BUILD_CFLAGS"
+ CXXFLAGS_JDKLIB_EXTRA="$CXXFLAGS_JDKLIB_EXTRA $STATIC_BUILD_CFLAGS"
+ STATIC_BUILD=true
+ elif test "x$enable_static_build" = "xno"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if static build is enabled" >&5
+$as_echo_n "checking if static build is enabled... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ elif test "x$enable_static_build" != "x"; then
+ as_fn_error $? "--enable-static-build can only be assigned \"yes\" or \"no\"" "$LINENO" 5
+ fi
+
+
+
+
# First determine the toolchain type (compiler family)
@@ -29126,8 +29172,19 @@
OBJ_SUFFIX='.o'
EXE_SUFFIX=''
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- SHARED_LIBRARY='lib$1.dylib'
- SHARED_LIBRARY_SUFFIX='.dylib'
+ # For full static builds, we're overloading the SHARED_LIBRARY
+ # variables in order to limit the amount of changes required.
+ # It would be better to remove SHARED and just use LIBRARY and
+ # LIBRARY_SUFFIX for libraries that can be built either
+ # shared or static and use STATIC_* for libraries that are
+ # always built statically.
+ if test "x$STATIC_BUILD" = xtrue; then
+ SHARED_LIBRARY='lib$1.a'
+ SHARED_LIBRARY_SUFFIX='.a'
+ else
+ SHARED_LIBRARY='lib$1.dylib'
+ SHARED_LIBRARY_SUFFIX='.dylib'
+ fi
fi
fi
@@ -44314,7 +44371,11 @@
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
# Linking is different on MacOSX
- SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+ if test "x$STATIC_BUILD" = xtrue; then
+ SHARED_LIBRARY_FLAGS ='-undefined dynamic_lookup'
+ else
+ SHARED_LIBRARY_FLAGS="-dynamiclib -compatibility_version 1.0.0 -current_version 1.0.0 $PICFLAG"
+ fi
SET_EXECUTABLE_ORIGIN='-Xlinker -rpath -Xlinker @loader_path/.'
SET_SHARED_LIBRARY_ORIGIN="$SET_EXECUTABLE_ORIGIN"
SET_SHARED_LIBRARY_NAME='-Xlinker -install_name -Xlinker @rpath/$1'
@@ -44818,7 +44879,9 @@
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK \
-I${JDK_TOPDIR}/src/java.base/share/native/include \
-I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS/native/include \
- -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include"
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/include \
+ -I${JDK_TOPDIR}/src/java.base/share/native/libjava \
+ -I${JDK_TOPDIR}/src/java.base/$OPENJDK_TARGET_OS_TYPE/native/libjava"
# The shared libraries are compiled using the picflag.
CFLAGS_JDKLIB="$COMMON_CCXXFLAGS_JDK $CFLAGS_JDK $PICFLAG $CFLAGS_JDKLIB_EXTRA"
--- a/common/autoconf/jdk-options.m4 Thu Nov 12 18:27:55 2015 -0800
+++ b/common/autoconf/jdk-options.m4 Wed Jul 05 21:00:20 2017 +0200
@@ -665,3 +665,37 @@
AC_SUBST(GCOV_ENABLED)
])
+
+################################################################################
+#
+# Static build support. When enabled will generate static
+# libraries instead of shared libraries for all JDK libs.
+#
+AC_DEFUN_ONCE([JDKOPT_SETUP_STATIC_BUILD],
+[
+ AC_ARG_ENABLE([static-build], [AS_HELP_STRING([--enable-static-build],
+ [enable static library build @<:@disabled@:>@])])
+ STATIC_BUILD=false
+ if test "x$enable_static_build" = "xyes"; then
+ AC_MSG_CHECKING([if static build is enabled])
+ AC_MSG_RESULT([yes])
+ if test "x$OPENJDK_TARGET_OS" != "xmacosx"; then
+ AC_MSG_ERROR([--enable-static-build is only supported for macosx builds])
+ fi
+ STATIC_BUILD_CFLAGS="-DSTATIC_BUILD=1"
+ LEGACY_EXTRA_CFLAGS="$LEGACY_EXTRA_CFLAGS $STATIC_BUILD_CFLAGS"
+ LEGACY_EXTRA_CXXFLAGS="$LEGACY_EXTRA_CXXFLAGS $STATIC_BUILD_CFLAGS"
+ CFLAGS_JDKLIB_EXTRA="$CFLAGS_JDKLIB_EXTRA $STATIC_BUILD_CFLAGS"
+ CXXFLAGS_JDKLIB_EXTRA="$CXXFLAGS_JDKLIB_EXTRA $STATIC_BUILD_CFLAGS"
+ STATIC_BUILD=true
+ elif test "x$enable_static_build" = "xno"; then
+ AC_MSG_CHECKING([if static build is enabled])
+ AC_MSG_RESULT([no])
+ elif test "x$enable_static_build" != "x"; then
+ AC_MSG_ERROR([--enable-static-build can only be assigned "yes" or "no"])
+ fi
+
+ AC_SUBST(STATIC_BUILD)
+])
+
+
--- a/common/autoconf/spec.gmk.in Thu Nov 12 18:27:55 2015 -0800
+++ b/common/autoconf/spec.gmk.in Wed Jul 05 21:00:20 2017 +0200
@@ -417,6 +417,7 @@
STATIC_LIBRARY_SUFFIX:=@STATIC_LIBRARY_SUFFIX@
EXE_SUFFIX:=@EXE_SUFFIX@
OBJ_SUFFIX:=@OBJ_SUFFIX@
+STATIC_BUILD:=@STATIC_BUILD@
STRIPFLAGS:=@STRIPFLAGS@
--- a/common/autoconf/toolchain.m4 Thu Nov 12 18:27:55 2015 -0800
+++ b/common/autoconf/toolchain.m4 Wed Jul 05 21:00:20 2017 +0200
@@ -72,8 +72,19 @@
OBJ_SUFFIX='.o'
EXE_SUFFIX=''
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
- SHARED_LIBRARY='lib[$]1.dylib'
- SHARED_LIBRARY_SUFFIX='.dylib'
+ # For full static builds, we're overloading the SHARED_LIBRARY
+ # variables in order to limit the amount of changes required.
+ # It would be better to remove SHARED and just use LIBRARY and
+ # LIBRARY_SUFFIX for libraries that can be built either
+ # shared or static and use STATIC_* for libraries that are
+ # always built statically.
+ if test "x$STATIC_BUILD" = xtrue; then
+ SHARED_LIBRARY='lib[$]1.a'
+ SHARED_LIBRARY_SUFFIX='.a'
+ else
+ SHARED_LIBRARY='lib[$]1.dylib'
+ SHARED_LIBRARY_SUFFIX='.dylib'
+ fi
fi
fi
--- a/hotspot/.hgignore Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/.hgignore Wed Jul 05 21:00:20 2017 +0200
@@ -11,3 +11,12 @@
^.hgtip
.DS_Store
\.class$
+^\.?mx.jvmci/
+^src/jdk.vm.ci/share/classes/\w[\w\.]*/.*\.xml
+^src/jdk.vm.ci/share/classes/\w[\w\.]*/.*\.iml
+^src/jdk.vm.ci/share/classes/\w[\w\.]*/nbproject
+^src/jdk.vm.ci/share/classes/\w[\w\.]*/\..*
+^test/compiler/jvmci/\w[\w\.]*/.*\.xml
+^test/compiler/jvmci/\w[\w\.]*/.*\.iml
+^test/compiler/jvmci/\w[\w\.]*/nbproject
+^test/compiler/jvmci/\w[\w\.]*/\..*
--- a/hotspot/.hgtags Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/.hgtags Wed Jul 05 21:00:20 2017 +0200
@@ -494,3 +494,4 @@
20dff0211deda8d5877fda0e80b6d165ab93c6c2 jdk9-b89
7fe46dc64bb3a8df554b24cde0153ffb24f39c5e jdk9-b90
3fd5c2ca4c20c183628b6dbeb8df821a961419e3 jdk9-b91
+53cb98d68a1aeb08d29c89d6da748de60c448e37 jdk9-b92
--- a/hotspot/agent/src/os/linux/symtab.c Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/agent/src/os/linux/symtab.c Wed Jul 05 21:00:20 2017 +0200
@@ -545,6 +545,7 @@
return (uintptr_t)NULL;
item.key = (char*) strdup(sym_name);
+ item.data = NULL;
hsearch_r(item, FIND, &ret, symtab->hash_table);
if (ret) {
struct elf_symbol * sym = (struct elf_symbol *)(ret->data);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java Wed Jul 05 21:00:20 2017 +0200
@@ -40,8 +40,7 @@
// FIXME: access should be synchronized and cleared when VM is
// resumed
// String fields
- private static IntField offsetField;
- private static IntField countField;
+ private static ByteField coderField;
private static OopField valueField;
// ThreadGroup fields
private static OopField threadGroupParentField;
@@ -96,20 +95,30 @@
if (charArray == null) {
return null;
}
- return charArrayToString(charArray, 0, (int) charArray.getLength());
+ int length = (int)charArray.getLength();
+ StringBuffer buf = new StringBuffer(length);
+ for (int i = 0; i < length; i++) {
+ buf.append(charArray.getCharAt(i));
+ }
+ return buf.toString();
}
- public static String charArrayToString(TypeArray charArray, int offset, int length) {
- if (charArray == null) {
+ public static String byteArrayToString(TypeArray byteArray, byte coder) {
+ if (byteArray == null) {
return null;
}
- final int limit = offset + length;
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(offset >= 0 && limit <= charArray.getLength(), "out of bounds");
- }
+ int length = (int)byteArray.getLength() >> coder;
StringBuffer buf = new StringBuffer(length);
- for (int i = offset; i < limit; i++) {
- buf.append(charArray.getCharAt(i));
+ if (coder == 0) {
+ // Latin1 encoded
+ for (int i = 0; i < length; i++) {
+ buf.append((char)(byteArray.getByteAt(i) & 0xff));
+ }
+ } else {
+ // UTF16 encoded
+ for (int i = 0; i < length; i++) {
+ buf.append(byteArray.getCharAt(i));
+ }
}
return buf.toString();
}
@@ -141,21 +150,14 @@
}
public static String stringOopToString(Oop stringOop) {
- if (offsetField == null) {
- InstanceKlass k = (InstanceKlass) stringOop.getKlass();
- offsetField = (IntField) k.findField("offset", "I"); // optional
- countField = (IntField) k.findField("count", "I"); // optional
- valueField = (OopField) k.findField("value", "[C");
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(valueField != null, "Field \'value\' of java.lang.String not found");
- }
+ InstanceKlass k = (InstanceKlass) stringOop.getKlass();
+ coderField = (ByteField) k.findField("coder", "B");
+ valueField = (OopField) k.findField("value", "[B");
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(coderField != null, "Field \'coder\' of java.lang.String not found");
+ Assert.that(valueField != null, "Field \'value\' of java.lang.String not found");
}
- if (offsetField != null && countField != null) {
- return charArrayToString((TypeArray) valueField.getValue(stringOop),
- offsetField.getValue(stringOop),
- countField.getValue(stringOop));
- }
- return charArrayToString((TypeArray) valueField.getValue(stringOop));
+ return byteArrayToString((TypeArray) valueField.getValue(stringOop), coderField.getValue(stringOop));
}
public static String stringOopToEscapedString(Oop stringOop) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Wed Jul 05 21:00:20 2017 +0200
@@ -268,8 +268,8 @@
VM vm = VM.getVM();
SystemDictionary sysDict = vm.getSystemDictionary();
InstanceKlass strKlass = sysDict.getStringKlass();
- // String has a field named 'value' of type 'char[]'.
- stringValueField = (OopField) strKlass.findField("value", "[C");
+ // String has a field named 'value' of type 'byte[]'.
+ stringValueField = (OopField) strKlass.findField("value", "[B");
}
private long stringSize(Instance instance) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/Hashtable.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/Hashtable.java Wed Jul 05 21:00:20 2017 +0200
@@ -61,9 +61,8 @@
long h = 0;
int s = 0;
int len = buf.length;
- // Emulate the unsigned int in java_lang_String::hash_code
while (len-- > 0) {
- h = 31*h + (0xFFFFFFFFL & buf[s]);
+ h = 31*h + (0xFFL & buf[s]);
s++;
}
return h & 0xFFFFFFFFL;
--- a/hotspot/make/Makefile Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/Makefile Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -403,6 +403,8 @@
$(install-dir)
$(EXPORT_SERVER_DIR)/%.dSYM: $(C2_BUILD_DIR)/%.dSYM
$(install-dir)
+$(EXPORT_SERVER_DIR)/%.symbols: $(C2_BUILD_DIR)/%.symbols
+ $(install-file)
endif
# Client (C1)
--- a/hotspot/make/bsd/makefiles/buildtree.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/bsd/makefiles/buildtree.make Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -224,6 +224,11 @@
echo "OPENJDK = $(OPENJDK)"; \
echo "$(LP64_SETTING/$(DATA_MODE))"; \
echo; \
+ echo "STATIC_BUILD = $(STATIC_BUILD)"; \
+ echo "COMPILER_WARNINGS_FATAL = $(COMPILER_WARNINGS_FATAL)"; \
+ echo "EXTRA_LDFLAGS = $(EXTRA_LDFLAGS)"; \
+ echo "LIBRARY_SUFFIX = $(LIBRARY_SUFFIX)"; \
+ echo; \
echo "# Used for platform dispatching"; \
echo "TARGET_DEFINES = -DTARGET_OS_FAMILY_\$$(Platform_os_family)"; \
echo "TARGET_DEFINES += -DTARGET_ARCH_\$$(Platform_arch)"; \
--- a/hotspot/make/bsd/makefiles/defs.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/bsd/makefiles/defs.make Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -186,13 +186,16 @@
# executed multiple times. We reduce the noise by at least checking that
# BUILD_FLAVOR has been set.
ifneq ($(BUILD_FLAVOR),)
- ifeq ($(BUILD_FLAVOR), product)
- FULL_DEBUG_SYMBOLS ?= 1
- ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
- else
- # debug variants always get Full Debug Symbols (if available)
- ENABLE_FULL_DEBUG_SYMBOLS = 1
- endif
+ # FULL_DEBUG_SYMBOLS not created for individual static libraries
+ ifeq ($(STATIC_BUILD),false)
+ ifeq ($(BUILD_FLAVOR), product)
+ FULL_DEBUG_SYMBOLS ?= 1
+ ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
+ else
+ # debug variants always get Full Debug Symbols (if available)
+ ENABLE_FULL_DEBUG_SYMBOLS = 1
+ endif
+ endif
$(eval $(call print_info, "ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)"))
# since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
@@ -256,16 +259,24 @@
JDK_INCLUDE_SUBDIR=bsd
# Library suffix
-ifeq ($(OS_VENDOR),Darwin)
- LIBRARY_SUFFIX=dylib
+ifneq ($(STATIC_BUILD),true)
+ ifeq ($(OS_VENDOR),Darwin)
+ LIBRARY_SUFFIX=dylib
+ else
+ LIBRARY_SUFFIX=so
+ endif
else
- LIBRARY_SUFFIX=so
+ LIBRARY_SUFFIX=a
endif
+
EXPORT_LIST += $(EXPORT_DOCS_DIR)/platform/jvmti/jvmti.html
+# jsig library not needed for static builds
+ifneq ($(STATIC_BUILD),true)
# client and server subdirectories have symbolic links to ../libjsig.so
-EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
+ EXPORT_LIST += $(EXPORT_LIB_ARCH_DIR)/libjsig.$(LIBRARY_SUFFIX)
+endif
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(ZIP_DEBUGINFO_FILES),1)
@@ -286,6 +297,9 @@
ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
+ ifeq ($(STATIC_BUILD),true)
+ EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.symbols
+ endif
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(ZIP_DEBUGINFO_FILES),1)
@@ -303,6 +317,9 @@
ifeq ($(JVM_VARIANT_CLIENT),true)
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
+ ifeq ($(STATIC_BUILD),true)
+ EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.symbols
+ endif
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(ZIP_DEBUGINFO_FILES),1)
@@ -320,6 +337,9 @@
ifeq ($(JVM_VARIANT_MINIMAL1),true)
EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/libjvm.$(LIBRARY_SUFFIX)
+ ifeq ($(STATIC_BUILD),true)
+ EXPORT_LIST += $(EXPORT_MINIMAL_DIR)/libjvm.symbols
+ endif
endif
# Serviceability Binaries
@@ -388,7 +408,9 @@
endif
# Binaries to 'universalize' if built
- UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX)
+ ifneq ($(STATIC_BUILD),true)
+ UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/libjsig.$(LIBRARY_SUFFIX)
+ endif
UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/libsaproc.$(LIBRARY_SUFFIX)
UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/server/libjvm.$(LIBRARY_SUFFIX)
UNIVERSAL_LIPO_LIST += $(EXPORT_LIB_DIR)/client/libjvm.$(LIBRARY_SUFFIX)
@@ -396,6 +418,13 @@
# Files to simply copy in place
UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/server/Xusage.txt
UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/client/Xusage.txt
+
+ ifeq ($(STATIC_BUILD),true)
+ UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/server/libjvm.symbols
+ UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/client/libjvm.symbols
+ UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/minimal/libjvm.symbols
+ endif
+
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(ZIP_DEBUGINFO_FILES),1)
UNIVERSAL_COPY_LIST += $(EXPORT_LIB_DIR)/server/libjvm.diz
--- a/hotspot/make/bsd/makefiles/dtrace.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/bsd/makefiles/dtrace.make Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -37,15 +37,15 @@
# Bsd does not build libjvm_db, does not compile on macosx
# disabled in build: rule in vm.make
JVM_DB = libjvm_db
-LIBJVM_DB = libjvm_db.dylib
+LIBJVM_DB = libjvm_db.$(LIBRARY_SUFFIX)
-LIBJVM_DB_DEBUGINFO = libjvm_db.dylib.dSYM
+LIBJVM_DB_DEBUGINFO = libjvm_db.$(LIBRARY_SUFFIX).dSYM
LIBJVM_DB_DIZ = libjvm_db.diz
JVM_DTRACE = jvm_dtrace
-LIBJVM_DTRACE = libjvm_dtrace.dylib
+LIBJVM_DTRACE = libjvm_dtrace.$(LIBRARY_SUFFIX)
-LIBJVM_DTRACE_DEBUGINFO = libjvm_dtrace.dylib.dSYM
+LIBJVM_DTRACE_DEBUGINFO = libjvm_dtrace.$(LIBRARY_SUFFIX).dSYM
LIBJVM_DTRACE_DIZ = libjvm_dtrace.diz
JVMOFFS = JvmOffsets
@@ -167,14 +167,14 @@
LFLAGS_GENOFFS += -L.
-lib$(GENOFFS).dylib: $(DTRACE_SRCDIR)/$(GENOFFS).cpp $(DTRACE_SRCDIR)/$(GENOFFS).h \
+lib$(GENOFFS).$(LIBRARY_SUFFIX): $(DTRACE_SRCDIR)/$(GENOFFS).cpp $(DTRACE_SRCDIR)/$(GENOFFS).h \
$(LIBJVM.o)
$(QUIETLY) $(CXX) $(CXXFLAGS) $(GENOFFS_CFLAGS) $(SHARED_FLAG) $(PICFLAG) \
$(LFLAGS_GENOFFS) -o $@ $(DTRACE_SRCDIR)/$(GENOFFS).cpp -ljvm
-$(GENOFFS): $(DTRACE_SRCDIR)/$(GENOFFS)Main.c lib$(GENOFFS).dylib
+$(GENOFFS): $(DTRACE_SRCDIR)/$(GENOFFS)Main.c lib$(GENOFFS).$(LIBRARY_SUFFIX)
$(QUIETLY) $(LINK.CXX) -o $@ $(DTRACE_SRCDIR)/$(GENOFFS)Main.c \
- ./lib$(GENOFFS).dylib
+ ./lib$(GENOFFS).$(LIBRARY_SUFFIX)
# $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
$(JVMOFFS).h: $(GENOFFS)
--- a/hotspot/make/bsd/makefiles/gcc.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/bsd/makefiles/gcc.make Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -187,7 +187,14 @@
CFLAGS += $(LIBFFI_CFLAGS)
CFLAGS += $(LLVM_CFLAGS)
endif
+
+ifeq ($(STATIC_BUILD),true)
+CXXFLAGS += -DSTATIC_BUILD
+CFLAGS += -DSTATIC_BUILD
+else
CFLAGS += $(VM_PICFLAG)
+endif
+
CFLAGS += -fno-rtti
CFLAGS += -fno-exceptions
ifeq ($(USE_CLANG),)
--- a/hotspot/make/bsd/makefiles/jsig.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/bsd/makefiles/jsig.make Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -28,9 +28,9 @@
JSIG = jsig
ifeq ($(OS_VENDOR), Darwin)
- LIBJSIG = lib$(JSIG).dylib
+ LIBJSIG = lib$(JSIG).$(LIBRARY_SUFFIX)
- LIBJSIG_DEBUGINFO = lib$(JSIG).dylib.dSYM
+ LIBJSIG_DEBUGINFO = lib$(JSIG).$(LIBRARY_SUFFIX).dSYM
LIBJSIG_DIZ = lib$(JSIG).diz
else
LIBJSIG = lib$(JSIG).so
@@ -61,8 +61,14 @@
$(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE)
@echo $(LOG_INFO) Making signal interposition lib...
+ifeq ($(STATIC_BUILD),true)
+ $(QUIETLY) $(CC) -c $(SYMFLAG) $(EXTRA_CFLAGS) $(ARCHFLAG) $(PICFLAG) \
+ $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) -o $(JSIG).o $<
+ $(QUIETLY) $(AR) $(ARFLAGS) $@ $(JSIG).o
+else
$(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \
- $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $<
+ $(LFLAGS_JSIG) $(JSIG_DEBUG_CFLAGS) $(EXTRA_CFLAGS) -o $@ $<
+endif
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(OS_VENDOR), Darwin)
$(DSYMUTIL) $@
--- a/hotspot/make/bsd/makefiles/rules.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/bsd/makefiles/rules.make Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,11 @@
COMPILE.CC = $(CC_COMPILE) -c
GENASM.CC = $(CC_COMPILE) -S
LINK.CC = $(CC) $(LFLAGS) $(AOUT_FLAGS) $(PROF_AOUT_FLAGS)
+ifeq ($(STATIC_BUILD),true)
+LINK_LIB.CC = $(AR) $(ARFLAGS)
+else
LINK_LIB.CC = $(CC) $(LFLAGS) $(SHARED_FLAG)
+endif
PREPROCESS.CC = $(CC_COMPILE) -E
COMPILE.CXX = $(CXX_COMPILE) -c
--- a/hotspot/make/bsd/makefiles/saproc.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/bsd/makefiles/saproc.make Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -28,9 +28,9 @@
SAPROC = saproc
ifeq ($(OS_VENDOR), Darwin)
- LIBSAPROC = lib$(SAPROC).dylib
+ LIBSAPROC = lib$(SAPROC).$(LIBRARY_SUFFIX)
- LIBSAPROC_DEBUGINFO = lib$(SAPROC).dylib.dSYM
+ LIBSAPROC_DEBUGINFO = lib$(SAPROC).$(LIBRARY_SUFFIX).dSYM
LIBSAPROC_DIZ = lib$(SAPROC).diz
else
LIBSAPROC = lib$(SAPROC).so
--- a/hotspot/make/bsd/makefiles/vm.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/bsd/makefiles/vm.make Wed Jul 05 21:00:20 2017 +0200
@@ -142,10 +142,10 @@
JVM = jvm
ifeq ($(OS_VENDOR), Darwin)
- LIBJVM = lib$(JVM).dylib
+ LIBJVM = lib$(JVM).$(LIBRARY_SUFFIX)
CFLAGS += -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE
- LIBJVM_DEBUGINFO = lib$(JVM).dylib.dSYM
+ LIBJVM_DEBUGINFO = lib$(JVM).$(LIBRARY_SUFFIX).dSYM
LIBJVM_DIZ = lib$(JVM).diz
else
LIBJVM = lib$(JVM).so
@@ -261,6 +261,16 @@
{ print $$0 } \
}' > $@ < $(MAPFILE)
+ifeq ($(STATIC_BUILD),true)
+EXPORTED_SYMBOLS = libjvm.symbols
+
+libjvm.symbols : mapfile
+ $(CP) mapfile libjvm.symbols
+
+else
+EXPORTED_SYMBOLS =
+endif
+
mapfile_reorder : mapfile $(REORDERFILE)
rm -f $@
cat $^ > $@
@@ -288,9 +298,11 @@
LFLAGS_VM += $(SONAMEFLAG:SONAME=$(LIBJVM))
ifeq ($(OS_VENDOR), Darwin)
- LFLAGS_VM += -Xlinker -rpath -Xlinker @loader_path/.
- LFLAGS_VM += -Xlinker -rpath -Xlinker @loader_path/..
- LFLAGS_VM += -Xlinker -install_name -Xlinker @rpath/$(@F)
+ ifneq ($(STATIC_BUILD),true)
+ LFLAGS_VM += -Xlinker -rpath -Xlinker @loader_path/.
+ LFLAGS_VM += -Xlinker -rpath -Xlinker @loader_path/..
+ LFLAGS_VM += -Xlinker -install_name -Xlinker @rpath/$(@F)
+ endif
else
LFLAGS_VM += -Wl,-z,defs
endif
@@ -345,6 +357,10 @@
endif
$(LIBJVM): $(LIBJVM.o) $(LIBJVM_MAPFILE) $(LD_SCRIPT)
+ifeq ($(STATIC_BUILD),true)
+ echo Linking static vm...;
+ $(LINK_LIB.CC) $@ $(LIBJVM.o)
+else
$(QUIETLY) { \
echo $(LOG_INFO) Linking vm...; \
$(LINK_LIB.CXX/PRE_HOOK) \
@@ -354,6 +370,8 @@
rm -f $@.1; ln -s $@ $@.1; \
}
+endif
+
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(OS_VENDOR), Darwin)
$(DSYMUTIL) $@
@@ -410,10 +428,10 @@
ifeq ($(OS_VENDOR), Darwin)
# no libjvm_db for macosx
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(EXPORTED_SYMBOLS)
echo "Doing vm.make build:"
else
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(EXPORTED_SYMBOLS)
endif
install: install_jvm install_jsig install_saproc
--- a/hotspot/make/gensrc/Gensrc-jdk.vm.ci.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/gensrc/Gensrc-jdk.vm.ci.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -56,10 +56,10 @@
################################################################################
PROC_SRC_SUBDIRS := \
- jdk.vm.ci.compiler \
jdk.vm.ci.hotspot \
jdk.vm.ci.hotspot.amd64 \
jdk.vm.ci.hotspot.sparc \
+ jdk.vm.ci.runtime \
#
PROC_SRC_DIRS := $(patsubst %, $(SRC_DIR)/%/src, $(PROC_SRC_SUBDIRS))
@@ -94,11 +94,7 @@
$(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors: \
$(GENSRC_DIR)/_gensrc_proc_done
$(MKDIR) -p $(@D)
- ($(CD) $(GENSRC_DIR)/META-INF/jvmci.options && \
- $(RM) -f $@; \
- for i in $$(ls); do \
- echo $${i}_OptionDescriptors >> $@; \
- done)
+ $(FIND) $(GENSRC_DIR) -name '*_OptionDescriptors.java' | $(SED) 's:.*/jdk\.vm\.ci/\(.*\)\.java:\1:' | $(TR) '/' '.' > $@
TARGETS += $(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors
--- a/hotspot/make/linux/makefiles/gcc.make Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/make/linux/makefiles/gcc.make Wed Jul 05 21:00:20 2017 +0200
@@ -61,6 +61,11 @@
CC_VER_MAJOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f1)
CC_VER_MINOR := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f2)
CC_VER_MICRO := $(shell $(CC) -dumpversion | sed 's/egcs-//' | cut -d'.' -f3)
+ # Workaround Ubuntu bug where -dumpversion doesn't print a micro version
+ # https://bugs.launchpad.net/ubuntu/+source/gcc-4.8/+bug/1360404
+ ifeq ($(CC_VER_MICRO),)
+ CC_VER_MICRO := "0"
+ endif
endif
ifeq ($(USE_CLANG), true)
@@ -224,6 +229,8 @@
WARNING_FLAGS += -Wtype-limits
# GCC < 4.8 don't accept this flag for C++.
WARNING_FLAGS += -Wno-format-zero-length
+ # GCC 4.8 reports less false positives than the older compilers.
+ WARNING_FLAGS += -Wuninitialized
endif
endif
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad Wed Jul 05 21:00:20 2017 +0200
@@ -14150,6 +14150,7 @@
instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
%{
+ predicate(!CompactStrings);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
@@ -14165,6 +14166,7 @@
instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
+ predicate(!CompactStrings);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
@@ -14184,6 +14186,7 @@
immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
iRegI tmp3, iRegI tmp4, rFlagsReg cr)
%{
+ predicate(!CompactStrings);
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
@@ -14203,6 +14206,7 @@
instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
iRegI_R0 result, iRegP_R10 tmp, rFlagsReg cr)
%{
+ predicate(!CompactStrings);
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(KILL tmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
@@ -14218,6 +14222,7 @@
instruct array_equals(iRegP_R1 ary1, iRegP_R2 ary2, iRegI_R0 result,
iRegP_R10 tmp, rFlagsReg cr)
%{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (AryEq ary1 ary2));
effect(KILL tmp, USE_KILL ary1, USE_KILL ary2, KILL cr);
--- a/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -483,15 +483,6 @@
return offset;
}
-
-// This is the fast version of java.lang.String.compare; it has not
-// OSR-entry and therefore, we generate a slow version for OSR's
-void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) {
- __ mov(r2, (address)__FUNCTION__);
- __ call_Unimplemented();
-}
-
-
void LIR_Assembler::add_debug_info_for_branch(address adr, CodeEmitInfo* info) {
_masm->code_section()->relocate(adr, relocInfo::poll_type);
int pc_offset = code_offset();
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -79,6 +79,9 @@
define_pd_global(uintx, TypeProfileLevel, 111);
+// No performance work done here yet.
+define_pd_global(bool, CompactStrings, false);
+
// avoid biased locking while we are bootstrapping the aarch64 build
define_pd_global(bool, UseBiasedLocking, false);
--- a/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/aarch64/vm/jvmciCodeInstaller_aarch64.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -38,11 +38,11 @@
Unimplemented();
}
-void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
+void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle& constant) {
Unimplemented();
}
-void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
Unimplemented();
}
--- a/hotspot/src/cpu/aarch64/vm/methodHandles_aarch64.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/aarch64/vm/methodHandles_aarch64.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -62,7 +62,7 @@
void MethodHandles::verify_klass(MacroAssembler* _masm,
Register obj, SystemDictionary::WKID klass_id,
const char* error_message) {
- Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
+ InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
Register temp = rscratch2;
Register temp2 = rscratch1; // used by MacroAssembler::cmpptr
--- a/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1276,7 +1276,7 @@
// return to caller
//
nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
- methodHandle method,
+ const methodHandle& method,
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -72,6 +72,9 @@
define_pd_global(uintx, TypeProfileLevel, 111);
+// No performance work done here yet.
+define_pd_global(bool, CompactStrings, false);
+
// Platform dependent flag handling: flags only defined on this platform.
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
--- a/hotspot/src/cpu/ppc/vm/jvmciCodeInstaller_ppc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/jvmciCodeInstaller_ppc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -38,11 +38,11 @@
Unimplemented();
}
-void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
+void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle& constant) {
Unimplemented();
}
-void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
Unimplemented();
}
--- a/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/methodHandles_ppc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -73,7 +73,7 @@
Register obj_reg, SystemDictionary::WKID klass_id,
Register temp_reg, Register temp2_reg,
const char* error_message) {
- Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
+ InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
Label L_ok, L_bad;
BLOCK_COMMENT("verify_klass {");
--- a/hotspot/src/cpu/ppc/vm/ppc.ad Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad Wed Jul 05 21:00:20 2017 +0200
@@ -2054,11 +2054,11 @@
return (UsePopCountInstruction && VM_Version::has_popcntw());
case Op_StrComp:
- return SpecialStringCompareTo;
+ return SpecialStringCompareTo && !CompactStrings;
case Op_StrEquals:
- return SpecialStringEquals;
+ return SpecialStringEquals && !CompactStrings;
case Op_StrIndexOf:
- return SpecialStringIndexOf;
+ return SpecialStringIndexOf && !CompactStrings;
}
return true; // Per default match rules are supported.
@@ -11077,7 +11077,7 @@
immP needleImm, immL offsetImm, immI_1 needlecntImm,
iRegIdst tmp1, iRegIdst tmp2,
flagsRegCR0 cr0, flagsRegCR1 cr1) %{
- predicate(SpecialStringIndexOf); // type check implicit by parameter type, See Matcher::match_rule_supported
+ predicate(SpecialStringIndexOf && !CompactStrings); // type check implicit by parameter type, See Matcher::match_rule_supported
match(Set result (StrIndexOf (Binary haystack haycnt) (Binary (AddP needleImm offsetImm) needlecntImm)));
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, KILL cr0, KILL cr1);
@@ -11120,7 +11120,7 @@
effect(USE_KILL needle, /* TDEF needle, */ TEMP_DEF result,
TEMP tmp1, TEMP tmp2);
// Required for EA: check if it is still a type_array.
- predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
+ predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(180);
@@ -11167,7 +11167,7 @@
effect(USE_KILL haycnt, /* better: TDEF haycnt, */ TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5, KILL cr0, KILL cr1, KILL cr6);
// Required for EA: check if it is still a type_array.
- predicate(SpecialStringIndexOf && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
+ predicate(SpecialStringIndexOf && !CompactStrings && n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop() &&
n->in(3)->in(1)->bottom_type()->is_aryptr()->const_oop()->is_type_array());
ins_cost(250);
@@ -11200,7 +11200,7 @@
effect(USE_KILL haycnt, USE_KILL needlecnt, /*better: TDEF haycnt, TDEF needlecnt,*/
TEMP_DEF result,
TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr0, KILL cr1, KILL cr6);
- predicate(SpecialStringIndexOf); // See Matcher::match_rule_supported.
+ predicate(SpecialStringIndexOf && !CompactStrings); // See Matcher::match_rule_supported.
ins_cost(300);
ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
@@ -11224,7 +11224,7 @@
match(Set result (StrEquals (Binary str1 str2) cntImm));
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2,
KILL cr0, KILL cr6, KILL ctr);
- predicate(SpecialStringEquals); // See Matcher::match_rule_supported.
+ predicate(SpecialStringEquals && !CompactStrings); // See Matcher::match_rule_supported.
ins_cost(250);
ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
@@ -11247,7 +11247,7 @@
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(TEMP_DEF result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP tmp5,
KILL cr0, KILL cr1, KILL cr6, KILL ctr);
- predicate(SpecialStringEquals); // See Matcher::match_rule_supported.
+ predicate(SpecialStringEquals && !CompactStrings); // See Matcher::match_rule_supported.
ins_cost(300);
ins_alignment(8); // 'compute_padding()' gets called, up to this number-1 nops will get inserted.
@@ -11267,6 +11267,7 @@
// Use dst register classes if register gets killed, as it is the case for TEMP operands!
instruct string_compare(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4RegI cnt2, iRegIdst result,
iRegPdst tmp, flagsRegCR0 cr0, regCTR ctr) %{
+ predicate(!CompactStrings);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(USE_KILL cnt1, USE_KILL cnt2, USE_KILL str1, USE_KILL str2, TEMP_DEF result, TEMP tmp, KILL cr0, KILL ctr);
ins_cost(300);
--- a/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/ppc/vm/sharedRuntime_ppc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1701,7 +1701,7 @@
// return to caller
//
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
- methodHandle method,
+ const methodHandle& method,
int compile_id,
BasicType *in_sig_bt,
VMRegPair *in_regs,
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -124,6 +124,8 @@
impdep1_op3 = 0x36,
aes3_op3 = 0x36,
sha_op3 = 0x36,
+ bmask_op3 = 0x36,
+ bshuffle_op3 = 0x36,
alignaddr_op3 = 0x36,
faligndata_op3 = 0x36,
flog3_op3 = 0x36,
@@ -194,6 +196,7 @@
fnegd_opf = 0x06,
alignaddr_opf = 0x18,
+ bmask_opf = 0x19,
fadds_opf = 0x41,
faddd_opf = 0x42,
@@ -204,6 +207,7 @@
fmuls_opf = 0x49,
fmuld_opf = 0x4a,
+ bshuffle_opf = 0x4c,
fdivs_opf = 0x4d,
fdivd_opf = 0x4e,
@@ -1226,6 +1230,9 @@
void edge8n( Register s1, Register s2, Register d ) { vis2_only(); emit_int32( op(arith_op) | rd(d) | op3(edge_op3) | rs1(s1) | opf(edge8n_opf) | rs2(s2)); }
+ void bmask( Register s1, Register s2, Register d ) { vis2_only(); emit_int32( op(arith_op) | rd(d) | op3(bmask_op3) | rs1(s1) | opf(bmask_opf) | rs2(s2)); }
+ void bshuffle( FloatRegister s1, FloatRegister s2, FloatRegister d ) { vis2_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(bshuffle_op3) | fs1(s1, FloatRegisterImpl::D) | opf(bshuffle_opf) | fs2(s2, FloatRegisterImpl::D)); }
+
// VIS3 instructions
void movstosw( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstosw_opf) | fs2(s, FloatRegisterImpl::S)); }
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -232,118 +232,6 @@
}
-// Optimized Library calls
-// This is the fast version of java.lang.String.compare; it has not
-// OSR-entry and therefore, we generate a slow version for OSR's
-void LIR_Assembler::emit_string_compare(LIR_Opr left, LIR_Opr right, LIR_Opr dst, CodeEmitInfo* info) {
- Register str0 = left->as_register();
- Register str1 = right->as_register();
-
- Label Ldone;
-
- Register result = dst->as_register();
- {
- // Get a pointer to the first character of string0 in tmp0
- // and get string0.length() in str0
- // Get a pointer to the first character of string1 in tmp1
- // and get string1.length() in str1
- // Also, get string0.length()-string1.length() in
- // o7 and get the condition code set
- // Note: some instructions have been hoisted for better instruction scheduling
-
- Register tmp0 = L0;
- Register tmp1 = L1;
- Register tmp2 = L2;
-
- int value_offset = java_lang_String:: value_offset_in_bytes(); // char array
- if (java_lang_String::has_offset_field()) {
- int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
- int count_offset = java_lang_String:: count_offset_in_bytes();
- __ load_heap_oop(str0, value_offset, tmp0);
- __ ld(str0, offset_offset, tmp2);
- __ add(tmp0, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
- __ ld(str0, count_offset, str0);
- __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
- } else {
- __ load_heap_oop(str0, value_offset, tmp1);
- __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp0);
- __ ld(tmp1, arrayOopDesc::length_offset_in_bytes(), str0);
- }
-
- // str1 may be null
- add_debug_info_for_null_check_here(info);
-
- if (java_lang_String::has_offset_field()) {
- int offset_offset = java_lang_String::offset_offset_in_bytes(); // first character position
- int count_offset = java_lang_String:: count_offset_in_bytes();
- __ load_heap_oop(str1, value_offset, tmp1);
- __ add(tmp0, tmp2, tmp0);
-
- __ ld(str1, offset_offset, tmp2);
- __ add(tmp1, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
- __ ld(str1, count_offset, str1);
- __ sll(tmp2, exact_log2(sizeof(jchar)), tmp2);
- __ add(tmp1, tmp2, tmp1);
- } else {
- __ load_heap_oop(str1, value_offset, tmp2);
- __ add(tmp2, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1);
- __ ld(tmp2, arrayOopDesc::length_offset_in_bytes(), str1);
- }
- __ subcc(str0, str1, O7);
- }
-
- {
- // Compute the minimum of the string lengths, scale it and store it in limit
- Register count0 = I0;
- Register count1 = I1;
- Register limit = L3;
-
- Label Lskip;
- __ sll(count0, exact_log2(sizeof(jchar)), limit); // string0 is shorter
- __ br(Assembler::greater, true, Assembler::pt, Lskip);
- __ delayed()->sll(count1, exact_log2(sizeof(jchar)), limit); // string1 is shorter
- __ bind(Lskip);
-
- // If either string is empty (or both of them) the result is the difference in lengths
- __ cmp(limit, 0);
- __ br(Assembler::equal, true, Assembler::pn, Ldone);
- __ delayed()->mov(O7, result); // result is difference in lengths
- }
-
- {
- // Neither string is empty
- Label Lloop;
-
- Register base0 = L0;
- Register base1 = L1;
- Register chr0 = I0;
- Register chr1 = I1;
- Register limit = L3;
-
- // Shift base0 and base1 to the end of the arrays, negate limit
- __ add(base0, limit, base0);
- __ add(base1, limit, base1);
- __ neg(limit); // limit = -min{string0.length(), string1.length()}
-
- __ lduh(base0, limit, chr0);
- __ bind(Lloop);
- __ lduh(base1, limit, chr1);
- __ subcc(chr0, chr1, chr0);
- __ br(Assembler::notZero, false, Assembler::pn, Ldone);
- assert(chr0 == result, "result must be pre-placed");
- __ delayed()->inccc(limit, sizeof(jchar));
- __ br(Assembler::notZero, true, Assembler::pt, Lloop);
- __ delayed()->lduh(base0, limit, chr0);
- }
-
- // If strings are equal up to min length, return the length difference.
- __ mov(O7, result);
-
- // Otherwise, return the difference between the first mismatched chars.
- __ bind(Ldone);
-}
-
-
// --------------------------------------------------------------------------------------------
void LIR_Assembler::monitorexit(LIR_Opr obj_opr, LIR_Opr lock_opr, Register hdr, int monitor_no) {
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -86,6 +86,8 @@
define_pd_global(uintx, TypeProfileLevel, 111);
+define_pd_global(bool, CompactStrings, true);
+
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
product(intx, UseVIS, 99, \
--- a/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/jvmciCodeInstaller_sparc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -66,6 +66,25 @@
}
}
+void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle& constant) {
+ address pc = _instructions->start() + pc_offset;
+ if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
+#ifdef _LP64
+ NativeMovConstReg32* move = nativeMovConstReg32_at(pc);
+ narrowKlass narrowOop = record_narrow_metadata_reference(constant);
+ move->set_data((intptr_t)narrowOop);
+ TRACE_jvmci_3("relocating (narrow metaspace constant) at %p/%p", pc, narrowOop);
+#else
+ fatal("compressed Klass* on 32bit");
+#endif
+ } else {
+ NativeMovConstReg* move = nativeMovConstReg_at(pc);
+ Metadata* reference = record_metadata_reference(constant);
+ move->set_data((intptr_t)reference);
+ TRACE_jvmci_3("relocating (metaspace constant) at %p/%p", pc, reference);
+ }
+}
+
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
address pc = _instructions->start() + pc_offset;
NativeInstruction* inst = nativeInstruction_at(pc);
@@ -87,10 +106,6 @@
}
}
-void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
- fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp");
-}
-
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
address pc = (address) inst;
if (inst->is_call()) {
@@ -168,16 +183,25 @@
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg) {
- if (jvmci_reg < RegisterImpl::number_of_registers) {
+ // JVMCI Registers are numbered as follows:
+ // 0..31: Thirty-two General Purpose registers (CPU Registers)
+ // 32..63: Thirty-two single precision float registers
+ // 64..95: Thirty-two double precision float registers
+ // 96..111: Sixteen quad precision float registers
+ if (jvmci_reg < 32) {
return as_Register(jvmci_reg)->as_VMReg();
} else {
- jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers;
- floatRegisterNumber += MAX2(0, floatRegisterNumber-32); // Beginning with f32, only every second register is going to be addressed
- if (floatRegisterNumber < FloatRegisterImpl::number_of_registers) {
- return as_FloatRegister(floatRegisterNumber)->as_VMReg();
+ jint floatRegisterNumber;
+ if(jvmci_reg < 64) { // Single precision
+ floatRegisterNumber = jvmci_reg - 32;
+ } else if(jvmci_reg < 96) {
+ floatRegisterNumber = 2 * (jvmci_reg - 64);
+ } else if(jvmci_reg < 112) {
+ floatRegisterNumber = 4 * (jvmci_reg - 96);
+ } else {
+ fatal("Unknown jvmci register");
}
- ShouldNotReachHere();
- return NULL;
+ return as_FloatRegister(floatRegisterNumber)->as_VMReg();
}
}
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -44,6 +44,9 @@
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
#include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS
+#ifdef COMPILER2
+#include "opto/intrinsicnode.hpp"
+#endif
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
@@ -4253,27 +4256,385 @@
}
}
-// Compare char[] arrays aligned to 4 bytes.
-void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
- Register limit, Register result,
- Register chr1, Register chr2, Label& Ldone) {
- Label Lvector, Lloop;
- assert(chr1 == result, "should be the same");
-
- // Note: limit contains number of bytes (2*char_elements) != 0.
- andcc(limit, 0x2, chr1); // trailing character ?
+#ifdef COMPILER2
+
+// Compress char[] to byte[] by compressing 16 bytes at once. Return 0 on failure.
+void MacroAssembler::string_compress_16(Register src, Register dst, Register cnt, Register result,
+ Register tmp1, Register tmp2, Register tmp3, Register tmp4,
+ FloatRegister ftmp1, FloatRegister ftmp2, FloatRegister ftmp3, Label& Ldone) {
+ Label Lloop, Lslow;
+ assert(UseVIS >= 3, "VIS3 is required");
+ assert_different_registers(src, dst, cnt, tmp1, tmp2, tmp3, tmp4, result);
+ assert_different_registers(ftmp1, ftmp2, ftmp3);
+
+ // Check if cnt >= 8 (= 16 bytes)
+ cmp(cnt, 8);
+ br(Assembler::less, false, Assembler::pn, Lslow);
+ delayed()->mov(cnt, result); // copy count
+
+ // Check for 8-byte alignment of src and dst
+ or3(src, dst, tmp1);
+ andcc(tmp1, 7, G0);
+ br(Assembler::notZero, false, Assembler::pn, Lslow);
+ delayed()->nop();
+
+ // Set mask for bshuffle instruction
+ Register mask = tmp4;
+ set(0x13579bdf, mask);
+ bmask(mask, G0, G0);
+
+ // Set mask to 0xff00 ff00 ff00 ff00 to check for non-latin1 characters
+ Assembler::sethi(0xff00fc00, mask); // mask = 0x0000 0000 ff00 fc00
+ add(mask, 0x300, mask); // mask = 0x0000 0000 ff00 ff00
+ sllx(mask, 32, tmp1); // tmp1 = 0xff00 ff00 0000 0000
+ or3(mask, tmp1, mask); // mask = 0xff00 ff00 ff00 ff00
+
+ // Load first 8 bytes
+ ldx(src, 0, tmp1);
+
+ bind(Lloop);
+ // Load next 8 bytes
+ ldx(src, 8, tmp2);
+
+ // Check for non-latin1 character by testing if the most significant byte of a char is set.
+ // Although we have to move the data between integer and floating point registers, this is
+ // still faster than the corresponding VIS instructions (ford/fand/fcmpd).
+ or3(tmp1, tmp2, tmp3);
+ btst(tmp3, mask);
+ // annul zeroing if branch is not taken to preserve original count
+ brx(Assembler::notZero, true, Assembler::pn, Ldone);
+ delayed()->mov(G0, result); // 0 - failed
+
+ // Move bytes into float register
+ movxtod(tmp1, ftmp1);
+ movxtod(tmp2, ftmp2);
+
+ // Compress by copying one byte per char from ftmp1 and ftmp2 to ftmp3
+ bshuffle(ftmp1, ftmp2, ftmp3);
+ stf(FloatRegisterImpl::D, ftmp3, dst, 0);
+
+ // Increment addresses and decrement count
+ inc(src, 16);
+ inc(dst, 8);
+ dec(cnt, 8);
+
+ cmp(cnt, 8);
+ // annul LDX if branch is not taken to prevent access past end of string
+ br(Assembler::greaterEqual, true, Assembler::pt, Lloop);
+ delayed()->ldx(src, 0, tmp1);
+
+ // Fallback to slow version
+ bind(Lslow);
+}
+
+// Compress char[] to byte[]. Return 0 on failure.
+void MacroAssembler::string_compress(Register src, Register dst, Register cnt, Register result, Register tmp, Label& Ldone) {
+ Label Lloop;
+ assert_different_registers(src, dst, cnt, tmp, result);
+
+ lduh(src, 0, tmp);
+
+ bind(Lloop);
+ inc(src, sizeof(jchar));
+ cmp(tmp, 0xff);
+ // annul zeroing if branch is not taken to preserve original count
+ br(Assembler::greater, true, Assembler::pn, Ldone); // don't check xcc
+ delayed()->mov(G0, result); // 0 - failed
+ deccc(cnt);
+ stb(tmp, dst, 0);
+ inc(dst);
+ // annul LDUH if branch is not taken to prevent access past end of string
+ br(Assembler::notZero, true, Assembler::pt, Lloop);
+ delayed()->lduh(src, 0, tmp); // hoisted
+}
+
+// Inflate byte[] to char[] by inflating 16 bytes at once.
+void MacroAssembler::string_inflate_16(Register src, Register dst, Register cnt, Register tmp,
+ FloatRegister ftmp1, FloatRegister ftmp2, FloatRegister ftmp3, FloatRegister ftmp4, Label& Ldone) {
+ Label Lloop, Lslow;
+ assert(UseVIS >= 3, "VIS3 is required");
+ assert_different_registers(src, dst, cnt, tmp);
+ assert_different_registers(ftmp1, ftmp2, ftmp3, ftmp4);
+
+ // Check if cnt >= 8 (= 16 bytes)
+ cmp(cnt, 8);
+ br(Assembler::less, false, Assembler::pn, Lslow);
+ delayed()->nop();
+
+ // Check for 8-byte alignment of src and dst
+ or3(src, dst, tmp);
+ andcc(tmp, 7, G0);
+ br(Assembler::notZero, false, Assembler::pn, Lslow);
+ // Initialize float register to zero
+ FloatRegister zerof = ftmp4;
+ delayed()->fzero(FloatRegisterImpl::D, zerof);
+
+ // Load first 8 bytes
+ ldf(FloatRegisterImpl::D, src, 0, ftmp1);
+
+ bind(Lloop);
+ inc(src, 8);
+ dec(cnt, 8);
+
+ // Inflate the string by interleaving each byte from the source array
+ // with a zero byte and storing the result in the destination array.
+ fpmerge(zerof, ftmp1->successor(), ftmp2);
+ stf(FloatRegisterImpl::D, ftmp2, dst, 8);
+ fpmerge(zerof, ftmp1, ftmp3);
+ stf(FloatRegisterImpl::D, ftmp3, dst, 0);
+
+ inc(dst, 16);
+
+ cmp(cnt, 8);
+ // annul LDX if branch is not taken to prevent access past end of string
+ br(Assembler::greaterEqual, true, Assembler::pt, Lloop);
+ delayed()->ldf(FloatRegisterImpl::D, src, 0, ftmp1);
+
+ // Fallback to slow version
+ bind(Lslow);
+}
+
+// Inflate byte[] to char[].
+void MacroAssembler::string_inflate(Register src, Register dst, Register cnt, Register tmp, Label& Ldone) {
+ Label Loop;
+ assert_different_registers(src, dst, cnt, tmp);
+
+ ldub(src, 0, tmp);
+ bind(Loop);
+ inc(src);
+ deccc(cnt);
+ sth(tmp, dst, 0);
+ inc(dst, sizeof(jchar));
+ // annul LDUB if branch is not taken to prevent access past end of string
+ br(Assembler::notZero, true, Assembler::pt, Loop);
+ delayed()->ldub(src, 0, tmp); // hoisted
+}
+
+void MacroAssembler::string_compare(Register str1, Register str2,
+ Register cnt1, Register cnt2,
+ Register tmp1, Register tmp2,
+ Register result, int ae) {
+ Label Ldone, Lloop;
+ assert_different_registers(str1, str2, cnt1, cnt2, tmp1, result);
+ int stride1, stride2;
+
+ // Note: Making use of the fact that compareTo(a, b) == -compareTo(b, a)
+ // we interchange str1 and str2 in the UL case and negate the result.
+ // Like this, str1 is always latin1 encoded, expect for the UU case.
+
+ if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
+ srl(cnt2, 1, cnt2);
+ }
+
+ // See if the lengths are different, and calculate min in cnt1.
+ // Save diff in case we need it for a tie-breaker.
+ Label Lskip;
+ Register diff = tmp1;
+ subcc(cnt1, cnt2, diff);
+ br(Assembler::greater, true, Assembler::pt, Lskip);
+ // cnt2 is shorter, so use its count:
+ delayed()->mov(cnt2, cnt1);
+ bind(Lskip);
+
+ // Rename registers
+ Register limit1 = cnt1;
+ Register limit2 = limit1;
+ Register chr1 = result;
+ Register chr2 = cnt2;
+ if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
+ // We need an additional register to keep track of two limits
+ assert_different_registers(str1, str2, cnt1, cnt2, tmp1, tmp2, result);
+ limit2 = tmp2;
+ }
+
+ // Is the minimum length zero?
+ cmp(limit1, (int)0); // use cast to resolve overloading ambiguity
+ br(Assembler::equal, true, Assembler::pn, Ldone);
+ // result is difference in lengths
+ if (ae == StrIntrinsicNode::UU) {
+ delayed()->sra(diff, 1, result); // Divide by 2 to get number of chars
+ } else {
+ delayed()->mov(diff, result);
+ }
+
+ // Load first characters
+ if (ae == StrIntrinsicNode::LL) {
+ stride1 = stride2 = sizeof(jbyte);
+ ldub(str1, 0, chr1);
+ ldub(str2, 0, chr2);
+ } else if (ae == StrIntrinsicNode::UU) {
+ stride1 = stride2 = sizeof(jchar);
+ lduh(str1, 0, chr1);
+ lduh(str2, 0, chr2);
+ } else {
+ stride1 = sizeof(jbyte);
+ stride2 = sizeof(jchar);
+ ldub(str1, 0, chr1);
+ lduh(str2, 0, chr2);
+ }
+
+ // Compare first characters
+ subcc(chr1, chr2, chr1);
+ br(Assembler::notZero, false, Assembler::pt, Ldone);
+ assert(chr1 == result, "result must be pre-placed");
+ delayed()->nop();
+
+ // Check if the strings start at same location
+ cmp(str1, str2);
+ brx(Assembler::equal, true, Assembler::pn, Ldone);
+ delayed()->mov(G0, result); // result is zero
+
+ // We have no guarantee that on 64 bit the higher half of limit is 0
+ signx(limit1);
+
+ // Get limit
+ if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
+ sll(limit1, 1, limit2);
+ subcc(limit2, stride2, chr2);
+ }
+ subcc(limit1, stride1, chr1);
+ br(Assembler::zero, true, Assembler::pn, Ldone);
+ // result is difference in lengths
+ if (ae == StrIntrinsicNode::UU) {
+ delayed()->sra(diff, 1, result); // Divide by 2 to get number of chars
+ } else {
+ delayed()->mov(diff, result);
+ }
+
+ // Shift str1 and str2 to the end of the arrays, negate limit
+ add(str1, limit1, str1);
+ add(str2, limit2, str2);
+ neg(chr1, limit1); // limit1 = -(limit1-stride1)
+ if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
+ neg(chr2, limit2); // limit2 = -(limit2-stride2)
+ }
+
+ // Compare the rest of the characters
+ if (ae == StrIntrinsicNode::UU) {
+ lduh(str1, limit1, chr1);
+ } else {
+ ldub(str1, limit1, chr1);
+ }
+
+ bind(Lloop);
+ if (ae == StrIntrinsicNode::LL) {
+ ldub(str2, limit2, chr2);
+ } else {
+ lduh(str2, limit2, chr2);
+ }
+
+ subcc(chr1, chr2, chr1);
+ br(Assembler::notZero, false, Assembler::pt, Ldone);
+ assert(chr1 == result, "result must be pre-placed");
+ delayed()->inccc(limit1, stride1);
+ if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
+ inccc(limit2, stride2);
+ }
+
+ // annul LDUB if branch is not taken to prevent access past end of string
+ br(Assembler::notZero, true, Assembler::pt, Lloop);
+ if (ae == StrIntrinsicNode::UU) {
+ delayed()->lduh(str1, limit2, chr1);
+ } else {
+ delayed()->ldub(str1, limit1, chr1);
+ }
+
+ // If strings are equal up to min length, return the length difference.
+ if (ae == StrIntrinsicNode::UU) {
+ // Divide by 2 to get number of chars
+ sra(diff, 1, result);
+ } else {
+ mov(diff, result);
+ }
+
+ // Otherwise, return the difference between the first mismatched chars.
+ bind(Ldone);
+ if(ae == StrIntrinsicNode::UL) {
+ // Negate result (see note above)
+ neg(result);
+ }
+}
+
+void MacroAssembler::array_equals(bool is_array_equ, Register ary1, Register ary2,
+ Register limit, Register tmp, Register result, bool is_byte) {
+ Label Ldone, Lvector, Lloop;
+ assert_different_registers(ary1, ary2, limit, tmp, result);
+
+ int length_offset = arrayOopDesc::length_offset_in_bytes();
+ int base_offset = arrayOopDesc::base_offset_in_bytes(is_byte ? T_BYTE : T_CHAR);
+
+ if (is_array_equ) {
+ // return true if the same array
+ cmp(ary1, ary2);
+ brx(Assembler::equal, true, Assembler::pn, Ldone);
+ delayed()->add(G0, 1, result); // equal
+
+ br_null(ary1, true, Assembler::pn, Ldone);
+ delayed()->mov(G0, result); // not equal
+
+ br_null(ary2, true, Assembler::pn, Ldone);
+ delayed()->mov(G0, result); // not equal
+
+ // load the lengths of arrays
+ ld(Address(ary1, length_offset), limit);
+ ld(Address(ary2, length_offset), tmp);
+
+ // return false if the two arrays are not equal length
+ cmp(limit, tmp);
+ br(Assembler::notEqual, true, Assembler::pn, Ldone);
+ delayed()->mov(G0, result); // not equal
+ }
+
+ cmp_zero_and_br(Assembler::zero, limit, Ldone, true, Assembler::pn);
+ delayed()->add(G0, 1, result); // zero-length arrays are equal
+
+ if (is_array_equ) {
+ // load array addresses
+ add(ary1, base_offset, ary1);
+ add(ary2, base_offset, ary2);
+ } else {
+ // We have no guarantee that on 64 bit the higher half of limit is 0
+ signx(limit);
+ }
+
+ if (is_byte) {
+ Label Lskip;
+ // check for trailing byte
+ andcc(limit, 0x1, tmp);
+ br(Assembler::zero, false, Assembler::pt, Lskip);
+ delayed()->nop();
+
+ // compare the trailing byte
+ sub(limit, sizeof(jbyte), limit);
+ ldub(ary1, limit, result);
+ ldub(ary2, limit, tmp);
+ cmp(result, tmp);
+ br(Assembler::notEqual, true, Assembler::pt, Ldone);
+ delayed()->mov(G0, result); // not equal
+
+ // only one byte?
+ cmp_zero_and_br(zero, limit, Ldone, true, Assembler::pn);
+ delayed()->add(G0, 1, result); // zero-length arrays are equal
+ bind(Lskip);
+ } else if (is_array_equ) {
+ // set byte count
+ sll(limit, exact_log2(sizeof(jchar)), limit);
+ }
+
+ // check for trailing character
+ andcc(limit, 0x2, tmp);
br(Assembler::zero, false, Assembler::pt, Lvector);
delayed()->nop();
// compare the trailing char
sub(limit, sizeof(jchar), limit);
- lduh(ary1, limit, chr1);
- lduh(ary2, limit, chr2);
- cmp(chr1, chr2);
+ lduh(ary1, limit, result);
+ lduh(ary2, limit, tmp);
+ cmp(result, tmp);
br(Assembler::notEqual, true, Assembler::pt, Ldone);
delayed()->mov(G0, result); // not equal
- // only one char ?
+ // only one char?
cmp_zero_and_br(zero, limit, Ldone, true, Assembler::pn);
delayed()->add(G0, 1, result); // zero-length arrays are equal
@@ -4284,21 +4645,23 @@
add(ary2, limit, ary2);
neg(limit, limit);
- lduw(ary1, limit, chr1);
+ lduw(ary1, limit, result);
bind(Lloop);
- lduw(ary2, limit, chr2);
- cmp(chr1, chr2);
+ lduw(ary2, limit, tmp);
+ cmp(result, tmp);
br(Assembler::notEqual, true, Assembler::pt, Ldone);
delayed()->mov(G0, result); // not equal
inccc(limit, 2*sizeof(jchar));
// annul LDUW if branch is not taken to prevent access past end of array
br(Assembler::notZero, true, Assembler::pt, Lloop);
- delayed()->lduw(ary1, limit, chr1); // hoisted
-
- // Caller should set it:
- // add(G0, 1, result); // equals
+ delayed()->lduw(ary1, limit, result); // hoisted
+
+ add(G0, 1, result); // equals
+ bind(Ldone);
}
+#endif
+
// Use BIS for zeroing (count is in bytes).
void MacroAssembler::bis_zeroing(Register to, Register count, Register temp, Label& Ldone) {
assert(UseBlockZeroing && VM_Version::has_block_zeroing(), "only works with BIS zeroing");
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1433,10 +1433,31 @@
void inc_counter(address counter_addr, Register Rtmp1, Register Rtmp2);
void inc_counter(int* counter_addr, Register Rtmp1, Register Rtmp2);
- // Compare char[] arrays aligned to 4 bytes.
- void char_arrays_equals(Register ary1, Register ary2,
- Register limit, Register result,
- Register chr1, Register chr2, Label& Ldone);
+#ifdef COMPILER2
+ // Compress char[] to byte[] by compressing 16 bytes at once. Return 0 on failure.
+ void string_compress_16(Register src, Register dst, Register cnt, Register result,
+ Register tmp1, Register tmp2, Register tmp3, Register tmp4,
+ FloatRegister ftmp1, FloatRegister ftmp2, FloatRegister ftmp3, Label& Ldone);
+
+ // Compress char[] to byte[]. Return 0 on failure.
+ void string_compress(Register src, Register dst, Register cnt, Register tmp, Register result, Label& Ldone);
+
+ // Inflate byte[] to char[] by inflating 16 bytes at once.
+ void string_inflate_16(Register src, Register dst, Register cnt, Register tmp,
+ FloatRegister ftmp1, FloatRegister ftmp2, FloatRegister ftmp3, FloatRegister ftmp4, Label& Ldone);
+
+ // Inflate byte[] to char[].
+ void string_inflate(Register src, Register dst, Register cnt, Register tmp, Label& Ldone);
+
+ void string_compare(Register str1, Register str2,
+ Register cnt1, Register cnt2,
+ Register tmp1, Register tmp2,
+ Register result, int ae);
+
+ void array_equals(bool is_array_equ, Register ary1, Register ary2,
+ Register limit, Register tmp, Register result, bool is_byte);
+#endif
+
// Use BIS for zeroing
void bis_zeroing(Register to, Register count, Register temp, Label& Ldone);
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -69,7 +69,7 @@
Register obj_reg, SystemDictionary::WKID klass_id,
Register temp_reg, Register temp2_reg,
const char* error_message) {
- Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
+ InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
bool did_save = false;
if (temp_reg == noreg || temp2_reg == noreg) {
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -417,6 +417,67 @@
//-------------------------------------------------------------------
+void NativeMovConstReg32::verify() {
+ NativeInstruction::verify();
+ // make sure code pattern is actually a "set_metadata" synthetic instruction
+ // see MacroAssembler::set_oop()
+ int i0 = long_at(sethi_offset);
+ int i1 = long_at(add_offset);
+
+ // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg"
+ Register rd = inv_rd(i0);
+ if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
+ fatal("not a set_metadata");
+ }
+}
+
+
+void NativeMovConstReg32::print() {
+ tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data());
+}
+
+
+intptr_t NativeMovConstReg32::data() const {
+ return data32(long_at(sethi_offset), long_at(add_offset));
+}
+
+
+void NativeMovConstReg32::set_data(intptr_t x) {
+ set_long_at(sethi_offset, set_data32_sethi( long_at(sethi_offset), x));
+ set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x));
+
+ // also store the value into an oop_Relocation cell, if any
+ CodeBlob* cb = CodeCache::find_blob(instruction_address());
+ nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
+ if (nm != NULL) {
+ RelocIterator iter(nm, instruction_address(), next_instruction_address());
+ oop* oop_addr = NULL;
+ Metadata** metadata_addr = NULL;
+ while (iter.next()) {
+ if (iter.type() == relocInfo::oop_type) {
+ oop_Relocation *r = iter.oop_reloc();
+ if (oop_addr == NULL) {
+ oop_addr = r->oop_addr();
+ *oop_addr = cast_to_oop(x);
+ } else {
+ assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
+ }
+ }
+ if (iter.type() == relocInfo::metadata_type) {
+ metadata_Relocation *r = iter.metadata_reloc();
+ if (metadata_addr == NULL) {
+ metadata_addr = r->metadata_addr();
+ *metadata_addr = (Metadata*)x;
+ } else {
+ assert(metadata_addr == r->metadata_addr(), "must be only one set-metadata here");
+ }
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------
+
void NativeMovConstRegPatching::verify() {
NativeInstruction::verify();
// Make sure code pattern is sethi/nop/add.
--- a/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/nativeInst_sparc.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -518,6 +518,46 @@
#endif // _LP64
+// An interface for accessing/manipulating 32 bit native set_metadata imm, reg instructions
+// (used to manipulate inlined data references, etc.)
+// set_metadata imm, reg
+// == sethi %hi22(imm), reg ; add reg, %lo10(imm), reg
+class NativeMovConstReg32;
+inline NativeMovConstReg32* nativeMovConstReg32_at(address address);
+class NativeMovConstReg32: public NativeInstruction {
+ public:
+ enum Sparc_specific_constants {
+ sethi_offset = 0,
+ add_offset = 4,
+ instruction_size = 8
+ };
+
+ address instruction_address() const { return addr_at(0); }
+ address next_instruction_address() const { return addr_at(instruction_size); }
+
+ // (The [set_]data accessor respects oop_type relocs also.)
+ intptr_t data() const;
+ void set_data(intptr_t x);
+
+ // report the destination register
+ Register destination() { return inv_rd(long_at(sethi_offset)); }
+
+ void verify();
+ void print();
+
+ // unit test stuff
+ static void test();
+
+ // Creation
+ friend inline NativeMovConstReg32* nativeMovConstReg32_at(address address) {
+ NativeMovConstReg32* test = (NativeMovConstReg32*)address;
+ #ifdef ASSERT
+ test->verify();
+ #endif
+ return test;
+ }
+};
+
// An interface for accessing/manipulating native set_metadata imm, reg instructions.
// (used to manipulate inlined data references, etc.)
// set_metadata imm, reg
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1955,7 +1955,7 @@
// return to caller
//
nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
- methodHandle method,
+ const methodHandle& method,
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
--- a/hotspot/src/cpu/sparc/vm/sparc.ad Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad Wed Jul 05 21:00:20 2017 +0200
@@ -2905,232 +2905,6 @@
__ float_cmp( $primary, -1, Fsrc1, Fsrc2, Rdst);
%}
-
- enc_class enc_String_Compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result) %{
- Label Ldone, Lloop;
- MacroAssembler _masm(&cbuf);
-
- Register str1_reg = reg_to_register_object($str1$$reg);
- Register str2_reg = reg_to_register_object($str2$$reg);
- Register cnt1_reg = reg_to_register_object($cnt1$$reg);
- Register cnt2_reg = reg_to_register_object($cnt2$$reg);
- Register result_reg = reg_to_register_object($result$$reg);
-
- assert(result_reg != str1_reg &&
- result_reg != str2_reg &&
- result_reg != cnt1_reg &&
- result_reg != cnt2_reg ,
- "need different registers");
-
- // Compute the minimum of the string lengths(str1_reg) and the
- // difference of the string lengths (stack)
-
- // See if the lengths are different, and calculate min in str1_reg.
- // Stash diff in O7 in case we need it for a tie-breaker.
- Label Lskip;
- __ subcc(cnt1_reg, cnt2_reg, O7);
- __ sll(cnt1_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
- __ br(Assembler::greater, true, Assembler::pt, Lskip);
- // cnt2 is shorter, so use its count:
- __ delayed()->sll(cnt2_reg, exact_log2(sizeof(jchar)), cnt1_reg); // scale the limit
- __ bind(Lskip);
-
- // reallocate cnt1_reg, cnt2_reg, result_reg
- // Note: limit_reg holds the string length pre-scaled by 2
- Register limit_reg = cnt1_reg;
- Register chr2_reg = cnt2_reg;
- Register chr1_reg = result_reg;
- // str{12} are the base pointers
-
- // Is the minimum length zero?
- __ cmp(limit_reg, (int)(0 * sizeof(jchar))); // use cast to resolve overloading ambiguity
- __ br(Assembler::equal, true, Assembler::pn, Ldone);
- __ delayed()->mov(O7, result_reg); // result is difference in lengths
-
- // Load first characters
- __ lduh(str1_reg, 0, chr1_reg);
- __ lduh(str2_reg, 0, chr2_reg);
-
- // Compare first characters
- __ subcc(chr1_reg, chr2_reg, chr1_reg);
- __ br(Assembler::notZero, false, Assembler::pt, Ldone);
- assert(chr1_reg == result_reg, "result must be pre-placed");
- __ delayed()->nop();
-
- {
- // Check after comparing first character to see if strings are equivalent
- Label LSkip2;
- // Check if the strings start at same location
- __ cmp(str1_reg, str2_reg);
- __ brx(Assembler::notEqual, true, Assembler::pt, LSkip2);
- __ delayed()->nop();
-
- // Check if the length difference is zero (in O7)
- __ cmp(G0, O7);
- __ br(Assembler::equal, true, Assembler::pn, Ldone);
- __ delayed()->mov(G0, result_reg); // result is zero
-
- // Strings might not be equal
- __ bind(LSkip2);
- }
-
- // We have no guarantee that on 64 bit the higher half of limit_reg is 0
- __ signx(limit_reg);
-
- __ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg);
- __ br(Assembler::equal, true, Assembler::pn, Ldone);
- __ delayed()->mov(O7, result_reg); // result is difference in lengths
-
- // Shift str1_reg and str2_reg to the end of the arrays, negate limit
- __ add(str1_reg, limit_reg, str1_reg);
- __ add(str2_reg, limit_reg, str2_reg);
- __ neg(chr1_reg, limit_reg); // limit = -(limit-2)
-
- // Compare the rest of the characters
- __ lduh(str1_reg, limit_reg, chr1_reg);
- __ bind(Lloop);
- // __ lduh(str1_reg, limit_reg, chr1_reg); // hoisted
- __ lduh(str2_reg, limit_reg, chr2_reg);
- __ subcc(chr1_reg, chr2_reg, chr1_reg);
- __ br(Assembler::notZero, false, Assembler::pt, Ldone);
- assert(chr1_reg == result_reg, "result must be pre-placed");
- __ delayed()->inccc(limit_reg, sizeof(jchar));
- // annul LDUH if branch is not taken to prevent access past end of string
- __ br(Assembler::notZero, true, Assembler::pt, Lloop);
- __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
-
- // If strings are equal up to min length, return the length difference.
- __ mov(O7, result_reg);
-
- // Otherwise, return the difference between the first mismatched chars.
- __ bind(Ldone);
- %}
-
-enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result) %{
- Label Lchar, Lchar_loop, Ldone;
- MacroAssembler _masm(&cbuf);
-
- Register str1_reg = reg_to_register_object($str1$$reg);
- Register str2_reg = reg_to_register_object($str2$$reg);
- Register cnt_reg = reg_to_register_object($cnt$$reg);
- Register tmp1_reg = O7;
- Register result_reg = reg_to_register_object($result$$reg);
-
- assert(result_reg != str1_reg &&
- result_reg != str2_reg &&
- result_reg != cnt_reg &&
- result_reg != tmp1_reg ,
- "need different registers");
-
- __ cmp(str1_reg, str2_reg); //same char[] ?
- __ brx(Assembler::equal, true, Assembler::pn, Ldone);
- __ delayed()->add(G0, 1, result_reg);
-
- __ cmp_zero_and_br(Assembler::zero, cnt_reg, Ldone, true, Assembler::pn);
- __ delayed()->add(G0, 1, result_reg); // count == 0
-
- //rename registers
- Register limit_reg = cnt_reg;
- Register chr1_reg = result_reg;
- Register chr2_reg = tmp1_reg;
-
- // We have no guarantee that on 64 bit the higher half of limit_reg is 0
- __ signx(limit_reg);
-
- //check for alignment and position the pointers to the ends
- __ or3(str1_reg, str2_reg, chr1_reg);
- __ andcc(chr1_reg, 0x3, chr1_reg);
- // notZero means at least one not 4-byte aligned.
- // We could optimize the case when both arrays are not aligned
- // but it is not frequent case and it requires additional checks.
- __ br(Assembler::notZero, false, Assembler::pn, Lchar); // char by char compare
- __ delayed()->sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg); // set byte count
-
- // Compare char[] arrays aligned to 4 bytes.
- __ char_arrays_equals(str1_reg, str2_reg, limit_reg, result_reg,
- chr1_reg, chr2_reg, Ldone);
- __ ba(Ldone);
- __ delayed()->add(G0, 1, result_reg);
-
- // char by char compare
- __ bind(Lchar);
- __ add(str1_reg, limit_reg, str1_reg);
- __ add(str2_reg, limit_reg, str2_reg);
- __ neg(limit_reg); //negate count
-
- __ lduh(str1_reg, limit_reg, chr1_reg);
- // Lchar_loop
- __ bind(Lchar_loop);
- __ lduh(str2_reg, limit_reg, chr2_reg);
- __ cmp(chr1_reg, chr2_reg);
- __ br(Assembler::notEqual, true, Assembler::pt, Ldone);
- __ delayed()->mov(G0, result_reg); //not equal
- __ inccc(limit_reg, sizeof(jchar));
- // annul LDUH if branch is not taken to prevent access past end of string
- __ br(Assembler::notZero, true, Assembler::pt, Lchar_loop);
- __ delayed()->lduh(str1_reg, limit_reg, chr1_reg); // hoisted
-
- __ add(G0, 1, result_reg); //equal
-
- __ bind(Ldone);
- %}
-
-enc_class enc_Array_Equals(o0RegP ary1, o1RegP ary2, g3RegP tmp1, notemp_iRegI result) %{
- Label Lvector, Ldone, Lloop;
- MacroAssembler _masm(&cbuf);
-
- Register ary1_reg = reg_to_register_object($ary1$$reg);
- Register ary2_reg = reg_to_register_object($ary2$$reg);
- Register tmp1_reg = reg_to_register_object($tmp1$$reg);
- Register tmp2_reg = O7;
- Register result_reg = reg_to_register_object($result$$reg);
-
- int length_offset = arrayOopDesc::length_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- // return true if the same array
- __ cmp(ary1_reg, ary2_reg);
- __ brx(Assembler::equal, true, Assembler::pn, Ldone);
- __ delayed()->add(G0, 1, result_reg); // equal
-
- __ br_null(ary1_reg, true, Assembler::pn, Ldone);
- __ delayed()->mov(G0, result_reg); // not equal
-
- __ br_null(ary2_reg, true, Assembler::pn, Ldone);
- __ delayed()->mov(G0, result_reg); // not equal
-
- //load the lengths of arrays
- __ ld(Address(ary1_reg, length_offset), tmp1_reg);
- __ ld(Address(ary2_reg, length_offset), tmp2_reg);
-
- // return false if the two arrays are not equal length
- __ cmp(tmp1_reg, tmp2_reg);
- __ br(Assembler::notEqual, true, Assembler::pn, Ldone);
- __ delayed()->mov(G0, result_reg); // not equal
-
- __ cmp_zero_and_br(Assembler::zero, tmp1_reg, Ldone, true, Assembler::pn);
- __ delayed()->add(G0, 1, result_reg); // zero-length arrays are equal
-
- // load array addresses
- __ add(ary1_reg, base_offset, ary1_reg);
- __ add(ary2_reg, base_offset, ary2_reg);
-
- // renaming registers
- Register chr1_reg = result_reg; // for characters in ary1
- Register chr2_reg = tmp2_reg; // for characters in ary2
- Register limit_reg = tmp1_reg; // length
-
- // set byte count
- __ sll(limit_reg, exact_log2(sizeof(jchar)), limit_reg);
-
- // Compare char[] arrays aligned to 4 bytes.
- __ char_arrays_equals(ary1_reg, ary2_reg, limit_reg, result_reg,
- chr1_reg, chr2_reg, Ldone);
- __ add(G0, 1, result_reg); // equals
-
- __ bind(Ldone);
- %}
-
enc_class enc_rethrow() %{
cbuf.set_insts_mark();
Register temp_reg = G3;
@@ -10275,33 +10049,204 @@
ins_pipe(long_memory_op);
%}
-instruct string_compare(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
- o7RegI tmp, flagsReg ccr) %{
+instruct string_compareL(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
+ o7RegI tmp, flagsReg ccr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp);
+ ins_cost(300);
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ $tmp$$Register, $tmp$$Register,
+ $result$$Register, StrIntrinsicNode::LL);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+instruct string_compareU(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
+ o7RegI tmp, flagsReg ccr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp);
ins_cost(300);
- format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %}
- ins_encode( enc_String_Compare(str1, str2, cnt1, cnt2, result) );
+ format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ $tmp$$Register, $tmp$$Register,
+ $result$$Register, StrIntrinsicNode::UU);
+ %}
ins_pipe(long_memory_op);
%}
-instruct string_equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
- o7RegI tmp, flagsReg ccr) %{
+instruct string_compareLU(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
+ o7RegI tmp1, g1RegI tmp2, flagsReg ccr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp1, KILL tmp2);
+ ins_cost(300);
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1,$tmp2" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ $tmp1$$Register, $tmp2$$Register,
+ $result$$Register, StrIntrinsicNode::LU);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+instruct string_compareUL(o0RegP str1, o1RegP str2, g3RegI cnt1, g4RegI cnt2, notemp_iRegI result,
+ o7RegI tmp1, g1RegI tmp2, flagsReg ccr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL ccr, KILL tmp1, KILL tmp2);
+ ins_cost(300);
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1,$tmp2" %}
+ ins_encode %{
+ __ string_compare($str2$$Register, $str1$$Register,
+ $cnt2$$Register, $cnt1$$Register,
+ $tmp1$$Register, $tmp2$$Register,
+ $result$$Register, StrIntrinsicNode::UL);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+instruct string_equalsL(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
+ o7RegI tmp, flagsReg ccr) %{
+ predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrEquals (Binary str1 str2) cnt));
effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr);
ins_cost(300);
- format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp" %}
- ins_encode( enc_String_Equals(str1, str2, cnt, result) );
+ format %{ "String Equals byte[] $str1,$str2,$cnt -> $result // KILL $tmp" %}
+ ins_encode %{
+ __ array_equals(false, $str1$$Register, $str2$$Register,
+ $cnt$$Register, $tmp$$Register,
+ $result$$Register, true /* byte */);
+ %}
ins_pipe(long_memory_op);
%}
-instruct array_equals(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result,
- o7RegI tmp2, flagsReg ccr) %{
+instruct string_equalsU(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI result,
+ o7RegI tmp, flagsReg ccr) %{
+ predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
+ match(Set result (StrEquals (Binary str1 str2) cnt));
+ effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp, KILL ccr);
+ ins_cost(300);
+ format %{ "String Equals char[] $str1,$str2,$cnt -> $result // KILL $tmp" %}
+ ins_encode %{
+ __ array_equals(false, $str1$$Register, $str2$$Register,
+ $cnt$$Register, $tmp$$Register,
+ $result$$Register, false /* byte */);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+instruct array_equalsB(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result,
+ o7RegI tmp2, flagsReg ccr) %{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (AryEq ary1 ary2));
effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
ins_cost(300);
format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1,$tmp2" %}
- ins_encode( enc_Array_Equals(ary1, ary2, tmp1, result));
+ ins_encode %{
+ __ array_equals(true, $ary1$$Register, $ary2$$Register,
+ $tmp1$$Register, $tmp2$$Register,
+ $result$$Register, true /* byte */);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+instruct array_equalsC(o0RegP ary1, o1RegP ary2, g3RegI tmp1, notemp_iRegI result,
+ o7RegI tmp2, flagsReg ccr) %{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
+ match(Set result (AryEq ary1 ary2));
+ effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL ccr);
+ ins_cost(300);
+ format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1,$tmp2" %}
+ ins_encode %{
+ __ array_equals(true, $ary1$$Register, $ary2$$Register,
+ $tmp1$$Register, $tmp2$$Register,
+ $result$$Register, false /* byte */);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+// char[] to byte[] compression
+instruct string_compress(o0RegP src, o1RegP dst, g3RegI len, notemp_iRegI result, iRegL tmp, flagsReg ccr) %{
+ predicate(UseVIS < 3);
+ match(Set result (StrCompressedCopy src (Binary dst len)));
+ effect(TEMP result, TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr);
+ ins_cost(300);
+ format %{ "String Compress $src,$dst,$len -> $result // KILL $tmp" %}
+ ins_encode %{
+ Label Ldone;
+ __ signx($len$$Register);
+ __ cmp_zero_and_br(Assembler::zero, $len$$Register, Ldone, false, Assembler::pn);
+ __ delayed()->mov($len$$Register, $result$$Register); // copy count
+ __ string_compress($src$$Register, $dst$$Register, $len$$Register, $result$$Register, $tmp$$Register, Ldone);
+ __ bind(Ldone);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+// fast char[] to byte[] compression using VIS instructions
+instruct string_compress_fast(o0RegP src, o1RegP dst, g3RegI len, notemp_iRegI result,
+ iRegL tmp1, iRegL tmp2, iRegL tmp3, iRegL tmp4,
+ regD ftmp1, regD ftmp2, regD ftmp3, flagsReg ccr) %{
+ predicate(UseVIS >= 3);
+ match(Set result (StrCompressedCopy src (Binary dst len)));
+ effect(TEMP result, TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ftmp1, TEMP ftmp2, TEMP ftmp3, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr);
+ ins_cost(300);
+ format %{ "String Compress Fast $src,$dst,$len -> $result // KILL $tmp1,$tmp2,$tmp3,$tmp4,$ftmp1,$ftmp2,$ftmp3" %}
+ ins_encode %{
+ Label Ldone;
+ __ signx($len$$Register);
+ __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $result$$Register,
+ $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, $tmp4$$Register,
+ $ftmp1$$FloatRegister, $ftmp2$$FloatRegister, $ftmp3$$FloatRegister, Ldone);
+ __ cmp_and_brx_short($len$$Register, 0, Assembler::equal, Assembler::pn, Ldone);
+ __ string_compress($src$$Register, $dst$$Register, $len$$Register, $result$$Register, $tmp1$$Register, Ldone);
+ __ bind(Ldone);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+// byte[] to char[] inflation
+instruct string_inflate(Universe dummy, o0RegP src, o1RegP dst, g3RegI len,
+ iRegL tmp, flagsReg ccr) %{
+ match(Set dummy (StrInflatedCopy src (Binary dst len)));
+ effect(TEMP tmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr);
+ ins_cost(300);
+ format %{ "String Inflate $src,$dst,$len // KILL $tmp" %}
+ ins_encode %{
+ Label Ldone;
+ __ signx($len$$Register);
+ __ cmp_and_brx_short($len$$Register, 0, Assembler::equal, Assembler::pn, Ldone);
+ __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register, Ldone);
+ __ bind(Ldone);
+ %}
+ ins_pipe(long_memory_op);
+%}
+
+// fast byte[] to char[] inflation using VIS instructions
+instruct string_inflate_fast(Universe dummy, o0RegP src, o1RegP dst, g3RegI len,
+ iRegL tmp, regD ftmp1, regD ftmp2, regD ftmp3, regD ftmp4, flagsReg ccr) %{
+ predicate(UseVIS >= 3);
+ match(Set dummy (StrInflatedCopy src (Binary dst len)));
+ effect(TEMP tmp, TEMP ftmp1, TEMP ftmp2, TEMP ftmp3, TEMP ftmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL ccr);
+ ins_cost(300);
+ format %{ "String Inflate Fast $src,$dst,$len // KILL $tmp,$ftmp1,$ftmp2,$ftmp3,$ftmp4" %}
+ ins_encode %{
+ Label Ldone;
+ __ signx($len$$Register);
+ __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register,
+ $ftmp1$$FloatRegister, $ftmp2$$FloatRegister, $ftmp3$$FloatRegister, $ftmp4$$FloatRegister, Ldone);
+ __ cmp_and_brx_short($len$$Register, 0, Assembler::equal, Assembler::pn, Ldone);
+ __ string_inflate($src$$Register, $dst$$Register, $len$$Register, $tmp$$Register, Ldone);
+ __ bind(Ldone);
+ %}
ins_pipe(long_memory_op);
%}
--- a/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -83,7 +83,26 @@
declare_constant(VM_Version::vis1_instructions_m) \
declare_constant(VM_Version::vis2_instructions_m) \
declare_constant(VM_Version::vis3_instructions_m) \
- declare_constant(VM_Version::cbcond_instructions_m)
+ declare_constant(VM_Version::cbcond_instructions_m) \
+ declare_constant(VM_Version::v8_instructions_m) \
+ declare_constant(VM_Version::hardware_mul32_m) \
+ declare_constant(VM_Version::hardware_div32_m) \
+ declare_constant(VM_Version::hardware_fsmuld_m) \
+ declare_constant(VM_Version::hardware_popc_m) \
+ declare_constant(VM_Version::v9_instructions_m) \
+ declare_constant(VM_Version::sun4v_m) \
+ declare_constant(VM_Version::blk_init_instructions_m) \
+ declare_constant(VM_Version::fmaf_instructions_m) \
+ declare_constant(VM_Version::fmau_instructions_m) \
+ declare_constant(VM_Version::sparc64_family_m) \
+ declare_constant(VM_Version::M_family_m) \
+ declare_constant(VM_Version::T_family_m) \
+ declare_constant(VM_Version::T1_model_m) \
+ declare_constant(VM_Version::sparc5_instructions_m) \
+ declare_constant(VM_Version::aes_instructions_m) \
+ declare_constant(VM_Version::sha1_instruction_m) \
+ declare_constant(VM_Version::sha256_instruction_m) \
+ declare_constant(VM_Version::sha512_instruction_m)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -3036,6 +3036,35 @@
emit_int8(imm8);
}
+void Assembler::pcmpeqw(XMMRegister dst, XMMRegister src) {
+ NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+ emit_simd_arith(0x75, dst, src, VEX_SIMD_66,
+ false, (VM_Version::supports_avx512dq() == false));
+}
+
+void Assembler::vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+ assert(UseAVX > 0, "some form of AVX must be enabled");
+ emit_vex_arith(0x75, dst, nds, src, VEX_SIMD_66, vector_len,
+ false, (VM_Version::supports_avx512dq() == false));
+}
+
+void Assembler::pmovmskb(Register dst, XMMRegister src) {
+ assert(VM_Version::supports_sse2(), "");
+ int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, true, VEX_OPCODE_0F,
+ false, AVX_128bit, (VM_Version::supports_avx512dq() == false));
+ emit_int8((unsigned char)0xD7);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::vpmovmskb(Register dst, XMMRegister src) {
+ assert(VM_Version::supports_avx2(), "");
+ int vector_len = AVX_256bit;
+ int encode = vex_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66,
+ vector_len, VEX_OPCODE_0F, true, false);
+ emit_int8((unsigned char)0xD7);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
void Assembler::pextrd(Register dst, XMMRegister src, int imm8) {
assert(VM_Version::supports_sse4_1(), "");
int encode = simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, VEX_SIMD_66, /* no_mask_reg */ true,
@@ -3108,6 +3137,17 @@
emit_int8((unsigned char)(0xC0 | encode));
}
+void Assembler::vpmovzxbw(XMMRegister dst, Address src) {
+ assert(VM_Version::supports_avx(), "");
+ InstructionMark im(this);
+ bool vector256 = true;
+ assert(dst != xnoreg, "sanity");
+ int dst_enc = dst->encoding();
+ vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector256);
+ emit_int8(0x30);
+ emit_operand(dst, src);
+}
+
// generic
void Assembler::pop(Register dst) {
int encode = prefix_and_encode(dst->encoding());
@@ -5370,6 +5410,16 @@
emit_int8((unsigned char)(0xC0 | encode));
}
+// duplicate 2-bytes integer data from src into 16 locations in dest
+void Assembler::vpbroadcastw(XMMRegister dst, XMMRegister src) {
+ assert(VM_Version::supports_avx2(), "");
+ bool vector_len = AVX_256bit;
+ int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66,
+ vector_len, VEX_OPCODE_0F_38, false);
+ emit_int8(0x79);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
// duplicate 1-byte integer data from src into 16||32|64 locations in dest : requires AVX512BW and AVX512VL
void Assembler::evpbroadcastb(XMMRegister dst, XMMRegister src, int vector_len) {
_instruction_uses_vl = true;
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1682,6 +1682,12 @@
void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
void pcmpestri(XMMRegister xmm1, Address src, int imm8);
+ void pcmpeqw(XMMRegister dst, XMMRegister src);
+ void vpcmpeqw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
+
+ void pmovmskb(Register dst, XMMRegister src);
+ void vpmovmskb(Register dst, XMMRegister src);
+
// SSE 4.1 extract
void pextrd(Register dst, XMMRegister src, int imm8);
void pextrq(Register dst, XMMRegister src, int imm8);
@@ -1698,6 +1704,8 @@
void pmovzxbw(XMMRegister dst, XMMRegister src);
void pmovzxbw(XMMRegister dst, Address src);
+ void vpmovzxbw(XMMRegister dst, Address src);
+
#ifndef _LP64 // no 32bit push/pop on amd64
void popl(Address dst);
#endif
@@ -2116,6 +2124,9 @@
// duplicate 4-bytes integer data from src into 8 locations in dest
void vpbroadcastd(XMMRegister dst, XMMRegister src);
+ // duplicate 2-bytes integer data from src into 16 locations in dest
+ void vpbroadcastw(XMMRegister dst, XMMRegister src);
+
// duplicate n-bytes integer data from src into vector_len locations in dest
void evpbroadcastb(XMMRegister dst, XMMRegister src, int vector_len);
void evpbroadcastb(XMMRegister dst, Address src, int vector_len);
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -509,86 +509,6 @@
}
-// This is the fast version of java.lang.String.compare; it has not
-// OSR-entry and therefore, we generate a slow version for OSR's
-void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) {
- __ movptr (rbx, rcx); // receiver is in rcx
- __ movptr (rax, arg1->as_register());
-
- // Get addresses of first characters from both Strings
- __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes()));
- if (java_lang_String::has_offset_field()) {
- __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
- __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes()));
- __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
- } else {
- __ movl (rax, Address(rsi, arrayOopDesc::length_offset_in_bytes()));
- __ lea (rsi, Address(rsi, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
- }
-
- // rbx, may be NULL
- add_debug_info_for_null_check_here(info);
- __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes()));
- if (java_lang_String::has_offset_field()) {
- __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
- __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes()));
- __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
- } else {
- __ movl (rbx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));
- __ lea (rdi, Address(rdi, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
- }
-
- // compute minimum length (in rax) and difference of lengths (on top of stack)
- __ mov (rcx, rbx);
- __ subptr(rbx, rax); // subtract lengths
- __ push (rbx); // result
- __ cmov (Assembler::lessEqual, rax, rcx);
-
- // is minimum length 0?
- Label noLoop, haveResult;
- __ testptr (rax, rax);
- __ jcc (Assembler::zero, noLoop);
-
- // compare first characters
- __ load_unsigned_short(rcx, Address(rdi, 0));
- __ load_unsigned_short(rbx, Address(rsi, 0));
- __ subl(rcx, rbx);
- __ jcc(Assembler::notZero, haveResult);
- // starting loop
- __ decrement(rax); // we already tested index: skip one
- __ jcc(Assembler::zero, noLoop);
-
- // set rsi.edi to the end of the arrays (arrays have same length)
- // negate the index
-
- __ lea(rsi, Address(rsi, rax, Address::times_2, type2aelembytes(T_CHAR)));
- __ lea(rdi, Address(rdi, rax, Address::times_2, type2aelembytes(T_CHAR)));
- __ negptr(rax);
-
- // compare the strings in a loop
-
- Label loop;
- __ align(wordSize);
- __ bind(loop);
- __ load_unsigned_short(rcx, Address(rdi, rax, Address::times_2, 0));
- __ load_unsigned_short(rbx, Address(rsi, rax, Address::times_2, 0));
- __ subl(rcx, rbx);
- __ jcc(Assembler::notZero, haveResult);
- __ increment(rax);
- __ jcc(Assembler::notZero, loop);
-
- // strings are equal up to min length
-
- __ bind(noLoop);
- __ pop(rax);
- return_op(LIR_OprFact::illegalOpr);
-
- __ bind(haveResult);
- // leave instruction is going to discard the TOS value
- __ mov (rax, rcx); // result of call is in rax,
-}
-
-
void LIR_Assembler::return_op(LIR_Opr result) {
assert(result->is_illegal() || !result->is_single_cpu() || result->as_register() == rax, "word returns are in rax,");
if (!result->is_illegal() && result->is_float_kind() && !result->is_xmm_register()) {
@@ -1667,8 +1587,8 @@
Register Rtmp1 = noreg;
// check if it needs to be profiled
- ciMethodData* md;
- ciProfileData* data;
+ ciMethodData* md = NULL;
+ ciProfileData* data = NULL;
if (op->should_profile()) {
ciMethod* method = op->profiled_method();
@@ -1827,8 +1747,8 @@
CodeStub* stub = op->stub();
// check if it needs to be profiled
- ciMethodData* md;
- ciProfileData* data;
+ ciMethodData* md = NULL;
+ ciProfileData* data = NULL;
if (op->should_profile()) {
ciMethod* method = op->profiled_method();
@@ -2005,7 +1925,8 @@
case lir_cond_greater: acond = Assembler::greater; ncond = Assembler::lessEqual; break;
case lir_cond_belowEqual: acond = Assembler::belowEqual; ncond = Assembler::above; break;
case lir_cond_aboveEqual: acond = Assembler::aboveEqual; ncond = Assembler::below; break;
- default: ShouldNotReachHere();
+ default: acond = Assembler::equal; ncond = Assembler::notEqual;
+ ShouldNotReachHere();
}
if (opr1->is_cpu_register()) {
@@ -3181,27 +3102,23 @@
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;
Address::ScaleFactor scale;
switch (elem_size) {
case 1 :
- shift_amount = 0;
scale = Address::times_1;
break;
case 2 :
- shift_amount = 1;
scale = Address::times_2;
break;
case 4 :
- shift_amount = 2;
scale = Address::times_4;
break;
case 8 :
- shift_amount = 3;
scale = Address::times_8;
break;
default:
+ scale = Address::no_scale;
ShouldNotReachHere();
}
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -195,7 +195,7 @@
LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {
- LIR_Opr r;
+ LIR_Opr r = NULL;
if (type == T_LONG) {
r = LIR_OprFact::longConst(x);
} else if (type == T_INT) {
@@ -484,7 +484,7 @@
__ cmp(lir_cond_equal, right.result(), LIR_OprFact::longConst(0));
__ branch(lir_cond_equal, T_LONG, new DivByZeroStub(info));
- address entry;
+ address entry = NULL;
switch (x->op()) {
case Bytecodes::_lrem:
entry = CAST_FROM_FN_PTR(address, SharedRuntime::lrem);
@@ -1072,7 +1072,7 @@
void LIRGenerator::do_Convert(Convert* x) {
// flags that vary for the different operations and different SSE-settings
- bool fixed_input, fixed_result, round_result, needs_stub;
+ bool fixed_input = false, fixed_result = false, round_result = false, needs_stub = false;
switch (x->op()) {
case Bytecodes::_i2l: // fall through
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -91,6 +91,8 @@
define_pd_global(uintx, TypeProfileLevel, 111);
+define_pd_global(bool, CompactStrings, true);
+
define_pd_global(bool, PreserveFramePointer, false);
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
--- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_32.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -48,7 +48,7 @@
// between loads, which is much more efficient than lfence.
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
- const char *name;
+ const char *name = NULL;
switch (type) {
case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
case T_BYTE: name = "jni_fast_GetByteField"; break;
@@ -122,7 +122,7 @@
slowcase_entry_pclist[count++] = __ pc();
__ bind (slow);
- address slow_case_addr;
+ address slow_case_addr = NULL;
switch (type) {
case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
@@ -256,7 +256,7 @@
}
address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
- const char *name;
+ const char *name = NULL;
switch (type) {
case T_FLOAT: name = "jni_fast_GetFloatField"; break;
case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
@@ -337,7 +337,7 @@
slowcase_entry_pclist[count++] = __ pc();
__ bind (slow);
- address slow_case_addr;
+ address slow_case_addr = NULL;
switch (type) {
case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr(); break;
--- a/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/jniFastGetField_x86_64.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -51,7 +51,7 @@
// since that may scratch r10!
address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
- const char *name;
+ const char *name = NULL;
switch (type) {
case T_BOOLEAN: name = "jni_fast_GetBooleanField"; break;
case T_BYTE: name = "jni_fast_GetByteField"; break;
@@ -111,7 +111,7 @@
slowcase_entry_pclist[count++] = __ pc();
__ bind (slow);
- address slow_case_addr;
+ address slow_case_addr = NULL;
switch (type) {
case T_BOOLEAN: slow_case_addr = jni_GetBooleanField_addr(); break;
case T_BYTE: slow_case_addr = jni_GetByteField_addr(); break;
@@ -153,7 +153,7 @@
}
address JNI_FastGetField::generate_fast_get_float_field0(BasicType type) {
- const char *name;
+ const char *name = NULL;
switch (type) {
case T_FLOAT: name = "jni_fast_GetFloatField"; break;
case T_DOUBLE: name = "jni_fast_GetDoubleField"; break;
@@ -206,7 +206,7 @@
slowcase_entry_pclist[count++] = __ pc();
__ bind (slow);
- address slow_case_addr;
+ address slow_case_addr = NULL;
switch (type) {
case T_FLOAT: slow_case_addr = jni_GetFloatField_addr(); break;
case T_DOUBLE: slow_case_addr = jni_GetDoubleField_addr();
--- a/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/jvmciCodeInstaller_x86.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -85,6 +85,23 @@
}
}
+void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle& constant) {
+ address pc = _instructions->start() + pc_offset;
+ if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
+#ifdef _LP64
+ address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
+ *((narrowKlass*) operand) = record_narrow_metadata_reference(constant);
+ TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
+#else
+ fatal("compressed Klass* on 32bit");
+#endif
+ } else {
+ address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
+ *((Metadata**) operand) = record_metadata_reference(constant);
+ TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
+ }
+}
+
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
address pc = _instructions->start() + pc_offset;
@@ -100,16 +117,6 @@
TRACE_jvmci_3("relocating at " PTR_FORMAT "/" PTR_FORMAT " with destination at " PTR_FORMAT " (%d)", p2i(pc), p2i(operand), p2i(dest), data_offset);
}
-void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
- if (cb->is_nmethod()) {
- nmethod* nm = (nmethod*) cb;
- nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
- } else {
- nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
- }
- _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
-}
-
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
address pc = (address) inst;
if (inst->is_call()) {
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -46,6 +46,9 @@
#include "gc/g1/heapRegion.hpp"
#endif // INCLUDE_ALL_GCS
#include "crc32c.h"
+#ifdef COMPILER2
+#include "opto/intrinsicnode.hpp"
+#endif
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
@@ -6299,25 +6302,34 @@
}
}
+#ifdef COMPILER2
+
// IndexOf for constant substrings with size >= 8 chars
// which don't need to be loaded through stack.
void MacroAssembler::string_indexofC8(Register str1, Register str2,
Register cnt1, Register cnt2,
int int_cnt2, Register result,
- XMMRegister vec, Register tmp) {
+ XMMRegister vec, Register tmp,
+ int ae) {
ShortBranchVerifier sbv(this);
assert(UseSSE42Intrinsics, "SSE4.2 is required");
-
- // This method uses pcmpestri instruction with bound registers
+ assert(ae != StrIntrinsicNode::LU, "Invalid encoding");
+
+ // This method uses the pcmpestri instruction with bound registers
// inputs:
// xmm - substring
// rax - substring length (elements count)
// mem - scanned string
// rdx - string length (elements count)
// 0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
+ // 0xc - mode: 1100 (substring search) + 00 (unsigned bytes)
// outputs:
// rcx - matched index in string
assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
+ int mode = (ae == StrIntrinsicNode::LL) ? 0x0c : 0x0d; // bytes or shorts
+ int stride = (ae == StrIntrinsicNode::LL) ? 16 : 8; //UU, UL -> 8
+ Address::ScaleFactor scale1 = (ae == StrIntrinsicNode::LL) ? Address::times_1 : Address::times_2;
+ Address::ScaleFactor scale2 = (ae == StrIntrinsicNode::UL) ? Address::times_1 : scale1;
Label RELOAD_SUBSTR, SCAN_TO_SUBSTR, SCAN_SUBSTR,
RET_FOUND, RET_NOT_FOUND, EXIT, FOUND_SUBSTR,
@@ -6326,20 +6338,28 @@
// Note, inline_string_indexOf() generates checks:
// if (substr.count > string.count) return -1;
// if (substr.count == 0) return 0;
- assert(int_cnt2 >= 8, "this code isused only for cnt2 >= 8 chars");
+ assert(int_cnt2 >= stride, "this code is used only for cnt2 >= 8 chars");
// Load substring.
- movdqu(vec, Address(str2, 0));
+ if (ae == StrIntrinsicNode::UL) {
+ pmovzxbw(vec, Address(str2, 0));
+ } else {
+ movdqu(vec, Address(str2, 0));
+ }
movl(cnt2, int_cnt2);
movptr(result, str1); // string addr
- if (int_cnt2 > 8) {
+ if (int_cnt2 > stride) {
jmpb(SCAN_TO_SUBSTR);
// Reload substr for rescan, this code
// is executed only for large substrings (> 8 chars)
bind(RELOAD_SUBSTR);
- movdqu(vec, Address(str2, 0));
+ if (ae == StrIntrinsicNode::UL) {
+ pmovzxbw(vec, Address(str2, 0));
+ } else {
+ movdqu(vec, Address(str2, 0));
+ }
negptr(cnt2); // Jumped here with negative cnt2, convert to positive
bind(RELOAD_STR);
@@ -6358,15 +6378,15 @@
cmpl(cnt1, cnt2);
jccb(Assembler::negative, RET_NOT_FOUND); // Left less then substring
- addptr(result, 2);
+ addptr(result, (1<<scale1));
} // (int_cnt2 > 8)
// Scan string for start of substr in 16-byte vectors
bind(SCAN_TO_SUBSTR);
- pcmpestri(vec, Address(result, 0), 0x0d);
+ pcmpestri(vec, Address(result, 0), mode);
jccb(Assembler::below, FOUND_CANDIDATE); // CF == 1
- subl(cnt1, 8);
+ subl(cnt1, stride);
jccb(Assembler::lessEqual, RET_NOT_FOUND); // Scanned full string
cmpl(cnt1, cnt2);
jccb(Assembler::negative, RET_NOT_FOUND); // Left less then substring
@@ -6376,19 +6396,19 @@
// Found a potential substr
bind(FOUND_CANDIDATE);
// Matched whole vector if first element matched (tmp(rcx) == 0).
- if (int_cnt2 == 8) {
+ if (int_cnt2 == stride) {
jccb(Assembler::overflow, RET_FOUND); // OF == 1
} else { // int_cnt2 > 8
jccb(Assembler::overflow, FOUND_SUBSTR);
}
// After pcmpestri tmp(rcx) contains matched element index
// Compute start addr of substr
- lea(result, Address(result, tmp, Address::times_2));
+ lea(result, Address(result, tmp, scale1));
// Make sure string is still long enough
subl(cnt1, tmp);
cmpl(cnt1, cnt2);
- if (int_cnt2 == 8) {
+ if (int_cnt2 == stride) {
jccb(Assembler::greaterEqual, SCAN_TO_SUBSTR);
} else { // int_cnt2 > 8
jccb(Assembler::greaterEqual, MATCH_SUBSTR_HEAD);
@@ -6399,11 +6419,11 @@
movl(result, -1);
jmpb(EXIT);
- if (int_cnt2 > 8) {
+ if (int_cnt2 > stride) {
// This code is optimized for the case when whole substring
// is matched if its head is matched.
bind(MATCH_SUBSTR_HEAD);
- pcmpestri(vec, Address(result, 0), 0x0d);
+ pcmpestri(vec, Address(result, 0), mode);
// Reload only string if does not match
jccb(Assembler::noOverflow, RELOAD_STR); // OF == 0
@@ -6412,31 +6432,41 @@
bind(FOUND_SUBSTR);
// First 8 chars are already matched.
negptr(cnt2);
- addptr(cnt2, 8);
+ addptr(cnt2, stride);
bind(SCAN_SUBSTR);
- subl(cnt1, 8);
- cmpl(cnt2, -8); // Do not read beyond substring
+ subl(cnt1, stride);
+ cmpl(cnt2, -stride); // Do not read beyond substring
jccb(Assembler::lessEqual, CONT_SCAN_SUBSTR);
// Back-up strings to avoid reading beyond substring:
// cnt1 = cnt1 - cnt2 + 8
addl(cnt1, cnt2); // cnt2 is negative
- addl(cnt1, 8);
- movl(cnt2, 8); negptr(cnt2);
+ addl(cnt1, stride);
+ movl(cnt2, stride); negptr(cnt2);
bind(CONT_SCAN_SUBSTR);
if (int_cnt2 < (int)G) {
- movdqu(vec, Address(str2, cnt2, Address::times_2, int_cnt2*2));
- pcmpestri(vec, Address(result, cnt2, Address::times_2, int_cnt2*2), 0x0d);
+ int tail_off1 = int_cnt2<<scale1;
+ int tail_off2 = int_cnt2<<scale2;
+ if (ae == StrIntrinsicNode::UL) {
+ pmovzxbw(vec, Address(str2, cnt2, scale2, tail_off2));
+ } else {
+ movdqu(vec, Address(str2, cnt2, scale2, tail_off2));
+ }
+ pcmpestri(vec, Address(result, cnt2, scale1, tail_off1), mode);
} else {
// calculate index in register to avoid integer overflow (int_cnt2*2)
movl(tmp, int_cnt2);
addptr(tmp, cnt2);
- movdqu(vec, Address(str2, tmp, Address::times_2, 0));
- pcmpestri(vec, Address(result, tmp, Address::times_2, 0), 0x0d);
+ if (ae == StrIntrinsicNode::UL) {
+ pmovzxbw(vec, Address(str2, tmp, scale2, 0));
+ } else {
+ movdqu(vec, Address(str2, tmp, scale2, 0));
+ }
+ pcmpestri(vec, Address(result, tmp, scale1, 0), mode);
}
// Need to reload strings pointers if not matched whole vector
jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
- addptr(cnt2, 8);
+ addptr(cnt2, stride);
jcc(Assembler::negative, SCAN_SUBSTR);
// Fall through if found full substring
@@ -6446,7 +6476,9 @@
// Found result if we matched full small substring.
// Compute substr offset
subptr(result, str1);
- shrl(result, 1); // index
+ if (ae == StrIntrinsicNode::UU || ae == StrIntrinsicNode::UL) {
+ shrl(result, 1); // index
+ }
bind(EXIT);
} // string_indexofC8
@@ -6455,9 +6487,12 @@
void MacroAssembler::string_indexof(Register str1, Register str2,
Register cnt1, Register cnt2,
int int_cnt2, Register result,
- XMMRegister vec, Register tmp) {
+ XMMRegister vec, Register tmp,
+ int ae) {
ShortBranchVerifier sbv(this);
assert(UseSSE42Intrinsics, "SSE4.2 is required");
+ assert(ae != StrIntrinsicNode::LU, "Invalid encoding");
+
//
// int_cnt2 is length of small (< 8 chars) constant substring
// or (-1) for non constant substring in which case its length
@@ -6467,18 +6502,22 @@
// if (substr.count > string.count) return -1;
// if (substr.count == 0) return 0;
//
- assert(int_cnt2 == -1 || (0 < int_cnt2 && int_cnt2 < 8), "should be != 0");
-
- // This method uses pcmpestri instruction with bound registers
+ int stride = (ae == StrIntrinsicNode::LL) ? 16 : 8; //UU, UL -> 8
+ assert(int_cnt2 == -1 || (0 < int_cnt2 && int_cnt2 < stride), "should be != 0");
+ // This method uses the pcmpestri instruction with bound registers
// inputs:
// xmm - substring
// rax - substring length (elements count)
// mem - scanned string
// rdx - string length (elements count)
// 0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
+ // 0xc - mode: 1100 (substring search) + 00 (unsigned bytes)
// outputs:
// rcx - matched index in string
assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
+ int mode = (ae == StrIntrinsicNode::LL) ? 0x0c : 0x0d; // bytes or shorts
+ Address::ScaleFactor scale1 = (ae == StrIntrinsicNode::LL) ? Address::times_1 : Address::times_2;
+ Address::ScaleFactor scale2 = (ae == StrIntrinsicNode::UL) ? Address::times_1 : scale1;
Label RELOAD_SUBSTR, SCAN_TO_SUBSTR, SCAN_SUBSTR, ADJUST_STR,
RET_FOUND, RET_NOT_FOUND, CLEANUP, FOUND_SUBSTR,
@@ -6492,23 +6531,40 @@
movptr(tmp, rsp); // save old SP
if (int_cnt2 > 0) { // small (< 8 chars) constant substring
- if (int_cnt2 == 1) { // One char
+ if (int_cnt2 == (1>>scale2)) { // One byte
+ assert((ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UL), "Only possible for latin1 encoding");
+ load_unsigned_byte(result, Address(str2, 0));
+ movdl(vec, result); // move 32 bits
+ } else if (ae == StrIntrinsicNode::LL && int_cnt2 == 3) { // Three bytes
+ // Not enough header space in 32-bit VM: 12+3 = 15.
+ movl(result, Address(str2, -1));
+ shrl(result, 8);
+ movdl(vec, result); // move 32 bits
+ } else if (ae != StrIntrinsicNode::UL && int_cnt2 == (2>>scale2)) { // One char
load_unsigned_short(result, Address(str2, 0));
movdl(vec, result); // move 32 bits
- } else if (int_cnt2 == 2) { // Two chars
+ } else if (ae != StrIntrinsicNode::UL && int_cnt2 == (4>>scale2)) { // Two chars
movdl(vec, Address(str2, 0)); // move 32 bits
- } else if (int_cnt2 == 4) { // Four chars
+ } else if (ae != StrIntrinsicNode::UL && int_cnt2 == (8>>scale2)) { // Four chars
movq(vec, Address(str2, 0)); // move 64 bits
- } else { // cnt2 = { 3, 5, 6, 7 }
+ } else { // cnt2 = { 3, 5, 6, 7 } || (ae == StrIntrinsicNode::UL && cnt2 ={2, ..., 7})
// Array header size is 12 bytes in 32-bit VM
// + 6 bytes for 3 chars == 18 bytes,
// enough space to load vec and shift.
assert(HeapWordSize*TypeArrayKlass::header_size() >= 12,"sanity");
- movdqu(vec, Address(str2, (int_cnt2*2)-16));
- psrldq(vec, 16-(int_cnt2*2));
+ if (ae == StrIntrinsicNode::UL) {
+ int tail_off = int_cnt2-8;
+ pmovzxbw(vec, Address(str2, tail_off));
+ psrldq(vec, -2*tail_off);
+ }
+ else {
+ int tail_off = int_cnt2*(1<<scale2);
+ movdqu(vec, Address(str2, tail_off-16));
+ psrldq(vec, 16-tail_off);
+ }
}
} else { // not constant substring
- cmpl(cnt2, 8);
+ cmpl(cnt2, stride);
jccb(Assembler::aboveEqual, BIG_STRINGS); // Both strings are big enough
// We can read beyond string if srt+16 does not cross page boundary
@@ -6521,12 +6577,17 @@
// Move small strings to stack to allow load 16 bytes into vec.
subptr(rsp, 16);
- int stk_offset = wordSize-2;
+ int stk_offset = wordSize-(1<<scale2);
push(cnt2);
bind(COPY_SUBSTR);
- load_unsigned_short(result, Address(str2, cnt2, Address::times_2, -2));
- movw(Address(rsp, cnt2, Address::times_2, stk_offset), result);
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UL) {
+ load_unsigned_byte(result, Address(str2, cnt2, scale2, -1));
+ movb(Address(rsp, cnt2, scale2, stk_offset), result);
+ } else if (ae == StrIntrinsicNode::UU) {
+ load_unsigned_short(result, Address(str2, cnt2, scale2, -2));
+ movw(Address(rsp, cnt2, scale2, stk_offset), result);
+ }
decrement(cnt2);
jccb(Assembler::notZero, COPY_SUBSTR);
@@ -6535,7 +6596,7 @@
} // non constant
bind(CHECK_STR);
- cmpl(cnt1, 8);
+ cmpl(cnt1, stride);
jccb(Assembler::aboveEqual, BIG_STRINGS);
// Check cross page boundary.
@@ -6545,7 +6606,7 @@
jccb(Assembler::belowEqual, BIG_STRINGS);
subptr(rsp, 16);
- int stk_offset = -2;
+ int stk_offset = -(1<<scale1);
if (int_cnt2 < 0) { // not constant
push(cnt2);
stk_offset += wordSize;
@@ -6553,8 +6614,13 @@
movl(cnt2, cnt1);
bind(COPY_STR);
- load_unsigned_short(result, Address(str1, cnt2, Address::times_2, -2));
- movw(Address(rsp, cnt2, Address::times_2, stk_offset), result);
+ if (ae == StrIntrinsicNode::LL) {
+ load_unsigned_byte(result, Address(str1, cnt2, scale1, -1));
+ movb(Address(rsp, cnt2, scale1, stk_offset), result);
+ } else {
+ load_unsigned_short(result, Address(str1, cnt2, scale1, -2));
+ movw(Address(rsp, cnt2, scale1, stk_offset), result);
+ }
decrement(cnt2);
jccb(Assembler::notZero, COPY_STR);
@@ -6566,7 +6632,11 @@
bind(BIG_STRINGS);
// Load substring.
if (int_cnt2 < 0) { // -1
- movdqu(vec, Address(str2, 0));
+ if (ae == StrIntrinsicNode::UL) {
+ pmovzxbw(vec, Address(str2, 0));
+ } else {
+ movdqu(vec, Address(str2, 0));
+ }
push(cnt2); // substr count
push(str2); // substr addr
push(str1); // string addr
@@ -6597,37 +6667,43 @@
bind(RELOAD_SUBSTR);
movptr(str2, Address(rsp, 2*wordSize));
movl(cnt2, Address(rsp, 3*wordSize));
- movdqu(vec, Address(str2, 0));
+ if (ae == StrIntrinsicNode::UL) {
+ pmovzxbw(vec, Address(str2, 0));
+ } else {
+ movdqu(vec, Address(str2, 0));
+ }
// We came here after the beginning of the substring was
// matched but the rest of it was not so we need to search
// again. Start from the next element after the previous match.
subptr(str1, result); // Restore counter
- shrl(str1, 1);
+ if (ae == StrIntrinsicNode::UU || ae == StrIntrinsicNode::UL) {
+ shrl(str1, 1);
+ }
addl(cnt1, str1);
decrementl(cnt1); // Shift to next element
cmpl(cnt1, cnt2);
jccb(Assembler::negative, RET_NOT_FOUND); // Left less then substring
- addptr(result, 2);
+ addptr(result, (1<<scale1));
} // non constant
// Scan string for start of substr in 16-byte vectors
bind(SCAN_TO_SUBSTR);
assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
- pcmpestri(vec, Address(result, 0), 0x0d);
+ pcmpestri(vec, Address(result, 0), mode);
jccb(Assembler::below, FOUND_CANDIDATE); // CF == 1
- subl(cnt1, 8);
+ subl(cnt1, stride);
jccb(Assembler::lessEqual, RET_NOT_FOUND); // Scanned full string
cmpl(cnt1, cnt2);
jccb(Assembler::negative, RET_NOT_FOUND); // Left less then substring
addptr(result, 16);
bind(ADJUST_STR);
- cmpl(cnt1, 8); // Do not read beyond string
+ cmpl(cnt1, stride); // Do not read beyond string
jccb(Assembler::greaterEqual, SCAN_TO_SUBSTR);
// Back-up string to avoid reading beyond string.
- lea(result, Address(result, cnt1, Address::times_2, -16));
- movl(cnt1, 8);
+ lea(result, Address(result, cnt1, scale1, -16));
+ movl(cnt1, stride);
jmpb(SCAN_TO_SUBSTR);
// Found a potential substr
@@ -6646,13 +6722,12 @@
bind(FOUND_SUBSTR);
// Compute start addr of substr
- lea(result, Address(result, tmp, Address::times_2));
-
+ lea(result, Address(result, tmp, scale1));
if (int_cnt2 > 0) { // Constant substring
// Repeat search for small substring (< 8 chars)
// from new point without reloading substring.
// Have to check that we don't read beyond string.
- cmpl(tmp, 8-int_cnt2);
+ cmpl(tmp, stride-int_cnt2);
jccb(Assembler::greater, ADJUST_STR);
// Fall through if matched whole substring.
} else { // non constant
@@ -6660,12 +6735,12 @@
addl(tmp, cnt2);
// Found result if we matched whole substring.
- cmpl(tmp, 8);
+ cmpl(tmp, stride);
jccb(Assembler::lessEqual, RET_FOUND);
// Repeat search for small substring (<= 8 chars)
// from new point 'str1' without reloading substring.
- cmpl(cnt2, 8);
+ cmpl(cnt2, stride);
// Have to check that we don't read beyond string.
jccb(Assembler::lessEqual, ADJUST_STR);
@@ -6678,26 +6753,40 @@
jccb(Assembler::equal, CHECK_NEXT);
bind(SCAN_SUBSTR);
- pcmpestri(vec, Address(str1, 0), 0x0d);
+ pcmpestri(vec, Address(str1, 0), mode);
// Need to reload strings pointers if not matched whole vector
jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
bind(CHECK_NEXT);
- subl(cnt2, 8);
+ subl(cnt2, stride);
jccb(Assembler::lessEqual, RET_FOUND_LONG); // Found full substring
addptr(str1, 16);
- addptr(str2, 16);
- subl(cnt1, 8);
- cmpl(cnt2, 8); // Do not read beyond substring
+ if (ae == StrIntrinsicNode::UL) {
+ addptr(str2, 8);
+ } else {
+ addptr(str2, 16);
+ }
+ subl(cnt1, stride);
+ cmpl(cnt2, stride); // Do not read beyond substring
jccb(Assembler::greaterEqual, CONT_SCAN_SUBSTR);
// Back-up strings to avoid reading beyond substring.
- lea(str2, Address(str2, cnt2, Address::times_2, -16));
- lea(str1, Address(str1, cnt2, Address::times_2, -16));
+
+ if (ae == StrIntrinsicNode::UL) {
+ lea(str2, Address(str2, cnt2, scale2, -8));
+ lea(str1, Address(str1, cnt2, scale1, -16));
+ } else {
+ lea(str2, Address(str2, cnt2, scale2, -16));
+ lea(str1, Address(str1, cnt2, scale1, -16));
+ }
subl(cnt1, cnt2);
- movl(cnt2, 8);
- addl(cnt1, 8);
+ movl(cnt2, stride);
+ addl(cnt1, stride);
bind(CONT_SCAN_SUBSTR);
- movdqu(vec, Address(str2, 0));
+ if (ae == StrIntrinsicNode::UL) {
+ pmovzxbw(vec, Address(str2, 0));
+ } else {
+ movdqu(vec, Address(str2, 0));
+ }
jmpb(SCAN_SUBSTR);
bind(RET_FOUND_LONG);
@@ -6707,20 +6796,143 @@
bind(RET_FOUND);
// Compute substr offset
subptr(result, str1);
- shrl(result, 1); // index
-
+ if (ae == StrIntrinsicNode::UU || ae == StrIntrinsicNode::UL) {
+ shrl(result, 1); // index
+ }
bind(CLEANUP);
pop(rsp); // restore SP
} // string_indexof
-// Compare strings.
+void MacroAssembler::string_indexof_char(Register str1, Register cnt1, Register ch, Register result,
+ XMMRegister vec1, XMMRegister vec2, XMMRegister vec3, Register tmp) {
+ ShortBranchVerifier sbv(this);
+ assert(UseSSE42Intrinsics, "SSE4.2 is required");
+
+ int stride = 8;
+
+ Label FOUND_CHAR, SCAN_TO_CHAR, SCAN_TO_CHAR_LOOP,
+ SCAN_TO_8_CHAR, SCAN_TO_8_CHAR_LOOP, SCAN_TO_16_CHAR_LOOP,
+ RET_NOT_FOUND, SCAN_TO_8_CHAR_INIT,
+ FOUND_SEQ_CHAR, DONE_LABEL;
+
+ movptr(result, str1);
+ if (UseAVX >= 2) {
+ cmpl(cnt1, stride);
+ jccb(Assembler::less, SCAN_TO_CHAR_LOOP);
+ cmpl(cnt1, 2*stride);
+ jccb(Assembler::less, SCAN_TO_8_CHAR_INIT);
+ movdl(vec1, ch);
+ vpbroadcastw(vec1, vec1);
+ vpxor(vec2, vec2);
+ movl(tmp, cnt1);
+ andl(tmp, 0xFFFFFFF0); //vector count (in chars)
+ andl(cnt1,0x0000000F); //tail count (in chars)
+
+ bind(SCAN_TO_16_CHAR_LOOP);
+ vmovdqu(vec3, Address(result, 0));
+ vpcmpeqw(vec3, vec3, vec1, true);
+ vptest(vec2, vec3);
+ jcc(Assembler::carryClear, FOUND_CHAR);
+ addptr(result, 32);
+ subl(tmp, 2*stride);
+ jccb(Assembler::notZero, SCAN_TO_16_CHAR_LOOP);
+ jmp(SCAN_TO_8_CHAR);
+ bind(SCAN_TO_8_CHAR_INIT);
+ movdl(vec1, ch);
+ pshuflw(vec1, vec1, 0x00);
+ pshufd(vec1, vec1, 0);
+ pxor(vec2, vec2);
+ }
+ if (UseAVX >= 2 || UseSSE42Intrinsics) {
+ bind(SCAN_TO_8_CHAR);
+ cmpl(cnt1, stride);
+ if (UseAVX >= 2) {
+ jccb(Assembler::less, SCAN_TO_CHAR);
+ }
+ if (!(UseAVX >= 2)) {
+ jccb(Assembler::less, SCAN_TO_CHAR_LOOP);
+ movdl(vec1, ch);
+ pshuflw(vec1, vec1, 0x00);
+ pshufd(vec1, vec1, 0);
+ pxor(vec2, vec2);
+ }
+ movl(tmp, cnt1);
+ andl(tmp, 0xFFFFFFF8); //vector count (in chars)
+ andl(cnt1,0x00000007); //tail count (in chars)
+
+ bind(SCAN_TO_8_CHAR_LOOP);
+ movdqu(vec3, Address(result, 0));
+ pcmpeqw(vec3, vec1);
+ ptest(vec2, vec3);
+ jcc(Assembler::carryClear, FOUND_CHAR);
+ addptr(result, 16);
+ subl(tmp, stride);
+ jccb(Assembler::notZero, SCAN_TO_8_CHAR_LOOP);
+ }
+ bind(SCAN_TO_CHAR);
+ testl(cnt1, cnt1);
+ jcc(Assembler::zero, RET_NOT_FOUND);
+
+ bind(SCAN_TO_CHAR_LOOP);
+ load_unsigned_short(tmp, Address(result, 0));
+ cmpl(ch, tmp);
+ jccb(Assembler::equal, FOUND_SEQ_CHAR);
+ addptr(result, 2);
+ subl(cnt1, 1);
+ jccb(Assembler::zero, RET_NOT_FOUND);
+ jmp(SCAN_TO_CHAR_LOOP);
+
+ bind(RET_NOT_FOUND);
+ movl(result, -1);
+ jmpb(DONE_LABEL);
+
+ if (UseAVX >= 2 || UseSSE42Intrinsics) {
+ bind(FOUND_CHAR);
+ if (UseAVX >= 2) {
+ vpmovmskb(tmp, vec3);
+ } else {
+ pmovmskb(tmp, vec3);
+ }
+ bsfl(ch, tmp);
+ addl(result, ch);
+ }
+
+ bind(FOUND_SEQ_CHAR);
+ subptr(result, str1);
+ shrl(result, 1);
+
+ bind(DONE_LABEL);
+} // string_indexof_char
+
+// helper function for string_compare
+void MacroAssembler::load_next_elements(Register elem1, Register elem2, Register str1, Register str2,
+ Address::ScaleFactor scale, Address::ScaleFactor scale1,
+ Address::ScaleFactor scale2, Register index, int ae) {
+ if (ae == StrIntrinsicNode::LL) {
+ load_unsigned_byte(elem1, Address(str1, index, scale, 0));
+ load_unsigned_byte(elem2, Address(str2, index, scale, 0));
+ } else if (ae == StrIntrinsicNode::UU) {
+ load_unsigned_short(elem1, Address(str1, index, scale, 0));
+ load_unsigned_short(elem2, Address(str2, index, scale, 0));
+ } else {
+ load_unsigned_byte(elem1, Address(str1, index, scale1, 0));
+ load_unsigned_short(elem2, Address(str2, index, scale2, 0));
+ }
+}
+
+// Compare strings, used for char[] and byte[].
void MacroAssembler::string_compare(Register str1, Register str2,
Register cnt1, Register cnt2, Register result,
- XMMRegister vec1) {
+ XMMRegister vec1, int ae) {
ShortBranchVerifier sbv(this);
Label LENGTH_DIFF_LABEL, POP_LABEL, DONE_LABEL, WHILE_HEAD_LABEL;
-
+ int stride, stride2, adr_stride, adr_stride1, adr_stride2;
+ Address::ScaleFactor scale, scale1, scale2;
+
+ if (ae == StrIntrinsicNode::LU || ae == StrIntrinsicNode::UL) {
+ shrl(cnt2, 1);
+ }
// Compute the minimum of the string lengths and the
// difference of the string lengths (stack).
// Do the conditional move stuff
@@ -6732,32 +6944,68 @@
// Is the minimum length zero?
testl(cnt2, cnt2);
jcc(Assembler::zero, LENGTH_DIFF_LABEL);
-
- // Compare first characters
- load_unsigned_short(result, Address(str1, 0));
- load_unsigned_short(cnt1, Address(str2, 0));
+ if (ae == StrIntrinsicNode::LL) {
+ // Load first bytes
+ load_unsigned_byte(result, Address(str1, 0));
+ load_unsigned_byte(cnt1, Address(str2, 0));
+ } else if (ae == StrIntrinsicNode::UU) {
+ // Load first characters
+ load_unsigned_short(result, Address(str1, 0));
+ load_unsigned_short(cnt1, Address(str2, 0));
+ } else {
+ load_unsigned_byte(result, Address(str1, 0));
+ load_unsigned_short(cnt1, Address(str2, 0));
+ }
subl(result, cnt1);
jcc(Assembler::notZero, POP_LABEL);
+
+ if (ae == StrIntrinsicNode::UU) {
+ // Divide length by 2 to get number of chars
+ shrl(cnt2, 1);
+ }
cmpl(cnt2, 1);
jcc(Assembler::equal, LENGTH_DIFF_LABEL);
- // Check if the strings start at the same location.
- cmpptr(str1, str2);
- jcc(Assembler::equal, LENGTH_DIFF_LABEL);
-
- Address::ScaleFactor scale = Address::times_2;
- int stride = 8;
+ // Check if the strings start at the same location and setup scale and stride
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ cmpptr(str1, str2);
+ jcc(Assembler::equal, LENGTH_DIFF_LABEL);
+ if (ae == StrIntrinsicNode::LL) {
+ scale = Address::times_1;
+ stride = 16;
+ } else {
+ scale = Address::times_2;
+ stride = 8;
+ }
+ } else {
+ scale = Address::no_scale; // not used
+ scale1 = Address::times_1;
+ scale2 = Address::times_2;
+ stride = 8;
+ }
if (UseAVX >= 2 && UseSSE42Intrinsics) {
Label COMPARE_WIDE_VECTORS, VECTOR_NOT_EQUAL, COMPARE_WIDE_TAIL, COMPARE_SMALL_STR;
Label COMPARE_WIDE_VECTORS_LOOP, COMPARE_16_CHARS, COMPARE_INDEX_CHAR;
Label COMPARE_TAIL_LONG;
int pcmpmask = 0x19;
+ if (ae == StrIntrinsicNode::LL) {
+ pcmpmask &= ~0x01;
+ }
// Setup to compare 16-chars (32-bytes) vectors,
// start from first character again because it has aligned address.
- int stride2 = 16;
- int adr_stride = stride << scale;
+ if (ae == StrIntrinsicNode::LL) {
+ stride2 = 32;
+ } else {
+ stride2 = 16;
+ }
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ adr_stride = stride << scale;
+ } else {
+ adr_stride1 = 8; //stride << scale1;
+ adr_stride2 = 16; //stride << scale2;
+ }
assert(result == rax && cnt2 == rdx && cnt1 == rcx, "pcmpestri");
// rax and rdx are used by pcmpestri as elements counters
@@ -6767,26 +7015,39 @@
// fast path : compare first 2 8-char vectors.
bind(COMPARE_16_CHARS);
- movdqu(vec1, Address(str1, 0));
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ movdqu(vec1, Address(str1, 0));
+ } else {
+ pmovzxbw(vec1, Address(str1, 0));
+ }
pcmpestri(vec1, Address(str2, 0), pcmpmask);
jccb(Assembler::below, COMPARE_INDEX_CHAR);
- movdqu(vec1, Address(str1, adr_stride));
- pcmpestri(vec1, Address(str2, adr_stride), pcmpmask);
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ movdqu(vec1, Address(str1, adr_stride));
+ pcmpestri(vec1, Address(str2, adr_stride), pcmpmask);
+ } else {
+ pmovzxbw(vec1, Address(str1, adr_stride1));
+ pcmpestri(vec1, Address(str2, adr_stride2), pcmpmask);
+ }
jccb(Assembler::aboveEqual, COMPARE_WIDE_VECTORS);
addl(cnt1, stride);
// Compare the characters at index in cnt1
- bind(COMPARE_INDEX_CHAR); //cnt1 has the offset of the mismatching character
- load_unsigned_short(result, Address(str1, cnt1, scale));
- load_unsigned_short(cnt2, Address(str2, cnt1, scale));
+ bind(COMPARE_INDEX_CHAR); // cnt1 has the offset of the mismatching character
+ load_next_elements(result, cnt2, str1, str2, scale, scale1, scale2, cnt1, ae);
subl(result, cnt2);
jmp(POP_LABEL);
// Setup the registers to start vector comparison loop
bind(COMPARE_WIDE_VECTORS);
- lea(str1, Address(str1, result, scale));
- lea(str2, Address(str2, result, scale));
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ lea(str1, Address(str1, result, scale));
+ lea(str2, Address(str2, result, scale));
+ } else {
+ lea(str1, Address(str1, result, scale1));
+ lea(str2, Address(str2, result, scale2));
+ }
subl(result, stride2);
subl(cnt2, stride2);
jccb(Assembler::zero, COMPARE_WIDE_TAIL);
@@ -6794,8 +7055,13 @@
// In a loop, compare 16-chars (32-bytes) at once using (vpxor+vptest)
bind(COMPARE_WIDE_VECTORS_LOOP);
- vmovdqu(vec1, Address(str1, result, scale));
- vpxor(vec1, Address(str2, result, scale));
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ vmovdqu(vec1, Address(str1, result, scale));
+ vpxor(vec1, Address(str2, result, scale));
+ } else {
+ vpmovzxbw(vec1, Address(str1, result, scale1));
+ vpxor(vec1, Address(str2, result, scale2));
+ }
vptest(vec1, vec1);
jccb(Assembler::notZero, VECTOR_NOT_EQUAL);
addptr(result, stride2);
@@ -6818,8 +7084,13 @@
bind(VECTOR_NOT_EQUAL);
// clean upper bits of YMM registers
vpxor(vec1, vec1);
- lea(str1, Address(str1, result, scale));
- lea(str2, Address(str2, result, scale));
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ lea(str1, Address(str1, result, scale));
+ lea(str2, Address(str2, result, scale));
+ } else {
+ lea(str1, Address(str1, result, scale1));
+ lea(str2, Address(str2, result, scale2));
+ }
jmp(COMPARE_16_CHARS);
// Compare tail chars, length between 1 to 15 chars
@@ -6828,13 +7099,22 @@
cmpl(cnt2, stride);
jccb(Assembler::less, COMPARE_SMALL_STR);
- movdqu(vec1, Address(str1, 0));
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ movdqu(vec1, Address(str1, 0));
+ } else {
+ pmovzxbw(vec1, Address(str1, 0));
+ }
pcmpestri(vec1, Address(str2, 0), pcmpmask);
jcc(Assembler::below, COMPARE_INDEX_CHAR);
subptr(cnt2, stride);
jccb(Assembler::zero, LENGTH_DIFF_LABEL);
- lea(str1, Address(str1, result, scale));
- lea(str2, Address(str2, result, scale));
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ lea(str1, Address(str1, result, scale));
+ lea(str2, Address(str2, result, scale));
+ } else {
+ lea(str1, Address(str1, result, scale1));
+ lea(str2, Address(str2, result, scale2));
+ }
negptr(cnt2);
jmpb(WHILE_HEAD_LABEL);
@@ -6846,10 +7126,17 @@
// start from first character again because it has aligned address.
movl(result, cnt2);
andl(cnt2, ~(stride - 1)); // cnt2 holds the vector count
+ if (ae == StrIntrinsicNode::LL) {
+ pcmpmask &= ~0x01;
+ }
jccb(Assembler::zero, COMPARE_TAIL);
-
- lea(str1, Address(str1, result, scale));
- lea(str2, Address(str2, result, scale));
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ lea(str1, Address(str1, result, scale));
+ lea(str2, Address(str2, result, scale));
+ } else {
+ lea(str1, Address(str1, result, scale1));
+ lea(str2, Address(str2, result, scale2));
+ }
negptr(result);
// pcmpestri
@@ -6865,8 +7152,13 @@
assert(result == rax && cnt2 == rdx && cnt1 == rcx, "pcmpestri");
bind(COMPARE_WIDE_VECTORS);
- movdqu(vec1, Address(str1, result, scale));
- pcmpestri(vec1, Address(str2, result, scale), pcmpmask);
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ movdqu(vec1, Address(str1, result, scale));
+ pcmpestri(vec1, Address(str2, result, scale), pcmpmask);
+ } else {
+ pmovzxbw(vec1, Address(str1, result, scale1));
+ pcmpestri(vec1, Address(str2, result, scale2), pcmpmask);
+ }
// After pcmpestri cnt1(rcx) contains mismatched element index
jccb(Assembler::below, VECTOR_NOT_EQUAL); // CF==1
@@ -6881,15 +7173,19 @@
movl(cnt2, stride);
movl(result, stride);
negptr(result);
- movdqu(vec1, Address(str1, result, scale));
- pcmpestri(vec1, Address(str2, result, scale), pcmpmask);
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ movdqu(vec1, Address(str1, result, scale));
+ pcmpestri(vec1, Address(str2, result, scale), pcmpmask);
+ } else {
+ pmovzxbw(vec1, Address(str1, result, scale1));
+ pcmpestri(vec1, Address(str2, result, scale2), pcmpmask);
+ }
jccb(Assembler::aboveEqual, LENGTH_DIFF_LABEL);
// Mismatched characters in the vectors
bind(VECTOR_NOT_EQUAL);
addptr(cnt1, result);
- load_unsigned_short(result, Address(str1, cnt1, scale));
- load_unsigned_short(cnt2, Address(str2, cnt1, scale));
+ load_next_elements(result, cnt2, str1, str2, scale, scale1, scale2, cnt1, ae);
subl(result, cnt2);
jmpb(POP_LABEL);
@@ -6898,15 +7194,19 @@
// Fallthru to tail compare
}
// Shift str2 and str1 to the end of the arrays, negate min
- lea(str1, Address(str1, cnt2, scale));
- lea(str2, Address(str2, cnt2, scale));
+ if (ae == StrIntrinsicNode::LL || ae == StrIntrinsicNode::UU) {
+ lea(str1, Address(str1, cnt2, scale));
+ lea(str2, Address(str2, cnt2, scale));
+ } else {
+ lea(str1, Address(str1, cnt2, scale1));
+ lea(str2, Address(str2, cnt2, scale2));
+ }
decrementl(cnt2); // first character was compared already
negptr(cnt2);
// Compare the rest of the elements
bind(WHILE_HEAD_LABEL);
- load_unsigned_short(result, Address(str1, cnt2, scale, 0));
- load_unsigned_short(cnt1, Address(str2, cnt2, scale, 0));
+ load_next_elements(result, cnt1, str1, str2, scale, scale1, scale2, cnt2, ae);
subl(result, cnt1);
jccb(Assembler::notZero, POP_LABEL);
increment(cnt2);
@@ -6915,6 +7215,10 @@
// Strings are equal up to min length. Return the length difference.
bind(LENGTH_DIFF_LABEL);
pop(result);
+ if (ae == StrIntrinsicNode::UU) {
+ // Divide diff by 2 to get number of chars
+ sarl(result, 1);
+ }
jmpb(DONE_LABEL);
// Discard the stored length difference
@@ -6923,23 +7227,164 @@
// That's it
bind(DONE_LABEL);
-}
-
-// Compare char[] arrays aligned to 4 bytes or substrings.
-void MacroAssembler::char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
- Register limit, Register result, Register chr,
- XMMRegister vec1, XMMRegister vec2) {
+ if(ae == StrIntrinsicNode::UL) {
+ negl(result);
+ }
+}
+
+// Search for Non-ASCII character (Negative byte value) in a byte array,
+// return true if it has any and false otherwise.
+void MacroAssembler::has_negatives(Register ary1, Register len,
+ Register result, Register tmp1,
+ XMMRegister vec1, XMMRegister vec2) {
+
+ // rsi: byte array
+ // rcx: len
+ // rax: result
ShortBranchVerifier sbv(this);
- Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR;
+ assert_different_registers(ary1, len, result, tmp1);
+ assert_different_registers(vec1, vec2);
+ Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_CHAR, COMPARE_VECTORS, COMPARE_BYTE;
+
+ // len == 0
+ testl(len, len);
+ jcc(Assembler::zero, FALSE_LABEL);
+
+ movl(result, len); // copy
+
+ if (UseAVX >= 2) {
+ // With AVX2, use 32-byte vector compare
+ Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
+
+ // Compare 32-byte vectors
+ andl(result, 0x0000001f); // tail count (in bytes)
+ andl(len, 0xffffffe0); // vector count (in bytes)
+ jccb(Assembler::zero, COMPARE_TAIL);
+
+ lea(ary1, Address(ary1, len, Address::times_1));
+ negptr(len);
+
+ movl(tmp1, 0x80808080); // create mask to test for Unicode chars in vector
+ movdl(vec2, tmp1);
+ vpbroadcastd(vec2, vec2);
+
+ bind(COMPARE_WIDE_VECTORS);
+ vmovdqu(vec1, Address(ary1, len, Address::times_1));
+ vptest(vec1, vec2);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ addptr(len, 32);
+ jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
+
+ testl(result, result);
+ jccb(Assembler::zero, FALSE_LABEL);
+
+ vmovdqu(vec1, Address(ary1, result, Address::times_1, -32));
+ vptest(vec1, vec2);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ jmpb(FALSE_LABEL);
+
+ bind(COMPARE_TAIL); // len is zero
+ movl(len, result);
+ // Fallthru to tail compare
+ } else if (UseSSE42Intrinsics) {
+ // With SSE4.2, use double quad vector compare
+ Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
+
+ // Compare 16-byte vectors
+ andl(result, 0x0000000f); // tail count (in bytes)
+ andl(len, 0xfffffff0); // vector count (in bytes)
+ jccb(Assembler::zero, COMPARE_TAIL);
+
+ lea(ary1, Address(ary1, len, Address::times_1));
+ negptr(len);
+
+ movl(tmp1, 0x80808080);
+ movdl(vec2, tmp1);
+ pshufd(vec2, vec2, 0);
+
+ bind(COMPARE_WIDE_VECTORS);
+ movdqu(vec1, Address(ary1, len, Address::times_1));
+ ptest(vec1, vec2);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ addptr(len, 16);
+ jcc(Assembler::notZero, COMPARE_WIDE_VECTORS);
+
+ testl(result, result);
+ jccb(Assembler::zero, FALSE_LABEL);
+
+ movdqu(vec1, Address(ary1, result, Address::times_1, -16));
+ ptest(vec1, vec2);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ jmpb(FALSE_LABEL);
+
+ bind(COMPARE_TAIL); // len is zero
+ movl(len, result);
+ // Fallthru to tail compare
+ }
+
+ // Compare 4-byte vectors
+ andl(len, 0xfffffffc); // vector count (in bytes)
+ jccb(Assembler::zero, COMPARE_CHAR);
+
+ lea(ary1, Address(ary1, len, Address::times_1));
+ negptr(len);
+
+ bind(COMPARE_VECTORS);
+ movl(tmp1, Address(ary1, len, Address::times_1));
+ andl(tmp1, 0x80808080);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ addptr(len, 4);
+ jcc(Assembler::notZero, COMPARE_VECTORS);
+
+ // Compare trailing char (final 2 bytes), if any
+ bind(COMPARE_CHAR);
+ testl(result, 0x2); // tail char
+ jccb(Assembler::zero, COMPARE_BYTE);
+ load_unsigned_short(tmp1, Address(ary1, 0));
+ andl(tmp1, 0x00008080);
+ jccb(Assembler::notZero, TRUE_LABEL);
+ subptr(result, 2);
+ lea(ary1, Address(ary1, 2));
+
+ bind(COMPARE_BYTE);
+ testl(result, 0x1); // tail byte
+ jccb(Assembler::zero, FALSE_LABEL);
+ load_unsigned_byte(tmp1, Address(ary1, 0));
+ andl(tmp1, 0x00000080);
+ jccb(Assembler::notEqual, TRUE_LABEL);
+ jmpb(FALSE_LABEL);
+
+ bind(TRUE_LABEL);
+ movl(result, 1); // return true
+ jmpb(DONE);
+
+ bind(FALSE_LABEL);
+ xorl(result, result); // return false
+
+ // That's it
+ bind(DONE);
+ if (UseAVX >= 2) {
+ // clean upper bits of YMM registers
+ vpxor(vec1, vec1);
+ vpxor(vec2, vec2);
+ }
+}
+
+// Compare char[] or byte[] arrays aligned to 4 bytes or substrings.
+void MacroAssembler::arrays_equals(bool is_array_equ, Register ary1, Register ary2,
+ Register limit, Register result, Register chr,
+ XMMRegister vec1, XMMRegister vec2, bool is_char) {
+ ShortBranchVerifier sbv(this);
+ Label TRUE_LABEL, FALSE_LABEL, DONE, COMPARE_VECTORS, COMPARE_CHAR, COMPARE_BYTE;
int length_offset = arrayOopDesc::length_offset_in_bytes();
- int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
-
- // Check the input args
- cmpptr(ary1, ary2);
- jcc(Assembler::equal, TRUE_LABEL);
+ int base_offset = arrayOopDesc::base_offset_in_bytes(is_char ? T_CHAR : T_BYTE);
if (is_array_equ) {
+ // Check the input args
+ cmpptr(ary1, ary2);
+ jcc(Assembler::equal, TRUE_LABEL);
+
// Need additional checks for arrays_equals.
testptr(ary1, ary1);
jcc(Assembler::zero, FALSE_LABEL);
@@ -6962,7 +7407,10 @@
lea(ary2, Address(ary2, base_offset));
}
- shll(limit, 1); // byte count != 0
+ if (is_array_equ && is_char) {
+ // arrays_equals when used for char[].
+ shll(limit, 1); // byte count != 0
+ }
movl(result, limit); // copy
if (UseAVX >= 2) {
@@ -6970,7 +7418,7 @@
Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
// Compare 32-byte vectors
- andl(result, 0x0000001e); // tail count (in bytes)
+ andl(result, 0x0000001f); // tail count (in bytes)
andl(limit, 0xffffffe0); // vector count (in bytes)
jccb(Assembler::zero, COMPARE_TAIL);
@@ -7007,7 +7455,7 @@
Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
// Compare 16-byte vectors
- andl(result, 0x0000000e); // tail count (in bytes)
+ andl(result, 0x0000000f); // tail count (in bytes)
andl(limit, 0xfffffff0); // vector count (in bytes)
jccb(Assembler::zero, COMPARE_TAIL);
@@ -7059,12 +7507,26 @@
// Compare trailing char (final 2 bytes), if any
bind(COMPARE_CHAR);
testl(result, 0x2); // tail char
- jccb(Assembler::zero, TRUE_LABEL);
+ jccb(Assembler::zero, COMPARE_BYTE);
load_unsigned_short(chr, Address(ary1, 0));
load_unsigned_short(limit, Address(ary2, 0));
cmpl(chr, limit);
jccb(Assembler::notEqual, FALSE_LABEL);
+ if (is_array_equ && is_char) {
+ bind(COMPARE_BYTE);
+ } else {
+ lea(ary1, Address(ary1, 2));
+ lea(ary2, Address(ary2, 2));
+
+ bind(COMPARE_BYTE);
+ testl(result, 0x1); // tail byte
+ jccb(Assembler::zero, TRUE_LABEL);
+ load_unsigned_byte(chr, Address(ary1, 0));
+ load_unsigned_byte(limit, Address(ary2, 0));
+ cmpl(chr, limit);
+ jccb(Assembler::notEqual, FALSE_LABEL);
+ }
bind(TRUE_LABEL);
movl(result, 1); // return true
jmpb(DONE);
@@ -7081,6 +7543,8 @@
}
}
+#endif
+
void MacroAssembler::generate_fill(BasicType t, bool aligned,
Register to, Register value, Register count,
Register rtmp, XMMRegister xtmp) {
@@ -9085,6 +9549,179 @@
#undef BLOCK_COMMENT
+// Compress char[] array to byte[].
+void MacroAssembler::char_array_compress(Register src, Register dst, Register len,
+ XMMRegister tmp1Reg, XMMRegister tmp2Reg,
+ XMMRegister tmp3Reg, XMMRegister tmp4Reg,
+ Register tmp5, Register result) {
+ Label copy_chars_loop, return_length, return_zero, done;
+
+ // rsi: src
+ // rdi: dst
+ // rdx: len
+ // rcx: tmp5
+ // rax: result
+
+ // rsi holds start addr of source char[] to be compressed
+ // rdi holds start addr of destination byte[]
+ // rdx holds length
+
+ assert(len != result, "");
+
+ // save length for return
+ push(len);
+
+ if (UseSSE42Intrinsics) {
+ Label copy_32_loop, copy_16, copy_tail;
+
+ movl(result, len);
+ movl(tmp5, 0xff00ff00); // create mask to test for Unicode chars in vectors
+
+ // vectored compression
+ andl(len, 0xfffffff0); // vector count (in chars)
+ andl(result, 0x0000000f); // tail count (in chars)
+ testl(len, len);
+ jccb(Assembler::zero, copy_16);
+
+ // compress 16 chars per iter
+ movdl(tmp1Reg, tmp5);
+ pshufd(tmp1Reg, tmp1Reg, 0); // store Unicode mask in tmp1Reg
+ pxor(tmp4Reg, tmp4Reg);
+
+ lea(src, Address(src, len, Address::times_2));
+ lea(dst, Address(dst, len, Address::times_1));
+ negptr(len);
+
+ bind(copy_32_loop);
+ movdqu(tmp2Reg, Address(src, len, Address::times_2)); // load 1st 8 characters
+ por(tmp4Reg, tmp2Reg);
+ movdqu(tmp3Reg, Address(src, len, Address::times_2, 16)); // load next 8 characters
+ por(tmp4Reg, tmp3Reg);
+ ptest(tmp4Reg, tmp1Reg); // check for Unicode chars in next vector
+ jcc(Assembler::notZero, return_zero);
+ packuswb(tmp2Reg, tmp3Reg); // only ASCII chars; compress each to 1 byte
+ movdqu(Address(dst, len, Address::times_1), tmp2Reg);
+ addptr(len, 16);
+ jcc(Assembler::notZero, copy_32_loop);
+
+ // compress next vector of 8 chars (if any)
+ bind(copy_16);
+ movl(len, result);
+ andl(len, 0xfffffff8); // vector count (in chars)
+ andl(result, 0x00000007); // tail count (in chars)
+ testl(len, len);
+ jccb(Assembler::zero, copy_tail);
+
+ movdl(tmp1Reg, tmp5);
+ pshufd(tmp1Reg, tmp1Reg, 0); // store Unicode mask in tmp1Reg
+ pxor(tmp3Reg, tmp3Reg);
+
+ movdqu(tmp2Reg, Address(src, 0));
+ ptest(tmp2Reg, tmp1Reg); // check for Unicode chars in vector
+ jccb(Assembler::notZero, return_zero);
+ packuswb(tmp2Reg, tmp3Reg); // only LATIN1 chars; compress each to 1 byte
+ movq(Address(dst, 0), tmp2Reg);
+ addptr(src, 16);
+ addptr(dst, 8);
+
+ bind(copy_tail);
+ movl(len, result);
+ }
+ // compress 1 char per iter
+ testl(len, len);
+ jccb(Assembler::zero, return_length);
+ lea(src, Address(src, len, Address::times_2));
+ lea(dst, Address(dst, len, Address::times_1));
+ negptr(len);
+
+ bind(copy_chars_loop);
+ load_unsigned_short(result, Address(src, len, Address::times_2));
+ testl(result, 0xff00); // check if Unicode char
+ jccb(Assembler::notZero, return_zero);
+ movb(Address(dst, len, Address::times_1), result); // ASCII char; compress to 1 byte
+ increment(len);
+ jcc(Assembler::notZero, copy_chars_loop);
+
+ // if compression succeeded, return length
+ bind(return_length);
+ pop(result);
+ jmpb(done);
+
+ // if compression failed, return 0
+ bind(return_zero);
+ xorl(result, result);
+ addptr(rsp, wordSize);
+
+ bind(done);
+}
+
+// Inflate byte[] array to char[].
+void MacroAssembler::byte_array_inflate(Register src, Register dst, Register len,
+ XMMRegister tmp1, Register tmp2) {
+ Label copy_chars_loop, done;
+
+ // rsi: src
+ // rdi: dst
+ // rdx: len
+ // rcx: tmp2
+
+ // rsi holds start addr of source byte[] to be inflated
+ // rdi holds start addr of destination char[]
+ // rdx holds length
+ assert_different_registers(src, dst, len, tmp2);
+
+ if (UseSSE42Intrinsics) {
+ Label copy_8_loop, copy_bytes, copy_tail;
+
+ movl(tmp2, len);
+ andl(tmp2, 0x00000007); // tail count (in chars)
+ andl(len, 0xfffffff8); // vector count (in chars)
+ jccb(Assembler::zero, copy_tail);
+
+ // vectored inflation
+ lea(src, Address(src, len, Address::times_1));
+ lea(dst, Address(dst, len, Address::times_2));
+ negptr(len);
+
+ // inflate 8 chars per iter
+ bind(copy_8_loop);
+ pmovzxbw(tmp1, Address(src, len, Address::times_1)); // unpack to 8 words
+ movdqu(Address(dst, len, Address::times_2), tmp1);
+ addptr(len, 8);
+ jcc(Assembler::notZero, copy_8_loop);
+
+ bind(copy_tail);
+ movl(len, tmp2);
+
+ cmpl(len, 4);
+ jccb(Assembler::less, copy_bytes);
+
+ movdl(tmp1, Address(src, 0)); // load 4 byte chars
+ pmovzxbw(tmp1, tmp1);
+ movq(Address(dst, 0), tmp1);
+ subptr(len, 4);
+ addptr(src, 4);
+ addptr(dst, 8);
+
+ bind(copy_bytes);
+ }
+ testl(len, len);
+ jccb(Assembler::zero, done);
+ lea(src, Address(src, len, Address::times_1));
+ lea(dst, Address(dst, len, Address::times_2));
+ negptr(len);
+
+ // inflate 1 char per iter
+ bind(copy_chars_loop);
+ load_unsigned_byte(tmp2, Address(src, len, Address::times_1)); // load byte char
+ movw(Address(dst, len, Address::times_2), tmp2); // inflate byte char to word
+ increment(len);
+ jcc(Assembler::notZero, copy_chars_loop);
+
+ bind(done);
+}
+
+
Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
switch (cond) {
// Note some conditions are synonyms for others
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
#include "utilities/macros.hpp"
#include "runtime/rtmLocking.hpp"
-
// MacroAssembler extends Assembler by frequently used macros.
//
// Instructions for which a 'better' code sequence exists depending
@@ -1212,32 +1211,50 @@
// clear memory of size 'cnt' qwords, starting at 'base'.
void clear_mem(Register base, Register cnt, Register rtmp);
+#ifdef COMPILER2
+ void string_indexof_char(Register str1, Register cnt1, Register ch, Register result,
+ XMMRegister vec1, XMMRegister vec2, XMMRegister vec3, Register tmp);
+
// IndexOf strings.
// Small strings are loaded through stack if they cross page boundary.
void string_indexof(Register str1, Register str2,
Register cnt1, Register cnt2,
int int_cnt2, Register result,
- XMMRegister vec, Register tmp);
+ XMMRegister vec, Register tmp,
+ int ae);
// IndexOf for constant substrings with size >= 8 elements
// which don't need to be loaded through stack.
void string_indexofC8(Register str1, Register str2,
Register cnt1, Register cnt2,
int int_cnt2, Register result,
- XMMRegister vec, Register tmp);
+ XMMRegister vec, Register tmp,
+ int ae);
// Smallest code: we don't need to load through stack,
// check string tail.
+ // helper function for string_compare
+ void load_next_elements(Register elem1, Register elem2, Register str1, Register str2,
+ Address::ScaleFactor scale, Address::ScaleFactor scale1,
+ Address::ScaleFactor scale2, Register index, int ae);
// Compare strings.
void string_compare(Register str1, Register str2,
Register cnt1, Register cnt2, Register result,
- XMMRegister vec1);
+ XMMRegister vec1, int ae);
- // Compare char[] arrays.
- void char_arrays_equals(bool is_array_equ, Register ary1, Register ary2,
- Register limit, Register result, Register chr,
- XMMRegister vec1, XMMRegister vec2);
+ // Search for Non-ASCII character (Negative byte value) in a byte array,
+ // return true if it has any and false otherwise.
+ void has_negatives(Register ary1, Register len,
+ Register result, Register tmp1,
+ XMMRegister vec1, XMMRegister vec2);
+
+ // Compare char[] or byte[] arrays.
+ void arrays_equals(bool is_array_equ, Register ary1, Register ary2,
+ Register limit, Register result, Register chr,
+ XMMRegister vec1, XMMRegister vec2, bool is_char);
+
+#endif
// Fill primitive arrays
void generate_fill(BasicType t, bool aligned,
@@ -1332,6 +1349,15 @@
void fold_8bit_crc32(Register crc, Register table, Register tmp);
void fold_8bit_crc32(XMMRegister crc, Register table, XMMRegister xtmp, Register tmp);
+ // Compress char[] array to byte[].
+ void char_array_compress(Register src, Register dst, Register len,
+ XMMRegister tmp1, XMMRegister tmp2, XMMRegister tmp3,
+ XMMRegister tmp4, Register tmp5, Register result);
+
+ // Inflate byte[] array to char[].
+ void byte_array_inflate(Register src, Register dst, Register len,
+ XMMRegister tmp1, Register tmp2);
+
#undef VIRTUAL
};
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -63,7 +63,7 @@
void MethodHandles::verify_klass(MacroAssembler* _masm,
Register obj, SystemDictionary::WKID klass_id,
const char* error_message) {
- Klass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
+ InstanceKlass** klass_addr = SystemDictionary::well_known_klass_addr(klass_id);
KlassHandle klass = SystemDictionary::well_known_klass(klass_id);
Register temp = rdi;
Register temp2 = noreg;
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1502,7 +1502,7 @@
// return to caller
//
nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
- methodHandle method,
+ const methodHandle& method,
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1694,7 +1694,7 @@
};
static void verify_oop_args(MacroAssembler* masm,
- methodHandle method,
+ const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) {
Register temp_reg = rbx; // not part of any compiled calling seq
@@ -1804,7 +1804,7 @@
// return to caller
//
nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
- methodHandle method,
+ const methodHandle& method,
int compile_id,
BasicType* in_sig_bt,
VMRegPair* in_regs,
--- a/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -82,6 +82,7 @@
declare_constant(VM_Version::CPU_AVX512CD) \
declare_constant(VM_Version::CPU_AVX512BW)
-#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
+ declare_preprocessor_constant("VM_Version::CPU_AVX512VL", CPU_AVX512VL)
#endif // CPU_X86_VM_VMSTRUCTS_X86_HPP
--- a/hotspot/src/cpu/x86/vm/x86_32.ad Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jul 05 21:00:20 2017 +0200
@@ -11435,16 +11435,62 @@
ins_pipe( pipe_slow );
%}
-instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
- eAXRegI result, regD tmp1, eFlagsReg cr) %{
+instruct string_compareL(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
+ eAXRegI result, regD tmp1, eFlagsReg cr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
- format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register, $result$$Register,
+ $tmp1$$XMMRegister, StrIntrinsicNode::LL);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_compareU(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
+ eAXRegI result, regD tmp1, eFlagsReg cr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+ format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
ins_encode %{
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register, $result$$Register,
- $tmp1$$XMMRegister);
+ $tmp1$$XMMRegister, StrIntrinsicNode::UU);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_compareLU(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
+ eAXRegI result, regD tmp1, eFlagsReg cr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register, $result$$Register,
+ $tmp1$$XMMRegister, StrIntrinsicNode::LU);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_compareUL(eSIRegP str1, eDXRegI cnt1, eDIRegP str2, eCXRegI cnt2,
+ eAXRegI result, regD tmp1, eFlagsReg cr) %{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
+ ins_encode %{
+ __ string_compare($str2$$Register, $str1$$Register,
+ $cnt2$$Register, $cnt1$$Register, $result$$Register,
+ $tmp1$$XMMRegister, StrIntrinsicNode::UL);
%}
ins_pipe( pipe_slow );
%}
@@ -11457,21 +11503,78 @@
format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
ins_encode %{
- __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
- $cnt$$Register, $result$$Register, $tmp3$$Register,
- $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ __ arrays_equals(false, $str1$$Register, $str2$$Register,
+ $cnt$$Register, $result$$Register, $tmp3$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
+ %}
+
+ ins_pipe( pipe_slow );
+%}
+
+// fast search of substring with known size.
+instruct string_indexof_conL(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
+ eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
+ effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
+
+ format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
+ ins_encode %{
+ int icnt2 = (int)$int_cnt2$$constant;
+ if (icnt2 >= 16) {
+ // IndexOf for constant substrings with size >= 16 elements
+ // which don't need to be loaded through stack.
+ __ string_indexofC8($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ icnt2, $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
+ } else {
+ // Small strings are loaded through stack if they cross page boundary.
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ icnt2, $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
+ }
%}
ins_pipe( pipe_slow );
%}
// fast search of substring with known size.
-instruct string_indexof_con(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
- eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
- predicate(UseSSE42Intrinsics);
+instruct string_indexof_conU(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
+ eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
- format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
+ format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
+ ins_encode %{
+ int icnt2 = (int)$int_cnt2$$constant;
+ if (icnt2 >= 8) {
+ // IndexOf for constant substrings with size >= 8 elements
+ // which don't need to be loaded through stack.
+ __ string_indexofC8($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ icnt2, $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
+ } else {
+ // Small strings are loaded through stack if they cross page boundary.
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ icnt2, $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// fast search of substring with known size.
+instruct string_indexof_conUL(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2,
+ eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
+ effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
+
+ format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
ins_encode %{
int icnt2 = (int)$int_cnt2$$constant;
if (icnt2 >= 8) {
@@ -11480,47 +11583,154 @@
__ string_indexofC8($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
icnt2, $result$$Register,
- $vec$$XMMRegister, $tmp$$Register);
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
} else {
// Small strings are loaded through stack if they cross page boundary.
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
icnt2, $result$$Register,
- $vec$$XMMRegister, $tmp$$Register);
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
}
%}
ins_pipe( pipe_slow );
%}
-instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
- eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
- predicate(UseSSE42Intrinsics);
+instruct string_indexofL(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
+ eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
- format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
+ format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
ins_encode %{
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
(-1), $result$$Register,
- $vec$$XMMRegister, $tmp$$Register);
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_indexofU(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
+ eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
+
+ format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
+ ins_encode %{
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ (-1), $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_indexofUL(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2,
+ eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
+
+ format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
+ ins_encode %{
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ (-1), $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_indexofU_char(eDIRegP str1, eDXRegI cnt1, eAXRegI ch,
+ eBXRegI result, regD vec1, regD vec2, regD vec3, eCXRegI tmp, eFlagsReg cr) %{
+ predicate(UseSSE42Intrinsics);
+ match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
+ effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr);
+ format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %}
+ ins_encode %{
+ __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register,
+ $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register);
%}
ins_pipe( pipe_slow );
%}
// fast array equals
-instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
- regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
+instruct array_equalsB(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
+ regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
%{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
+ match(Set result (AryEq ary1 ary2));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
+ //ins_cost(300);
+
+ format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
+ ins_encode %{
+ __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
+ $tmp3$$Register, $result$$Register, $tmp4$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct array_equalsC(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
+ regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
+%{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (AryEq ary1 ary2));
effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
//ins_cost(300);
- format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
- ins_encode %{
- __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
- $tmp3$$Register, $result$$Register, $tmp4$$Register,
- $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
+ ins_encode %{
+ __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
+ $tmp3$$Register, $result$$Register, $tmp4$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct has_negatives(eSIRegP ary1, eCXRegI len, eAXRegI result,
+ regD tmp1, regD tmp2, eBXRegI tmp3, eFlagsReg cr)
+%{
+ match(Set result (HasNegatives ary1 len));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr);
+
+ format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %}
+ ins_encode %{
+ __ has_negatives($ary1$$Register, $len$$Register,
+ $result$$Register, $tmp3$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// fast char[] to byte[] compression
+instruct string_compress(eSIRegP src, eDIRegP dst, eDXRegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4,
+ eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{
+ match(Set result (StrCompressedCopy src (Binary dst len)));
+ effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
+
+ format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %}
+ ins_encode %{
+ __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
+ $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// fast byte[] to char[] inflation
+instruct string_inflate(Universe dummy, eSIRegP src, eDIRegP dst, eDXRegI len,
+ regD tmp1, eCXRegI tmp2, eFlagsReg cr) %{
+ match(Set dummy (StrInflatedCopy src (Binary dst len)));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
+
+ format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %}
+ ins_encode %{
+ __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
+ $tmp1$$XMMRegister, $tmp2$$Register);
%}
ins_pipe( pipe_slow );
%}
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Wed Jul 05 21:00:20 2017 +0200
@@ -10447,30 +10447,108 @@
ins_pipe( pipe_slow );
%}
-instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
- rax_RegI result, regD tmp1, rFlagsReg cr)
-%{
+instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
+ rax_RegI result, regD tmp1, rFlagsReg cr)
+%{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL);
match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
- format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register, $result$$Register,
+ $tmp1$$XMMRegister, StrIntrinsicNode::LL);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
+ rax_RegI result, regD tmp1, rFlagsReg cr)
+%{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+ format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
ins_encode %{
__ string_compare($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register, $result$$Register,
- $tmp1$$XMMRegister);
+ $tmp1$$XMMRegister, StrIntrinsicNode::UU);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
+ rax_RegI result, regD tmp1, rFlagsReg cr)
+%{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
+ ins_encode %{
+ __ string_compare($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register, $result$$Register,
+ $tmp1$$XMMRegister, StrIntrinsicNode::LU);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2,
+ rax_RegI result, regD tmp1, rFlagsReg cr)
+%{
+ predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL);
+ match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
+
+ format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
+ ins_encode %{
+ __ string_compare($str2$$Register, $str1$$Register,
+ $cnt2$$Register, $cnt1$$Register, $result$$Register,
+ $tmp1$$XMMRegister, StrIntrinsicNode::UL);
%}
ins_pipe( pipe_slow );
%}
// fast search of substring with known size.
-instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
- rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
-%{
- predicate(UseSSE42Intrinsics);
+instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
+ rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
+%{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
- format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
+ format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
+ ins_encode %{
+ int icnt2 = (int)$int_cnt2$$constant;
+ if (icnt2 >= 16) {
+ // IndexOf for constant substrings with size >= 16 elements
+ // which don't need to be loaded through stack.
+ __ string_indexofC8($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ icnt2, $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
+ } else {
+ // Small strings are loaded through stack if they cross page boundary.
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ icnt2, $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// fast search of substring with known size.
+instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
+ rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
+%{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
+ effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
+
+ format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
ins_encode %{
int icnt2 = (int)$int_cnt2$$constant;
if (icnt2 >= 8) {
@@ -10479,31 +10557,108 @@
__ string_indexofC8($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
icnt2, $result$$Register,
- $vec$$XMMRegister, $tmp$$Register);
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
+ } else {
+ // Small strings are loaded through stack if they cross page boundary.
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ icnt2, $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// fast search of substring with known size.
+instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
+ rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
+%{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
+ effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
+
+ format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
+ ins_encode %{
+ int icnt2 = (int)$int_cnt2$$constant;
+ if (icnt2 >= 8) {
+ // IndexOf for constant substrings with size >= 8 elements
+ // which don't need to be loaded through stack.
+ __ string_indexofC8($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ icnt2, $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
} else {
// Small strings are loaded through stack if they cross page boundary.
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
icnt2, $result$$Register,
- $vec$$XMMRegister, $tmp$$Register);
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
}
%}
ins_pipe( pipe_slow );
%}
-instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
- rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
-%{
- predicate(UseSSE42Intrinsics);
+instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
+ rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
+%{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL));
match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
- format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
+ format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
ins_encode %{
__ string_indexof($str1$$Register, $str2$$Register,
$cnt1$$Register, $cnt2$$Register,
(-1), $result$$Register,
- $vec$$XMMRegister, $tmp$$Register);
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
+ rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
+%{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU));
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
+
+ format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
+ ins_encode %{
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ (-1), $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
+ rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
+%{
+ predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL));
+ match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
+ effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
+
+ format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
+ ins_encode %{
+ __ string_indexof($str1$$Register, $str2$$Register,
+ $cnt1$$Register, $cnt2$$Register,
+ (-1), $result$$Register,
+ $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch,
+ rbx_RegI result, regD vec1, regD vec2, regD vec3, rcx_RegI tmp, rFlagsReg cr)
+%{
+ predicate(UseSSE42Intrinsics);
+ match(Set result (StrIndexOfChar (Binary str1 cnt1) ch));
+ effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr);
+ format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %}
+ ins_encode %{
+ __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register,
+ $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register);
%}
ins_pipe( pipe_slow );
%}
@@ -10517,26 +10672,86 @@
format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
ins_encode %{
- __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
- $cnt$$Register, $result$$Register, $tmp3$$Register,
- $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ __ arrays_equals(false, $str1$$Register, $str2$$Register,
+ $cnt$$Register, $result$$Register, $tmp3$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
%}
ins_pipe( pipe_slow );
%}
// fast array equals
-instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
+instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
+ regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
+%{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL);
+ match(Set result (AryEq ary1 ary2));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
+
+ format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
+ ins_encode %{
+ __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
+ $tmp3$$Register, $result$$Register, $tmp4$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
%{
+ predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU);
match(Set result (AryEq ary1 ary2));
effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
- //ins_cost(300);
-
- format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
- ins_encode %{
- __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
- $tmp3$$Register, $result$$Register, $tmp4$$Register,
- $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+
+ format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
+ ins_encode %{
+ __ arrays_equals(true, $ary1$$Register, $ary2$$Register,
+ $tmp3$$Register, $result$$Register, $tmp4$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result,
+ regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
+%{
+ match(Set result (HasNegatives ary1 len));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr);
+
+ format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %}
+ ins_encode %{
+ __ has_negatives($ary1$$Register, $len$$Register,
+ $result$$Register, $tmp3$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// fast char[] to byte[] compression
+instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, regD tmp1, regD tmp2, regD tmp3, regD tmp4,
+ rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
+ match(Set result (StrCompressedCopy src (Binary dst len)));
+ effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
+
+ format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %}
+ ins_encode %{
+ __ char_array_compress($src$$Register, $dst$$Register, $len$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
+ $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// fast byte[] to char[] inflation
+instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len,
+ regD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{
+ match(Set dummy (StrInflatedCopy src (Binary dst len)));
+ effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr);
+
+ format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %}
+ ins_encode %{
+ __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register,
+ $tmp1$$XMMRegister, $tmp2$$Register);
%}
ins_pipe( pipe_slow );
%}
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -69,6 +69,9 @@
define_pd_global(bool, PreserveFramePointer, false);
+// No performance work done here yet.
+define_pd_global(bool, CompactStrings, false);
+
#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
\
product(bool, UseFastEmptyMethods, true, \
--- a/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -76,7 +76,7 @@
}
nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
- methodHandle method,
+ const methodHandle& method,
int compile_id,
BasicType *sig_bt,
VMRegPair *regs,
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,15 +22,18 @@
*/
package jdk.vm.ci.amd64;
-import static jdk.vm.ci.code.MemoryBarriers.*;
-import static jdk.vm.ci.code.Register.*;
+import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
+import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
+import static jdk.vm.ci.code.Register.SPECIAL;
-import java.nio.*;
-import java.util.*;
+import java.nio.ByteOrder;
+import java.util.EnumSet;
-import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.PlatformKind;
/**
* Represents the AMD64 architecture.
@@ -65,9 +68,7 @@
r8, r9, r10, r11, r12, r13, r14, r15
};
- private static final int XMM_REFERENCE_MAP_SHIFT = 2;
-
- public static final RegisterCategory XMM = new RegisterCategory("XMM", cpuRegisters.length, XMM_REFERENCE_MAP_SHIFT);
+ public static final RegisterCategory XMM = new RegisterCategory("XMM");
// XMM registers
public static final Register xmm0 = new Register(16, 0, "xmm0", XMM);
@@ -79,8 +80,8 @@
public static final Register xmm6 = new Register(22, 6, "xmm6", XMM);
public static final Register xmm7 = new Register(23, 7, "xmm7", XMM);
- public static final Register xmm8 = new Register(24, 8, "xmm8", XMM);
- public static final Register xmm9 = new Register(25, 9, "xmm9", XMM);
+ public static final Register xmm8 = new Register(24, 8, "xmm8", XMM);
+ public static final Register xmm9 = new Register(25, 9, "xmm9", XMM);
public static final Register xmm10 = new Register(26, 10, "xmm10", XMM);
public static final Register xmm11 = new Register(27, 11, "xmm11", XMM);
public static final Register xmm12 = new Register(28, 12, "xmm12", XMM);
@@ -88,28 +89,77 @@
public static final Register xmm14 = new Register(30, 14, "xmm14", XMM);
public static final Register xmm15 = new Register(31, 15, "xmm15", XMM);
- public static final Register[] xmmRegisters = {
+ public static final Register xmm16 = new Register(32, 16, "xmm16", XMM);
+ public static final Register xmm17 = new Register(33, 17, "xmm17", XMM);
+ public static final Register xmm18 = new Register(34, 18, "xmm18", XMM);
+ public static final Register xmm19 = new Register(35, 19, "xmm19", XMM);
+ public static final Register xmm20 = new Register(36, 20, "xmm20", XMM);
+ public static final Register xmm21 = new Register(37, 21, "xmm21", XMM);
+ public static final Register xmm22 = new Register(38, 22, "xmm22", XMM);
+ public static final Register xmm23 = new Register(39, 23, "xmm23", XMM);
+
+ public static final Register xmm24 = new Register(40, 24, "xmm24", XMM);
+ public static final Register xmm25 = new Register(41, 25, "xmm25", XMM);
+ public static final Register xmm26 = new Register(42, 26, "xmm26", XMM);
+ public static final Register xmm27 = new Register(43, 27, "xmm27", XMM);
+ public static final Register xmm28 = new Register(44, 28, "xmm28", XMM);
+ public static final Register xmm29 = new Register(45, 29, "xmm29", XMM);
+ public static final Register xmm30 = new Register(46, 30, "xmm30", XMM);
+ public static final Register xmm31 = new Register(47, 31, "xmm31", XMM);
+
+ public static final Register[] xmmRegistersSSE = {
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
};
- public static final Register[] cpuxmmRegisters = {
+ public static final Register[] xmmRegistersAVX512 = {
+ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
+ xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
+ xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
+ xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31
+ };
+
+ public static final RegisterCategory MASK = new RegisterCategory("MASK", false);
+
+ public static final Register k0 = new Register(48, 0, "k0", MASK);
+ public static final Register k1 = new Register(49, 1, "k1", MASK);
+ public static final Register k2 = new Register(50, 2, "k2", MASK);
+ public static final Register k3 = new Register(51, 3, "k3", MASK);
+ public static final Register k4 = new Register(52, 4, "k4", MASK);
+ public static final Register k5 = new Register(53, 5, "k5", MASK);
+ public static final Register k6 = new Register(54, 6, "k6", MASK);
+ public static final Register k7 = new Register(55, 7, "k7", MASK);
+
+ public static final Register[] valueRegistersSSE = {
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
};
+ public static final Register[] valueRegistersAVX512 = {
+ rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
+ r8, r9, r10, r11, r12, r13, r14, r15,
+ xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
+ xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
+ xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
+ xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31,
+ k0, k1, k2, k3, k4, k5, k6, k7
+ };
+
/**
* Register used to construct an instruction-relative address.
*/
- public static final Register rip = new Register(32, -1, "rip", SPECIAL);
+ public static final Register rip = new Register(56, -1, "rip", SPECIAL);
public static final Register[] allRegisters = {
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
+ xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
+ xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31,
+ k0, k1, k2, k3, k4, k5, k6, k7,
rip
};
@@ -151,7 +201,8 @@
AVX512PF,
AVX512ER,
AVX512CD,
- AVX512BW
+ AVX512BW,
+ AVX512VL
}
private final EnumSet<CPUFeature> features;
@@ -166,11 +217,21 @@
private final EnumSet<Flag> flags;
+ private final AMD64Kind largestKind;
+
public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
- super("AMD64", JavaKind.Long, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, cpuRegisters.length + (xmmRegisters.length << XMM_REFERENCE_MAP_SHIFT), 8);
+ super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, 8);
this.features = features;
this.flags = flags;
assert features.contains(CPUFeature.SSE2) : "minimum config for x64";
+
+ if (features.contains(CPUFeature.AVX512F)) {
+ largestKind = AMD64Kind.V512_QWORD;
+ } else if (features.contains(CPUFeature.AVX)) {
+ largestKind = AMD64Kind.V256_QWORD;
+ } else {
+ largestKind = AMD64Kind.V128_QWORD;
+ }
}
public EnumSet<CPUFeature> getFeatures() {
@@ -182,50 +243,60 @@
}
@Override
+ public Register[] getAvailableValueRegisters() {
+ if (features.contains(CPUFeature.AVX512F)) {
+ return valueRegistersAVX512;
+ } else {
+ return valueRegistersSSE;
+ }
+ }
+
+ @Override
public PlatformKind getPlatformKind(JavaKind javaKind) {
- if (javaKind.isObject()) {
- return getWordKind();
- } else {
- return javaKind;
+ switch (javaKind) {
+ case Boolean:
+ case Byte:
+ return AMD64Kind.BYTE;
+ case Short:
+ case Char:
+ return AMD64Kind.WORD;
+ case Int:
+ return AMD64Kind.DWORD;
+ case Long:
+ case Object:
+ return AMD64Kind.QWORD;
+ case Float:
+ return AMD64Kind.SINGLE;
+ case Double:
+ return AMD64Kind.DOUBLE;
+ default:
+ return null;
}
}
@Override
public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
- if (!(platformKind instanceof JavaKind)) {
- return false;
+ AMD64Kind kind = (AMD64Kind) platformKind;
+ if (kind.isInteger()) {
+ return category.equals(CPU);
+ } else if (kind.isXMM()) {
+ return category.equals(XMM);
+ } else {
+ assert kind.isMask();
+ return category.equals(MASK);
}
-
- JavaKind kind = (JavaKind) platformKind;
- if (category.equals(CPU)) {
- switch (kind) {
- case Boolean:
- case Byte:
- case Char:
- case Short:
- case Int:
- case Long:
- return true;
- }
- } else if (category.equals(XMM)) {
- switch (kind) {
- case Float:
- case Double:
- return true;
- }
- }
-
- return false;
}
@Override
- public PlatformKind getLargestStorableKind(RegisterCategory category) {
+ public AMD64Kind getLargestStorableKind(RegisterCategory category) {
if (category.equals(CPU)) {
- return JavaKind.Long;
+ return AMD64Kind.QWORD;
} else if (category.equals(XMM)) {
- return JavaKind.Double;
+ return largestKind;
+ } else if (category.equals(MASK)) {
+ return AMD64Kind.MASK64;
} else {
- return JavaKind.Illegal;
+ return null;
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.amd64/src/jdk/vm/ci/amd64/AMD64Kind.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.amd64;
+
+import jdk.vm.ci.meta.PlatformKind;
+
+public enum AMD64Kind implements PlatformKind {
+
+ // scalar
+ BYTE(1),
+ WORD(2),
+ DWORD(4),
+ QWORD(8),
+ SINGLE(4),
+ DOUBLE(8),
+
+ // SSE2
+ V32_BYTE(4, BYTE),
+ V32_WORD(4, WORD),
+ V64_BYTE(8, BYTE),
+ V64_WORD(8, WORD),
+ V64_DWORD(8, DWORD),
+ V128_BYTE(16, BYTE),
+ V128_WORD(16, WORD),
+ V128_DWORD(16, DWORD),
+ V128_QWORD(16, QWORD),
+ V128_SINGLE(16, SINGLE),
+ V128_DOUBLE(16, DOUBLE),
+
+ // AVX
+ V256_BYTE(32, BYTE),
+ V256_WORD(32, WORD),
+ V256_DWORD(32, DWORD),
+ V256_QWORD(32, QWORD),
+ V256_SINGLE(32, SINGLE),
+ V256_DOUBLE(32, DOUBLE),
+
+ // AVX512
+ V512_BYTE(64, BYTE),
+ V512_WORD(64, WORD),
+ V512_DWORD(64, DWORD),
+ V512_QWORD(64, QWORD),
+ V512_SINGLE(64, SINGLE),
+ V512_DOUBLE(64, DOUBLE),
+
+ MASK8(1),
+ MASK16(2),
+ MASK32(4),
+ MASK64(8);
+
+ private final int size;
+ private final int vectorLength;
+
+ private final AMD64Kind scalar;
+ private final EnumKey<AMD64Kind> key = new EnumKey<>(this);
+
+ private AMD64Kind(int size) {
+ this.size = size;
+ this.scalar = this;
+ this.vectorLength = 1;
+ }
+
+ private AMD64Kind(int size, AMD64Kind scalar) {
+ this.size = size;
+ this.scalar = scalar;
+
+ assert size % scalar.size == 0;
+ this.vectorLength = size / scalar.size;
+ }
+
+ public AMD64Kind getScalar() {
+ return scalar;
+ }
+
+ public int getSizeInBytes() {
+ return size;
+ }
+
+ public int getVectorLength() {
+ return vectorLength;
+ }
+
+ public Key getKey() {
+ return key;
+ }
+
+ public boolean isInteger() {
+ switch (this) {
+ case BYTE:
+ case WORD:
+ case DWORD:
+ case QWORD:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isXMM() {
+ switch (this) {
+ case SINGLE:
+ case DOUBLE:
+ case V32_BYTE:
+ case V32_WORD:
+ case V64_BYTE:
+ case V64_WORD:
+ case V64_DWORD:
+ case V128_BYTE:
+ case V128_WORD:
+ case V128_DWORD:
+ case V128_QWORD:
+ case V128_SINGLE:
+ case V128_DOUBLE:
+ case V256_BYTE:
+ case V256_WORD:
+ case V256_DWORD:
+ case V256_QWORD:
+ case V256_SINGLE:
+ case V256_DOUBLE:
+ case V512_BYTE:
+ case V512_WORD:
+ case V512_DWORD:
+ case V512_QWORD:
+ case V512_SINGLE:
+ case V512_DOUBLE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isMask() {
+ switch (this) {
+ case MASK8:
+ case MASK16:
+ case MASK32:
+ case MASK64:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public char getTypeChar() {
+ switch (this) {
+ case BYTE:
+ return 'b';
+ case WORD:
+ return 'w';
+ case DWORD:
+ return 'd';
+ case QWORD:
+ return 'q';
+ case SINGLE:
+ return 'S';
+ case DOUBLE:
+ return 'D';
+ case V32_BYTE:
+ case V32_WORD:
+ case V64_BYTE:
+ case V64_WORD:
+ case V64_DWORD:
+ return 'v';
+ case V128_BYTE:
+ case V128_WORD:
+ case V128_DWORD:
+ case V128_QWORD:
+ case V128_SINGLE:
+ case V128_DOUBLE:
+ return 'x';
+ case V256_BYTE:
+ case V256_WORD:
+ case V256_DWORD:
+ case V256_QWORD:
+ case V256_SINGLE:
+ case V256_DOUBLE:
+ return 'y';
+ case V512_BYTE:
+ case V512_WORD:
+ case V512_DWORD:
+ case V512_QWORD:
+ case V512_SINGLE:
+ case V512_DOUBLE:
+ return 'z';
+ case MASK8:
+ case MASK16:
+ case MASK32:
+ case MASK64:
+ return 'k';
+ default:
+ return '-';
+ }
+ }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/AbstractAddress.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2013, 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.
- */
-package jdk.vm.ci.code;
-
-/**
- * Abstract base class that represents a platform specific address.
- */
-public abstract class AbstractAddress {
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,11 +22,12 @@
*/
package jdk.vm.ci.code;
-import java.nio.*;
-import java.util.*;
+import java.nio.ByteOrder;
+import java.util.Arrays;
import jdk.vm.ci.code.Register.RegisterCategory;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.PlatformKind;
/**
* Represents a CPU architecture, including information such as its endianness, CPU registers, word
@@ -35,13 +36,6 @@
public abstract class Architecture {
/**
- * The number of entries required in a {@link ReferenceMap} covering all the registers that may
- * store references. The index of a register in the reference map is given by
- * {@link Register#getReferenceMapIndex()}.
- */
- private final int registerReferenceMapSize;
-
- /**
* The architecture specific type of a native word.
*/
private final PlatformKind wordKind;
@@ -85,7 +79,7 @@
private final int returnAddressSize;
protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, Register[] registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset,
- int registerReferenceMapSize, int returnAddressSize) {
+ int returnAddressSize) {
this.name = name;
this.registers = registers;
this.wordKind = wordKind;
@@ -93,7 +87,6 @@
this.unalignedMemoryAccess = unalignedMemoryAccess;
this.implicitMemoryBarriers = implicitMemoryBarriers;
this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
- this.registerReferenceMapSize = registerReferenceMapSize;
this.returnAddressSize = returnAddressSize;
}
@@ -107,10 +100,6 @@
return getName().toLowerCase();
}
- public int getRegisterReferenceMapSize() {
- return registerReferenceMapSize;
- }
-
/**
* Gets the natural size of words (typically registers and pointers) of this architecture, in
* bytes.
@@ -131,13 +120,23 @@
}
/**
- * Gets an array of all available registers on this architecture. The index of each register in
- * this array is equal to its {@linkplain Register#number number}.
+ * Gets an array of all registers that exist on this architecture. This contains all registers
+ * that exist in the specification of this architecture. Not all of them may be available on
+ * this particular architecture instance. The index of each register in this array is equal to
+ * its {@linkplain Register#number number}.
*/
public Register[] getRegisters() {
return registers.clone();
}
+ /**
+ * Gets an array of all registers available for storing values on this architecture. This may be
+ * a subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU.
+ */
+ public Register[] getAvailableValueRegisters() {
+ return getRegisters();
+ }
+
public ByteOrder getByteOrder() {
return byteOrder;
}
@@ -207,7 +206,6 @@
assert this.byteOrder.equals(that.byteOrder);
assert this.implicitMemoryBarriers == that.implicitMemoryBarriers;
assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset;
- assert this.registerReferenceMapSize == that.registerReferenceMapSize;
assert Arrays.equals(this.registers, that.registers);
assert this.returnAddressSize == that.returnAddressSize;
assert this.unalignedMemoryAccess == that.unalignedMemoryAccess;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BailoutException.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BailoutException.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.Locale;
/**
* Exception thrown when the compiler refuses to compile a method because of problems with the
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,12 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.Arrays;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaValue;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.Value;
/**
* Represents the Java bytecode frame state(s) at a given position including {@link Value locations}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodePosition.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodePosition.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,9 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.Objects;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Represents a code position, that is, a chain of inlined methods with bytecode locations, that is
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CallingConvention.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CallingConvention.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,10 @@
*/
package jdk.vm.ci.code;
-import static jdk.vm.ci.code.ValueUtil.*;
-
-import jdk.vm.ci.meta.*;
+import static jdk.vm.ci.code.ValueUtil.isAllocatableValue;
+import static jdk.vm.ci.code.ValueUtil.isStackSlot;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Value;
/**
* A calling convention describes the locations in which the arguments for a call are placed and the
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeCacheProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeCacheProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,14 @@
*/
package jdk.vm.ci.code;
-import jdk.vm.ci.code.CompilationResult.*;
-import jdk.vm.ci.code.DataSection.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.CompilationResult.Call;
+import jdk.vm.ci.code.CompilationResult.DataPatch;
+import jdk.vm.ci.code.CompilationResult.Mark;
+import jdk.vm.ci.code.DataSection.Data;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.SpeculationLog;
/**
* Access to code cache related details and requirements.
@@ -32,26 +37,62 @@
public interface CodeCacheProvider {
/**
- * Adds the given compilation result as an implementation of the given method without making it
- * the default implementation.
+ * Installs code for a given method based on a given compilation result without making it the
+ * default implementation of the method.
*
- * @param method a method to which the executable code is begin added
+ * @param method a method implemented by the installed code
* @param compResult the compilation result to be added
- * @param speculationLog the speculation log to be used
- * @return a reference to the compiled and ready-to-run code or throws a
- * {@link BailoutException} if the code installation failed
+ * @param log the speculation log to be used
+ * @param installedCode a predefined {@link InstalledCode} object to use as a reference to the
+ * installed code. If {@code null}, a new {@link InstalledCode} object will be
+ * created.
+ * @return a reference to the ready-to-run code
+ * @throws BailoutException if the code installation failed
*/
- InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode);
+ default InstalledCode addCode(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode installedCode) {
+ return installCode(new CompilationRequest(method), compResult, installedCode, log, false);
+ }
/**
- * Sets the given compilation result as the default implementation of the given method.
+ * Installs code for a given method based on a given compilation result and makes it the default
+ * implementation of the method.
*
- * @param method a method to which the executable code is begin added
+ * @param method a method implemented by the installed code and for which the installed code
+ * becomes the default implementation
+ * @param compResult the compilation result to be added
+ * @return a reference to the ready-to-run code
+ * @throws BailoutException if the code installation failed
+ */
+ default InstalledCode setDefaultCode(ResolvedJavaMethod method, CompilationResult compResult) {
+ return installCode(new CompilationRequest(method), compResult, null, null, true);
+ }
+
+ /**
+ * Installs code based on a given compilation result.
+ *
+ * @param compRequest details of the method compiled to produce {@code compResult} or
+ * {@code null} if the input to {@code compResult} was not a
+ * {@link ResolvedJavaMethod}
* @param compResult the compilation result to be added
- * @return a reference to the compiled and ready-to-run code or null if the code installation
- * failed
+ * @param installedCode a pre-allocated {@link InstalledCode} object to use as a reference to
+ * the installed code. If {@code null}, a new {@link InstalledCode} object will be
+ * created.
+ * @param log the speculation log to be used
+ * @param isDefault specifies if the installed code should be made the default implementation of
+ * {@code compRequest.getMethod()}. The default implementation for a method is the
+ * code executed for standard calls to the method. This argument is ignored if
+ * {@code compRequest == null}.
+ * @return a reference to the compiled and ready-to-run installed code
+ * @throws BailoutException if the code installation failed
*/
- InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult);
+ InstalledCode installCode(CompilationRequest compRequest, CompilationResult compResult, InstalledCode installedCode, SpeculationLog log, boolean isDefault);
+
+ /**
+ * Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be
+ * raised the next time {@code installedCode} is
+ * {@linkplain InstalledCode#executeVarargs(Object...) executed}.
+ */
+ void invalidateInstalledCode(InstalledCode installedCode);
/**
* Gets a name for a {@link Mark} mark.
@@ -102,4 +143,16 @@
* Create a new speculation log for the target runtime.
*/
SpeculationLog createSpeculationLog();
+
+ /**
+ * Returns the maximum absolute offset of a PC relative call to a given address from any
+ * position in the code cache or -1 when not applicable. Intended for determining the required
+ * size of address/offset fields.
+ */
+ long getMaxCallTargetOffset(long address);
+
+ /**
+ * Determines if debug info should also be emitted at non-safepoint locations.
+ */
+ boolean shouldDebugNonSafepoints();
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,15 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.MetaUtil;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.Signature;
/**
* Miscellaneous collection of utility methods used by {@code jdk.vm.ci.code} and its clients.
@@ -323,49 +329,12 @@
public interface RefMapFormatter {
String formatStackSlot(int frameRefMapIndex);
-
- String formatRegister(int regRefMapIndex);
}
/**
- * Formats a location in a register reference map.
+ * Formats a location present in a reference map.
*/
- public static class DefaultRegFormatter implements RefMapFormatter {
-
- private final Register[] registers;
-
- public DefaultRegFormatter(Architecture arch) {
- registers = new Register[arch.getRegisterReferenceMapSize()];
- for (Register r : arch.getRegisters()) {
- if (r.getReferenceMapIndex() >= 0) {
- registers[r.getReferenceMapIndex()] = r;
- }
- }
- }
-
- public String formatStackSlot(int frameRefMapIndex) {
- return null;
- }
-
- public String formatRegister(int regRefMapIndex) {
- int i = regRefMapIndex;
- int idx = 0;
- while (registers[i] == null) {
- i--;
- idx++;
- }
- if (idx == 0) {
- return registers[i].toString();
- } else {
- return String.format("%s+%d", registers[i].toString(), idx);
- }
- }
- }
-
- /**
- * Formats a location present in a register or frame reference map.
- */
- public static class DefaultRefMapFormatter extends DefaultRegFormatter {
+ public static class DefaultRefMapFormatter implements RefMapFormatter {
/**
* The size of a stack slot.
@@ -383,8 +352,7 @@
*/
public final int refMapToFPOffset;
- public DefaultRefMapFormatter(Architecture arch, int slotSize, Register fp, int refMapToFPOffset) {
- super(arch);
+ public DefaultRefMapFormatter(int slotSize, Register fp, int refMapToFPOffset) {
this.slotSize = slotSize;
this.fp = fp;
this.refMapToFPOffset = refMapToFPOffset;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequest.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Represents a request to compile a method.
+ */
+public class CompilationRequest {
+
+ private final ResolvedJavaMethod method;
+
+ private final int entryBCI;
+
+ /**
+ * Creates a request to compile a method starting at its entry point.
+ *
+ * @param method the method to be compiled
+ */
+ public CompilationRequest(ResolvedJavaMethod method) {
+ this(method, -1);
+ }
+
+ /**
+ * Creates a request to compile a method starting at a given BCI.
+ *
+ * @param method the method to be compiled
+ * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
+ * method's entry point
+ */
+ public CompilationRequest(ResolvedJavaMethod method, int entryBCI) {
+ assert method != null;
+ this.method = method;
+ this.entryBCI = entryBCI;
+ }
+
+ /**
+ * Gets the method to be compiled.
+ */
+ public ResolvedJavaMethod getMethod() {
+ return method;
+ }
+
+ /**
+ * Gets the bytecode index (BCI) at which to start compiling where -1 denotes a non-OSR
+ * compilation request and all other values denote an on stack replacement (OSR) compilation
+ * request.
+ */
+ public int getEntryBCI() {
+ return entryBCI;
+ }
+
+ @Override
+ public String toString() {
+ return method.format("%H.%n(%p)@" + entryBCI);
+ }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationResult.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,13 +22,24 @@
*/
package jdk.vm.ci.code;
-import static java.util.Collections.*;
-import static jdk.vm.ci.meta.MetaUtil.*;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.unmodifiableList;
+import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.meta.Assumptions.*;
+import jdk.vm.ci.meta.Assumptions.Assumption;
+import jdk.vm.ci.meta.InvokeTarget;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.MetaUtil;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.VMConstant;
/**
* Represents the output from compiling a method, including the compiled machine code, associated
@@ -115,8 +126,8 @@
public enum MetaSpaceAccessType {
Move,
- Store, // store only works for compressed oops (memory <- 32bit value). Compressed oops is
- // not supported using AOT. TODO: Look at HotSpotStoreConstantOp
+ Store, // store only works for compressed oops (memory <- 32bit value). Compressed oops is
+ // not supported using AOT. TODO: Look at HotSpotStoreConstantOp
Compare; // HotSpotCompareMemoryConstantOp, HotSpotCompareConstantOp
private MetaSpaceAccessType() {
@@ -128,13 +139,11 @@
*/
public static final class MetaSpaceAccess extends Infopoint {
- private static final long serialVersionUID = 1701958512608684706L;
-
/**
* Metaspace reference.
*/
public final Object reference; // Object here is a HotSpotResolvedObjectType or a
- // HotSpotMetaSpaceConstant
+ // HotSpotMetaSpaceConstant
public final MetaSpaceAccessType type;
@@ -296,6 +305,15 @@
}
return false;
}
+
+ @Override
+ public String toString() {
+ if (initialized) {
+ return String.format("DataSection[0x%x]", offset);
+ } else {
+ return "DataSection[?]";
+ }
+ }
}
/**
@@ -528,8 +546,6 @@
}
}
- private int id = -1;
-
/**
* Specifies whether this compilation is a {@code +ImmutableCode} {@code +GeneratePIC}
* compilation.
@@ -612,7 +628,6 @@
CompilationResult that = (CompilationResult) obj;
// @formatter:off
if (this.entryBCI == that.entryBCI &&
- this.id == that.id &&
this.customStackAreaOffset == that.customStackAreaOffset &&
this.totalFrameSize == that.totalFrameSize &&
this.targetCodeSize == that.targetCodeSize &&
@@ -633,20 +648,6 @@
}
/**
- * @return the compile id
- */
- public int getId() {
- return id;
- }
-
- /**
- * @param id the compile id to set
- */
- public void setId(int id) {
- this.id = id;
- }
-
- /**
* @return true is this is a {@code +ImmutableCode} {@code +GeneratePIC} compilation, false
* otherwise.
*/
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DataSection.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DataSection.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,15 +22,18 @@
*/
package jdk.vm.ci.code;
-import static jdk.vm.ci.meta.MetaUtil.*;
+import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
-import java.nio.*;
-import java.util.*;
-import java.util.function.*;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Objects;
+import java.util.function.Consumer;
-import jdk.vm.ci.code.CompilationResult.*;
-import jdk.vm.ci.code.DataSection.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.CompilationResult.DataPatch;
+import jdk.vm.ci.code.CompilationResult.DataSectionReference;
+import jdk.vm.ci.code.DataSection.Data;
+import jdk.vm.ci.meta.SerializableConstant;
public final class DataSection implements Iterable<Data> {
@@ -176,11 +179,27 @@
*/
public DataSectionReference insertData(Data data) {
assert !finalLayout;
- if (data.ref == null) {
- data.ref = new DataSectionReference();
+ synchronized (data) {
+ if (data.ref == null) {
+ data.ref = new DataSectionReference();
+ dataItems.add(data);
+ }
+ return data.ref;
+ }
+ }
+
+ /**
+ * Transfers all {@link Data} from the provided other {@link DataSection} to this
+ * {@link DataSection}, and empties the other section.
+ */
+ public void addAll(DataSection other) {
+ assert !finalLayout && !other.finalLayout;
+
+ for (Data data : other.dataItems) {
+ assert data.ref != null;
dataItems.add(data);
}
- return data.ref;
+ other.dataItems.clear();
}
/**
@@ -195,14 +214,16 @@
dataItems.sort((a, b) -> a.alignment - b.alignment);
int position = 0;
+ int alignment = 1;
for (Data d : dataItems) {
- sectionAlignment = lcm(sectionAlignment, d.alignment);
+ alignment = lcm(alignment, d.alignment);
position = align(position, d.alignment);
d.ref.setOffset(position);
position += d.size;
}
+ sectionAlignment = alignment;
sectionSize = position;
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DebugInfo.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/DebugInfo.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.Objects;
/**
* Represents the debugging information for a particular point of execution. This information
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InstalledCode.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InstalledCode.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,14 +29,19 @@
public class InstalledCode {
/**
- * Raw address of this code blob.
+ * Raw address address of entity representing this installed code.
*/
- private long address;
+ protected long address;
+
+ /**
+ * Raw address of entryPoint of this installed code.
+ */
+ protected long entryPoint;
/**
* Counts how often the address field was reassigned.
*/
- private long version;
+ protected long version;
protected final String name;
@@ -44,27 +49,29 @@
this.name = name;
}
- public final void setAddress(long address) {
- this.address = address;
- version++;
- }
-
/**
- * @return the address of this code blob
+ * @return the address of entity representing this installed code.
*/
public final long getAddress() {
return address;
}
/**
- * @return the address of this code blob
+ * @return the address of the normal entry point of the installed code.
+ */
+ public final long getEntryPoint() {
+ return entryPoint;
+ }
+
+ /**
+ * @return the version number of this installed code
*/
public final long getVersion() {
return version;
}
/**
- * Returns the name of this code blob.
+ * Returns the name of this installed code.
*/
public String getName() {
return name;
@@ -79,10 +86,19 @@
}
/**
- * Returns the number of instruction bytes for this code.
+ * @return true if the code represented by this object is still valid for invocation, false
+ * otherwise (may happen due to deopt, etc.)
*/
- public long getCodeSize() {
- return 0;
+ public boolean isValid() {
+ return entryPoint != 0;
+ }
+
+ /**
+ * @return true if the code represented by this object still exists and might have live
+ * activations, false otherwise (may happen due to deopt, etc.)
+ */
+ public boolean isAlive() {
+ return address != 0;
}
/**
@@ -93,17 +109,9 @@
}
/**
- * @return true if the code represented by this object is still valid, false otherwise (may
- * happen due to deopt, etc.)
- */
- public boolean isValid() {
- return address != 0;
- }
-
- /**
* Invalidates this installed code such that any subsequent
* {@linkplain #executeVarargs(Object...) invocation} will throw an
- * {@link InvalidInstalledCodeException}.
+ * {@link InvalidInstalledCodeException} and all existing invocations will be deoptimized.
*/
public void invalidate() {
throw new UnsupportedOperationException();
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Location.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Location.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,8 @@
*/
package jdk.vm.ci.code;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
/**
* Represents a target machine register.
@@ -80,22 +81,15 @@
public static class RegisterCategory {
private final String name;
-
- private final int referenceMapOffset;
- private final int referenceMapShift;
+ private final boolean mayContainReference;
public RegisterCategory(String name) {
- this(name, 0, 0);
+ this(name, true);
}
- public RegisterCategory(String name, int referenceMapOffset) {
- this(name, referenceMapOffset, 0);
- }
-
- public RegisterCategory(String name, int referenceMapOffset, int referenceMapShift) {
+ public RegisterCategory(String name, boolean mayContainReference) {
this.name = name;
- this.referenceMapOffset = referenceMapOffset;
- this.referenceMapShift = referenceMapShift;
+ this.mayContainReference = mayContainReference;
}
@Override
@@ -112,7 +106,7 @@
public boolean equals(Object obj) {
if (obj instanceof RegisterCategory) {
RegisterCategory that = (RegisterCategory) obj;
- return this.referenceMapOffset == that.referenceMapOffset && this.referenceMapShift == that.referenceMapShift && this.name.equals(that.name);
+ return this.name.equals(that.name);
}
return false;
}
@@ -138,10 +132,10 @@
}
/**
- * Get the start index of this register in the {@link ReferenceMap}.
+ * Determine whether this register needs to be part of the reference map.
*/
- public int getReferenceMapIndex() {
- return (encoding << registerCategory.referenceMapShift) + registerCategory.referenceMapOffset;
+ public boolean mayContainReference() {
+ return registerCategory.mayContainReference;
}
/**
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterAttributes.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterAttributes.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.Arrays;
/**
* A collection of register attributes. The specific attribute values for a register may be local to
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,8 +22,10 @@
*/
package jdk.vm.ci.code;
-import jdk.vm.ci.code.CallingConvention.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.CallingConvention.Type;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.PlatformKind;
/**
* A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterSaveLayout.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterSaveLayout.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,11 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.TreeMap;
/**
* A map from registers to frame slots. This can be used to describe where callee saved registers
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,9 @@
*/
package jdk.vm.ci.code;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
/**
* Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SourceStackTrace.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SourceStackTrace.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackLockValue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackLockValue.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,9 @@
*/
package jdk.vm.ci.code;
-import static jdk.vm.ci.code.ValueUtil.*;
-
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaValue;
+import jdk.vm.ci.meta.Value;
/**
* Represents lock information in the debug information.
@@ -32,10 +32,10 @@
public final class StackLockValue implements JavaValue {
private JavaValue owner;
- private StackSlotValue slot;
+ private AllocatableValue slot;
private final boolean eliminated;
- public StackLockValue(JavaValue object, StackSlotValue slot, boolean eliminated) {
+ public StackLockValue(JavaValue object, AllocatableValue slot, boolean eliminated) {
this.owner = object;
this.slot = slot;
this.eliminated = eliminated;
@@ -81,8 +81,7 @@
return false;
}
- public void setSlot(StackSlotValue stackSlot) {
- assert slot == null || (isVirtualStackSlot(slot) && (slot.equals(stackSlot) || isStackSlot(stackSlot))) : String.format("Can not set slot for %s to %s", this, stackSlot);
+ public void setSlot(AllocatableValue stackSlot) {
slot = stackSlot;
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,13 +22,14 @@
*/
package jdk.vm.ci.code;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.LIRKind;
/**
* Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an
* incoming stack-based argument in a method's {@linkplain #isInCallerFrame() caller's frame}.
*/
-public final class StackSlot extends StackSlotValue {
+public final class StackSlot extends AllocatableValue {
private final int offset;
private final boolean addFrameSize;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlotValue.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2014, 2014, 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.
- */
-package jdk.vm.ci.code;
-
-import jdk.vm.ci.meta.*;
-
-/**
- * Common base class for {@linkplain StackSlot real} and {@linkplain VirtualStackSlot virtual} stack
- * slots.
- */
-public abstract class StackSlotValue extends AllocatableValue {
-
- public StackSlotValue(LIRKind lirKind) {
- super(lirKind);
- }
-
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,10 @@
*/
package jdk.vm.ci.code;
-import static jdk.vm.ci.meta.MetaUtil.*;
-
-import jdk.vm.ci.meta.*;
+import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
/**
* Represents the target machine for a compiler, including the CPU architecture, the size of
@@ -50,9 +51,9 @@
public final int wordSize;
/**
- * The kind to be used for representing raw pointers and CPU registers.
+ * The {@link JavaKind} to be used for representing raw pointers and CPU registers in Java code.
*/
- public final JavaKind wordKind;
+ public final JavaKind wordJavaKind;
/**
* The stack alignment requirement of the platform. For example, from Appendix D of <a
@@ -78,10 +79,12 @@
this.arch = arch;
this.isMP = isMP;
this.wordSize = arch.getWordSize();
- this.wordKind = JavaKind.fromWordSize(wordSize);
+ this.wordJavaKind = JavaKind.fromWordSize(wordSize);
this.stackAlignment = stackAlignment;
this.implicitNullCheckLimit = implicitNullCheckLimit;
this.inlineObjects = inlineObjects;
+
+ assert arch.getPlatformKind(wordJavaKind).equals(arch.getWordKind());
}
@Override
@@ -101,7 +104,7 @@
this.inlineObjects == that.inlineObjects &&
this.isMP == that.isMP &&
this.stackAlignment == that.stackAlignment &&
- this.wordKind.equals(that.wordKind) &&
+ this.wordJavaKind.equals(that.wordJavaKind) &&
this.wordSize == that.wordSize &&
this.arch.equals(that.arch)) {
return true;
@@ -116,10 +119,6 @@
return identityHashCodeString(this);
}
- public int getSizeInBytes(PlatformKind kind) {
- return kind.getSizeInBytes();
- }
-
public LIRKind getLIRKind(JavaKind javaKind) {
PlatformKind platformKind = arch.getPlatformKind(javaKind);
if (javaKind.isObject()) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/UnsignedMath.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2011, 2011, 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.
- */
-package jdk.vm.ci.code;
-
-import java.math.*;
-
-//JaCoCo Exclude
-
-/**
- * Utilities for unsigned comparisons. All methods have correct, but slow, standard Java
- * implementations so that they can be used with compilers not supporting the intrinsics.
- */
-public class UnsignedMath {
-
- private static final long MASK = 0xffffffffL;
-
- /**
- * Unsigned comparison aboveThan for two numbers.
- */
- public static boolean aboveThan(int a, int b) {
- return (a & MASK) > (b & MASK);
- }
-
- /**
- * Unsigned comparison aboveOrEqual for two numbers.
- */
- public static boolean aboveOrEqual(int a, int b) {
- return (a & MASK) >= (b & MASK);
- }
-
- /**
- * Unsigned comparison belowThan for two numbers.
- */
- public static boolean belowThan(int a, int b) {
- return (a & MASK) < (b & MASK);
- }
-
- /**
- * Unsigned comparison belowOrEqual for two numbers.
- */
- public static boolean belowOrEqual(int a, int b) {
- return (a & MASK) <= (b & MASK);
- }
-
- /**
- * Unsigned comparison aboveThan for two numbers.
- */
- public static boolean aboveThan(long a, long b) {
- return (a > b) ^ ((a < 0) != (b < 0));
- }
-
- /**
- * Unsigned comparison aboveOrEqual for two numbers.
- */
- public static boolean aboveOrEqual(long a, long b) {
- return (a >= b) ^ ((a < 0) != (b < 0));
- }
-
- /**
- * Unsigned comparison belowThan for two numbers.
- */
- public static boolean belowThan(long a, long b) {
- return (a < b) ^ ((a < 0) != (b < 0));
- }
-
- /**
- * Unsigned comparison belowOrEqual for two numbers.
- */
- public static boolean belowOrEqual(long a, long b) {
- return (a <= b) ^ ((a < 0) != (b < 0));
- }
-
- /**
- * Unsigned division for two numbers.
- */
- public static int divide(int a, int b) {
- return (int) ((a & MASK) / (b & MASK));
- }
-
- /**
- * Unsigned remainder for two numbers.
- */
- public static int remainder(int a, int b) {
- return (int) ((a & MASK) % (b & MASK));
- }
-
- /**
- * Unsigned division for two numbers.
- */
- public static long divide(long a, long b) {
- return bi(a).divide(bi(b)).longValue();
- }
-
- /**
- * Unsigned remainder for two numbers.
- */
- public static long remainder(long a, long b) {
- return bi(a).remainder(bi(b)).longValue();
- }
-
- private static BigInteger bi(long unsigned) {
- return unsigned >= 0 ? BigInteger.valueOf(unsigned) : BigInteger.valueOf(unsigned & 0x7fffffffffffffffL).setBit(63);
- }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,14 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaValue;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.Value;
/**
* Utility class for working with the {@link Value} class and its subclasses.
@@ -60,6 +65,11 @@
return value instanceof JavaConstant;
}
+ public static JavaConstant asConstantJavaValue(JavaValue value) {
+ assert value != null;
+ return (JavaConstant) value;
+ }
+
public static boolean isAllocatableValue(Value value) {
assert value != null;
return value instanceof AllocatableValue;
@@ -80,26 +90,6 @@
return (StackSlot) value;
}
- public static boolean isStackSlotValue(Value value) {
- assert value != null;
- return value instanceof StackSlotValue;
- }
-
- public static StackSlotValue asStackSlotValue(Value value) {
- assert value != null;
- return (StackSlotValue) value;
- }
-
- public static boolean isVirtualStackSlot(Value value) {
- assert value != null;
- return value instanceof VirtualStackSlot;
- }
-
- public static VirtualStackSlot asVirtualStackSlot(Value value) {
- assert value != null;
- return (VirtualStackSlot) value;
- }
-
public static boolean isRegister(Value value) {
assert value != null;
return value instanceof RegisterValue;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualObject.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,15 @@
*/
package jdk.vm.ci.code;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Set;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaValue;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* An instance of this class represents an object whose allocation was removed by escape analysis.
@@ -134,45 +140,6 @@
return id;
}
- private boolean checkValues() {
- assert (values == null) == (slotKinds == null);
- if (values != null) {
- assert values.length == slotKinds.length;
- if (!type.isArray()) {
- ResolvedJavaField[] fields = type.getInstanceFields(true);
- int fieldIndex = 0;
- for (int i = 0; i < values.length; i++) {
- ResolvedJavaField field = fields[fieldIndex++];
- JavaKind valKind = slotKinds[i].getStackKind();
- if (field.getJavaKind() == JavaKind.Object) {
- assert valKind.isObject() : field + ": " + valKind + " != " + field.getJavaKind();
- } else {
- if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && field.getJavaKind() == JavaKind.Int) {
- assert fields[fieldIndex].getJavaKind() == JavaKind.Int;
- fieldIndex++;
- } else {
- assert valKind == field.getJavaKind().getStackKind() : field + ": " + valKind + " != " + field.getJavaKind();
- }
- }
- }
- assert fields.length == fieldIndex : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
- } else {
- JavaKind componentKind = type.getComponentType().getJavaKind().getStackKind();
- if (componentKind == JavaKind.Object) {
- for (int i = 0; i < values.length; i++) {
- assert slotKinds[i].isObject() : slotKinds[i] + " != " + componentKind;
- }
- } else {
- for (int i = 0; i < values.length; i++) {
- assert slotKinds[i] == componentKind || componentKind.getBitCount() >= slotKinds[i].getBitCount() ||
- (componentKind == JavaKind.Int && slotKinds[i].getBitCount() >= JavaKind.Int.getBitCount()) : slotKinds[i] + " != " + componentKind;
- }
- }
- }
- }
- return true;
- }
-
/**
* Overwrites the current set of values with a new one.
*
@@ -183,7 +150,6 @@
public void setValues(JavaValue[] values, JavaKind[] slotKinds) {
this.values = values;
this.slotKinds = slotKinds;
- assert checkValues();
}
@Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/VirtualStackSlot.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2014, 2014, 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.
- */
-package jdk.vm.ci.code;
-
-import jdk.vm.ci.meta.*;
-
-/**
- * {@link VirtualStackSlot}s are stack slots that are not yet fixed to specific frame offset. They
- * are replaced by real {@link StackSlot}s with a fixed position in the frame before code emission.
- */
-public abstract class VirtualStackSlot extends StackSlotValue {
-
- private final int id;
-
- public VirtualStackSlot(int id, LIRKind lirKind) {
- super(lirKind);
- this.id = id;
- }
-
- public int getId() {
- return id;
- }
-
- @Override
- public String toString() {
- return "vstack:" + id + getKindSuffix();
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + id;
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (!super.equals(obj)) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- VirtualStackSlot other = (VirtualStackSlot) obj;
- if (id != other.id) {
- return false;
- }
- return true;
- }
-
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java Wed Jul 05 21:00:20 2017 +0200
@@ -18,10 +18,10 @@
* if you need additional information or have any questions.
*/
/**
- * Package that defines the interface between a Java application that wants to install code and the
- * runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider}
- * interface. The method
- * {@link jdk.vm.ci.code.CodeCacheProvider#addMethod(jdk.vm.ci.meta.ResolvedJavaMethod, CompilationResult, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
- * can be used to install code for a given method.
+ * Package that defines the interface between a Java application that wants to install code and the runtime.
+ * The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider} interface.
+ * The method {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompilationResult, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
+ * can be used to install code.
*/
package jdk.vm.ci.code;
+
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code.stack;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
public interface InspectedFrame {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/StackIntrospection.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/StackIntrospection.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code.stack;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
public interface StackIntrospection {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,8 @@
*/
package jdk.vm.ci.common;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Locale;
/**
* Indicates a condition in JVMCI related code that should never occur during normal operation.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.compiler/src/jdk/vm/ci/compiler/Compiler.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.compiler;
-
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.options.*;
-
-public interface Compiler {
- int INVOCATION_ENTRY_BCI = -1;
-
- @Option(help = "", type = OptionType.Debug) OptionValue<String> PrintFilter = new OptionValue<>(null);
- @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintCompilation = new OptionValue<>(false);
- @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintAfterCompilation = new OptionValue<>(false);
- @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintBailout = new OptionValue<>(false);
- @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> ExitVMOnBailout = new OptionValue<>(false);
- @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> ExitVMOnException = new OptionValue<>(true);
- @Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintStackTraceOnException = new OptionValue<>(false);
-
- /**
- * Request the compilation of a method by this JVMCI compiler. The compiler should compile the
- * method to machine code and install it in the code cache if the compilation is successful.
- *
- * @param method the method that should be compiled
- * @param entryBCI the BCI at which to start compiling where -1 denotes a non-OSR compilation
- * request and all other values denote an OSR compilation request
- * @param jvmciEnv pointer to native {@code JVMCIEnv} object
- * @param id a unique identifier for this compilation
- */
- void compileMethod(ResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id);
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.compiler/src/jdk/vm/ci/compiler/CompilerFactory.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.compiler;
-
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.runtime.*;
-
-/**
- * Factory for a JVMCI compiler.
- */
-public interface CompilerFactory {
-
- /**
- * Get the name of this compiler. The compiler will be selected when the jvmci.compiler system
- * property is equal to this name.
- */
- String getCompilerName();
-
- /**
- * Initialize an {@link Architecture}. The compiler has the opportunity to extend the
- * {@link Architecture} description with a custom subclass.
- */
- Architecture initializeArchitecture(Architecture arch);
-
- /**
- * Create a new instance of the {@link Compiler}.
- */
- Compiler createCompiler(JVMCIRuntime runtime);
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.compiler/src/jdk/vm/ci/compiler/StartupEventListener.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.compiler;
-
-public interface StartupEventListener {
-
- /**
- * This method is called before any of the {@link CompilerFactory} methods.
- */
- void beforeJVMCIStartup();
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,18 +22,26 @@
*/
package jdk.vm.ci.hotspot.amd64;
-import static jdk.vm.ci.inittimer.InitTimer.*;
+import static jdk.vm.ci.inittimer.InitTimer.timer;
-import java.util.*;
+import java.util.EnumSet;
-import jdk.vm.ci.amd64.*;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.compiler.*;
-import jdk.vm.ci.hotspot.*;
-import jdk.vm.ci.inittimer.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.runtime.*;
-import jdk.vm.ci.service.*;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
+import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
+import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
+import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
+import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.inittimer.InitTimer;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.runtime.JVMCIBackend;
+import jdk.vm.ci.service.ServiceProvider;
@ServiceProvider(HotSpotJVMCIBackendFactory.class)
public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
@@ -68,6 +76,9 @@
if ((config.x86CPUFeatures & config.cpuLZCNT) != 0) {
features.add(AMD64.CPUFeature.LZCNT);
}
+ if ((config.x86CPUFeatures & config.cpuERMS) != 0) {
+ features.add(AMD64.CPUFeature.ERMS);
+ }
if ((config.x86CPUFeatures & config.cpuAVX) != 0) {
features.add(AMD64.CPUFeature.AVX);
}
@@ -77,12 +88,42 @@
if ((config.x86CPUFeatures & config.cpuAES) != 0) {
features.add(AMD64.CPUFeature.AES);
}
- if ((config.x86CPUFeatures & config.cpuERMS) != 0) {
- features.add(AMD64.CPUFeature.ERMS);
+ if ((config.x86CPUFeatures & config.cpu3DNOWPREFETCH) != 0) {
+ features.add(AMD64.CPUFeature.AMD_3DNOW_PREFETCH);
}
if ((config.x86CPUFeatures & config.cpuBMI1) != 0) {
features.add(AMD64.CPUFeature.BMI1);
}
+ if ((config.x86CPUFeatures & config.cpuBMI2) != 0) {
+ features.add(AMD64.CPUFeature.BMI2);
+ }
+ if ((config.x86CPUFeatures & config.cpuRTM) != 0) {
+ features.add(AMD64.CPUFeature.RTM);
+ }
+ if ((config.x86CPUFeatures & config.cpuADX) != 0) {
+ features.add(AMD64.CPUFeature.ADX);
+ }
+ if ((config.x86CPUFeatures & config.cpuAVX512F) != 0) {
+ features.add(AMD64.CPUFeature.AVX512F);
+ }
+ if ((config.x86CPUFeatures & config.cpuAVX512DQ) != 0) {
+ features.add(AMD64.CPUFeature.AVX512DQ);
+ }
+ if ((config.x86CPUFeatures & config.cpuAVX512PF) != 0) {
+ features.add(AMD64.CPUFeature.AVX512PF);
+ }
+ if ((config.x86CPUFeatures & config.cpuAVX512ER) != 0) {
+ features.add(AMD64.CPUFeature.AVX512ER);
+ }
+ if ((config.x86CPUFeatures & config.cpuAVX512CD) != 0) {
+ features.add(AMD64.CPUFeature.AVX512CD);
+ }
+ if ((config.x86CPUFeatures & config.cpuAVX512BW) != 0) {
+ features.add(AMD64.CPUFeature.AVX512BW);
+ }
+ if ((config.x86CPUFeatures & config.cpuAVX512VL) != 0) {
+ features.add(AMD64.CPUFeature.AVX512VL);
+ }
return features;
}
@@ -97,12 +138,12 @@
return flags;
}
- protected TargetDescription createTarget(HotSpotVMConfig config, CompilerFactory compilerFactory) {
+ protected TargetDescription createTarget(HotSpotVMConfig config) {
final int stackFrameAlignment = 16;
final int implicitNullCheckLimit = 4096;
final boolean inlineObjects = true;
Architecture arch = new AMD64(computeFeatures(config), computeFlags(config));
- return new TargetDescription(compilerFactory.initializeArchitecture(arch), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+ return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
}
protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMCIRuntimeProvider runtime) {
@@ -132,15 +173,16 @@
}
@SuppressWarnings("try")
- public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host) {
+ public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, JVMCIBackend host) {
assert host == null;
- TargetDescription target = createTarget(runtime.getConfig(), compilerFactory);
+ TargetDescription target = createTarget(runtime.getConfig());
RegisterConfig regConfig;
HotSpotCodeCacheProvider codeCache;
ConstantReflectionProvider constantReflection;
HotSpotMetaAccessProvider metaAccess;
+ StackIntrospection stackIntrospection;
try (InitTimer t = timer("create providers")) {
try (InitTimer rt = timer("create MetaAccess provider")) {
metaAccess = createMetaAccess(runtime);
@@ -154,13 +196,16 @@
try (InitTimer rt = timer("create ConstantReflection provider")) {
constantReflection = createConstantReflection(runtime);
}
+ try (InitTimer rt = timer("create StackIntrospection provider")) {
+ stackIntrospection = new HotSpotStackIntrospection(runtime);
+ }
}
try (InitTimer rt = timer("instantiate backend")) {
- return createBackend(metaAccess, codeCache, constantReflection);
+ return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}
- protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection) {
- return new JVMCIBackend(metaAccess, codeCache, constantReflection);
+ protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) {
+ return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,16 +22,47 @@
*/
package jdk.vm.ci.hotspot.amd64;
-import static jdk.vm.ci.amd64.AMD64.*;
-
-import java.util.*;
+import static jdk.vm.ci.amd64.AMD64.r12;
+import static jdk.vm.ci.amd64.AMD64.r15;
+import static jdk.vm.ci.amd64.AMD64.r8;
+import static jdk.vm.ci.amd64.AMD64.r9;
+import static jdk.vm.ci.amd64.AMD64.rax;
+import static jdk.vm.ci.amd64.AMD64.rcx;
+import static jdk.vm.ci.amd64.AMD64.rdi;
+import static jdk.vm.ci.amd64.AMD64.rdx;
+import static jdk.vm.ci.amd64.AMD64.rsi;
+import static jdk.vm.ci.amd64.AMD64.rsp;
+import static jdk.vm.ci.amd64.AMD64.xmm0;
+import static jdk.vm.ci.amd64.AMD64.xmm1;
+import static jdk.vm.ci.amd64.AMD64.xmm2;
+import static jdk.vm.ci.amd64.AMD64.xmm3;
+import static jdk.vm.ci.amd64.AMD64.xmm4;
+import static jdk.vm.ci.amd64.AMD64.xmm5;
+import static jdk.vm.ci.amd64.AMD64.xmm6;
+import static jdk.vm.ci.amd64.AMD64.xmm7;
-import jdk.vm.ci.amd64.*;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.code.CallingConvention.*;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.hotspot.*;
-import jdk.vm.ci.meta.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.CallingConvention.Type;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterAttributes;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.StackSlot;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.Value;
public class AMD64HotSpotRegisterConfig implements RegisterConfig {
@@ -86,28 +117,30 @@
*/
private final boolean needsNativeStackHomeSpace;
- private static Register[] initAllocatable(boolean reserveForHeapBase) {
- Register[] registers = null;
- // @formatter:off
- if (reserveForHeapBase) {
- registers = new Register[] {
- rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, /*r12,*/ r13, r14, /*r15, */
- xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
- xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
- };
- } else {
- registers = new Register[] {
- rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, /*r15, */
- xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
- xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
- };
+ private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
+ Register[] allRegisters = arch.getAvailableValueRegisters();
+ Register[] registers = new Register[allRegisters.length - (reserveForHeapBase ? 3 : 2)];
+
+ int idx = 0;
+ for (Register reg : allRegisters) {
+ if (reg.equals(rsp) || reg.equals(r15)) {
+ // skip stack pointer and thread register
+ continue;
+ }
+ if (reserveForHeapBase && reg.equals(r12)) {
+ // skip heap base register
+ continue;
+ }
+
+ registers[idx++] = reg;
}
- // @formatter:on
+
+ assert idx == registers.length;
return registers;
}
public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
- this(architecture, config, initAllocatable(config.useCompressedOops));
+ this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
assert callerSaved.length >= allocatable.length;
}
@@ -125,7 +158,7 @@
this.needsNativeStackHomeSpace = false;
}
- this.allocatable = allocatable.clone();
+ this.allocatable = allocatable;
Set<Register> callerSaveSet = new HashSet<>();
Collections.addAll(callerSaveSet, allocatable);
Collections.addAll(callerSaveSet, xmmParameterRegisters);
@@ -134,7 +167,7 @@
callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
allAllocatableAreCallerSaved = true;
- attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters);
+ attributesMap = RegisterAttributes.createMap(this, architecture.getRegisters());
}
@Override
@@ -221,7 +254,7 @@
if (locations[i] == null) {
LIRKind lirKind = target.getLIRKind(kind);
locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
- currentStackOffset += Math.max(target.getSizeInBytes(lirKind.getPlatformKind()), target.wordSize);
+ currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,28 +22,36 @@
*/
package jdk.vm.ci.hotspot.sparc;
-import static jdk.vm.ci.inittimer.InitTimer.*;
+import static jdk.vm.ci.inittimer.InitTimer.timer;
-import java.util.*;
+import java.util.EnumSet;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.compiler.*;
-import jdk.vm.ci.hotspot.*;
-import jdk.vm.ci.inittimer.*;
-import jdk.vm.ci.runtime.*;
-import jdk.vm.ci.service.*;
-import jdk.vm.ci.sparc.*;
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
+import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
+import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
+import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
+import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.inittimer.InitTimer;
+import jdk.vm.ci.runtime.JVMCIBackend;
+import jdk.vm.ci.service.ServiceProvider;
+import jdk.vm.ci.sparc.SPARC;
import jdk.vm.ci.sparc.SPARC.CPUFeature;
@ServiceProvider(HotSpotJVMCIBackendFactory.class)
public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
- protected TargetDescription createTarget(HotSpotVMConfig config, CompilerFactory compilerFactory) {
+ protected TargetDescription createTarget(HotSpotVMConfig config) {
final int stackFrameAlignment = 16;
final int implicitNullCheckLimit = 4096;
final boolean inlineObjects = false;
Architecture arch = new SPARC(computeFeatures(config));
- return new TargetDescription(compilerFactory.initializeArchitecture(arch), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+ return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
}
protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
@@ -64,8 +72,62 @@
if ((config.sparcFeatures & config.cbcondInstructions) != 0) {
features.add(CPUFeature.CBCOND);
}
- if (config.useBlockZeroing) {
- features.add(CPUFeature.BLOCK_ZEROING);
+ if ((config.sparcFeatures & config.v8Instructions) != 0) {
+ features.add(CPUFeature.V8);
+ }
+ if ((config.sparcFeatures & config.hardwareMul32) != 0) {
+ features.add(CPUFeature.HARDWARE_MUL32);
+ }
+ if ((config.sparcFeatures & config.hardwareDiv32) != 0) {
+ features.add(CPUFeature.HARDWARE_DIV32);
+ }
+ if ((config.sparcFeatures & config.hardwareFsmuld) != 0) {
+ features.add(CPUFeature.HARDWARE_FSMULD);
+ }
+ if ((config.sparcFeatures & config.hardwarePopc) != 0) {
+ features.add(CPUFeature.HARDWARE_POPC);
+ }
+ if ((config.sparcFeatures & config.v9Instructions) != 0) {
+ features.add(CPUFeature.V9);
+ }
+ if ((config.sparcFeatures & config.sun4v) != 0) {
+ features.add(CPUFeature.SUN4V);
+ }
+ if ((config.sparcFeatures & config.blkInitInstructions) != 0) {
+ features.add(CPUFeature.BLK_INIT_INSTRUCTIONS);
+ }
+ if ((config.sparcFeatures & config.fmafInstructions) != 0) {
+ features.add(CPUFeature.FMAF);
+ }
+ if ((config.sparcFeatures & config.fmauInstructions) != 0) {
+ features.add(CPUFeature.FMAU);
+ }
+ if ((config.sparcFeatures & config.sparc64Family) != 0) {
+ features.add(CPUFeature.SPARC64_FAMILY);
+ }
+ if ((config.sparcFeatures & config.mFamily) != 0) {
+ features.add(CPUFeature.M_FAMILY);
+ }
+ if ((config.sparcFeatures & config.tFamily) != 0) {
+ features.add(CPUFeature.T_FAMILY);
+ }
+ if ((config.sparcFeatures & config.t1Model) != 0) {
+ features.add(CPUFeature.T1_MODEL);
+ }
+ if ((config.sparcFeatures & config.sparc5Instructions) != 0) {
+ features.add(CPUFeature.SPARC5);
+ }
+ if ((config.sparcFeatures & config.aesInstructions) != 0) {
+ features.add(CPUFeature.SPARC64_FAMILY);
+ }
+ if ((config.sparcFeatures & config.sha1Instruction) != 0) {
+ features.add(CPUFeature.SHA1);
+ }
+ if ((config.sparcFeatures & config.sha256Instruction) != 0) {
+ features.add(CPUFeature.SHA256);
+ }
+ if ((config.sparcFeatures & config.sha512Instruction) != 0) {
+ features.add(CPUFeature.SHA512);
}
return features;
}
@@ -81,20 +143,22 @@
}
@SuppressWarnings("try")
- public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host) {
+ public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, JVMCIBackend host) {
assert host == null;
- TargetDescription target = createTarget(runtime.getConfig(), compilerFactory);
+ TargetDescription target = createTarget(runtime.getConfig());
HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime);
- RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target, runtime.getConfig());
+ RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target.arch, runtime.getConfig());
HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target, regConfig);
HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
+ StackIntrospection stackIntrospection = new HotSpotStackIntrospection(runtime);
try (InitTimer rt = timer("instantiate backend")) {
- return createBackend(metaAccess, codeCache, constantReflection);
+ return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}
- protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, HotSpotConstantReflectionProvider constantReflection) {
- return new JVMCIBackend(metaAccess, codeCache, constantReflection);
+ protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, HotSpotConstantReflectionProvider constantReflection,
+ StackIntrospection stackIntrospection) {
+ return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,16 +22,72 @@
*/
package jdk.vm.ci.hotspot.sparc;
-import static jdk.vm.ci.sparc.SPARC.*;
-
-import java.util.*;
+import static jdk.vm.ci.code.CallingConvention.Type.JavaCall;
+import static jdk.vm.ci.code.CallingConvention.Type.JavaCallee;
+import static jdk.vm.ci.code.CallingConvention.Type.NativeCall;
+import static jdk.vm.ci.meta.JavaKind.Void;
+import static jdk.vm.ci.meta.Value.ILLEGAL;
+import static jdk.vm.ci.sparc.SPARC.REGISTER_SAFE_AREA_SIZE;
+import static jdk.vm.ci.sparc.SPARC.d0;
+import static jdk.vm.ci.sparc.SPARC.d2;
+import static jdk.vm.ci.sparc.SPARC.d4;
+import static jdk.vm.ci.sparc.SPARC.d6;
+import static jdk.vm.ci.sparc.SPARC.f0;
+import static jdk.vm.ci.sparc.SPARC.f1;
+import static jdk.vm.ci.sparc.SPARC.f2;
+import static jdk.vm.ci.sparc.SPARC.f3;
+import static jdk.vm.ci.sparc.SPARC.f4;
+import static jdk.vm.ci.sparc.SPARC.f5;
+import static jdk.vm.ci.sparc.SPARC.f6;
+import static jdk.vm.ci.sparc.SPARC.f7;
+import static jdk.vm.ci.sparc.SPARC.g0;
+import static jdk.vm.ci.sparc.SPARC.g2;
+import static jdk.vm.ci.sparc.SPARC.g6;
+import static jdk.vm.ci.sparc.SPARC.i0;
+import static jdk.vm.ci.sparc.SPARC.i1;
+import static jdk.vm.ci.sparc.SPARC.i2;
+import static jdk.vm.ci.sparc.SPARC.i3;
+import static jdk.vm.ci.sparc.SPARC.i4;
+import static jdk.vm.ci.sparc.SPARC.i5;
+import static jdk.vm.ci.sparc.SPARC.i6;
+import static jdk.vm.ci.sparc.SPARC.i7;
+import static jdk.vm.ci.sparc.SPARC.l0;
+import static jdk.vm.ci.sparc.SPARC.l1;
+import static jdk.vm.ci.sparc.SPARC.l2;
+import static jdk.vm.ci.sparc.SPARC.l3;
+import static jdk.vm.ci.sparc.SPARC.l4;
+import static jdk.vm.ci.sparc.SPARC.l5;
+import static jdk.vm.ci.sparc.SPARC.l6;
+import static jdk.vm.ci.sparc.SPARC.l7;
+import static jdk.vm.ci.sparc.SPARC.o0;
+import static jdk.vm.ci.sparc.SPARC.o1;
+import static jdk.vm.ci.sparc.SPARC.o2;
+import static jdk.vm.ci.sparc.SPARC.o3;
+import static jdk.vm.ci.sparc.SPARC.o4;
+import static jdk.vm.ci.sparc.SPARC.o5;
+import static jdk.vm.ci.sparc.SPARC.sp;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.code.CallingConvention.*;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.hotspot.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.sparc.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.CallingConvention;
+import jdk.vm.ci.code.CallingConvention.Type;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.RegisterAttributes;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.StackSlot;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.sparc.SPARC;
public class SPARCHotSpotRegisterConfig implements RegisterConfig {
@@ -41,6 +97,11 @@
private final RegisterAttributes[] attributesMap;
+ /**
+ * Does native code (C++ code) spill arguments in registers to the parent frame?
+ */
+ private final boolean addNativeRegisterArgumentSlots;
+
@Override
public Register[] getAllocatableRegisters() {
return allocatable.clone();
@@ -50,22 +111,9 @@
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
- // Special treatment for double precision
- // TODO: This is wasteful it uses only half of the registers as float.
- if (kind == JavaKind.Double) {
- if (reg.getRegisterCategory().equals(FPUd)) {
- list.add(reg);
- }
- } else if (kind == JavaKind.Float) {
- if (reg.getRegisterCategory().equals(FPUs)) {
- list.add(reg);
- }
- } else {
- list.add(reg);
- }
+ list.add(reg);
}
}
-
Register[] ret = list.toArray(new Register[list.size()]);
return ret;
}
@@ -78,76 +126,57 @@
private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5};
private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
- private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
+ private final Register[] fpuFloatParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
+
// @formatter:off
- private final Register[] callerSaveRegisters =
- {g1, g2, g3, g4, g5, g6, g7,
- o0, o1, o2, o3, o4, o5, o7,
- f0, f1, f2, f3, f4, f5, f6, f7,
- f8, f9, f10, f11, f12, f13, f14, f15,
- f16, f17, f18, f19, f20, f21, f22, f23,
- f24, f25, f26, f27, f28, f29, f30, f31,
- d32, d34, d36, d38, d40, d42, d44, d46,
- d48, d50, d52, d54, d56, d58, d60, d62};
- // @formatter:on
+ private final Register[] callerSaveRegisters;
/**
* Registers saved by the callee. This lists all L and I registers which are saved in the
* register window.
*/
- private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7};
+ private final Register[] calleeSaveRegisters = {
+ l0, l1, l2, l3, l4, l5, l6, l7,
+ i0, i1, i2, i3, i4, i5, i6, i7};
+ // @formatter:on
+
+ private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
+ Register[] allRegisters = arch.getAvailableValueRegisters();
+ Register[] registers = new Register[allRegisters.length - (reserveForHeapBase ? 4 : 3)];
- private static Register[] initAllocatable(boolean reserveForHeapBase) {
- Register[] registers = null;
- if (reserveForHeapBase) {
- // @formatter:off
- registers = new Register[]{
- // TODO this is not complete
- // o7 cannot be used as register because it is always overwritten on call
- // and the current register handler would ignore this fact if the called
- // method still does not modify registers, in fact o7 is modified by the Call instruction
- // There would be some extra handlin necessary to be able to handle the o7 properly for local usage
- g1, g4, g5,
- o0, o1, o2, o3, o4, o5, /*o6,o7,*/
- l0, l1, l2, l3, l4, l5, l6, l7,
- i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
- //f0, f1, f2, f3, f4, f5, f6, f7,
- f8, f9, f10, f11, f12, f13, f14, f15,
- f16, f17, f18, f19, f20, f21, f22, f23,
- f24, f25, f26, f27, f28, f29, f30, f31,
- d32, d34, d36, d38, d40, d42, d44, d46,
- d48, d50, d52, d54, d56, d58, d60, d62
- };
- // @formatter:on
- } else {
- // @formatter:off
- registers = new Register[]{
- // TODO this is not complete
- g1, g4, g5,
- o0, o1, o2, o3, o4, o5, /*o6, o7,*/
- l0, l1, l2, l3, l4, l5, l6, l7,
- i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
-// f0, f1, f2, f3, f4, f5, f6, f7
- f8, f9, f10, f11, f12, f13, f14, f15,
- f16, f17, f18, f19, f20, f21, f22, f23,
- f24, f25, f26, f27, f28, f29, f30, f31,
- d32, d34, d36, d38, d40, d42, d44, d46,
- d48, d50, d52, d54, d56, d58, d60, d62
- };
- // @formatter:on
+ int idx = 0;
+ for (Register reg : allRegisters) {
+ if (reg.equals(sp) || reg.equals(g2) || reg.equals(g0)) {
+ // skip g0, stack pointer and thread register
+ continue;
+ }
+ if (reserveForHeapBase && reg.equals(g6)) {
+ // skip heap base register
+ continue;
+ }
+
+ registers[idx++] = reg;
}
+ assert idx == registers.length;
return registers;
}
- public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
- this(target, initAllocatable(config.useCompressedOops));
+ public SPARCHotSpotRegisterConfig(Architecture arch, HotSpotVMConfig config) {
+ this(arch, initAllocatable(arch, config.useCompressedOops), config);
}
- public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) {
- this.architecture = target.arch;
+ public SPARCHotSpotRegisterConfig(Architecture arch, Register[] allocatable, HotSpotVMConfig config) {
+ this.architecture = arch;
this.allocatable = allocatable.clone();
+ this.addNativeRegisterArgumentSlots = config.linuxOs;
+ HashSet<Register> callerSaveSet = new HashSet<>();
+ Collections.addAll(callerSaveSet, arch.getAvailableValueRegisters());
+ for (Register cs : calleeSaveRegisters) {
+ callerSaveSet.remove(cs);
+ }
+ this.callerSaveRegisters = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters);
}
@@ -172,21 +201,31 @@
@Override
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) {
- if (type == Type.JavaCall || type == Type.NativeCall) {
+ if (type == JavaCall || type == NativeCall) {
return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
}
- if (type == Type.JavaCallee) {
+ if (type == JavaCallee) {
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
}
throw JVMCIError.shouldNotReachHere();
}
public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
- if (architecture.canStoreValue(FPUs, kind) || architecture.canStoreValue(FPUd, kind)) {
- return fpuParameterRegisters;
+ switch (kind) {
+ case Boolean:
+ case Byte:
+ case Short:
+ case Char:
+ case Int:
+ case Long:
+ case Object:
+ return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
+ case Double:
+ case Float:
+ return fpuFloatParameterRegisters;
+ default:
+ throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
}
- assert architecture.canStoreValue(CPU, kind);
- return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
}
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) {
@@ -213,7 +252,7 @@
}
break;
case Double:
- if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
+ if (!stackOnly && currentFloating < fpuFloatParameterRegisters.length) {
if (currentFloating % 2 != 0) {
// Make register number even to be a double reg
currentFloating++;
@@ -224,8 +263,8 @@
}
break;
case Float:
- if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
- Register register = fpuParameterRegisters[currentFloating++];
+ if (!stackOnly && currentFloating < fpuFloatParameterRegisters.length) {
+ Register register = fpuFloatParameterRegisters[currentFloating++];
locations[i] = register.asValue(target.getLIRKind(kind));
}
break;
@@ -234,20 +273,27 @@
}
if (locations[i] == null) {
+ LIRKind lirKind = target.getLIRKind(kind);
// Stack slot is always aligned to its size in bytes but minimum wordsize
- int typeSize = SPARC.spillSlotSize(target, kind);
+ int typeSize = lirKind.getPlatformKind().getSizeInBytes();
currentStackOffset = roundUp(currentStackOffset, typeSize);
- int slotOffset = currentStackOffset + SPARC.REGISTER_SAFE_AREA_SIZE;
- locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), slotOffset, !type.out);
+ int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
+ locations[i] = StackSlot.get(lirKind, slotOffset, !type.out);
currentStackOffset += typeSize;
}
}
- JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
- AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
- // Space where callee may spill outgoing parameters o0...o5
- int lowerOutgoingSpace = Math.min(locations.length, 6) * target.wordSize;
- return new CallingConvention(currentStackOffset + lowerOutgoingSpace, returnLocation, locations);
+ JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
+ AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
+
+ int outArgSpillArea;
+ if (type == NativeCall && addNativeRegisterArgumentSlots) {
+ // Space for native callee which may spill our outgoing arguments
+ outArgSpillArea = Math.min(locations.length, generalParameterRegisters.length) * target.wordSize;
+ } else {
+ outArgSpillArea = 0;
+ }
+ return new CallingConvention(currentStackOffset + outArgSpillArea, returnLocation, locations);
}
private static int roundUp(int number, int mod) {
@@ -256,7 +302,7 @@
@Override
public Register getReturnRegister(JavaKind kind) {
- return getReturnRegister(kind, Type.JavaCallee);
+ return getReturnRegister(kind, JavaCallee);
}
private static Register getReturnRegister(JavaKind kind, Type type) {
@@ -268,7 +314,7 @@
case Int:
case Long:
case Object:
- return type == Type.JavaCallee ? i0 : o0;
+ return type == JavaCallee ? i0 : o0;
case Float:
return f0;
case Double:
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
package jdk.vm.ci.hotspot;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import java.lang.reflect.Constructor;
@@ -36,7 +37,6 @@
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.SpeculationLog;
import sun.misc.Unsafe;
/**
@@ -44,7 +44,7 @@
* pointer as an argument (e.g., {@link #getSymbol(long)}) is undefined if the argument does not
* denote a valid native object.
*/
-public final class CompilerToVM {
+final class CompilerToVM {
/**
* Initializes the native part of the JVMCI runtime.
*/
@@ -62,6 +62,14 @@
}
/**
+ * Gets the {@link CompilerToVM} instance associated with the singleton
+ * {@link HotSpotJVMCIRuntime} instance.
+ */
+ public static CompilerToVM compilerToVM() {
+ return runtime().getCompilerToVM();
+ }
+
+ /**
* Copies the original bytecode of {@code method} into a new byte array and returns it.
*
* @return a new byte array containing the original bytecode of {@code method}
@@ -301,7 +309,7 @@
* {@link HotSpotVMConfig#codeInstallResultDependenciesFailed} or
* {@link HotSpotVMConfig#codeInstallResultDependenciesInvalid}.
*/
- public native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog);
+ native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, HotSpotSpeculationLog speculationLog);
public native int getMetadata(TargetDescription target, HotSpotCompiledCode compiledCode, HotSpotMetaData metaData);
@@ -317,18 +325,18 @@
* @param timeUnitsPerSecond the granularity of the units for the {@code time} value
* @param installedCode the nmethod installed as a result of the compilation
*/
- public synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethodImpl method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond,
+ synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethodImpl method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond,
InstalledCode installedCode);
/**
* Resets all compilation statistics.
*/
- public native void resetCompilationStatistics();
+ native void resetCompilationStatistics();
/**
* Initializes the fields of {@code config}.
*/
- native long initializeConfiguration();
+ native long initializeConfiguration(HotSpotVMConfig config);
/**
* Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic
@@ -367,7 +375,7 @@
* @param address an address that may be called from any code in the code cache
* @return -1 if {@code address == 0}
*/
- public native long getMaxCallTargetOffset(long address);
+ native long getMaxCallTargetOffset(long address);
/**
* Gets a textual disassembly of {@code codeBlob}.
@@ -376,7 +384,7 @@
* {@code codeBlob} could not be disassembled for some reason
*/
// The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage
- public synchronized native String disassembleCodeBlob(long codeBlob);
+ synchronized native String disassembleCodeBlob(InstalledCode installedCode);
/**
* Gets a stack trace element for {@code method} at bytecode index {@code bci}.
@@ -454,12 +462,12 @@
* Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be
* raised the next time {@code installedCode} is executed.
*/
- public native void invalidateInstalledCode(InstalledCode installedCode);
+ native void invalidateInstalledCode(InstalledCode installedCode);
/**
* Collects the current values of all JVMCI benchmark counters, summed up over all threads.
*/
- public native long[] collectCounters();
+ native long[] collectCounters();
/**
* Determines if {@code metaspaceMethodData} is mature.
@@ -489,7 +497,7 @@
* @param methods the methods to look for, where {@code null} means that any frame is returned
* @return the frame, or {@code null} if the end of the stack was reached during the search
*/
- public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, HotSpotResolvedJavaMethodImpl[] methods, int initialSkip);
+ native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, ResolvedJavaMethod[] methods, int initialSkip);
/**
* Materializes all virtual objects within {@code stackFrame} updates its locals.
@@ -512,30 +520,34 @@
/**
* Determines if debug info should also be emitted at non-safepoint locations.
*/
- public native boolean shouldDebugNonSafepoints();
+
+ native boolean shouldDebugNonSafepoints();
/**
* Writes {@code length} bytes from {@code bytes} starting at offset {@code offset} to the
* HotSpot's log stream.
*
- * @exception NullPointerException if <code>bytes</code> is <code>null</code>.
+ * @exception NullPointerException if {@code bytes == null}
* @exception IndexOutOfBoundsException if copying would cause access of data outside array
- * bounds.
+ * bounds
*/
- public native void writeDebugOutput(byte[] bytes, int offset, int length);
+ native void writeDebugOutput(byte[] bytes, int offset, int length);
/**
* Flush HotSpot's log stream.
*/
- public native void flushDebugOutput();
+ native void flushDebugOutput();
/**
- * Read a value representing a metaspace Method* and return the
- * {@link HotSpotResolvedJavaMethodImpl} wrapping it. This method does no checking that the
- * location actually contains a valid Method*. If the {@code base} object is a
+ * Read a HotSpot Method* value from the memory location described by {@code base} plus
+ * {@code displacement} and return the {@link HotSpotResolvedJavaMethodImpl} wrapping it. This
+ * method does no checking that the memory location actually contains a valid pointer and may
+ * crash the VM if an invalid location is provided. If the {@code base} is null then
+ * {@code displacement} is used by itself. If {@code base} is a
* {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
* {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
- * and used as the base. Otherwise the object itself is used as the base.
+ * and added to {@code displacement}. Any other non-null object type causes an
+ * {@link IllegalArgumentException} to be thrown.
*
* @param base an object to read from or null
* @param displacement
@@ -544,12 +556,14 @@
native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement);
/**
- * Read a value representing a metaspace ConstantPool* and return the
- * {@link HotSpotConstantPool} wrapping it. This method does no checking that the location
- * actually contains a valid ConstantPool*. If the {@code base} object is a
- * {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
- * {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
- * and used as the base. Otherwise the object itself is used as the base.
+ * Read a HotSpot ConstantPool* value from the memory location described by {@code base} plus
+ * {@code displacement} and return the {@link HotSpotConstantPool} wrapping it. This method does
+ * no checking that the memory location actually contains a valid pointer and may crash the VM
+ * if an invalid location is provided. If the {@code base} is null then {@code displacement} is
+ * used by itself. If {@code base} is a {@link HotSpotResolvedJavaMethodImpl},
+ * {@link HotSpotConstantPool} or {@link HotSpotResolvedObjectTypeImpl} then the metaspace
+ * pointer is fetched from that object and added to {@code displacement}. Any other non-null
+ * object type causes an {@link IllegalArgumentException} to be thrown.
*
* @param base an object to read from or null
* @param displacement
@@ -558,12 +572,15 @@
native HotSpotConstantPool getConstantPool(Object base, long displacement);
/**
- * Read a value representing a metaspace Klass* and return the
- * {@link HotSpotResolvedObjectTypeImpl} wrapping it. The method does no checking that the
- * location actually contains a valid Klass*. If the {@code base} object is a
+ * Read a HotSpot Klass* value from the memory location described by {@code base} plus
+ * {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This
+ * method does no checking that the memory location actually contains a valid pointer and may
+ * crash the VM if an invalid location is provided. If the {@code base} is null then
+ * {@code displacement} is used by itself. If {@code base} is a
* {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
* {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
- * and used as the base. Otherwise the object itself is used as the base.
+ * and added to {@code displacement}. Any other non-null object type causes an
+ * {@link IllegalArgumentException} to be thrown.
*
* @param base an object to read from or null
* @param displacement
@@ -571,4 +588,17 @@
* @return null or the resolved method for this location
*/
native HotSpotResolvedObjectTypeImpl getResolvedJavaType(Object base, long displacement, boolean compressed);
+
+ /**
+ * Return the size of the HotSpot ProfileData* pointed at by {@code position}. If
+ * {@code position} is outside the space of the MethodData then an
+ * {@link IllegalArgumentException} is thrown. A {@code position} inside the MethodData but that
+ * isn't pointing at a valid ProfileData will crash the VM.
+ *
+ * @param metaspaceMethodData
+ * @param position
+ * @return the size of the ProfileData item pointed at by {@code position}
+ * @throws IllegalArgumentException if an out of range position is given
+ */
+ native int methodDataProfileDataSize(long metaspaceMethodData, int position);
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,15 +22,30 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.*;
+import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.COMPRESSED_NULL;
-import java.lang.reflect.*;
+import java.lang.reflect.Field;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.code.CompilationResult.*;
-import jdk.vm.ci.code.DataSection.*;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.BailoutException;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.CompilationRequest;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.CompilationResult.Call;
+import jdk.vm.ci.code.CompilationResult.ConstantReference;
+import jdk.vm.ci.code.CompilationResult.DataPatch;
+import jdk.vm.ci.code.CompilationResult.Mark;
+import jdk.vm.ci.code.DataSection;
+import jdk.vm.ci.code.DataSection.Data;
+import jdk.vm.ci.code.DataSection.DataBuilder;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.RegisterConfig;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.SerializableConstant;
+import jdk.vm.ci.meta.SpeculationLog;
+import jdk.vm.ci.meta.VMConstant;
/**
* HotSpot implementation of {@link CodeCacheProvider}.
@@ -98,72 +113,64 @@
return runtime.getConfig().runtimeCallStackSize;
}
- public InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) {
- HotSpotJVMCIRuntime.runtime().notifyInstall(this, installedCode, compResult);
+ private InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) {
+ ((HotSpotJVMCIRuntime) runtime).notifyInstall(this, installedCode, compResult);
return installedCode;
}
- private InstalledCode installCode(CompilationResult compResult, HotSpotCompiledNmethod compiledCode, InstalledCode installedCode, SpeculationLog log) {
- int result = runtime.getCompilerToVM().installCode(target, compiledCode, installedCode, log);
- if (result != config.codeInstallResultOk) {
- String msg = compiledCode.getInstallationFailureMessage();
- String resultDesc = config.getCodeInstallResultDescription(result);
- if (msg != null) {
- msg = String.format("Code installation failed: %s%n%s", resultDesc, msg);
+ public InstalledCode installCode(CompilationRequest compRequest, CompilationResult compResult, InstalledCode installedCode, SpeculationLog log, boolean isDefault) {
+ HotSpotResolvedJavaMethod method = compRequest != null ? (HotSpotResolvedJavaMethod) compRequest.getMethod() : null;
+ InstalledCode resultInstalledCode;
+ if (installedCode == null) {
+ if (method == null) {
+ // Must be a stub
+ resultInstalledCode = new HotSpotRuntimeStub(compResult.getName());
} else {
- msg = String.format("Code installation failed: %s", resultDesc);
+ resultInstalledCode = new HotSpotNmethod(method, compResult.getName(), isDefault);
}
- if (result == config.codeInstallResultDependenciesInvalid) {
- throw new AssertionError(resultDesc + " " + msg);
+ } else {
+ resultInstalledCode = installedCode;
+ }
+ HotSpotCompiledCode compiledCode;
+ if (method != null) {
+ final int id;
+ final long jvmciEnv;
+ if (compRequest instanceof HotSpotCompilationRequest) {
+ HotSpotCompilationRequest hsCompRequest = (HotSpotCompilationRequest) compRequest;
+ id = hsCompRequest.getId();
+ jvmciEnv = hsCompRequest.getJvmciEnv();
+ } else {
+ id = method.allocateCompileId(compRequest.getEntryBCI());
+ jvmciEnv = 0L;
}
- throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg);
+ compiledCode = new HotSpotCompiledNmethod(method, compResult, id, jvmciEnv);
+ } else {
+ compiledCode = new HotSpotCompiledCode(compResult);
}
- return logOrDump(installedCode, compResult);
- }
-
- public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv, boolean isDefault) {
- if (compResult.getId() == -1) {
- compResult.setId(method.allocateCompileId(compResult.getEntryBCI()));
+ int result = runtime.getCompilerToVM().installCode(target, compiledCode, resultInstalledCode, (HotSpotSpeculationLog) log);
+ if (result != config.codeInstallResultOk) {
+ String resultDesc = config.getCodeInstallResultDescription(result);
+ if (compiledCode instanceof HotSpotCompiledNmethod) {
+ HotSpotCompiledNmethod compiledNmethod = (HotSpotCompiledNmethod) compiledCode;
+ String msg = compiledNmethod.getInstallationFailureMessage();
+ if (msg != null) {
+ msg = String.format("Code installation failed: %s%n%s", resultDesc, msg);
+ } else {
+ msg = String.format("Code installation failed: %s", resultDesc);
+ }
+ if (result == config.codeInstallResultDependenciesInvalid) {
+ throw new AssertionError(resultDesc + " " + msg);
+ }
+ throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg);
+ } else {
+ throw new BailoutException("Error installing %s: %s", compResult.getName(), resultDesc);
+ }
}
- HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault);
- HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(method, compResult, jvmciEnv);
- return installCode(compResult, compiledCode, installedCode, method.getSpeculationLog());
+ return logOrDump(resultInstalledCode, compResult);
}
- @Override
- public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode predefinedInstalledCode) {
- HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
- if (compResult.getId() == -1) {
- compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI()));
- }
- InstalledCode installedCode = predefinedInstalledCode;
- if (installedCode == null) {
- HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false);
- installedCode = code;
- }
- HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(hotspotMethod, compResult);
- return installCode(compResult, compiledCode, installedCode, log);
- }
-
- @Override
- public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) {
- HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
- return installMethod(hotspotMethod, compResult, 0L, true);
- }
-
- public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
- HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
- if (compResult.getId() == -1) {
- compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI()));
- }
- HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true);
- HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compResult);
- CompilerToVM vm = runtime.getCompilerToVM();
- int result = vm.installCode(target, compiled, code, null);
- if (result != runtime.getConfig().codeInstallResultOk) {
- return null;
- }
- return code;
+ public void invalidateInstalledCode(InstalledCode installedCode) {
+ runtime.getCompilerToVM().invalidateInstalledCode(installedCode);
}
public boolean needsDataPatch(JavaConstant constant) {
@@ -176,35 +183,29 @@
if (constant instanceof VMConstant) {
VMConstant vmConstant = (VMConstant) constant;
boolean compressed;
- long raw;
- if (constant instanceof HotSpotObjectConstant) {
- HotSpotObjectConstant c = (HotSpotObjectConstant) vmConstant;
+ if (constant instanceof HotSpotConstant) {
+ HotSpotConstant c = (HotSpotConstant) vmConstant;
compressed = c.isCompressed();
- raw = 0xDEADDEADDEADDEADL;
- } else if (constant instanceof HotSpotMetaspaceConstant) {
- HotSpotMetaspaceConstant meta = (HotSpotMetaspaceConstant) constant;
- compressed = meta.isCompressed();
- raw = meta.rawValue();
} else {
throw new JVMCIError(String.valueOf(constant));
}
- size = target.getSizeInBytes(compressed ? JavaKind.Int : target.wordKind);
+ size = compressed ? 4 : target.wordSize;
if (size == 4) {
builder = (buffer, patch) -> {
patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
- buffer.putInt((int) raw);
+ buffer.putInt(0xDEADDEAD);
};
} else {
assert size == 8;
builder = (buffer, patch) -> {
patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
- buffer.putLong(raw);
+ buffer.putLong(0xDEADDEADDEADDEADL);
};
}
} else if (JavaConstant.isNull(constant)) {
boolean compressed = COMPRESSED_NULL.equals(constant);
- size = target.getSizeInBytes(compressed ? JavaKind.Int : target.wordKind);
+ size = compressed ? 4 : target.wordSize;
builder = DataBuilder.zero(size);
} else if (constant instanceof SerializableConstant) {
SerializableConstant s = (SerializableConstant) constant;
@@ -250,8 +251,7 @@
public String disassemble(InstalledCode code) {
if (code.isValid()) {
- long codeBlob = code.getAddress();
- return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob);
+ return runtime.getCompilerToVM().disassembleCodeBlob(code);
}
return null;
}
@@ -259,4 +259,35 @@
public SpeculationLog createSpeculationLog() {
return new HotSpotSpeculationLog();
}
+
+ public long getMaxCallTargetOffset(long address) {
+ return runtime.getCompilerToVM().getMaxCallTargetOffset(address);
+ }
+
+ public boolean shouldDebugNonSafepoints() {
+ return runtime.getCompilerToVM().shouldDebugNonSafepoints();
+ }
+
+ /**
+ * Notifies the VM of statistics for a completed compilation.
+ *
+ * @param id the identifier of the compilation
+ * @param method the method compiled
+ * @param osr specifies if the compilation was for on-stack-replacement
+ * @param processedBytecodes the number of bytecodes processed during the compilation, including
+ * the bytecodes of all inlined methods
+ * @param time the amount time spent compiling {@code method}
+ * @param timeUnitsPerSecond the granularity of the units for the {@code time} value
+ * @param installedCode the nmethod installed as a result of the compilation
+ */
+ public void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, InstalledCode installedCode) {
+ runtime.getCompilerToVM().notifyCompilationStatistics(id, (HotSpotResolvedJavaMethodImpl) method, osr, processedBytecodes, time, timeUnitsPerSecond, installedCode);
+ }
+
+ /**
+ * Resets all compilation statistics.
+ */
+ public void resetCompilationStatistics() {
+ runtime.getCompilerToVM().resetCompilationStatistics();
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.CompilationRequest;
+
+/**
+ * A compilation request with extra HotSpot specific context such as a compilation identifier and
+ * the address of a {@code JVMCIEnv} object that provides native context for a compilation.
+ */
+public class HotSpotCompilationRequest extends CompilationRequest {
+ private final long jvmciEnv;
+ private final int id;
+
+ /**
+ * Creates a request to compile a method starting at a given BCI and allocates an identifier to
+ * the request.
+ *
+ * @param method the method to be compiled
+ * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
+ * method's entry point
+ * @param jvmciEnv address of a native {@code JVMCIEnv} object or 0L
+ */
+ public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv) {
+ this(method, entryBCI, jvmciEnv, method.allocateCompileId(entryBCI));
+ }
+
+ /**
+ * Creates a request to compile a method starting at a given BCI.
+ *
+ * @param method the method to be compiled
+ * @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
+ * method's entry point
+ * @param jvmciEnv address of a native {@code JVMCIEnv} object or 0L
+ * @param id an identifier for the request
+ */
+ public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
+ super(method, entryBCI);
+ this.jvmciEnv = jvmciEnv;
+ this.id = id;
+ }
+
+ @Override
+ public HotSpotResolvedJavaMethod getMethod() {
+ return (HotSpotResolvedJavaMethod) super.getMethod();
+ }
+
+ /**
+ * Gets the address of the native {@code JVMCIEnv} object or 0L if no such object exists.
+ */
+ public long getJvmciEnv() {
+ return jvmciEnv;
+ }
+
+ /**
+ * Gets the VM allocated identifier for this compilation.
+ */
+ public int getId() {
+ return id;
+ }
+
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledCode.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,12 +22,16 @@
*/
package jdk.vm.ci.hotspot;
-import java.nio.*;
-import java.util.*;
-import java.util.stream.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Stream;
import java.util.stream.Stream.Builder;
-import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.BytecodeFrame;
+import jdk.vm.ci.code.CompilationResult;
import jdk.vm.ci.code.CompilationResult.CodeAnnotation;
import jdk.vm.ci.code.CompilationResult.CodeComment;
import jdk.vm.ci.code.CompilationResult.DataPatch;
@@ -36,14 +40,15 @@
import jdk.vm.ci.code.CompilationResult.JumpTable;
import jdk.vm.ci.code.CompilationResult.Mark;
import jdk.vm.ci.code.CompilationResult.Site;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.DataSection;
import jdk.vm.ci.meta.Assumptions.Assumption;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* A {@link CompilationResult} with additional HotSpot-specific information required for installing
* the code in HotSpot's code cache.
*/
-public abstract class HotSpotCompiledCode {
+public class HotSpotCompiledCode {
public final String name;
public final Site[] sites;
@@ -113,9 +118,7 @@
targetCodeSize = compResult.getTargetCodeSize();
DataSection data = compResult.getDataSection();
- if (!data.isFinalized()) {
- data.finalizeLayout();
- }
+ data.finalizeLayout();
dataSection = new byte[data.getSectionSize()];
ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder());
@@ -176,4 +179,9 @@
Arrays.sort(result, new SiteComparator());
return result;
}
+
+ @Override
+ public String toString() {
+ return name;
+ }
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,8 +22,8 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.inittimer.*;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.inittimer.SuppressFBWarnings;
/**
* {@link HotSpotCompiledCode} destined for installation as an nmethod.
@@ -32,8 +32,17 @@
public final HotSpotResolvedJavaMethod method;
public final int entryBCI;
+
+ /**
+ * Compilation identifier.
+ */
public final int id;
+
+ /**
+ * Address of a native {@code JVMCIEnv} object or 0L if no such object exists.
+ */
public final long jvmciEnv;
+
public final boolean hasUnsafeAccess;
/**
@@ -42,15 +51,11 @@
*/
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "set by the VM") private String installationFailureMessage;
- public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) {
- this(method, compResult, 0L);
- }
-
- public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv) {
+ public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, int id, long jvmciEnv) {
super(compResult);
this.method = method;
this.entryBCI = compResult.getEntryBCI();
- this.id = compResult.getId();
+ this.id = id;
this.jvmciEnv = jvmciEnv;
this.hasUnsafeAccess = compResult.hasUnsafeAccess();
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompressedNullConstant.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,9 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
/**
* The compressed representation of the {@link JavaConstant#NULL_POINTER null constant}.
@@ -48,6 +50,14 @@
return true;
}
+ public Constant compress() {
+ throw new IllegalArgumentException();
+ }
+
+ public Constant uncompress() {
+ return NULL_POINTER;
+ }
+
@Override
public boolean isDefaultForKind() {
return true;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstant.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstant.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Constant;
/**
* Marker interface for hotspot specific constants.
@@ -30,4 +30,8 @@
public interface HotSpotConstant extends Constant {
boolean isCompressed();
+
+ Constant compress();
+
+ Constant uncompress();
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,18 +22,27 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-import java.lang.invoke.*;
+import java.lang.invoke.MethodHandle;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaField;
+import jdk.vm.ci.meta.JavaMethod;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
/**
* Implementation of {@link ConstantPool} for HotSpot.
*/
-public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
+final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
/**
* Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}.
@@ -121,10 +130,6 @@
this.tag = tag;
}
- private static HotSpotVMConfig config() {
- return runtime().getConfig();
- }
-
/**
* Maps JVM_CONSTANT tags to {@link JVM_CONSTANT} values. Using a separate class for lazy
* initialization.
@@ -204,7 +209,7 @@
* @return holder for this constant pool
*/
private HotSpotResolvedObjectType getHolder() {
- return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().constantPoolHolderOffset, false);
+ return compilerToVM().getResolvedJavaType(this, config().constantPoolHolderOffset, false);
}
/**
@@ -224,7 +229,7 @@
} else {
assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE ||
opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + opcode;
- index = rawIndex + runtime().getConfig().constantPoolCpCacheIndexTag;
+ index = rawIndex + config().constantPoolCpCacheIndexTag;
}
return index;
}
@@ -241,7 +246,7 @@
if (isInvokedynamicIndex(index)) {
return decodeInvokedynamicIndex(index);
} else {
- return index - runtime().getConfig().constantPoolCpCacheIndexTag;
+ return index - config().constantPoolCpCacheIndexTag;
}
}
@@ -260,7 +265,7 @@
return ~i;
}
- public long getMetaspaceConstantPool() {
+ long getMetaspaceConstantPool() {
return metaspaceConstantPool;
}
@@ -276,7 +281,7 @@
*/
private JVM_CONSTANT getTagAt(int index) {
assertBounds(index);
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset);
final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
if (tag == 0) {
@@ -293,7 +298,7 @@
*/
private long getEntryAt(int index) {
assertBounds(index);
- return UNSAFE.getAddress(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getAddress(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@@ -304,7 +309,7 @@
*/
private int getIntAt(int index) {
assertTag(index, JVM_CONSTANT.Integer);
- return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@@ -315,7 +320,7 @@
*/
private long getLongAt(int index) {
assertTag(index, JVM_CONSTANT.Long);
- return UNSAFE.getLong(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getLong(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@@ -326,7 +331,7 @@
*/
private float getFloatAt(int index) {
assertTag(index, JVM_CONSTANT.Float);
- return UNSAFE.getFloat(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getFloat(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@@ -337,7 +342,7 @@
*/
private double getDoubleAt(int index) {
assertTag(index, JVM_CONSTANT.Double);
- return UNSAFE.getDouble(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getDouble(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@@ -348,7 +353,7 @@
*/
private int getNameAndTypeAt(int index) {
assertTag(index, JVM_CONSTANT.NameAndType);
- return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@@ -359,7 +364,7 @@
* @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry
*/
private int getNameAndTypeRefIndexAt(int index) {
- return runtime().getCompilerToVM().lookupNameAndTypeRefIndexInPool(this, index);
+ return compilerToVM().lookupNameAndTypeRefIndexInPool(this, index);
}
/**
@@ -370,7 +375,7 @@
* @return name as {@link String}
*/
private String getNameOf(int which) {
- return runtime().getCompilerToVM().lookupNameInPool(this, which);
+ return compilerToVM().lookupNameInPool(this, which);
}
/**
@@ -394,7 +399,7 @@
* @return signature as {@link String}
*/
private String getSignatureOf(int which) {
- return runtime().getCompilerToVM().lookupSignatureInPool(this, which);
+ return compilerToVM().lookupSignatureInPool(this, which);
}
/**
@@ -417,7 +422,7 @@
* @return klass reference index
*/
private int getKlassRefIndexAt(int index) {
- return runtime().getCompilerToVM().lookupKlassRefIndexInPool(this, index);
+ return compilerToVM().lookupKlassRefIndexInPool(this, index);
}
/**
@@ -427,22 +432,11 @@
* @param index constant pool index
* @return klass reference index
*/
- private int getUncachedKlassRefIndexAt(int index, JVM_CONSTANT tag) {
- int resultIndex;
- if (tag == JVM_CONSTANT.MethodRef || tag == JVM_CONSTANT.Fieldref || tag == JVM_CONSTANT.InterfaceMethodref) {
- assertTagIsFieldOrMethod(index);
- final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
- // klass ref index is in the low 16-bits.
- resultIndex = refIndex & 0xFFFF;
- } else {
- resultIndex = index;
- }
-
- // Read the tag only once because it could change between multiple reads.
- final JVM_CONSTANT klassTag = getTagAt(resultIndex);
- assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError : klassTag;
-
- return resultIndex;
+ private int getUncachedKlassRefIndexAt(int index) {
+ assertTagIsFieldOrMethod(index);
+ final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+ // klass ref index is in the low 16-bits.
+ return refIndex & 0xFFFF;
}
/**
@@ -478,7 +472,7 @@
@Override
public int length() {
- return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolLengthOffset);
+ return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolLengthOffset);
}
@Override
@@ -505,13 +499,13 @@
* "pseudo strings" (arbitrary live objects) patched into a String entry. Such
* entries do not have a symbol in the constant pool slot.
*/
- Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
+ Object string = compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
return HotSpotObjectConstantImpl.forObject(string);
case MethodHandle:
case MethodHandleInError:
case MethodType:
case MethodTypeInError:
- Object obj = runtime().getCompilerToVM().resolveConstantInPool(this, cpi);
+ Object obj = compilerToVM().resolveConstantInPool(this, cpi);
return HotSpotObjectConstantImpl.forObject(obj);
default:
throw new JVMCIError("Unknown constant pool tag %s", tag);
@@ -521,7 +515,7 @@
@Override
public String lookupUtf8(int cpi) {
assertTag(cpi, JVM_CONSTANT.Utf8);
- return runtime().getCompilerToVM().getSymbol(getEntryAt(cpi));
+ return compilerToVM().getSymbol(getEntryAt(cpi));
}
@Override
@@ -533,7 +527,7 @@
public JavaConstant lookupAppendix(int cpi, int opcode) {
assert Bytecodes.isInvoke(opcode);
final int index = rawIndexToConstantPoolIndex(cpi, opcode);
- Object appendix = runtime().getCompilerToVM().lookupAppendixInPool(this, index);
+ Object appendix = compilerToVM().lookupAppendixInPool(this, index);
if (appendix == null) {
return null;
} else {
@@ -558,7 +552,7 @@
@Override
public JavaMethod lookupMethod(int cpi, int opcode) {
final int index = rawIndexToConstantPoolIndex(cpi, opcode);
- final HotSpotResolvedJavaMethod method = runtime().getCompilerToVM().lookupMethodInPool(this, index, (byte) opcode);
+ final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, index, (byte) opcode);
if (method != null) {
return method;
} else {
@@ -570,7 +564,7 @@
return new HotSpotMethodUnresolved(name, signature, holder);
} else {
final int klassIndex = getKlassRefIndexAt(index);
- final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, klassIndex);
+ final Object type = compilerToVM().lookupKlassInPool(this, klassIndex);
JavaType holder = getJavaType(type);
return new HotSpotMethodUnresolved(name, signature, holder);
}
@@ -583,7 +577,7 @@
if (elem != null && elem.lastCpi == cpi) {
return elem.javaType;
} else {
- final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, cpi);
+ final Object type = compilerToVM().lookupKlassInPool(this, cpi);
JavaType result = getJavaType(type);
if (result instanceof ResolvedJavaType) {
this.lastLookupType = new LookupTypeCacheElement(cpi, result);
@@ -609,7 +603,7 @@
long[] info = new long[2];
HotSpotResolvedObjectTypeImpl resolvedHolder;
try {
- resolvedHolder = runtime().getCompilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
+ resolvedHolder = compilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
} catch (Throwable t) {
/*
* If there was an exception resolving the field we give up and return an unresolved
@@ -643,8 +637,8 @@
break;
case Bytecodes.INVOKEDYNAMIC: {
// invokedynamic instructions point to a constant pool cache entry.
- index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag;
- index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
+ index = decodeConstantPoolCacheIndex(cpi) + config().constantPoolCpCacheIndexTag;
+ index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
break;
}
case Bytecodes.GETSTATIC:
@@ -657,7 +651,7 @@
case Bytecodes.INVOKEINTERFACE: {
// invoke and field instructions point to a constant pool cache entry.
index = rawIndexToConstantPoolIndex(cpi, opcode);
- index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
+ index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
break;
}
default:
@@ -673,11 +667,15 @@
case MethodRef:
case Fieldref:
case InterfaceMethodref:
+ index = getUncachedKlassRefIndexAt(index);
+ // Read the tag only once because it could change between multiple reads.
+ final JVM_CONSTANT klassTag = getTagAt(index);
+ assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError : klassTag;
+ // fall through
case Class:
case UnresolvedClass:
case UnresolvedClassInError:
- index = getUncachedKlassRefIndexAt(index, tag);
- final HotSpotResolvedObjectTypeImpl type = runtime().getCompilerToVM().resolveTypeInPool(this, index);
+ final HotSpotResolvedObjectTypeImpl type = compilerToVM().resolveTypeInPool(this, index);
Class<?> klass = type.mirror();
if (!klass.isPrimitive() && !klass.isArray()) {
UNSAFE.ensureClassInitialized(klass);
@@ -687,14 +685,14 @@
if (Bytecodes.isInvokeHandleAlias(opcode)) {
final int methodRefCacheIndex = rawIndexToConstantPoolIndex(cpi, opcode);
if (isInvokeHandle(methodRefCacheIndex, type)) {
- runtime().getCompilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
+ compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
}
}
}
break;
case InvokeDynamic:
if (isInvokedynamicIndex(cpi)) {
- runtime().getCompilerToVM().resolveInvokeDynamicInPool(this, cpi);
+ compilerToVM().resolveInvokeDynamicInPool(this, cpi);
}
break;
default:
@@ -704,7 +702,7 @@
}
private boolean isInvokeHandle(int methodRefCacheIndex, HotSpotResolvedObjectTypeImpl klass) {
- assertTag(runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
+ assertTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameOf(methodRefCacheIndex), runtime().getHostJVMCIBackend().getMetaAccess());
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,12 +22,24 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider.Options.*;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
+
+import java.lang.reflect.Array;
-import java.lang.reflect.*;
-
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.options.*;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaField;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.MemoryAccessProvider;
+import jdk.vm.ci.meta.MethodHandleAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.options.Option;
+import jdk.vm.ci.options.OptionType;
+import jdk.vm.ci.options.OptionValue;
+import jdk.vm.ci.options.StableOptionValue;
/**
* HotSpot implementation of {@link ConstantReflectionProvider}.
@@ -61,11 +73,6 @@
}
@Override
- public boolean isEmbeddable(Constant constant) {
- return true;
- }
-
- @Override
public Boolean constantEquals(Constant x, Constant y) {
if (x == y) {
return true;
@@ -110,8 +117,8 @@
}
Class<?> componentType = ((HotSpotObjectConstantImpl) array).object().getClass().getComponentType();
JavaKind kind = runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(componentType).getJavaKind();
- int arraybase = runtime.getArrayBaseOffset(kind);
- int scale = runtime.getArrayIndexScale(kind);
+ int arraybase = getArrayBaseOffset(kind);
+ int scale = getArrayIndexScale(kind);
if (offset < arraybase) {
return -1;
}
@@ -207,6 +214,10 @@
return HotSpotObjectConstantImpl.forObject(value);
}
+ public JavaConstant forObject(Object value) {
+ return HotSpotObjectConstantImpl.forObject(value);
+ }
+
@Override
public ResolvedJavaType asJavaType(Constant constant) {
if (constant instanceof HotSpotObjectConstant) {
@@ -216,7 +227,7 @@
}
}
if (constant instanceof HotSpotMetaspaceConstant) {
- Object obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant);
+ MetaspaceWrapperObject obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant);
if (obj instanceof HotSpotResolvedObjectTypeImpl) {
return (ResolvedJavaType) obj;
}
@@ -251,7 +262,7 @@
* {@code value} was read
*/
protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
- return !value.isDefaultForKind() || TrustFinalDefaultFields.getValue();
+ return !value.isDefaultForKind() || Options.TrustFinalDefaultFields.getValue();
}
/**
@@ -327,7 +338,7 @@
if (!hotspotField.isStable()) {
return readNonStableFieldValue(field, receiver);
} else {
- return readStableFieldValue(field, receiver, false);
+ return readStableFieldValue(field, receiver, hotspotField.isDefaultStable());
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java Wed Jul 05 21:00:20 2017 +0200
@@ -23,7 +23,6 @@
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
import sun.misc.Unsafe;
@@ -59,18 +58,6 @@
return size;
}
- /**
- * @return a copy of this code blob if it is {@linkplain #isValid() valid}, null otherwise.
- */
- public byte[] getBlob() {
- if (!isValid()) {
- return null;
- }
- byte[] blob = new byte[size];
- UNSAFE.copyMemory(null, getAddress(), blob, Unsafe.ARRAY_BYTE_BASE_OFFSET, size);
- return blob;
- }
-
@Override
public abstract String toString();
@@ -79,7 +66,6 @@
return codeStart;
}
- @Override
public long getCodeSize() {
return codeSize;
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIBackendFactory.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,12 +22,11 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.compiler.*;
-import jdk.vm.ci.runtime.*;
+import jdk.vm.ci.runtime.JVMCIBackend;
public interface HotSpotJVMCIBackendFactory {
- JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host);
+ JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, JVMCIBackend host);
/**
* Gets the CPU architecture of this backend.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,19 +22,18 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.compiler.*;
-import jdk.vm.ci.compiler.Compiler;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.runtime.*;
-import jdk.vm.ci.service.*;
+import jdk.vm.ci.code.CompilationRequest;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.runtime.JVMCICompiler;
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
+import jdk.vm.ci.runtime.JVMCIRuntime;
+import jdk.vm.ci.service.Services;
final class HotSpotJVMCICompilerConfig {
- private static class DummyCompilerFactory implements CompilerFactory, Compiler {
+ private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler {
- public void compileMethod(ResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
+ public void compileMethod(CompilationRequest request) {
throw new JVMCIError("no JVMCI compiler selected");
}
@@ -42,16 +41,12 @@
return "<none>";
}
- public Architecture initializeArchitecture(Architecture arch) {
- return arch;
- }
-
- public Compiler createCompiler(JVMCIRuntime runtime) {
+ public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
return this;
}
}
- private static CompilerFactory compilerFactory;
+ private static JVMCICompilerFactory compilerFactory;
/**
* Selects the system compiler.
@@ -61,7 +56,7 @@
*/
static Boolean selectCompiler(String compilerName) {
assert compilerFactory == null;
- for (CompilerFactory factory : Services.load(CompilerFactory.class)) {
+ for (JVMCICompilerFactory factory : Services.load(JVMCICompilerFactory.class)) {
if (factory.getCompilerName().equals(compilerName)) {
compilerFactory = factory;
return Boolean.TRUE;
@@ -71,7 +66,7 @@
throw new JVMCIError("JVMCI compiler '%s' not found", compilerName);
}
- static CompilerFactory getCompilerFactory() {
+ static JVMCICompilerFactory getCompilerFactory() {
if (compilerFactory == null) {
compilerFactory = new DummyCompilerFactory();
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,17 @@
*/
package jdk.vm.ci.hotspot;
-import java.lang.ref.*;
-import java.util.*;
+import java.lang.ref.Reference;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JVMCIMetaAccessContext;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* This class manages the set of metadata roots that must be scanned during garbage collection.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,54 +22,55 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.inittimer.InitTimer.*;
+import static jdk.vm.ci.inittimer.InitTimer.timer;
-import java.util.*;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.compiler.*;
-import jdk.vm.ci.compiler.Compiler;
-import jdk.vm.ci.inittimer.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.runtime.*;
-import jdk.vm.ci.service.*;
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.inittimer.InitTimer;
+import jdk.vm.ci.meta.JVMCIMetaAccessContext;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.runtime.JVMCI;
+import jdk.vm.ci.runtime.JVMCIBackend;
+import jdk.vm.ci.runtime.JVMCICompiler;
+import jdk.vm.ci.service.Services;
//JaCoCo Exclude
+/**
+ * HotSpot implementation of a JVMCI runtime.
+ *
+ * The initialization of this class is very fragile since it's initialized both through
+ * {@link JVMCI#initialize()} or through calling {@link HotSpotJVMCIRuntime#runtime()} and
+ * {@link HotSpotJVMCIRuntime#runtime()} is also called by {@link JVMCI#initialize()}. So this class
+ * can't have a static initializer and any required initialization must be done as part of
+ * {@link #runtime()}. This allows the initialization to funnel back through
+ * {@link JVMCI#initialize()} without deadlocking.
+ */
public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
- /**
- * The proper initialization of this class is complex because it's tangled up with the
- * initialization of the JVMCI and really should only ever be triggered through
- * {@link JVMCI#getRuntime}. However since {@link #runtime} can also be called directly it
- * should also trigger proper initialization. To ensure proper ordering, the static initializer
- * of this class initializes {@link JVMCI} and then access to {@link DelayedInit#instance}
- * triggers the final initialization of the {@link HotSpotJVMCIRuntime}.
- */
- static {
- JVMCI.initialize();
- }
-
@SuppressWarnings("try")
static class DelayedInit {
private static final HotSpotJVMCIRuntime instance;
static {
- try (InitTimer t0 = timer("HotSpotJVMCIRuntime.<clinit>")) {
- try (InitTimer t = timer("StartupEventListener.beforeJVMCIStartup")) {
- for (StartupEventListener l : Services.load(StartupEventListener.class)) {
- l.beforeJVMCIStartup();
- }
- }
-
- try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) {
- instance = new HotSpotJVMCIRuntime();
- }
-
- try (InitTimer t = timer("HotSpotJVMCIRuntime.completeInitialization")) {
- instance.completeInitialization();
- }
+ try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) {
+ instance = new HotSpotJVMCIRuntime();
}
}
}
@@ -78,20 +79,10 @@
* Gets the singleton {@link HotSpotJVMCIRuntime} object.
*/
public static HotSpotJVMCIRuntime runtime() {
- assert DelayedInit.instance != null;
+ JVMCI.initialize();
return DelayedInit.instance;
}
- /**
- * Do deferred initialization.
- */
- public void completeInitialization() {
- compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
- for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
- vmEventListener.completeInitialization(this);
- }
- }
-
public static HotSpotJVMCIBackendFactory findFactory(String architecture) {
for (HotSpotJVMCIBackendFactory factory : Services.load(HotSpotJVMCIBackendFactory.class)) {
if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
@@ -106,7 +97,7 @@
* Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend.
*/
public static JavaKind getHostWordKind() {
- return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordKind;
+ return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind;
}
protected final CompilerToVM compilerToVm;
@@ -114,16 +105,19 @@
protected final HotSpotVMConfig config;
private final JVMCIBackend hostBackend;
- private Compiler compiler;
+ private volatile JVMCICompiler compiler;
protected final JVMCIMetaAccessContext metaAccessContext;
private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
private final Iterable<HotSpotVMEventListener> vmEventListeners;
+ @SuppressWarnings("unused") private final String[] trivialPrefixes;
+
@SuppressWarnings("try")
private HotSpotJVMCIRuntime() {
compilerToVm = new CompilerToVM();
+
try (InitTimer t = timer("HotSpotVMConfig<init>")) {
config = new HotSpotVMConfig(compilerToVm);
}
@@ -135,10 +129,8 @@
factory = findFactory(hostArchitecture);
}
- CompilerFactory compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
-
try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) {
- hostBackend = registerBackend(factory.createJVMCIBackend(this, compilerFactory, null));
+ hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
}
vmEventListeners = Services.load(HotSpotVMEventListener.class);
@@ -154,6 +146,12 @@
context = new HotSpotJVMCIMetaAccessContext();
}
metaAccessContext = context;
+
+ if (Boolean.valueOf(System.getProperty("jvmci.printconfig"))) {
+ printConfig(config, compilerToVm);
+ }
+
+ trivialPrefixes = HotSpotJVMCICompilerConfig.getCompilerFactory().getTrivialPrefixes();
}
private JVMCIBackend registerBackend(JVMCIBackend backend) {
@@ -179,7 +177,14 @@
return metaAccessContext;
}
- public Compiler getCompiler() {
+ public JVMCICompiler getCompiler() {
+ if (compiler == null) {
+ synchronized (this) {
+ if (compiler == null) {
+ compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
+ }
+ }
+ }
return compiler;
}
@@ -211,7 +216,7 @@
return backends.get(arch);
}
- public Map<Class<? extends Architecture>, JVMCIBackend> getBackends() {
+ public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() {
return Collections.unmodifiableMap(backends);
}
@@ -220,7 +225,7 @@
*/
@SuppressWarnings({"unused"})
private void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
- compiler.compileMethod(method, entryBCI, jvmciEnv, id);
+ getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
}
/**
@@ -247,4 +252,105 @@
vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compResult);
}
}
+
+ private static void printConfig(HotSpotVMConfig config, CompilerToVM vm) {
+ Field[] fields = config.getClass().getDeclaredFields();
+ Map<String, Field> sortedFields = new TreeMap<>();
+ for (Field f : fields) {
+ if (!f.isSynthetic() && !Modifier.isStatic(f.getModifiers())) {
+ f.setAccessible(true);
+ sortedFields.put(f.getName(), f);
+ }
+ }
+ for (Field f : sortedFields.values()) {
+ try {
+ String line = String.format("%9s %-40s = %s%n", f.getType().getSimpleName(), f.getName(), pretty(f.get(config)));
+ byte[] lineBytes = line.getBytes();
+ vm.writeDebugOutput(lineBytes, 0, lineBytes.length);
+ vm.flushDebugOutput();
+ } catch (Exception e) {
+ }
+ }
+ }
+
+ private static String pretty(Object value) {
+ if (value == null) {
+ return "null";
+ }
+
+ Class<?> klass = value.getClass();
+ if (value instanceof String) {
+ return "\"" + value + "\"";
+ } else if (value instanceof Method) {
+ return "method \"" + ((Method) value).getName() + "\"";
+ } else if (value instanceof Class<?>) {
+ return "class \"" + ((Class<?>) value).getSimpleName() + "\"";
+ } else if (value instanceof Integer) {
+ if ((Integer) value < 10) {
+ return value.toString();
+ }
+ return value + " (0x" + Integer.toHexString((Integer) value) + ")";
+ } else if (value instanceof Long) {
+ if ((Long) value < 10 && (Long) value > -10) {
+ return value + "l";
+ }
+ return value + "l (0x" + Long.toHexString((Long) value) + "l)";
+ } else if (klass.isArray()) {
+ StringBuilder str = new StringBuilder();
+ int dimensions = 0;
+ while (klass.isArray()) {
+ dimensions++;
+ klass = klass.getComponentType();
+ }
+ int length = Array.getLength(value);
+ str.append(klass.getSimpleName()).append('[').append(length).append(']');
+ for (int i = 1; i < dimensions; i++) {
+ str.append("[]");
+ }
+ str.append(" {");
+ for (int i = 0; i < length; i++) {
+ str.append(pretty(Array.get(value, i)));
+ if (i < length - 1) {
+ str.append(", ");
+ }
+ }
+ str.append('}');
+ return str.toString();
+ }
+ return value.toString();
+ }
+
+ public OutputStream getLogStream() {
+ return new OutputStream() {
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (b == null) {
+ throw new NullPointerException();
+ } else if (off < 0 || off > b.length || len < 0 || (off + len) > b.length || (off + len) < 0) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return;
+ }
+ compilerToVm.writeDebugOutput(b, off, len);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ write(new byte[]{(byte) b}, 0, 1);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ compilerToVm.flushDebugOutput();
+ }
+ };
+ }
+
+ /**
+ * Collects the current values of all JVMCI benchmark counters, summed up over all threads.
+ */
+ public long[] collectCounters() {
+ return compilerToVm.collectCounters();
+ }
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntimeProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntimeProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,11 +22,15 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.compiler.Compiler;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.runtime.*;
-import sun.misc.*;
+import java.io.OutputStream;
+
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.JVMCIMetaAccessContext;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.runtime.JVMCIRuntime;
+import sun.misc.Unsafe;
//JaCoCo Exclude
@@ -39,7 +43,10 @@
CompilerToVM getCompilerToVM();
- Compiler getCompiler();
+ /**
+ * Gets an output stream that writes to the HotSpot's {@code tty} stream.
+ */
+ OutputStream getLogStream();
/**
* Converts a name to a Java type. This method attempts to resolve {@code name} to a
@@ -70,7 +77,7 @@
*
* @return the offset in bytes
*/
- default int getArrayBaseOffset(JavaKind kind) {
+ static int getArrayBaseOffset(JavaKind kind) {
switch (kind) {
case Boolean:
return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
@@ -100,7 +107,7 @@
*
* @return the scale in order to convert the index into a byte offset
*/
- default int getArrayIndexScale(JavaKind kind) {
+ static int getArrayIndexScale(JavaKind kind) {
switch (kind) {
case Boolean:
return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJavaType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJavaType.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaType;
/**
* Common base class for all HotSpot {@link JavaType} implementations.
@@ -39,5 +39,4 @@
public final String getName() {
return name;
}
-
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,8 +22,10 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.MemoryAccessProvider;
/**
* HotSpot specific extension of {@link MemoryAccessProvider}.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -23,8 +23,6 @@
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-
-import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
import jdk.vm.ci.meta.Constant;
@@ -36,7 +34,7 @@
/**
* HotSpot implementation of {@link MemoryAccessProvider}.
*/
-public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
+class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
protected final HotSpotJVMCIRuntimeProvider runtime;
@@ -54,7 +52,7 @@
private boolean isValidObjectFieldDisplacement(Constant base, long displacement) {
if (base instanceof HotSpotMetaspaceConstant) {
- Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
+ MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
if (displacement == runtime.getConfig().classMirrorOffset) {
// Klass::_java_mirror is valid for all Klass* values
@@ -68,8 +66,9 @@
}
private static long asRawPointer(Constant base) {
- if (base instanceof HotSpotMetaspaceConstant) {
- return ((HotSpotMetaspaceConstant) base).rawValue();
+ if (base instanceof HotSpotMetaspaceConstantImpl) {
+ MetaspaceWrapperObject meta = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
+ return meta.getMetaspacePointer();
} else if (base instanceof PrimitiveConstant) {
PrimitiveConstant prim = (PrimitiveConstant) base;
if (prim.getJavaKind().isNumericInteger()) {
@@ -119,7 +118,7 @@
}
}
if (base instanceof HotSpotMetaspaceConstant) {
- Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
+ MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
if (displacement == runtime.getConfig().classMirrorOffset) {
assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
@@ -211,8 +210,7 @@
if (klass == null) {
return JavaConstant.NULL_POINTER;
}
- TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
- return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, klass.getMetaspaceKlass(), klass, false);
+ return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, false);
}
@Override
@@ -221,15 +219,14 @@
if (klass == null) {
return HotSpotCompressedNullConstant.COMPRESSED_NULL;
}
- return HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Int, encoding.compress(klass.getMetaspaceKlass()), klass, true);
+ return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, true);
}
@Override
public Constant readMethodPointerConstant(Constant base, long displacement) {
- TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
assert (base instanceof HotSpotObjectConstantImpl);
Object baseObject = ((HotSpotObjectConstantImpl) base).object();
HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
- return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, method.getMetaspaceMethod(), method, false);
+ return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false);
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,14 +22,31 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
+import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-import java.lang.reflect.*;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.CodeUtil;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
// JaCoCo Exclude
@@ -292,9 +309,9 @@
int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object());
ResolvedJavaType elementType = lookupJavaType.getComponentType();
JavaKind elementKind = elementType.getJavaKind();
- final int headerSize = runtime.getArrayBaseOffset(elementKind);
+ final int headerSize = getArrayBaseOffset(elementKind);
TargetDescription target = runtime.getHostJVMCIBackend().getTarget();
- int sizeOfElement = target.getSizeInBytes(elementKind);
+ int sizeOfElement = getArrayIndexScale(elementKind);
int alignment = target.wordSize;
int log2ElementSize = CodeUtil.log2(sizeOfElement);
return computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,6 +22,8 @@
*/
package jdk.vm.ci.hotspot;
+import jdk.vm.ci.inittimer.SuppressFBWarnings;
+
public class HotSpotMetaData {
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] pcDescBytes;
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] scopesDescBytes;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,18 +22,11 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.VMConstant;
public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant {
- Constant compress(CompressEncoding encoding);
-
- Constant uncompress(CompressEncoding encoding);
-
HotSpotResolvedObjectType asResolvedJavaType();
HotSpotResolvedJavaMethod asResolvedJavaMethod();
-
- long rawValue();
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,59 +22,75 @@
*/
package jdk.vm.ci.hotspot;
-import java.util.*;
+import java.util.Objects;
-import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.VMConstant;
-public final class HotSpotMetaspaceConstantImpl extends PrimitiveConstant implements HotSpotMetaspaceConstant, VMConstant, HotSpotProxified {
+final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant, HotSpotProxified {
- static HotSpotMetaspaceConstantImpl forMetaspaceObject(JavaKind kind, long primitive, Object metaspaceObject, boolean compressed) {
- return new HotSpotMetaspaceConstantImpl(kind, primitive, metaspaceObject, compressed);
+ static HotSpotMetaspaceConstantImpl forMetaspaceObject(MetaspaceWrapperObject metaspaceObject, boolean compressed) {
+ return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed);
}
- static Object getMetaspaceObject(Constant constant) {
+ static MetaspaceWrapperObject getMetaspaceObject(Constant constant) {
return ((HotSpotMetaspaceConstantImpl) constant).metaspaceObject;
}
- private final Object metaspaceObject;
+ private final MetaspaceWrapperObject metaspaceObject;
private final boolean compressed;
- private HotSpotMetaspaceConstantImpl(JavaKind kind, long primitive, Object metaspaceObject, boolean compressed) {
- super(kind, primitive);
+ private HotSpotMetaspaceConstantImpl(MetaspaceWrapperObject metaspaceObject, boolean compressed) {
this.metaspaceObject = metaspaceObject;
this.compressed = compressed;
}
@Override
public int hashCode() {
- return super.hashCode() ^ System.identityHashCode(metaspaceObject);
+ return System.identityHashCode(metaspaceObject) ^ (compressed ? 1 : 2);
}
@Override
public boolean equals(Object o) {
- return o == this || (o instanceof HotSpotMetaspaceConstantImpl && super.equals(o) && Objects.equals(metaspaceObject, ((HotSpotMetaspaceConstantImpl) o).metaspaceObject));
+ if (o == this) {
+ return true;
+ }
+ if (!(o instanceof HotSpotMetaspaceConstantImpl)) {
+ return false;
+ }
+
+ HotSpotMetaspaceConstantImpl other = (HotSpotMetaspaceConstantImpl) o;
+ return Objects.equals(this.metaspaceObject, other.metaspaceObject) && this.compressed == other.compressed;
+ }
+
+ @Override
+ public String toValueString() {
+ return String.format("meta{%s%s}", metaspaceObject, compressed ? ";compressed" : "");
}
@Override
public String toString() {
- return super.toString() + "{" + metaspaceObject + (compressed ? ";compressed}" : "}");
+ return toValueString();
+ }
+
+ public boolean isDefaultForKind() {
+ return false;
}
public boolean isCompressed() {
return compressed;
}
- public JavaConstant compress(CompressEncoding encoding) {
+ public Constant compress() {
assert !isCompressed();
- HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Int, encoding.compress(asLong()), metaspaceObject, true);
+ HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, true);
assert res.isCompressed();
return res;
}
- public JavaConstant uncompress(CompressEncoding encoding) {
+ public Constant uncompress() {
assert isCompressed();
- HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Long, encoding.uncompress(asInt()), metaspaceObject, false);
+ HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, false);
assert !res.isCompressed();
return res;
}
@@ -92,8 +108,4 @@
}
return null;
}
-
- public long rawValue() {
- return asLong();
- }
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,12 +22,17 @@
*/
package jdk.vm.ci.hotspot;
-import static java.util.FormattableFlags.*;
-import java.util.*;
+import static java.util.FormattableFlags.ALTERNATE;
+import static java.util.FormattableFlags.LEFT_JUSTIFY;
+import static java.util.FormattableFlags.UPPERCASE;
-import jdk.vm.ci.meta.*;
+import java.util.Formattable;
+import java.util.Formatter;
-public abstract class HotSpotMethod implements JavaMethod, Formattable /* , JavaMethodContex */{
+import jdk.vm.ci.meta.JavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+abstract class HotSpotMethod implements JavaMethod, Formattable /* , JavaMethodContex */{
public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
if (flags == 0 && width < 0) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,24 +22,31 @@
*/
package jdk.vm.ci.hotspot;
-import static java.lang.String.*;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static java.lang.String.format;
+import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-import java.util.*;
+import java.util.Arrays;
-import jdk.vm.ci.hotspot.HotSpotMethodDataAccessor.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.meta.JavaMethodProfile.*;
-import jdk.vm.ci.meta.JavaTypeProfile.*;
-import sun.misc.*;
+import jdk.vm.ci.hotspot.HotSpotMethodDataAccessor.Tag;
+import jdk.vm.ci.meta.DeoptimizationReason;
+import jdk.vm.ci.meta.JavaMethodProfile;
+import jdk.vm.ci.meta.JavaMethodProfile.ProfiledMethod;
+import jdk.vm.ci.meta.JavaTypeProfile;
+import jdk.vm.ci.meta.JavaTypeProfile.ProfiledType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.TriState;
+import sun.misc.Unsafe;
/**
* Access to a HotSpot MethodData structure (defined in methodData.hpp).
*/
public final class HotSpotMethodData {
- private static final HotSpotVMConfig config = runtime().getConfig();
+ private static final HotSpotVMConfig config = config();
private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(TriState.FALSE);
private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(TriState.UNKNOWN);
@@ -50,16 +57,16 @@
new BitData(),
new CounterData(),
new JumpData(),
- new TypeCheckData(),
+ new ReceiverTypeData(),
new VirtualCallData(),
new RetData(),
new BranchData(),
new MultiBranchData(),
new ArgInfoData(),
- null, // call_type_data_tag
- null, // virtual_call_type_data_tag
- null, // parameters_type_data_tag
- null, // speculative_trap_data_tag
+ new UnknownProfileData(Tag.CallTypeData),
+ new VirtualCallTypeData(),
+ new UnknownProfileData(Tag.ParametersTypeData),
+ new UnknownProfileData(Tag.SpeculativeTrapData),
};
// @formatter:on
@@ -127,7 +134,8 @@
}
HotSpotMethodDataAccessor result = getData(position);
- assert result != null : "NO_DATA tag is not allowed";
+ final Tag tag = AbstractMethodData.readTag(this, position);
+ assert result != null : "NO_DATA tag is not allowed " + tag;
return result;
}
@@ -193,12 +201,12 @@
private HotSpotResolvedJavaMethod readMethod(int position, int offsetInBytes) {
long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
- return runtime().compilerToVm.getResolvedJavaMethod(null, metaspaceMethodData + fullOffsetInBytes);
+ return compilerToVM().getResolvedJavaMethod(null, metaspaceMethodData + fullOffsetInBytes);
}
private HotSpotResolvedObjectTypeImpl readKlass(int position, int offsetInBytes) {
long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
- return runtime().compilerToVm.getResolvedJavaType(null, metaspaceMethodData + fullOffsetInBytes, false);
+ return compilerToVM().getResolvedJavaType(null, metaspaceMethodData + fullOffsetInBytes, false);
}
private static int truncateLongToInt(long value) {
@@ -266,10 +274,10 @@
/**
* Corresponds to {@code exception_seen_flag}.
*/
- private static final int EXCEPTIONS_MASK = 0x2;
+ private static final int EXCEPTIONS_MASK = 1 << config.bitDataExceptionSeenFlag;
private final Tag tag;
- private final int staticSize;
+ protected final int staticSize;
protected AbstractMethodData(Tag tag, int staticSize) {
this.tag = tag;
@@ -291,8 +299,12 @@
}
@Override
- public int getSize(HotSpotMethodData data, int position) {
- return staticSize + getDynamicSize(data, position);
+ public final int getSize(HotSpotMethodData data, int position) {
+ int size = staticSize + getDynamicSize(data, position);
+ // Sanity check against VM
+ int vmSize = HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position);
+ assert size == vmSize : size + " != " + vmSize;
+ return size;
}
@Override
@@ -375,7 +387,7 @@
private static class BitData extends AbstractMethodData {
private static final int BIT_DATA_SIZE = cellIndexToOffset(0);
- private static final int BIT_DATA_NULL_SEEN_FLAG = 0x01;
+ private static final int BIT_DATA_NULL_SEEN_FLAG = 1 << config.bitDataNullSeenFlag;
private BitData() {
super(Tag.BitData, BIT_DATA_SIZE);
@@ -399,7 +411,7 @@
private static class CounterData extends BitData {
private static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
- private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(0);
+ private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(config.methodDataCountOffset);
public CounterData() {
super(Tag.CounterData, COUNTER_DATA_SIZE);
@@ -427,8 +439,8 @@
private static class JumpData extends AbstractMethodData {
private static final int JUMP_DATA_SIZE = cellIndexToOffset(2);
- protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(0);
- protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(1);
+ protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(config.jumpDataTakenOffset);
+ protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(config.jumpDataDisplacementOffset);
public JumpData() {
super(Tag.JumpData, JUMP_DATA_SIZE);
@@ -474,11 +486,11 @@
private abstract static class AbstractTypeData extends CounterData {
- protected static final int TYPE_DATA_ROW_SIZE = cellsToBytes(2);
+ protected static final int TYPE_DATA_ROW_SIZE = cellsToBytes(config.receiverTypeDataReceiverTypeRowCellCount);
- protected static final int NONPROFILED_COUNT_OFFSET = cellIndexToOffset(1);
- protected static final int TYPE_DATA_FIRST_TYPE_OFFSET = cellIndexToOffset(2);
- protected static final int TYPE_DATA_FIRST_TYPE_COUNT_OFFSET = cellIndexToOffset(3);
+ protected static final int NONPROFILED_COUNT_OFFSET = cellIndexToOffset(config.receiverTypeDataNonprofiledCountOffset);
+ protected static final int TYPE_DATA_FIRST_TYPE_OFFSET = cellIndexToOffset(config.receiverTypeDataReceiver0Offset);
+ protected static final int TYPE_DATA_FIRST_TYPE_COUNT_OFFSET = cellIndexToOffset(config.receiverTypeDataCount0Offset);
protected AbstractTypeData(Tag tag, int staticSize) {
super(tag, staticSize);
@@ -571,14 +583,18 @@
}
}
- private static class TypeCheckData extends AbstractTypeData {
+ private static class ReceiverTypeData extends AbstractTypeData {
private static final int TYPE_CHECK_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
- public TypeCheckData() {
+ public ReceiverTypeData() {
super(Tag.ReceiverTypeData, TYPE_CHECK_DATA_SIZE);
}
+ protected ReceiverTypeData(Tag tag, int staticSize) {
+ super(tag, staticSize);
+ }
+
@Override
public int getExecutionCount(HotSpotMethodData data, int position) {
return -1;
@@ -590,7 +606,7 @@
}
}
- private static class VirtualCallData extends AbstractTypeData {
+ private static class VirtualCallData extends ReceiverTypeData {
private static final int VIRTUAL_CALL_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * (config.typeProfileWidth + config.methodProfileWidth);
private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_OFFSET = TYPE_DATA_FIRST_TYPE_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
@@ -600,6 +616,10 @@
super(Tag.VirtualCallData, VIRTUAL_CALL_DATA_SIZE);
}
+ protected VirtualCallData(Tag tag, int staticSize) {
+ super(tag, staticSize);
+ }
+
@Override
public int getExecutionCount(HotSpotMethodData data, int position) {
final int typeProfileWidth = config.typeProfileWidth;
@@ -692,6 +712,19 @@
}
}
+ private static class VirtualCallTypeData extends VirtualCallData {
+
+ public VirtualCallTypeData() {
+ super(Tag.VirtualCallTypeData, 0);
+ }
+
+ @Override
+ protected int getDynamicSize(HotSpotMethodData data, int position) {
+ assert staticSize == 0;
+ return HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position);
+ }
+ }
+
private static class RetData extends CounterData {
private static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
@@ -705,7 +738,7 @@
private static class BranchData extends JumpData {
private static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
- private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(2);
+ private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(config.branchDataNotTakenOffset);
public BranchData() {
super(Tag.BranchData, BRANCH_DATA_SIZE);
@@ -737,8 +770,8 @@
private static class ArrayData extends AbstractMethodData {
- private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(0);
- protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(1);
+ private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(config.arrayDataArrayLenOffset);
+ protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(config.arrayDataArrayStartOffset);
public ArrayData(Tag tag, int staticSize) {
super(tag, staticSize);
@@ -762,7 +795,7 @@
private static class MultiBranchData extends ArrayData {
private static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1);
- private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = 2;
+ private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = config.multiBranchDataPerCaseCellCount;
private static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS);
private static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
@@ -854,6 +887,24 @@
}
}
+ private static class UnknownProfileData extends AbstractMethodData {
+ public UnknownProfileData(Tag tag) {
+ super(tag, 0);
+ }
+
+ @Override
+ protected int getDynamicSize(HotSpotMethodData data, int position) {
+ assert staticSize == 0;
+ return HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position);
+ }
+
+ @Override
+ public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ }
+
public void setCompiledIRSize(int size) {
UNSAFE.putInt(metaspaceMethodData + config.methodDataIRSizeOffset, size);
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,11 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
-
-import jdk.vm.ci.meta.*;
+import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
+import jdk.vm.ci.meta.JavaMethodProfile;
+import jdk.vm.ci.meta.JavaTypeProfile;
+import jdk.vm.ci.meta.ProfilingInfo;
+import jdk.vm.ci.meta.TriState;
/**
* Interface for accessor objects that encapsulate the logic for accessing the different kinds of
@@ -62,10 +64,6 @@
return value;
}
- private static HotSpotVMConfig config() {
- return runtime().getConfig();
- }
-
public static Tag getEnum(int value) {
Tag result = values()[value];
assert value == result.value;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,11 +22,16 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
-import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
-
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
+import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.MethodHandleAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider, HotSpotProxified {
@@ -155,6 +160,6 @@
Object object = ((HotSpotObjectConstantImpl) memberName).object();
/* Read the ResolvedJavaMethod from the injected field MemberName.vmtarget */
- return runtime().compilerToVm.getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
+ return compilerToVM().getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodUnresolved.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodUnresolved.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,12 +22,14 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaMethod;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.Signature;
/**
* Implementation of {@link JavaMethod} for unresolved HotSpot methods.
*/
-public final class HotSpotMethodUnresolved extends HotSpotMethod {
+final class HotSpotMethodUnresolved extends HotSpotMethod {
private final Signature signature;
protected JavaType holder;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,12 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
-
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.meta.*;
+import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a
@@ -45,34 +47,24 @@
private final HotSpotResolvedJavaMethod method;
private final boolean isDefault;
- private final boolean isExternal;
public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault) {
- this(method, name, isDefault, false);
- }
-
- public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault, boolean isExternal) {
super(name);
this.method = method;
this.isDefault = isDefault;
- this.isExternal = isExternal;
}
public boolean isDefault() {
return isDefault;
}
- public boolean isExternal() {
- return isExternal;
- }
-
public ResolvedJavaMethod getMethod() {
return method;
}
@Override
public void invalidate() {
- runtime().getCompilerToVM().invalidateInstalledCode(this);
+ compilerToVM().invalidateInstalledCode(this);
}
@Override
@@ -105,8 +97,7 @@
@Override
public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
assert checkArgs(args);
- assert !isExternal();
- return runtime().getCompilerToVM().executeInstalledCode(args, this);
+ return compilerToVM().executeInstalledCode(args, this);
}
@Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstant.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstant.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,13 @@
*/
package jdk.vm.ci.hotspot;
-import java.lang.invoke.*;
-import java.util.*;
+import java.lang.invoke.CallSite;
+import java.util.Objects;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.Assumptions;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.VMConstant;
/**
* Represents a constant non-{@code null} object reference, within the compiler and across the
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,20 +22,26 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
+import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.MethodHandle;
-import java.lang.invoke.*;
-
-import jdk.vm.ci.inittimer.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.inittimer.SuppressFBWarnings;
+import jdk.vm.ci.meta.Assumptions;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Represents a constant non-{@code null} object reference, within the compiler and across the
* compiler/runtime interface.
*/
-public final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotProxified {
+final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotProxified {
- public static JavaConstant forObject(Object object) {
+ static JavaConstant forObject(Object object) {
return forObject(object, false);
}
@@ -106,21 +112,6 @@
return object;
}
- /**
- * Determines if the object represented by this constant is {@link Object#equals(Object) equal}
- * to a given object.
- */
- public boolean isEqualTo(Object obj) {
- return object.equals(obj);
- }
-
- /**
- * Gets the class of the object represented by this constant.
- */
- public Class<?> getObjectClass() {
- return object.getClass();
- }
-
public boolean isCompressed() {
return compressed;
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotOopMap.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotOopMap.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,6 +22,8 @@
*/
package jdk.vm.ci.hotspot;
+import jdk.vm.ci.inittimer.SuppressFBWarnings;
+
public class HotSpotOopMap {
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int offset;
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int count;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,11 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.DeoptimizationReason;
+import jdk.vm.ci.meta.JavaMethodProfile;
+import jdk.vm.ci.meta.JavaTypeProfile;
+import jdk.vm.ci.meta.ProfilingInfo;
+import jdk.vm.ci.meta.TriState;
public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxified {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,10 @@
*/
package jdk.vm.ci.hotspot;
-import java.util.*;
+import java.util.Arrays;
-import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.Location;
+import jdk.vm.ci.code.ReferenceMap;
public final class HotSpotReferenceMap extends ReferenceMap {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ResolvedJavaField;
/**
* Represents a field in a HotSpot type.
@@ -45,4 +45,12 @@
* @return true if field has {@link Stable} annotation, false otherwise
*/
boolean isStable();
+
+ /**
+ * If this field is stable, checks if default values (0, null, etc.) should be considered stable
+ * as well.
+ *
+ * @return true if default values should be considered stable, false otherwise
+ */
+ boolean isDefaultStable();
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,20 +22,27 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
-import static jdk.vm.ci.hotspot.HotSpotResolvedJavaFieldImpl.Options.*;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.options.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.LocationIdentity;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ModifiersProvider;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.options.Option;
+import jdk.vm.ci.options.OptionType;
+import jdk.vm.ci.options.OptionValue;
/**
* Represents a field in a HotSpot type.
*/
-public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
+class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
static class Options {
//@formatter:off
@@ -91,7 +98,7 @@
}
}
- public HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
+ HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
this.holder = holder;
this.name = name;
this.type = type;
@@ -130,7 +137,7 @@
@Override
public boolean isInternal() {
- return (modifiers & runtime().getConfig().jvmAccFieldInternal) != 0;
+ return (modifiers & config().jvmAccFieldInternal) != 0;
}
/**
@@ -183,7 +190,7 @@
@Override
public boolean isSynthetic() {
- return (runtime().getConfig().syntheticFlag & modifiers) != 0;
+ return (config().syntheticFlag & modifiers) != 0;
}
/**
@@ -192,11 +199,11 @@
* @return true if field has {@link Stable} annotation, false otherwise
*/
public boolean isStable() {
- if ((runtime().getConfig().jvmAccFieldStable & modifiers) != 0) {
+ if ((config().jvmAccFieldStable & modifiers) != 0) {
return true;
}
assert getAnnotation(Stable.class) == null;
- if (ImplicitStableValues.getValue() && isImplicitStableField()) {
+ if (Options.ImplicitStableValues.getValue() && isImplicitStableField()) {
return true;
}
return false;
@@ -243,19 +250,25 @@
}
private boolean isImplicitStableField() {
- if (isSynthetic()) {
- if (isSyntheticImplicitStableField()) {
- return true;
- }
- } else if (isWellKnownImplicitStableField()) {
+ if (isSyntheticEnumSwitchMap()) {
+ return true;
+ }
+ if (isWellKnownImplicitStableField()) {
return true;
}
return false;
}
- private boolean isSyntheticImplicitStableField() {
- assert this.isSynthetic();
- if (isStatic() && isArray()) {
+ public boolean isDefaultStable() {
+ assert this.isStable();
+ if (isSyntheticEnumSwitchMap()) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isSyntheticEnumSwitchMap() {
+ if (isSynthetic() && isStatic() && isArray()) {
if (isFinal() && name.equals("$VALUES") || name.equals("ENUM$VALUES")) {
// generated int[] field for EnumClass::values()
return true;
@@ -281,6 +294,7 @@
}
private static final ResolvedJavaField STRING_VALUE_FIELD;
+
static {
try {
MetaAccessProvider metaAccess = runtime().getHostJVMCIBackend().getMetaAccess();
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,15 +22,27 @@
*/
package jdk.vm.ci.hotspot;
-import java.lang.reflect.*;
+import java.lang.reflect.Modifier;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.options.Option;
+import jdk.vm.ci.options.OptionType;
+import jdk.vm.ci.options.OptionValue;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
public interface HotSpotResolvedJavaMethod extends ResolvedJavaMethod {
+ public static class Options {
+ // @formatter:off
+ @Option(help = "", type = OptionType.Debug)
+ public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
+ // @formatter:on
+ }
+
/**
* Returns true if this method has a {@code CallerSensitive} annotation.
*
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,29 +22,47 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
-import static jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.Options.*;
+import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+import static jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod.Options.UseProfilingInformation;
+import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Executable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.options.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.DefaultProfilingInfo;
+import jdk.vm.ci.meta.ExceptionHandler;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaMethod;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.LineNumberTable;
+import jdk.vm.ci.meta.LineNumberTableImpl;
+import jdk.vm.ci.meta.Local;
+import jdk.vm.ci.meta.LocalImpl;
+import jdk.vm.ci.meta.LocalVariableTable;
+import jdk.vm.ci.meta.LocalVariableTableImpl;
+import jdk.vm.ci.meta.ModifiersProvider;
+import jdk.vm.ci.meta.ProfilingInfo;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
+import jdk.vm.ci.meta.SpeculationLog;
+import jdk.vm.ci.meta.TriState;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
-public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
-
- public static class Options {
- // @formatter:off
- @Option(help = "", type = OptionType.Debug)
- public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
- // @formatter:on
- }
+final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
/**
* Reference to metaspace Method object.
@@ -56,7 +74,7 @@
private final HotSpotSignature signature;
private HotSpotMethodData methodData;
private byte[] code;
- private Member toJavaCache;
+ private Executable toJavaCache;
/**
* Gets the holder of a HotSpot metaspace method native object.
@@ -66,10 +84,10 @@
* {@code metaspaceMethod}
*/
private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final long metaspaceConstMethod = UNSAFE.getAddress(metaspaceMethod + config.methodConstMethodOffset);
final long metaspaceConstantPool = UNSAFE.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
- return runtime().getCompilerToVM().getResolvedJavaType(null, metaspaceConstantPool + config.constantPoolHolderOffset, false);
+ return compilerToVM().getResolvedJavaType(null, metaspaceConstantPool + config.constantPoolHolderOffset, false);
}
/**
@@ -94,7 +112,7 @@
this.metaspaceMethod = metaspaceMethod;
this.holder = holder;
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final long constMethod = getConstMethod();
/*
@@ -106,7 +124,7 @@
if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) {
this.constantPool = holder.getConstantPool();
} else {
- this.constantPool = runtime().getCompilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
+ this.constantPool = compilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
}
final int nameIndex = UNSAFE.getChar(constMethod + config.constMethodNameIndexOffset);
@@ -126,7 +144,7 @@
*/
private long getConstMethod() {
assert metaspaceMethod != 0;
- return UNSAFE.getAddress(metaspaceMethod + runtime().getConfig().methodConstMethodOffset);
+ return UNSAFE.getAddress(metaspaceMethod + config().methodConstMethodOffset);
}
@Override
@@ -152,7 +170,7 @@
* @return flags of this method
*/
private int getFlags() {
- return UNSAFE.getByte(metaspaceMethod + runtime().getConfig().methodFlagsOffset);
+ return UNSAFE.getByte(metaspaceMethod + config().methodFlagsOffset);
}
/**
@@ -161,7 +179,7 @@
* @return flags of this method's ConstMethod
*/
private int getConstMethodFlags() {
- return UNSAFE.getChar(getConstMethod() + runtime().getConfig().constMethodFlagsOffset);
+ return UNSAFE.getChar(getConstMethod() + config().constMethodFlagsOffset);
}
@Override
@@ -172,20 +190,16 @@
/**
* Gets the address of the C++ Method object for this method.
*/
- public JavaConstant getMetaspaceMethodConstant() {
- return HotSpotMetaspaceConstantImpl.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this, false);
+ public Constant getMetaspaceMethodConstant() {
+ return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
- public long getMetaspaceMethod() {
+ public long getMetaspacePointer() {
return metaspaceMethod;
}
- public long getMetaspacePointer() {
- return getMetaspaceMethod();
- }
-
@Override
- public JavaConstant getEncoding() {
+ public Constant getEncoding() {
return getMetaspaceMethodConstant();
}
@@ -194,7 +208,7 @@
* modifiers as well as the HotSpot internal modifiers.
*/
public int getAllModifiers() {
- return UNSAFE.getInt(metaspaceMethod + runtime().getConfig().methodAccessFlagsOffset);
+ return UNSAFE.getInt(metaspaceMethod + config().methodAccessFlagsOffset);
}
@Override
@@ -213,7 +227,7 @@
return null;
}
if (code == null && holder.isLinked()) {
- code = runtime().getCompilerToVM().getBytecode(this);
+ code = compilerToVM().getBytecode(this);
assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length;
}
return code;
@@ -221,20 +235,20 @@
@Override
public int getCodeSize() {
- return UNSAFE.getChar(getConstMethod() + runtime().getConfig().constMethodCodeSizeOffset);
+ return UNSAFE.getChar(getConstMethod() + config().constMethodCodeSizeOffset);
}
@Override
public ExceptionHandler[] getExceptionHandlers() {
- final boolean hasExceptionTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasExceptionTable) != 0;
+ final boolean hasExceptionTable = (getConstMethodFlags() & config().constMethodHasExceptionTable) != 0;
if (!hasExceptionTable) {
return new ExceptionHandler[0];
}
- HotSpotVMConfig config = runtime().getConfig();
- final int exceptionTableLength = runtime().getCompilerToVM().getExceptionTableLength(this);
+ HotSpotVMConfig config = config();
+ final int exceptionTableLength = compilerToVM().getExceptionTableLength(this);
ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength];
- long exceptionTableElement = runtime().getCompilerToVM().getExceptionTableStart(this);
+ long exceptionTableElement = compilerToVM().getExceptionTableStart(this);
for (int i = 0; i < exceptionTableLength; i++) {
final int startPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset);
@@ -273,7 +287,7 @@
* @return true if CallerSensitive annotation present, false otherwise
*/
public boolean isCallerSensitive() {
- return (getFlags() & runtime().getConfig().methodFlagsCallerSensitive) != 0;
+ return (getFlags() & config().methodFlagsCallerSensitive) != 0;
}
/**
@@ -282,7 +296,7 @@
* @return true if ForceInline annotation present, false otherwise
*/
public boolean isForceInline() {
- return (getFlags() & runtime().getConfig().methodFlagsForceInline) != 0;
+ return (getFlags() & config().methodFlagsForceInline) != 0;
}
/**
@@ -291,14 +305,14 @@
* @return true if DontInline annotation present, false otherwise
*/
public boolean isDontInline() {
- return (getFlags() & runtime().getConfig().methodFlagsDontInline) != 0;
+ return (getFlags() & config().methodFlagsDontInline) != 0;
}
/**
* Manually adds a DontInline annotation to this method.
*/
public void setNotInlineable() {
- runtime().getCompilerToVM().doNotInlineOrCompile(this);
+ compilerToVM().doNotInlineOrCompile(this);
}
/**
@@ -308,7 +322,7 @@
* @return true if special method ignored by security stack walks, false otherwise
*/
public boolean ignoredBySecurityStackWalk() {
- return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(this);
+ return compilerToVM().methodIsIgnoredBySecurityStackWalk(this);
}
@Override
@@ -326,7 +340,7 @@
if (isAbstract() || isNative()) {
return 0;
}
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
return UNSAFE.getChar(getConstMethod() + config.methodMaxLocalsOffset);
}
@@ -335,7 +349,7 @@
if (isAbstract() || isNative()) {
return 0;
}
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
return config.extraStackEntries + UNSAFE.getChar(getConstMethod() + config.constMethodMaxStackOffset);
}
@@ -343,10 +357,10 @@
public StackTraceElement asStackTraceElement(int bci) {
if (bci < 0 || bci >= getCodeSize()) {
// HotSpot code can only construct stack trace elements for valid bcis
- StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(this, 0);
+ StackTraceElement ste = compilerToVM().getStackTraceElement(this, 0);
return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
}
- return runtime().getCompilerToVM().getStackTraceElement(this, bci);
+ return compilerToVM().getStackTraceElement(this, bci);
}
public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
@@ -361,7 +375,11 @@
// seeing A.foo().
return null;
}
- return runtime().getCompilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this);
+ if (this.isDefault()) {
+ // CHA for default methods doesn't work and may crash the VM
+ return null;
+ }
+ return compilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this);
}
@Override
@@ -375,7 +393,7 @@
* @return the value of {@code Method::_code}
*/
private long getCompiledCode() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
return UNSAFE.getAddress(metaspaceMethod + config.methodCodeOffset);
}
@@ -395,7 +413,7 @@
public boolean hasCompiledCodeAtLevel(int level) {
long compiledCode = getCompiledCode();
if (compiledCode != 0) {
- return UNSAFE.getInt(compiledCode + runtime().getConfig().nmethodCompLevelOffset) == level;
+ return UNSAFE.getInt(compiledCode + config().nmethodCompLevelOffset) == level;
}
return false;
}
@@ -407,7 +425,7 @@
ProfilingInfo info;
if (UseProfilingInformation.getValue() && methodData == null) {
- long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + runtime().getConfig().methodDataOffset);
+ long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + config().methodDataOffset);
if (metaspaceMethodData != 0) {
methodData = new HotSpotMethodData(metaspaceMethodData, this);
if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) {
@@ -429,7 +447,7 @@
@Override
public void reprofile() {
- runtime().getCompilerToVM().reprofile(this);
+ compilerToVM().reprofile(this);
}
@Override
@@ -439,31 +457,19 @@
@Override
public Annotation[][] getParameterAnnotations() {
- if (isConstructor()) {
- Constructor<?> javaConstructor = toJavaConstructor();
- return javaConstructor == null ? null : javaConstructor.getParameterAnnotations();
- }
- Method javaMethod = toJava();
+ Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getParameterAnnotations();
}
@Override
public Annotation[] getAnnotations() {
- if (isConstructor()) {
- Constructor<?> javaConstructor = toJavaConstructor();
- return javaConstructor == null ? new Annotation[0] : javaConstructor.getAnnotations();
- }
- Method javaMethod = toJava();
+ Executable javaMethod = toJava();
return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations();
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
- if (isConstructor()) {
- Constructor<?> javaConstructor = toJavaConstructor();
- return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass);
- }
- Method javaMethod = toJava();
+ Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
}
@@ -478,11 +484,7 @@
@Override
public Type[] getGenericParameterTypes() {
- if (isConstructor()) {
- Constructor<?> javaConstructor = toJavaConstructor();
- return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes();
- }
- Method javaMethod = toJava();
+ Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
}
@@ -498,25 +500,13 @@
return result;
}
- private Method toJava() {
+ private Executable toJava() {
if (toJavaCache != null) {
- return (Method) toJavaCache;
+ return toJavaCache;
}
try {
- Method result = holder.mirror().getDeclaredMethod(name, signatureToTypes());
- toJavaCache = result;
- return result;
- } catch (NoSuchMethodException | NoClassDefFoundError e) {
- return null;
- }
- }
-
- private Constructor<?> toJavaConstructor() {
- if (toJavaCache != null) {
- return (Constructor<?>) toJavaCache;
- }
- try {
- Constructor<?> result = holder.mirror().getDeclaredConstructor(signatureToTypes());
+ Class<?>[] parameterTypes = signatureToTypes();
+ Executable result = isConstructor() ? holder.mirror().getDeclaredConstructor(parameterTypes) : holder.mirror().getDeclaredMethod(name, parameterTypes);
toJavaCache = result;
return result;
} catch (NoSuchMethodException | NoClassDefFoundError e) {
@@ -529,7 +519,7 @@
if (isDontInline()) {
return false;
}
- return runtime().getCompilerToVM().canInlineMethod(this);
+ return compilerToVM().canInlineMethod(this);
}
@Override
@@ -537,17 +527,17 @@
if (isForceInline()) {
return true;
}
- return runtime().getCompilerToVM().shouldInlineMethod(this);
+ return compilerToVM().shouldInlineMethod(this);
}
@Override
public LineNumberTable getLineNumberTable() {
- final boolean hasLineNumberTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLineNumberTable) != 0;
+ final boolean hasLineNumberTable = (getConstMethodFlags() & config().constMethodHasLineNumberTable) != 0;
if (!hasLineNumberTable) {
return null;
}
- long[] values = runtime().getCompilerToVM().getLineNumberTable(this);
+ long[] values = compilerToVM().getLineNumberTable(this);
if (values == null || values.length == 0) {
// Empty table so treat is as non-existent
return null;
@@ -566,14 +556,14 @@
@Override
public LocalVariableTable getLocalVariableTable() {
- final boolean hasLocalVariableTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLocalVariableTable) != 0;
+ final boolean hasLocalVariableTable = (getConstMethodFlags() & config().constMethodHasLocalVariableTable) != 0;
if (!hasLocalVariableTable) {
return null;
}
- HotSpotVMConfig config = runtime().getConfig();
- long localVariableTableElement = runtime().getCompilerToVM().getLocalVariableTableStart(this);
- final int localVariableTableLength = runtime().getCompilerToVM().getLocalVariableTableLength(this);
+ HotSpotVMConfig config = config();
+ long localVariableTableElement = compilerToVM().getLocalVariableTableStart(this);
+ final int localVariableTableLength = compilerToVM().getLocalVariableTableLength(this);
Local[] locals = new Local[localVariableTableLength];
for (int i = 0; i < localVariableTableLength; i++) {
@@ -606,7 +596,7 @@
if (!isInVirtualMethodTable(resolved)) {
throw new JVMCIError("%s does not have a vtable entry in type %s", this, resolved);
}
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved);
return config.instanceKlassVtableStartOffset() + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
}
@@ -623,11 +613,11 @@
private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) {
if (!holder.isLinked()) {
- return runtime().getConfig().invalidVtableIndex;
+ return config().invalidVtableIndex;
}
if (holder.isInterface()) {
if (resolved.isInterface()) {
- return runtime().getConfig().invalidVtableIndex;
+ return config().invalidVtableIndex;
}
return getVtableIndexForInterfaceMethod(resolved);
}
@@ -640,8 +630,8 @@
* @return virtual table index
*/
private int getVtableIndex() {
- assert!holder.isInterface();
- HotSpotVMConfig config = runtime().getConfig();
+ assert !holder.isInterface();
+ HotSpotVMConfig config = config();
int result = UNSAFE.getInt(metaspaceMethod + config.methodVtableIndexOffset);
assert result >= config.nonvirtualVtableIndex : "must be linked";
return result;
@@ -649,7 +639,7 @@
private int getVtableIndexForInterfaceMethod(ResolvedJavaType resolved) {
HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved;
- return runtime().getCompilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this);
+ return compilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this);
}
/**
@@ -682,14 +672,14 @@
}
public int intrinsicId() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
return UNSAFE.getChar(metaspaceMethod + config.methodIntrinsicIdOffset);
}
@Override
public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) {
- assert!isConstructor();
- Method javaMethod = toJava();
+ assert !isConstructor();
+ Method javaMethod = (Method) toJava();
javaMethod.setAccessible(true);
Object[] objArguments = new Object[arguments.length];
@@ -714,13 +704,13 @@
* @return compile id
*/
public int allocateCompileId(int entryBCI) {
- return runtime().getCompilerToVM().allocateCompileId(this, entryBCI);
+ return compilerToVM().allocateCompileId(this, entryBCI);
}
public boolean hasCodeAtLevel(int entryBCI, int level) {
- if (entryBCI == runtime().getConfig().invocationEntryBci) {
+ if (entryBCI == config().invocationEntryBci) {
return hasCompiledCodeAtLevel(level);
}
- return runtime().getCompilerToVM().hasCompiledCodeForOSR(this, entryBCI, level);
+ return compilerToVM().hasCompiledCodeForOSR(this, entryBCI, level);
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,11 +22,11 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ResolvedJavaType;
public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType {
- public HotSpotResolvedJavaType(String name) {
+ HotSpotResolvedJavaType(String name) {
super(name);
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,14 +22,30 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.meta.Assumptions.*;
+import jdk.vm.ci.meta.Assumptions.AssumptionResult;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
*/
public interface HotSpotResolvedObjectType extends ResolvedJavaType {
+ /**
+ * Gets the JVMCI mirror for a {@link Class} object.
+ *
+ * @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
+ */
+ static HotSpotResolvedObjectType fromObjectClass(Class<?> javaClass) {
+ return HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass);
+ }
+
HotSpotResolvedObjectType getArrayClass();
ResolvedJavaType getComponentType();
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,24 +22,44 @@
*/
package jdk.vm.ci.hotspot;
-import static java.util.Objects.*;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static java.util.Objects.requireNonNull;
+import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
+import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.nio.*;
-import java.util.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.meta.Assumptions.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Assumptions.AssumptionResult;
+import jdk.vm.ci.meta.Assumptions.ConcreteMethod;
+import jdk.vm.ci.meta.Assumptions.ConcreteSubtype;
+import jdk.vm.ci.meta.Assumptions.LeafType;
+import jdk.vm.ci.meta.Assumptions.NoFinalizableSubclass;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.MetaUtil;
+import jdk.vm.ci.meta.ModifiersProvider;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.TrustedInterface;
/**
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
*/
-public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
+final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
/**
* The Java class this type represents.
@@ -58,7 +78,7 @@
*
* @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
*/
- public static HotSpotResolvedObjectTypeImpl fromObjectClass(Class<?> javaClass) {
+ static HotSpotResolvedObjectTypeImpl fromObjectClass(Class<?> javaClass) {
return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(javaClass);
}
@@ -108,11 +128,11 @@
/**
* Gets the metaspace Klass for this type.
*/
- public long getMetaspaceKlass() {
+ long getMetaspaceKlass() {
if (HotSpotJVMCIRuntime.getHostWordKind() == JavaKind.Long) {
- return UNSAFE.getLong(javaClass, (long) runtime().getConfig().klassOffset);
+ return UNSAFE.getLong(javaClass, (long) config().klassOffset);
}
- return UNSAFE.getInt(javaClass, (long) runtime().getConfig().klassOffset) & 0xFFFFFFFFL;
+ return UNSAFE.getInt(javaClass, (long) config().klassOffset) & 0xFFFFFFFFL;
}
public long getMetaspacePointer() {
@@ -129,7 +149,7 @@
}
public int getAccessFlags() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
}
@@ -149,7 +169,7 @@
@Override
public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
if (isArray()) {
return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
} else if (isInterface()) {
@@ -214,7 +234,7 @@
* @return value of the subklass field as metaspace klass pointer
*/
private HotSpotResolvedObjectTypeImpl getSubklass() {
- return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().subklassOffset, false);
+ return compilerToVM().getResolvedJavaType(this, config().subklassOffset, false);
}
@Override
@@ -241,7 +261,7 @@
if (!isInterface()) {
throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this);
}
- return runtime().getCompilerToVM().getImplementor(this);
+ return compilerToVM().getImplementor(this);
}
public HotSpotResolvedObjectTypeImpl getSupertype() {
@@ -289,14 +309,14 @@
}
@Override
- public JavaConstant getObjectHub() {
+ public Constant getObjectHub() {
return klass();
}
@Override
public AssumptionResult<Boolean> hasFinalizableSubclass() {
assert !isArray();
- if (!runtime().getCompilerToVM().hasFinalizableSubclass(this)) {
+ if (!compilerToVM().hasFinalizableSubclass(this)) {
return new AssumptionResult<>(false, new NoFinalizableSubclass(this));
}
return new AssumptionResult<>(true);
@@ -304,7 +324,7 @@
@Override
public boolean hasFinalizer() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
}
@@ -320,12 +340,12 @@
@Override
public boolean isInitialized() {
- return isArray() ? true : getInitState() == runtime().getConfig().instanceKlassStateFullyInitialized;
+ return isArray() ? true : getInitState() == config().instanceKlassStateFullyInitialized;
}
@Override
public boolean isLinked() {
- return isArray() ? true : getInitState() >= runtime().getConfig().instanceKlassStateLinked;
+ return isArray() ? true : getInitState() >= config().instanceKlassStateLinked;
}
/**
@@ -336,7 +356,7 @@
*/
private int getInitState() {
assert !isArray() : "_init_state only exists in InstanceKlass";
- return UNSAFE.getByte(getMetaspaceKlass() + runtime().getConfig().instanceKlassInitStateOffset) & 0xFF;
+ return UNSAFE.getByte(getMetaspaceKlass() + config().instanceKlassInitStateOffset) & 0xFF;
}
@Override
@@ -405,12 +425,12 @@
}
HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method;
HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType;
- return runtime().getCompilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType);
+ return compilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType);
}
public HotSpotConstantPool getConstantPool() {
if (constantPool == null) {
- constantPool = runtime().getCompilerToVM().getConstantPool(this, runtime().getConfig().instanceKlassConstantsOffset);
+ constantPool = compilerToVM().getConstantPool(this, config().instanceKlassConstantsOffset);
}
return constantPool;
}
@@ -424,7 +444,7 @@
assert !isArray();
assert !isInterface();
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final int layoutHelper = layoutHelper();
assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance";
@@ -438,7 +458,7 @@
}
public int layoutHelper() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset);
}
@@ -458,7 +478,7 @@
}
public int getVtableLength() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
if (isInterface() || isArray()) {
/* Everything has the core vtable of java.lang.Object */
return config.baseVtableLength();
@@ -547,7 +567,7 @@
* @param index index to the fields array
*/
public FieldInfo(int index) {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
// Get Klass::_fields
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
@@ -555,19 +575,19 @@
}
private int getAccessFlags() {
- return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset);
+ return readFieldSlot(config().fieldInfoAccessFlagsOffset);
}
private int getNameIndex() {
- return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset);
+ return readFieldSlot(config().fieldInfoNameIndexOffset);
}
private int getSignatureIndex() {
- return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset);
+ return readFieldSlot(config().fieldInfoSignatureIndexOffset);
}
public int getOffset() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset);
final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset);
final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize;
@@ -606,7 +626,7 @@
}
private boolean isInternal() {
- return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0;
+ return (getAccessFlags() & config().jvmAccFieldInternal) != 0;
}
public boolean isStatic() {
@@ -614,7 +634,7 @@
}
public boolean hasGenericSignature() {
- return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0;
+ return (getAccessFlags() & config().jvmAccFieldHasGenericSignature) != 0;
}
}
@@ -707,7 +727,7 @@
* See {@code FieldStreamBase::init_generic_signature_start_slot}
*/
private int getFieldCount() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
int metaspaceFieldsLength = UNSAFE.getInt(metaspaceFields + config.arrayU1LengthOffset);
int fieldCount = 0;
@@ -729,7 +749,7 @@
@Override
public String getSourceFileName() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
final int sourceFileNameIndex = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset);
if (sourceFileNameIndex == 0) {
return null;
@@ -784,21 +804,21 @@
/**
* Gets the metaspace Klass boxed in a {@link JavaConstant}.
*/
- public JavaConstant klass() {
- return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime().getHostJVMCIBackend().getTarget().wordKind, getMetaspaceKlass(), this, false);
+ public Constant klass() {
+ return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
public boolean isPrimaryType() {
- return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset();
+ return config().secondarySuperCacheOffset != superCheckOffset();
}
public int superCheckOffset() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset);
}
public long prototypeMarkWord() {
- HotSpotVMConfig config = runtime().getConfig();
+ HotSpotVMConfig config = config();
if (isArray()) {
return config.arrayPrototypeMarkWord();
} else {
@@ -874,7 +894,7 @@
}
public ResolvedJavaMethod getClassInitializer() {
- return runtime().getCompilerToVM().getClassInitializer(this);
+ return compilerToVM().getClassInitializer(this);
}
@Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,15 +22,21 @@
*/
package jdk.vm.ci.hotspot;
-import static java.util.Objects.*;
+import static java.util.Objects.requireNonNull;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Modifier;
+import java.net.URL;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.net.*;
-
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Implementation of {@link JavaType} for primitive HotSpot types.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, 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.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.code.InvalidInstalledCodeException;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Implementation of {@link InstalledCode} for code installed as a RuntimeStub.
+ */
+public class HotSpotRuntimeStub extends HotSpotInstalledCode {
+
+ public HotSpotRuntimeStub(String name) {
+ super(name);
+ }
+
+ public ResolvedJavaMethod getMethod() {
+ return null;
+ }
+
+ @Override
+ public boolean isValid() {
+ return true;
+ }
+
+ @Override
+ public void invalidate() {
+ }
+
+ @Override
+ public String toString() {
+ return String.format("InstalledRuntimeStub[stub=%s, codeBlob=0x%x]", name, getAddress());
+ }
+
+ @Override
+ public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
+ throw new InternalError("Cannot call stub " + name);
+ }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,16 +22,23 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.VMConstant;
+import jdk.vm.ci.meta.Value;
public final class HotSpotSentinelConstant extends Value implements JavaConstant, VMConstant {
- public HotSpotSentinelConstant(JavaKind kind) {
- super(LIRKind.reference(kind));
+ private final JavaKind javaKind;
+
+ public HotSpotSentinelConstant(LIRKind lirKind, JavaKind javaKind) {
+ super(lirKind);
+ this.javaKind = javaKind;
}
public JavaKind getJavaKind() {
- return (JavaKind) getLIRKind().getPlatformKind();
+ return javaKind;
}
@Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,14 @@
*/
package jdk.vm.ci.hotspot;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
/**
* Represents a method signature.
@@ -131,7 +135,7 @@
JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
return runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(kind.toJavaClass());
}
- return new HotSpotUnresolvedJavaType(name, runtime);
+ return HotSpotUnresolvedJavaType.create(runtime, name);
}
@Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,13 +22,63 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.SpeculationLog;
-public class HotSpotSpeculationLog extends SpeculationLog {
+public class HotSpotSpeculationLog implements SpeculationLog {
+
+ /** Written by the C++ code that performs deoptimization. */
+ private volatile Object lastFailed;
+
+ /** All speculations that have been a deoptimization reason. */
+ private Set<SpeculationReason> failedSpeculations;
+
+ /** Strong references to all reasons embededded in the current nmethod. */
+ private volatile Collection<SpeculationReason> speculations;
@Override
- public JavaConstant speculate(Object reason) {
- addSpeculation(reason);
+ public synchronized void collectFailedSpeculations() {
+ if (lastFailed != null) {
+ if (failedSpeculations == null) {
+ failedSpeculations = new HashSet<>(2);
+ }
+ failedSpeculations.add((SpeculationReason) lastFailed);
+ lastFailed = null;
+ speculations = null;
+ }
+ }
+
+ @Override
+ public boolean maySpeculate(SpeculationReason reason) {
+ if (failedSpeculations != null && failedSpeculations.contains(reason)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public JavaConstant speculate(SpeculationReason reason) {
+ assert maySpeculate(reason);
+
+ /*
+ * Objects referenced from nmethods are weak references. We need a strong reference to the
+ * reason objects that are embedded in nmethods, so we add them to the speculations
+ * collection.
+ */
+ if (speculations == null) {
+ synchronized (this) {
+ if (speculations == null) {
+ speculations = new ConcurrentLinkedQueue<>();
+ }
+ }
+ }
+ speculations.add(reason);
+
return HotSpotObjectConstantImpl.forObject(reason);
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackFrameReference.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,10 @@
*/
package jdk.vm.ci.hotspot;
-import java.util.*;
+import java.util.Arrays;
-import jdk.vm.ci.code.stack.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.stack.InspectedFrame;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
public class HotSpotStackFrameReference implements InspectedFrame {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotStackIntrospection.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.stack.InspectedFrameVisitor;
+import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+public class HotSpotStackIntrospection implements StackIntrospection {
+
+ protected final HotSpotJVMCIRuntimeProvider runtime;
+
+ public HotSpotStackIntrospection(HotSpotJVMCIRuntimeProvider runtime) {
+ this.runtime = runtime;
+ }
+
+ @Override
+ public <T> T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor<T> visitor) {
+ CompilerToVM compilerToVM = runtime.getCompilerToVM();
+ HotSpotStackFrameReference current = compilerToVM.getNextStackFrame(null, initialMethods, initialSkip);
+ while (current != null) {
+ T result = visitor.visitFrame(current);
+ if (result != null) {
+ return result;
+ }
+ current = compilerToVM.getNextStackFrame(current, matchingMethods, 0);
+ }
+ return null;
+ }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotUnresolvedField.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotUnresolvedField.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,18 +22,19 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaField;
+import jdk.vm.ci.meta.JavaType;
/**
* A implementation of {@link JavaField} for an unresolved field.
*/
-public class HotSpotUnresolvedField implements JavaField {
+class HotSpotUnresolvedField implements JavaField {
private final String name;
private final JavaType holder;
private final JavaType type;
- public HotSpotUnresolvedField(JavaType holder, String name, JavaType type) {
+ HotSpotUnresolvedField(JavaType holder, String name, JavaType type) {
this.name = name;
this.type = type;
this.holder = holder;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotUnresolvedJavaType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotUnresolvedJavaType.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,16 +22,18 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Implementation of {@link JavaType} for unresolved HotSpot classes.
*/
-public class HotSpotUnresolvedJavaType extends HotSpotJavaType {
+final class HotSpotUnresolvedJavaType extends HotSpotJavaType {
private final HotSpotJVMCIRuntimeProvider runtime;
- public HotSpotUnresolvedJavaType(String name, HotSpotJVMCIRuntimeProvider runtime) {
+ private HotSpotUnresolvedJavaType(String name, HotSpotJVMCIRuntimeProvider runtime) {
super(name);
assert name.charAt(0) == '[' || name.charAt(name.length() - 1) == ';' : name;
this.runtime = runtime;
@@ -40,7 +42,7 @@
/**
* Creates an unresolved type for a valid {@link JavaType#getName() type name}.
*/
- public static HotSpotUnresolvedJavaType create(HotSpotJVMCIRuntimeProvider runtime, String name) {
+ static HotSpotUnresolvedJavaType create(HotSpotJVMCIRuntimeProvider runtime, String name) {
return new HotSpotUnresolvedJavaType(name, runtime);
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java Wed Jul 05 21:00:20 2017 +0200
@@ -23,14 +23,23 @@
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.common.UnsafeUtil.readCString;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Iterator;
-import sun.misc.*;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.hotspotvmconfig.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.hotspotvmconfig.HotSpotVMAddress;
+import jdk.vm.ci.hotspotvmconfig.HotSpotVMConstant;
+import jdk.vm.ci.hotspotvmconfig.HotSpotVMData;
+import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
+import jdk.vm.ci.hotspotvmconfig.HotSpotVMFlag;
+import jdk.vm.ci.hotspotvmconfig.HotSpotVMManual;
+import jdk.vm.ci.hotspotvmconfig.HotSpotVMType;
+import sun.misc.Unsafe;
//JaCoCo Exclude
@@ -42,13 +51,20 @@
public class HotSpotVMConfig {
/**
+ * Gets the configuration associated with the singleton {@link HotSpotJVMCIRuntime}.
+ */
+ public static HotSpotVMConfig config() {
+ return runtime().getConfig();
+ }
+
+ /**
* Maximum allowed size of allocated area for a frame.
*/
public final int maxFrameSize = 16 * 1024;
public HotSpotVMConfig(CompilerToVM compilerToVm) {
// Get raw pointer to the array that contains all gHotSpotVM values.
- final long gHotSpotVMData = compilerToVm.initializeConfiguration();
+ final long gHotSpotVMData = compilerToVm.initializeConfiguration(this);
assert gHotSpotVMData != 0;
// Make FindBugs happy.
@@ -106,6 +122,8 @@
handleDeoptStub = deoptBlob + UNSAFE.getInt(deoptBlob + codeBlobCodeOffsetOffset) + UNSAFE.getInt(deoptBlob + deoptimizationBlobUnpackOffsetOffset);
uncommonTrapStub = deoptBlob + UNSAFE.getInt(deoptBlob + codeBlobCodeOffsetOffset) + UNSAFE.getInt(deoptBlob + deoptimizationBlobUncommonTrapOffsetOffset);
+ tlabAlignmentReserve = roundUp(threadLocalAllocBufferEndReserve(), minObjAlignment());
+
assert check();
assert HotSpotVMConfigVerifier.check();
}
@@ -844,6 +862,7 @@
@HotSpotVMConstant(name = "ASSERT") @Stable public boolean cAssertions;
public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
+ public final boolean linuxOs = System.getProperty("os.name", "").startsWith("Linux");
@HotSpotVMFlag(name = "CodeEntryAlignment") @Stable public int codeEntryAlignment;
@HotSpotVMFlag(name = "VerifyOops") @Stable public boolean verifyOops;
@@ -938,6 +957,16 @@
@HotSpotVMConstant(name = "VM_Version::CPU_ERMS", archs = {"amd64"}) @Stable public long cpuERMS;
@HotSpotVMConstant(name = "VM_Version::CPU_CLMUL", archs = {"amd64"}) @Stable public long cpuCLMUL;
@HotSpotVMConstant(name = "VM_Version::CPU_BMI1", archs = {"amd64"}) @Stable public long cpuBMI1;
+ @HotSpotVMConstant(name = "VM_Version::CPU_BMI2", archs = {"amd64"}) @Stable public long cpuBMI2;
+ @HotSpotVMConstant(name = "VM_Version::CPU_RTM", archs = {"amd64"}) @Stable public long cpuRTM;
+ @HotSpotVMConstant(name = "VM_Version::CPU_ADX", archs = {"amd64"}) @Stable public long cpuADX;
+ @HotSpotVMConstant(name = "VM_Version::CPU_AVX512F", archs = {"amd64"}) @Stable public long cpuAVX512F;
+ @HotSpotVMConstant(name = "VM_Version::CPU_AVX512DQ", archs = {"amd64"}) @Stable public long cpuAVX512DQ;
+ @HotSpotVMConstant(name = "VM_Version::CPU_AVX512PF", archs = {"amd64"}) @Stable public long cpuAVX512PF;
+ @HotSpotVMConstant(name = "VM_Version::CPU_AVX512ER", archs = {"amd64"}) @Stable public long cpuAVX512ER;
+ @HotSpotVMConstant(name = "VM_Version::CPU_AVX512CD", archs = {"amd64"}) @Stable public long cpuAVX512CD;
+ @HotSpotVMConstant(name = "VM_Version::CPU_AVX512BW", archs = {"amd64"}) @Stable public long cpuAVX512BW;
+ @HotSpotVMConstant(name = "VM_Version::CPU_AVX512VL", archs = {"amd64"}) @Stable public long cpuAVX512VL;
// SPARC specific values
@HotSpotVMField(name = "VM_Version::_features", type = "int", get = HotSpotVMField.Type.VALUE, archs = {"sparc"}) @Stable public int sparcFeatures;
@@ -945,6 +974,26 @@
@HotSpotVMConstant(name = "VM_Version::vis2_instructions_m", archs = {"sparc"}) @Stable public int vis2Instructions;
@HotSpotVMConstant(name = "VM_Version::vis1_instructions_m", archs = {"sparc"}) @Stable public int vis1Instructions;
@HotSpotVMConstant(name = "VM_Version::cbcond_instructions_m", archs = {"sparc"}) @Stable public int cbcondInstructions;
+ @HotSpotVMConstant(name = "VM_Version::v8_instructions_m", archs = {"sparc"}) @Stable public int v8Instructions;
+ @HotSpotVMConstant(name = "VM_Version::hardware_mul32_m", archs = {"sparc"}) @Stable public int hardwareMul32;
+ @HotSpotVMConstant(name = "VM_Version::hardware_div32_m", archs = {"sparc"}) @Stable public int hardwareDiv32;
+ @HotSpotVMConstant(name = "VM_Version::hardware_fsmuld_m", archs = {"sparc"}) @Stable public int hardwareFsmuld;
+ @HotSpotVMConstant(name = "VM_Version::hardware_popc_m", archs = {"sparc"}) @Stable public int hardwarePopc;
+ @HotSpotVMConstant(name = "VM_Version::v9_instructions_m", archs = {"sparc"}) @Stable public int v9Instructions;
+ @HotSpotVMConstant(name = "VM_Version::sun4v_m", archs = {"sparc"}) @Stable public int sun4v;
+ @HotSpotVMConstant(name = "VM_Version::blk_init_instructions_m", archs = {"sparc"}) @Stable public int blkInitInstructions;
+ @HotSpotVMConstant(name = "VM_Version::fmaf_instructions_m", archs = {"sparc"}) @Stable public int fmafInstructions;
+ @HotSpotVMConstant(name = "VM_Version::fmau_instructions_m", archs = {"sparc"}) @Stable public int fmauInstructions;
+ @HotSpotVMConstant(name = "VM_Version::sparc64_family_m", archs = {"sparc"}) @Stable public int sparc64Family;
+ @HotSpotVMConstant(name = "VM_Version::M_family_m", archs = {"sparc"}) @Stable public int mFamily;
+ @HotSpotVMConstant(name = "VM_Version::T_family_m", archs = {"sparc"}) @Stable public int tFamily;
+ @HotSpotVMConstant(name = "VM_Version::T1_model_m", archs = {"sparc"}) @Stable public int t1Model;
+ @HotSpotVMConstant(name = "VM_Version::sparc5_instructions_m", archs = {"sparc"}) @Stable public int sparc5Instructions;
+ @HotSpotVMConstant(name = "VM_Version::aes_instructions_m", archs = {"sparc"}) @Stable public int aesInstructions;
+ @HotSpotVMConstant(name = "VM_Version::sha1_instruction_m", archs = {"sparc"}) @Stable public int sha1Instruction;
+ @HotSpotVMConstant(name = "VM_Version::sha256_instruction_m", archs = {"sparc"}) @Stable public int sha256Instruction;
+ @HotSpotVMConstant(name = "VM_Version::sha512_instruction_m", archs = {"sparc"}) @Stable public int sha512Instruction;
+
@HotSpotVMFlag(name = "UseBlockZeroing", archs = {"sparc"}) @Stable public boolean useBlockZeroing;
@HotSpotVMFlag(name = "BlockZeroingLowLimit", archs = {"sparc"}) @Stable public int blockZeroingLowLimit;
@@ -1396,6 +1445,7 @@
@HotSpotVMField(name = "Thread::_allocated_bytes", type = "jlong", get = HotSpotVMField.Type.OFFSET) @Stable public int threadAllocatedBytesOffset;
@HotSpotVMFlag(name = "TLABWasteIncrement") @Stable public int tlabRefillWasteIncrement;
+ @HotSpotVMManual(name = "ThreadLocalAllocBuffer::alignment_reserve()") @Stable public int tlabAlignmentReserve;
@HotSpotVMField(name = "ThreadLocalAllocBuffer::_start", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferStartOffset;
@HotSpotVMField(name = "ThreadLocalAllocBuffer::_end", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferEndOffset;
@@ -1453,13 +1503,6 @@
return Integer.max(reserveSize, abstractVmVersionReserveForAllocationPrefetch);
}
- /**
- * See: {@code ThreadLocalAllocBuffer::alignment_reserve()}.
- */
- public final int tlabAlignmentReserve() {
- return roundUp(threadLocalAllocBufferEndReserve(), minObjAlignment());
- }
-
@HotSpotVMFlag(name = "TLABStats") @Stable public boolean tlabStats;
// FIXME This is only temporary until the GC code is changed.
@@ -1688,6 +1731,7 @@
@HotSpotVMConstant(name = "CodeInstaller::POLL_RETURN_NEAR") @Stable public int MARKID_POLL_RETURN_NEAR;
@HotSpotVMConstant(name = "CodeInstaller::POLL_FAR") @Stable public int MARKID_POLL_FAR;
@HotSpotVMConstant(name = "CodeInstaller::POLL_RETURN_FAR") @Stable public int MARKID_POLL_RETURN_FAR;
+ @HotSpotVMConstant(name = "CodeInstaller::CARD_TABLE_SHIFT") @Stable public int MARKID_CARD_TABLE_SHIFT;
@HotSpotVMConstant(name = "CodeInstaller::CARD_TABLE_ADDRESS") @Stable public int MARKID_CARD_TABLE_ADDRESS;
@HotSpotVMConstant(name = "CodeInstaller::HEAP_TOP_ADDRESS") @Stable public int MARKID_HEAP_TOP_ADDRESS;
@HotSpotVMConstant(name = "CodeInstaller::HEAP_END_ADDRESS") @Stable public int MARKID_HEAP_END_ADDRESS;
@@ -1695,6 +1739,20 @@
@HotSpotVMConstant(name = "CodeInstaller::CRC_TABLE_ADDRESS") @Stable public int MARKID_CRC_TABLE_ADDRESS;
@HotSpotVMConstant(name = "CodeInstaller::INVOKE_INVALID") @Stable public int MARKID_INVOKE_INVALID;
+ @HotSpotVMConstant(name = "BitData::exception_seen_flag") @Stable public int bitDataExceptionSeenFlag;
+ @HotSpotVMConstant(name = "BitData::null_seen_flag") @Stable public int bitDataNullSeenFlag;
+ @HotSpotVMConstant(name = "CounterData::count_off") @Stable public int methodDataCountOffset;
+ @HotSpotVMConstant(name = "JumpData::taken_off_set") @Stable public int jumpDataTakenOffset;
+ @HotSpotVMConstant(name = "JumpData::displacement_off_set") @Stable public int jumpDataDisplacementOffset;
+ @HotSpotVMConstant(name = "ReceiverTypeData::nonprofiled_count_off_set") @Stable public int receiverTypeDataNonprofiledCountOffset;
+ @HotSpotVMConstant(name = "ReceiverTypeData::receiver_type_row_cell_count") @Stable public int receiverTypeDataReceiverTypeRowCellCount;
+ @HotSpotVMConstant(name = "ReceiverTypeData::receiver0_offset") @Stable public int receiverTypeDataReceiver0Offset;
+ @HotSpotVMConstant(name = "ReceiverTypeData::count0_offset") @Stable public int receiverTypeDataCount0Offset;
+ @HotSpotVMConstant(name = "BranchData::not_taken_off_set") @Stable public int branchDataNotTakenOffset;
+ @HotSpotVMConstant(name = "ArrayData::array_len_off_set") @Stable public int arrayDataArrayLenOffset;
+ @HotSpotVMConstant(name = "ArrayData::array_start_off_set") @Stable public int arrayDataArrayStartOffset;
+ @HotSpotVMConstant(name = "MultiBranchData::per_case_cell_count") @Stable public int multiBranchDataPerCaseCellCount;
+
// Checkstyle: resume
private boolean check() {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigVerifier.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigVerifier.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,16 +22,25 @@
*/
package jdk.vm.ci.hotspot;
-import static java.lang.String.*;
+import static java.lang.String.format;
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Objects;
-import jdk.internal.org.objectweb.asm.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.internal.org.objectweb.asm.ClassReader;
+import jdk.internal.org.objectweb.asm.ClassVisitor;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
-import jdk.vm.ci.common.*;
-import sun.misc.*;
+import sun.misc.Unsafe;
/**
* A {@link ClassVisitor} that verifies {@link HotSpotVMConfig} does not access {@link Unsafe} from
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,8 +22,10 @@
*/
package jdk.vm.ci.hotspot;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.meta.JVMCIMetaAccessContext;
+import jdk.vm.ci.meta.ResolvedJavaType;
public interface HotSpotVMEventListener {
@@ -34,7 +36,7 @@
}
/**
- * Notify on successful install into the CodeCache.
+ * Notify on successful install into the code cache.
*
* @param hotSpotCodeCacheProvider
* @param installedCode
@@ -44,14 +46,6 @@
}
/**
- * Perform any extra initialization required.
- *
- * @param runtime
- */
- default void completeInitialization(HotSpotJVMCIRuntime runtime) {
- }
-
- /**
* Create a custom {@link JVMCIMetaAccessContext} to be used for managing the lifetime of loaded
* metadata. It a custom one isn't created then the default implementation will be a single
* context with globally shared instances of {@link ResolvedJavaType} that are never released.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVmSymbols.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVmSymbols.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,15 +22,14 @@
*/
package jdk.vm.ci.hotspot;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
+import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
-
-import sun.misc.*;
+import sun.misc.Unsafe;
/**
* Class to access the C++ {@code vmSymbols} table.
*/
-public final class HotSpotVmSymbols {
+final class HotSpotVmSymbols {
/**
* Returns the symbol in the {@code vmSymbols} table at position {@code index} as {@link String}
@@ -39,7 +38,7 @@
* @param index position in the symbol table
* @return the symbol at position id
*/
- public static String symbolAt(int index) {
+ static String symbolAt(int index) {
HotSpotJVMCIRuntimeProvider runtime = runtime();
HotSpotVMConfig config = runtime.getConfig();
assert config.vmSymbolsFirstSID <= index && index < config.vmSymbolsSIDLimit : "index " + index + " is out of bounds";
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
* It would preferable if this were the base class containing the pointer but that would require
* mixins since most of the wrapper types have complex supertype hierarchies.
*/
-public interface MetaspaceWrapperObject {
+interface MetaspaceWrapperObject {
long getMetaspacePointer();
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Stable.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Stable.java Wed Jul 05 21:00:20 2017 +0200
@@ -23,11 +23,14 @@
package jdk.vm.ci.hotspot;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
- * This annotation functions as an alias for the sun.invoke.Stable annotation within JVMCI code. It
- * is specially recognized during class file parsing in the same way as that annotation.
+ * This annotation functions as an alias for the java.lang.invoke.Stable annotation within JVMCI
+ * code. It is specially recognized during class file parsing in the same way as that annotation.
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SuppressFBWarnings.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2014, 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.
- */
-package jdk.vm.ci.hotspot;
-
-/**
- * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
- */
-public @interface SuppressFBWarnings {
- /**
- * The set of FindBugs <a
- * href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
- * suppressed in annotated element. The value can be a bug category, kind or pattern.
- */
- String[] value();
-
- /**
- * Reason why the warning is suppressed.
- */
- String justification();
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/events/EmptyEventProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/events/EmptyEventProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot.events;
-import jdk.vm.ci.common.*;
+import jdk.vm.ci.common.JVMCIError;
/**
* An empty implementation for {@link EventProvider}. This implementation is used when no logging is
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMAddress.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMAddress.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.hotspotvmconfig;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Refers to a C++ address in the VM.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMConstant.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMConstant.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.hotspotvmconfig;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Refers to a C++ constant in the VM.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMData.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMData.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.hotspotvmconfig;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Refers to a entry in {@code gHotSpotVMData}.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMField.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMField.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.hotspotvmconfig;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Refers to a C++ field in the VM.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMFlag.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMFlag.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.hotspotvmconfig;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Refers to a C++ flag in the VM.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMManual.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMManual.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.hotspotvmconfig;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Annotates a field in HotSpotVMConfig which is not read from the VM but is calculated manually.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspotvmconfig/src/jdk/vm/ci/hotspotvmconfig/HotSpotVMType.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.hotspotvmconfig;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Refers to a C++ type in the VM.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,8 +22,12 @@
*/
package jdk.vm.ci.meta;
-import java.lang.invoke.*;
-import java.util.*;
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
/**
* Class for recording assumptions made during compilation.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import java.lang.invoke.*;
+import java.lang.invoke.MethodHandle;
/**
* Reflection operations on values represented as {@linkplain JavaConstant constants}. All methods
@@ -142,8 +142,12 @@
/**
* Check if the constant is embeddable in the code.
+ *
+ * @param constant the constant to test
*/
- boolean isEmbeddable(Constant constant);
+ default boolean isEmbeddable(Constant constant) {
+ return true;
+ }
/**
* Gets access to the internals of {@link MethodHandle}.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DefaultProfilingInfo.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/DefaultProfilingInfo.java Wed Jul 05 21:00:20 2017 +0200
@@ -93,7 +93,7 @@
@Override
public String toString() {
- return "BaseProfilingInfo<" + this.toString(null, "; ") + ">";
+ return "DefaultProfilingInfo<" + this.toString(null, "; ") + ">";
}
public void setMature() {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ExceptionHandler.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ExceptionHandler.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import java.util.*;
+import java.util.Objects;
/**
* Represents an exception handler within the bytecodes.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JVMCIMetaAccessContext.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JVMCIMetaAccessContext.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,8 @@
*/
package jdk.vm.ci.meta;
-import java.util.*;
+import java.util.IllegalFormatException;
+import java.util.UnknownFormatConversionException;
/**
* Represents a reference to a Java field, either resolved or unresolved fields. Fields, like
@@ -77,7 +78,6 @@
* @return the result of formatting this field according to {@code format}
* @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
*/
- @SuppressWarnings("fallthrough")
default String format(String format) throws IllegalFormatException {
StringBuilder sb = new StringBuilder();
int index = 0;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import java.lang.reflect.*;
+import java.lang.reflect.Array;
//JaCoCo Exclude
@@ -31,7 +31,7 @@
* {@link JavaKind#Int} for {@code int} and {@link JavaKind#Object} for all object types. A kind has
* a single character short name, a Java name, and a set of flags further describing its behavior.
*/
-public enum JavaKind implements PlatformKind {
+public enum JavaKind {
/** The primitive boolean kind, represented as an int on the stack. */
Boolean('z', "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
@@ -70,7 +70,6 @@
private final boolean isStackInt;
private final Class<?> primitiveJavaClass;
private final Class<?> boxedJavaClass;
- private final EnumKey<JavaKind> key = new EnumKey<>(this);
private final int slotCount;
private JavaKind(char typeChar, String javaName, int slotCount, boolean isStackInt, Class<?> primitiveJavaClass, Class<?> boxedJavaClass) {
@@ -113,10 +112,6 @@
return javaName;
}
- public Key getKey() {
- return key;
- }
-
/**
* Checks whether this type is a Java primitive type.
*
@@ -460,37 +455,4 @@
throw new IllegalArgumentException("illegal call to bits on " + this);
}
}
-
- public JavaConstant getDefaultValue() {
- switch (this) {
- case Boolean:
- return JavaConstant.FALSE;
- case Int:
- return JavaConstant.INT_0;
- case Long:
- return JavaConstant.LONG_0;
- case Float:
- return JavaConstant.FLOAT_0;
- case Double:
- return JavaConstant.DOUBLE_0;
- case Object:
- return JavaConstant.NULL_POINTER;
- case Byte:
- case Char:
- case Short:
- return new PrimitiveConstant(this, 0);
- default:
- throw new IllegalArgumentException("illegal call to getDefaultValue on " + this);
- }
- }
-
- @Override
- public int getSizeInBytes() {
- return getByteCount();
- }
-
- @Override
- public int getVectorLength() {
- return 1;
- }
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,8 @@
*/
package jdk.vm.ci.meta;
-import java.util.*;
+import java.util.IllegalFormatException;
+import java.util.UnknownFormatConversionException;
/**
* Represents a reference to a Java method, either resolved or unresolved. Methods, like fields and
@@ -71,7 +72,6 @@
* @return the result of formatting this method according to {@code format}
* @throws IllegalFormatException if an illegal specifier is encountered in {@code format}
*/
- @SuppressWarnings("fallthrough")
default String format(String format) throws IllegalFormatException {
StringBuilder sb = new StringBuilder();
int index = 0;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethodProfile.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethodProfile.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import jdk.vm.ci.meta.JavaMethodProfile.*;
+import jdk.vm.ci.meta.JavaMethodProfile.ProfiledMethod;
/**
* This profile object represents the method profile at a specific BCI. The precision of the
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import static jdk.vm.ci.meta.MetaUtil.*;
+import static jdk.vm.ci.meta.MetaUtil.internalNameToJava;
/**
* Represents a resolved or unresolved type. Types include primitives, objects, {@code void}, and
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaTypeProfile.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaTypeProfile.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,9 @@
*/
package jdk.vm.ci.meta;
-import java.util.*;
+import java.util.ArrayList;
-import jdk.vm.ci.meta.JavaTypeProfile.*;
+import jdk.vm.ci.meta.JavaTypeProfile.ProfiledType;
/**
* This profile object represents the type profile at a specific BCI. The precision of the supplied
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import java.util.*;
+import java.util.ArrayList;
/**
* Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
@@ -57,10 +57,32 @@
*/
public final class LIRKind {
+ private static enum IllegalKind implements PlatformKind {
+ ILLEGAL;
+
+ private final EnumKey<IllegalKind> key = new EnumKey<>(this);
+
+ public Key getKey() {
+ return key;
+ }
+
+ public int getSizeInBytes() {
+ return 0;
+ }
+
+ public int getVectorLength() {
+ return 0;
+ }
+
+ public char getTypeChar() {
+ return '-';
+ }
+ }
+
/**
* The non-type. This uses {@link #unknownReference}, so it can never be part of an oop map.
*/
- public static final LIRKind Illegal = unknownReference(JavaKind.Illegal);
+ public static final LIRKind Illegal = unknownReference(IllegalKind.ILLEGAL);
private final PlatformKind platformKind;
private final int referenceMask;
@@ -70,7 +92,6 @@
private static final int UNKNOWN_REFERENCE = -1;
private LIRKind(PlatformKind platformKind, int referenceMask, AllocatableValue derivedReferenceBase) {
- assert platformKind != JavaKind.Object : "Kind.Object shouldn't be used in the backend";
this.platformKind = platformKind;
this.referenceMask = referenceMask;
this.derivedReferenceBase = derivedReferenceBase;
@@ -431,21 +452,9 @@
if (src.equals(dst)) {
return true;
}
- /*
- * TODO(je,rs) What we actually want is toStackKind(src.getPlatformKind()).equals(
- * dst.getPlatformKind()) but due to the handling of sub-integer at the current point
- * (phi-)moves from e.g. integer to short can happen. Therefore we compare stack kinds.
- */
- if (toStackKind(src.getPlatformKind()).equals(toStackKind(dst.getPlatformKind()))) {
+ if (src.getPlatformKind().equals(dst.getPlatformKind())) {
return !src.isUnknownReference() || dst.isUnknownReference();
}
return false;
}
-
- private static PlatformKind toStackKind(PlatformKind platformKind) {
- if (platformKind instanceof JavaKind) {
- return ((JavaKind) platformKind).getStackKind();
- }
- return platformKind;
- }
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTableImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTableImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,8 @@
*/
package jdk.vm.ci.meta;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
public class LocalVariableTableImpl implements LocalVariableTable {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocationIdentity.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocationIdentity.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import java.util.*;
+import java.util.IdentityHashMap;
// JaCoCo Exclude
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.meta;
-import java.lang.reflect.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
/**
* Provides access to the metadata of a class typically provided in a class file.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,17 @@
*/
package jdk.vm.ci.meta;
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
+import java.io.PrintStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
/**
* Miscellaneous collection of utility methods used by {@code jdk.vm.ci.meta} and its clients.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MethodHandleAccessProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import java.lang.invoke.*;
+import java.lang.invoke.MethodHandle;
/**
* Interface to access the internals of the {@link MethodHandle} implementation of the VM. An
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ModifiersProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,20 @@
*/
package jdk.vm.ci.meta;
-import static java.lang.reflect.Modifier.*;
+import static java.lang.reflect.Modifier.ABSTRACT;
+import static java.lang.reflect.Modifier.FINAL;
+import static java.lang.reflect.Modifier.INTERFACE;
+import static java.lang.reflect.Modifier.NATIVE;
+import static java.lang.reflect.Modifier.PRIVATE;
+import static java.lang.reflect.Modifier.PROTECTED;
+import static java.lang.reflect.Modifier.PUBLIC;
+import static java.lang.reflect.Modifier.STATIC;
+import static java.lang.reflect.Modifier.STRICT;
+import static java.lang.reflect.Modifier.SYNCHRONIZED;
+import static java.lang.reflect.Modifier.TRANSIENT;
+import static java.lang.reflect.Modifier.VOLATILE;
-import java.lang.reflect.*;
+import java.lang.reflect.Modifier;
/**
* A Java element (i.e., a class, interface, field or method) that is described by a set of Java
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,8 +29,6 @@
String name();
- JavaConstant getDefaultValue();
-
public interface Key {
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PrimitiveConstant.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PrimitiveConstant.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import java.nio.*;
+import java.nio.ByteBuffer;
/**
* Represents a primitive constant value, such as an integer or floating point number, within the
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,8 +22,8 @@
*/
package jdk.vm.ci.meta;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Modifier;
/**
* Represents a reference to a resolved Java field. Fields, like methods and types, are resolved
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,12 @@
*/
package jdk.vm.ci.meta;
-import java.lang.annotation.*;
-import java.lang.invoke.*;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
/**
* Represents a resolved Java method. Methods, like fields and types, are resolved through
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,10 @@
*/
package jdk.vm.ci.meta;
-import java.lang.annotation.*;
-import java.net.*;
+import java.lang.annotation.Annotation;
+import java.net.URL;
-import jdk.vm.ci.meta.Assumptions.*;
+import jdk.vm.ci.meta.Assumptions.AssumptionResult;
/**
* Represents a resolved Java type. Types include primitives, objects, {@code void}, and arrays
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SerializableConstant.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SerializableConstant.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.meta;
-import java.nio.*;
+import java.nio.ByteBuffer;
/**
* Represents a compile-time constant that can be converted to a byte array.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,47 +22,38 @@
*/
package jdk.vm.ci.meta;
-import java.util.*;
-import java.util.concurrent.*;
-
/**
- * Manages a list of unique deoptimization reasons.
+ * Manages unique deoptimization reasons. Reasons are embedded in compiled code and can be
+ * invalidated at run time. Subsequent compilations then should not speculate again on such
+ * invalidated reasons to avoid repeated deoptimization.
*
+ * All methods of this interface are called by the compiler. There is no need for API to register
+ * failed speculations during deoptimization, since every VM has different needs there.
*/
-public abstract class SpeculationLog {
- private volatile Object lastFailed;
- private volatile Collection<Object> speculations;
- private Set<Object> failedSpeculations;
+public interface SpeculationLog {
- public synchronized void collectFailedSpeculations() {
- if (lastFailed != null) {
- if (failedSpeculations == null) {
- failedSpeculations = new HashSet<>(2);
- }
- failedSpeculations.add(lastFailed);
- lastFailed = null;
- speculations = null;
- }
+ /**
+ * Marker interface for speculation objects that can be added to the speculation log.
+ */
+ public interface SpeculationReason {
}
- public boolean maySpeculate(Object reason) {
- if (failedSpeculations != null && failedSpeculations.contains(reason)) {
- return false;
- }
- return true;
- }
+ /**
+ * Must be called before compilation, i.e., before a compiler calls {@link #maySpeculate}.
+ */
+ void collectFailedSpeculations();
- protected void addSpeculation(Object reason) {
- assert maySpeculate(reason);
- if (speculations == null) {
- synchronized (this) {
- if (speculations == null) {
- speculations = new ConcurrentLinkedQueue<>();
- }
- }
- }
- speculations.add(reason);
- }
+ /**
+ * If this method returns true, the compiler is allowed to {@link #speculate} with the given
+ * reason.
+ */
+ boolean maySpeculate(SpeculationReason reason);
- public abstract JavaConstant speculate(Object reason);
+ /**
+ * Registers a speculation that was performed by the compiler.
+ *
+ * @return A compiler constant encapsulating the provided reason. It is usually passed as an
+ * argument to the deoptimization function.
+ */
+ JavaConstant speculate(SpeculationReason reason);
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options.processor/src/jdk/vm/ci/options/processor/OptionProcessor.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options.processor/src/jdk/vm/ci/options/processor/OptionProcessor.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,19 +22,40 @@
*/
package jdk.vm.ci.options.processor;
-import java.io.*;
-import java.util.*;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
-import javax.annotation.processing.*;
-import javax.lang.model.*;
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
-import javax.lang.model.util.*;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
import javax.tools.Diagnostic.Kind;
+import javax.tools.JavaFileObject;
-import jdk.vm.ci.options.*;
-
-import javax.tools.*;
+import jdk.vm.ci.options.Option;
+import jdk.vm.ci.options.OptionDescriptor;
+import jdk.vm.ci.options.OptionDescriptors;
+import jdk.vm.ci.options.OptionValue;
/**
* Processes static fields annotated with {@link Option}. An {@link OptionDescriptors}
@@ -105,11 +126,11 @@
DeclaredType declaredOptionValueType = declaredFieldType;
while (!types.isSameType(types.erasure(declaredOptionValueType), types.erasure(optionValueType))) {
List<? extends TypeMirror> directSupertypes = types.directSupertypes(declaredFieldType);
- assert!directSupertypes.isEmpty();
+ assert !directSupertypes.isEmpty();
declaredOptionValueType = (DeclaredType) directSupertypes.get(0);
}
- assert!declaredOptionValueType.getTypeArguments().isEmpty();
+ assert !declaredOptionValueType.getTypeArguments().isEmpty();
String optionType = declaredOptionValueType.getTypeArguments().get(0).toString();
if (optionType.startsWith("java.lang.")) {
optionType = optionType.substring("java.lang.".length());
@@ -194,8 +215,7 @@
if (info.options.size() == 1) {
out.printf(" return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue);
} else {
- out.printf(" case \"" + name + "\": return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName,
- optionValue);
+ out.printf(" case \"" + name + "\": return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue);
}
}
out.println(" }");
@@ -241,19 +261,6 @@
}
out.println("}");
}
-
- try {
- createOptionsFile(pkg, topDeclaringClass.toString(), originatingElements);
- } catch (IOException e) {
- processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), info.topDeclaringType);
- }
- }
-
- private void createOptionsFile(String pkg, String relativeName, Element... originatingElements) throws IOException {
- String filename = "META-INF/jvmci.options/" + pkg + "." + relativeName;
- FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements);
- PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
- writer.close();
}
protected PrintWriter createSourceFile(String pkg, String relativeName, Filer filer, Element... originatingElements) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/DerivedOptionValue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/DerivedOptionValue.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,10 @@
*/
package jdk.vm.ci.options;
-import java.io.*;
-import java.util.function.*;
+import java.io.Serializable;
+import java.util.function.Supplier;
-import jdk.vm.ci.options.OptionValue.*;
+import jdk.vm.ci.options.OptionValue.OverrideScope;
/**
* A cached value that needs to be recomputed when an option changes.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/JVMCIJarsOptionDescriptorsProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.options;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-import java.util.zip.*;
-
-import jdk.vm.ci.options.OptionsParser.*;
-
-/**
- * Access to the {@link OptionDescriptors} declared by
- * {@code META-INF/services/jdk.vm.ci.options.OptionDescriptors} files in {@code
- * <jre>/lib/jvmci/*.jar}.
- */
-class JVMCIJarsOptionDescriptorsProvider implements OptionDescriptorsProvider {
-
- static final String OptionDescriptorsServiceFile = "META-INF/services/" + OptionDescriptors.class.getName();
-
- private final Iterator<File> jars;
- private final List<OptionDescriptors> optionsDescriptorsList;
-
- JVMCIJarsOptionDescriptorsProvider() {
- List<File> jarsList = findJVMCIJars();
- this.jars = jarsList.iterator();
- this.optionsDescriptorsList = new ArrayList<>(jarsList.size() * 3);
- }
-
- /**
- * Finds the list of JVMCI jars.
- */
- private static List<File> findJVMCIJars() {
- File javaHome = new File(System.getProperty("java.home"));
- File lib = new File(javaHome, "lib");
- File jvmci = new File(lib, "jvmci");
-
- List<File> jarFiles = new ArrayList<>();
- if (jvmci.exists()) {
- for (String fileName : jvmci.list()) {
- if (fileName.endsWith(".jar")) {
- File file = new File(jvmci, fileName);
- if (file.isDirectory()) {
- continue;
- }
- jarFiles.add(file);
- }
- }
- }
- return jarFiles;
- }
-
- public OptionDescriptor get(String name) {
- // Look up loaded option descriptors first
- for (OptionDescriptors optionDescriptors : optionsDescriptorsList) {
- OptionDescriptor desc = optionDescriptors.get(name);
- if (desc != null) {
- return desc;
- }
- }
- while (jars.hasNext()) {
- File path = jars.next();
- try (JarFile jar = new JarFile(path)) {
- ZipEntry entry = jar.getEntry(OptionDescriptorsServiceFile);
- if (entry != null) {
- BufferedReader br = new BufferedReader(new InputStreamReader(jar.getInputStream(entry)));
- String line = null;
- OptionDescriptor desc = null;
- while ((line = br.readLine()) != null) {
- OptionDescriptors options;
- try {
- options = (OptionDescriptors) Class.forName(line).newInstance();
- optionsDescriptorsList.add(options);
- if (desc == null) {
- desc = options.get(name);
- }
- } catch (Exception e) {
- throw new InternalError("Error instantiating class " + line + " read from " + path, e);
- }
- }
- if (desc != null) {
- return desc;
- }
- }
- } catch (IOException e) {
- throw new InternalError("Error reading " + path, e);
- }
- }
- return null;
- }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/NestedBooleanOptionValue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/NestedBooleanOptionValue.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/Option.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/Option.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.options;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Describes the attributes of an option whose {@link OptionValue value} is in a static field
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionValue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionValue.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,9 +22,15 @@
*/
package jdk.vm.ci.options;
-import java.io.*;
-import java.util.*;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
/**
* An option value.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsLoader.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsLoader.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,9 @@
*/
package jdk.vm.ci.options;
-import java.util.*;
+import java.util.ServiceLoader;
+import java.util.SortedMap;
+import java.util.TreeMap;
/**
* Helper class used to load option descriptors. Only to be used in the slow-path.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsParser.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.options/src/jdk/vm/ci/options/OptionsParser.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,21 +22,33 @@
*/
package jdk.vm.ci.options;
-import static jdk.vm.ci.inittimer.InitTimer.*;
+import static jdk.vm.ci.inittimer.InitTimer.timer;
-import java.io.*;
-import java.util.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Formatter;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.SortedMap;
-import jdk.vm.ci.inittimer.*;
+import jdk.vm.ci.inittimer.InitTimer;
/**
* This class contains methods for parsing JVMCI options and matching them against a set of
- * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded from JVMCI jars, either
- * {@linkplain JVMCIJarsOptionDescriptorsProvider directly} or via a {@link ServiceLoader}.
+ * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded via a {@link ServiceLoader}.
*/
public class OptionsParser {
private static final OptionValue<Boolean> PrintFlags = new OptionValue<>(false);
+ private static final OptionValue<Boolean> ShowFlags = new OptionValue<>(false);
/**
* A service for looking up {@link OptionDescriptor}s.
@@ -54,7 +66,7 @@
}
/**
- * Parses the options in {@code <jre>/lib/jvmci/options} if {@code parseOptionsFile == true} and
+ * Parses the options in {@code <jdk>/lib/jvmci.options} if {@code parseOptionsFile == true} and
* the file exists followed by the JVMCI options in {@code options} if {@code options != null}.
*
* Called from VM. This method has an object return type to allow it to be called with a VM
@@ -62,87 +74,158 @@
*
* @param options JVMCI options as serialized (name, value) pairs
* @param parseOptionsFile specifies whether to look for and parse
- * {@code <jre>/lib/jvmci/options}
+ * {@code <jdk>/lib/jvmci.options}
*/
@SuppressWarnings("try")
public static Boolean parseOptionsFromVM(String[] options, boolean parseOptionsFile) {
+
try (InitTimer t = timer("ParseOptions")) {
- JVMCIJarsOptionDescriptorsProvider odp = new JVMCIJarsOptionDescriptorsProvider();
if (parseOptionsFile) {
File javaHome = new File(System.getProperty("java.home"));
File lib = new File(javaHome, "lib");
- File jvmci = new File(lib, "jvmci");
- File jvmciOptions = new File(jvmci, "options");
+ File jvmciOptions = new File(lib, "jvmci.options");
if (jvmciOptions.exists()) {
try (BufferedReader br = new BufferedReader(new FileReader(jvmciOptions))) {
String optionSetting = null;
int lineNo = 1;
+ List<String> optionSettings = new ArrayList<>();
while ((optionSetting = br.readLine()) != null) {
if (!optionSetting.isEmpty() && optionSetting.charAt(0) != '#') {
try {
- parseOptionSetting(optionSetting, null, odp);
+ parseOptionSettingTo(optionSetting, optionSettings);
} catch (Throwable e) {
throw new InternalError("Error parsing " + jvmciOptions + ", line " + lineNo, e);
}
}
lineNo++;
}
+ try {
+ parseOptions(optionSettings.toArray(new String[optionSettings.size()]), null, null, null);
+ } catch (Throwable e) {
+ throw new InternalError("Error parsing an option from " + jvmciOptions, e);
+ }
} catch (IOException e) {
throw new InternalError("Error reading " + jvmciOptions, e);
}
}
}
- if (options != null) {
- assert options.length % 2 == 0;
- for (int i = 0; i < options.length / 2; i++) {
- String name = options[i * 2];
- String value = options[i * 2 + 1];
- parseOption(OptionsLoader.options, name, value, null, odp);
- }
- }
+ parseOptions(options, null, null, null);
}
return Boolean.TRUE;
}
/**
- * Parses a given option setting.
+ * Parses an ordered list of (name, value) pairs assigning values to JVMCI options.
+ *
+ * @param optionSettings JVMCI options as serialized (name, value) pairs
+ * @param setter the object to notify of the parsed option and value
+ * @param odp if non-null, the service to use for looking up {@link OptionDescriptor}s
+ * @param options the options database to use if {@code odp == null}. If
+ * {@code options == null && odp == null}, {@link OptionsLoader#options} is used.
+ * @throws IllegalArgumentException if there's a problem parsing {@code option}
+ */
+ public static void parseOptions(String[] optionSettings, OptionConsumer setter, OptionDescriptorsProvider odp, SortedMap<String, OptionDescriptor> options) {
+ if (optionSettings != null && optionSettings.length != 0) {
+ assert optionSettings.length % 2 == 0;
+
+ moveHelpFlagsToTail(optionSettings);
+
+ for (int i = 0; i < optionSettings.length / 2; i++) {
+ String name = optionSettings[i * 2];
+ String value = optionSettings[i * 2 + 1];
+ parseOption(name, value, setter, odp, options);
+ }
+ if (PrintFlags.getValue() || ShowFlags.getValue()) {
+ Set<String> explicitlyAssigned = new HashSet<>(optionSettings.length / 2);
+ for (int i = 0; i < optionSettings.length / 2; i++) {
+ String name = optionSettings[i * 2];
+ explicitlyAssigned.add(name);
+ }
+ printFlags(resolveOptions(options), "JVMCI", System.out, explicitlyAssigned);
+ if (PrintFlags.getValue()) {
+ System.exit(0);
+ }
+ }
+ }
+ }
+
+ /**
+ * Moves all {@code PrintFlags} and {@code ShowFlags} option settings to the back of
+ * {@code optionSettings}. This allows the help message to show which options had their value
+ * explicitly set (even if to their default value).
+ */
+ private static void moveHelpFlagsToTail(String[] optionSettings) {
+ List<String> tail = null;
+ int insert = 0;
+ for (int i = 0; i < optionSettings.length / 2; i++) {
+ String name = optionSettings[i * 2];
+ String value = optionSettings[i * 2 + 1];
+ if (name.equals("ShowFlags") || name.equals("PrintFlags")) {
+ if (tail == null) {
+ tail = new ArrayList<>(4);
+ insert = i * 2;
+ }
+ tail.add(name);
+ tail.add(value);
+ } else if (tail != null) {
+ optionSettings[insert++] = name;
+ optionSettings[insert++] = value;
+ }
+ }
+ if (tail != null) {
+ assert tail.size() + insert == optionSettings.length;
+ String[] tailArr = tail.toArray(new String[tail.size()]);
+ System.arraycopy(tailArr, 0, optionSettings, insert, tailArr.length);
+ }
+ }
+
+ /**
+ * Parses a given option setting string to a list of (name, value) pairs.
*
* @param optionSetting a string matching the pattern {@code <name>=<value>}
- * @param setter the object to notify of the parsed option and value
*/
- public static void parseOptionSetting(String optionSetting, OptionConsumer setter, OptionDescriptorsProvider odp) {
+ public static void parseOptionSettingTo(String optionSetting, List<String> dst) {
int eqIndex = optionSetting.indexOf('=');
if (eqIndex == -1) {
throw new InternalError("Option setting has does not match the pattern <name>=<value>: " + optionSetting);
}
- String name = optionSetting.substring(0, eqIndex);
- String value = optionSetting.substring(eqIndex + 1);
- parseOption(OptionsLoader.options, name, value, setter, odp);
+ dst.add(optionSetting.substring(0, eqIndex));
+ dst.add(optionSetting.substring(eqIndex + 1));
+ }
+
+ /**
+ * Resolves {@code options} to a non-null value. This ensures {@link OptionsLoader#options} is
+ * only loaded if necessary.
+ */
+ private static SortedMap<String, OptionDescriptor> resolveOptions(SortedMap<String, OptionDescriptor> options) {
+ return options != null ? options : OptionsLoader.options;
}
/**
* Parses a given option name and value.
*
- * @param options
* @param name the option name
* @param valueString the option value as a string
* @param setter the object to notify of the parsed option and value
- * @param odp
- *
+ * @param odp if non-null, the service to use for looking up {@link OptionDescriptor}s
+ * @param options the options database to use if {@code odp == null}. If
+ * {@code options == null && odp == null}, {@link OptionsLoader#options} is used.
* @throws IllegalArgumentException if there's a problem parsing {@code option}
*/
- public static void parseOption(SortedMap<String, OptionDescriptor> options, String name, String valueString, OptionConsumer setter, OptionDescriptorsProvider odp) {
- OptionDescriptor desc = options.get(name);
- if (desc == null && odp != null) {
- desc = odp.get(name);
- }
- if (desc == null && name.equals("PrintFlags")) {
- desc = OptionDescriptor.create("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags);
+ private static void parseOption(String name, String valueString, OptionConsumer setter, OptionDescriptorsProvider odp, SortedMap<String, OptionDescriptor> options) {
+
+ OptionDescriptor desc = odp != null ? odp.get(name) : resolveOptions(options).get(name);
+ if (desc == null) {
+ if (name.equals("PrintFlags")) {
+ desc = OptionDescriptor.create("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags);
+ } else if (name.equals("ShowFlags")) {
+ desc = OptionDescriptor.create("ShowFlags", Boolean.class, "Prints all JVMCI flags and continues", OptionsParser.class, "ShowFlags", ShowFlags);
+ }
}
if (desc == null) {
- List<OptionDescriptor> matches = fuzzyMatch(options, name);
+ List<OptionDescriptor> matches = fuzzyMatch(resolveOptions(options), name);
Formatter msg = new Formatter();
msg.format("Could not find option %s", name);
if (!matches.isEmpty()) {
@@ -182,11 +265,6 @@
} else {
setter.set(desc, value);
}
-
- if (PrintFlags.getValue()) {
- printFlags(options, "JVMCI", System.out);
- System.exit(0);
- }
}
private static long parseLong(String v) {
@@ -252,16 +330,18 @@
return lines;
}
- public static void printFlags(SortedMap<String, OptionDescriptor> sortedOptions, String prefix, PrintStream out) {
+ private static void printFlags(SortedMap<String, OptionDescriptor> sortedOptions, String prefix, PrintStream out, Set<String> explicitlyAssigned) {
out.println("[List of " + prefix + " options]");
for (Map.Entry<String, OptionDescriptor> e : sortedOptions.entrySet()) {
e.getKey();
OptionDescriptor desc = e.getValue();
Object value = desc.getOptionValue().getValue();
List<String> helpLines = wrap(desc.getHelp(), 70);
- out.println(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, helpLines.get(0)));
+ String name = e.getKey();
+ String assign = explicitlyAssigned.contains(name) ? ":=" : " =";
+ out.printf("%9s %-40s %s %-14s %s%n", desc.getType().getSimpleName(), name, assign, value, helpLines.get(0));
for (int i = 1; i < helpLines.size(); i++) {
- out.println(String.format("%67s %s", " ", helpLines.get(i)));
+ out.printf("%67s %s%n", " ", helpLines.get(i));
}
}
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCI.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCI.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.runtime;
-import java.util.*;
+import java.util.Formatter;
public class JVMCI {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIBackend.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIBackend.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,8 +22,11 @@
*/
package jdk.vm.ci.runtime;
-import jdk.vm.ci.code.*;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.MetaAccessProvider;
/**
* A JVMCI backend encapsulates the capabilities needed by a Java based compiler for compiling and
@@ -35,11 +38,13 @@
private final MetaAccessProvider metaAccess;
private final CodeCacheProvider codeCache;
private final ConstantReflectionProvider constantReflection;
+ private final StackIntrospection stackIntrospection;
- public JVMCIBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection) {
+ public JVMCIBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) {
this.metaAccess = metaAccess;
this.codeCache = codeCache;
this.constantReflection = constantReflection;
+ this.stackIntrospection = stackIntrospection;
}
public MetaAccessProvider getMetaAccess() {
@@ -57,4 +62,8 @@
public TargetDescription getTarget() {
return codeCache.getTarget();
}
+
+ public StackIntrospection getStackIntrospection() {
+ return stackIntrospection;
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompiler.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.runtime;
+
+import jdk.vm.ci.code.CompilationRequest;
+
+public interface JVMCICompiler {
+ int INVOCATION_ENTRY_BCI = -1;
+
+ /**
+ * Services a compilation request. This object should compile the method to machine code and
+ * install it in the code cache if the compilation is successful.
+ */
+ void compileMethod(CompilationRequest request);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.runtime;
+
+/**
+ * Factory for a JVMCI compiler.
+ */
+public interface JVMCICompilerFactory {
+
+ /**
+ * Get the name of this compiler. The compiler will be selected when the jvmci.compiler system
+ * property is equal to this name.
+ */
+ String getCompilerName();
+
+ /**
+ * Create a new instance of the {@link JVMCICompiler}.
+ */
+ JVMCICompiler createCompiler(JVMCIRuntime runtime);
+
+ /**
+ * In a tiered system it might be advantageous for startup to keep the JVMCI compiler from
+ * compiling itself so provide a hook to request that certain packages are compiled only by an
+ * optimizing first tier. The prefixes should class or package names using / as the separator,
+ * i.e. jdk/vm/ci for instance.
+ *
+ * @return 0 or more Strings identifying packages that should by compiled by the first tier
+ * only.
+ */
+ default String[] getTrivialPrefixes() {
+ return null;
+ }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIRuntime.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCIRuntime.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
package jdk.vm.ci.runtime;
-import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.Architecture;
/**
* Interface for accessing the {@link JVMCI} APIs supported by the runtime.
@@ -30,6 +30,11 @@
public interface JVMCIRuntime {
/**
+ * Gets the default system compiler.
+ */
+ JVMCICompiler getCompiler();
+
+ /**
* Gets the host JVMCI backend.
*/
JVMCIBackend getHostJVMCIBackend();
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service.processor/src/jdk/vm/ci/service/processor/ServiceProviderProcessor.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service.processor/src/jdk/vm/ci/service/processor/ServiceProviderProcessor.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,18 +22,25 @@
*/
package jdk.vm.ci.service.processor;
-import java.io.*;
-import java.util.*;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
-import javax.annotation.processing.*;
-import javax.lang.model.*;
-import javax.lang.model.element.*;
-import javax.lang.model.type.*;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.MirroredTypeException;
+import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic.Kind;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
-import jdk.vm.ci.service.*;
-
-import javax.tools.*;
+import jdk.vm.ci.service.ServiceProvider;
@SupportedAnnotationTypes("jdk.vm.ci.service.ServiceProvider")
public class ServiceProviderProcessor extends AbstractProcessor {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/.checkstyle_checks.xml Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/.checkstyle_checks.xml Wed Jul 05 21:00:20 2017 +0200
@@ -32,6 +32,10 @@
<module name="NoWhitespaceAfter">
<property name="tokens" value="ARRAY_INIT,BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
</module>
+ <module name="AvoidStarImport">
+ <property name="allowClassImports" value="false"/>
+ <property name="allowStaticMemberImports" value="false"/>
+ </module>
<module name="NoWhitespaceBefore">
<property name="tokens" value="SEMI,DOT,POST_DEC,POST_INC"/>
</module>
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/src/jdk/vm/ci/service/ServiceProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/src/jdk/vm/ci/service/ServiceProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.service;
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
/**
* Annotates a service provider than can be loaded via {@linkplain Services#load(Class)} or
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/src/jdk/vm/ci/service/Services.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.service/src/jdk/vm/ci/service/Services.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,10 @@
*/
package jdk.vm.ci.service;
-import java.util.*;
+import java.util.Formatter;
+import java.util.Iterator;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
/**
* A mechanism for accessing service providers via JVMCI.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARC.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARC.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,14 +22,18 @@
*/
package jdk.vm.ci.sparc;
-import static java.nio.ByteOrder.*;
-import static jdk.vm.ci.code.MemoryBarriers.*;
+import static java.nio.ByteOrder.BIG_ENDIAN;
+import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD;
+import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
+import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
-import java.util.*;
+import java.util.Set;
-import jdk.vm.ci.code.*;
+import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.PlatformKind;
/**
* Represents the SPARC architecture.
@@ -37,95 +41,50 @@
public class SPARC extends Architecture {
public static final RegisterCategory CPU = new RegisterCategory("CPU");
+ public static final RegisterCategory FPUs = new RegisterCategory("FPUs");
+ public static final RegisterCategory FPUd = new RegisterCategory("FPUd");
+ public static final RegisterCategory FPUq = new RegisterCategory("FPUq");
// General purpose registers
- public static final Register r0 = new Register(0, 0, "g0", CPU);
- public static final Register r1 = new Register(1, 1, "g1", CPU);
- public static final Register r2 = new Register(2, 2, "g2", CPU);
- public static final Register r3 = new Register(3, 3, "g3", CPU);
- public static final Register r4 = new Register(4, 4, "g4", CPU);
- public static final Register r5 = new Register(5, 5, "g5", CPU);
- public static final Register r6 = new Register(6, 6, "g6", CPU);
- public static final Register r7 = new Register(7, 7, "g7", CPU);
-
- public static final Register r8 = new Register(8, 8, "o0", CPU);
- public static final Register r9 = new Register(9, 9, "o1", CPU);
- public static final Register r10 = new Register(10, 10, "o2", CPU);
- public static final Register r11 = new Register(11, 11, "o3", CPU);
- public static final Register r12 = new Register(12, 12, "o4", CPU);
- public static final Register r13 = new Register(13, 13, "o5", CPU);
- public static final Register r14 = new Register(14, 14, "o6", CPU);
- public static final Register r15 = new Register(15, 15, "o7", CPU);
+ public static final Register g0 = new Register(0, 0, "g0", CPU);
+ public static final Register g1 = new Register(1, 1, "g1", CPU);
+ public static final Register g2 = new Register(2, 2, "g2", CPU);
+ public static final Register g3 = new Register(3, 3, "g3", CPU);
+ public static final Register g4 = new Register(4, 4, "g4", CPU);
+ public static final Register g5 = new Register(5, 5, "g5", CPU);
+ public static final Register g6 = new Register(6, 6, "g6", CPU);
+ public static final Register g7 = new Register(7, 7, "g7", CPU);
- public static final Register r16 = new Register(16, 16, "l0", CPU);
- public static final Register r17 = new Register(17, 17, "l1", CPU);
- public static final Register r18 = new Register(18, 18, "l2", CPU);
- public static final Register r19 = new Register(19, 19, "l3", CPU);
- public static final Register r20 = new Register(20, 20, "l4", CPU);
- public static final Register r21 = new Register(21, 21, "l5", CPU);
- public static final Register r22 = new Register(22, 22, "l6", CPU);
- public static final Register r23 = new Register(23, 23, "l7", CPU);
-
- public static final Register r24 = new Register(24, 24, "i0", CPU);
- public static final Register r25 = new Register(25, 25, "i1", CPU);
- public static final Register r26 = new Register(26, 26, "i2", CPU);
- public static final Register r27 = new Register(27, 27, "i3", CPU);
- public static final Register r28 = new Register(28, 28, "i4", CPU);
- public static final Register r29 = new Register(29, 29, "i5", CPU);
- public static final Register r30 = new Register(30, 30, "i6", CPU);
- public static final Register r31 = new Register(31, 31, "i7", CPU);
+ public static final Register o0 = new Register(8, 8, "o0", CPU);
+ public static final Register o1 = new Register(9, 9, "o1", CPU);
+ public static final Register o2 = new Register(10, 10, "o2", CPU);
+ public static final Register o3 = new Register(11, 11, "o3", CPU);
+ public static final Register o4 = new Register(12, 12, "o4", CPU);
+ public static final Register o5 = new Register(13, 13, "o5", CPU);
+ public static final Register o6 = new Register(14, 14, "o6", CPU);
+ public static final Register o7 = new Register(15, 15, "o7", CPU);
- public static final Register g0 = r0;
- public static final Register g1 = r1;
- public static final Register g2 = r2;
- public static final Register g3 = r3;
- public static final Register g4 = r4;
- public static final Register g5 = r5;
- public static final Register g6 = r6;
- public static final Register g7 = r7;
-
- public static final Register o0 = r8;
- public static final Register o1 = r9;
- public static final Register o2 = r10;
- public static final Register o3 = r11;
- public static final Register o4 = r12;
- public static final Register o5 = r13;
- public static final Register o6 = r14;
- public static final Register o7 = r15;
+ public static final Register l0 = new Register(16, 16, "l0", CPU);
+ public static final Register l1 = new Register(17, 17, "l1", CPU);
+ public static final Register l2 = new Register(18, 18, "l2", CPU);
+ public static final Register l3 = new Register(19, 19, "l3", CPU);
+ public static final Register l4 = new Register(20, 20, "l4", CPU);
+ public static final Register l5 = new Register(21, 21, "l5", CPU);
+ public static final Register l6 = new Register(22, 22, "l6", CPU);
+ public static final Register l7 = new Register(23, 23, "l7", CPU);
- public static final Register l0 = r16;
- public static final Register l1 = r17;
- public static final Register l2 = r18;
- public static final Register l3 = r19;
- public static final Register l4 = r20;
- public static final Register l5 = r21;
- public static final Register l6 = r22;
- public static final Register l7 = r23;
-
- public static final Register i0 = r24;
- public static final Register i1 = r25;
- public static final Register i2 = r26;
- public static final Register i3 = r27;
- public static final Register i4 = r28;
- public static final Register i5 = r29;
- public static final Register i6 = r30;
- public static final Register i7 = r31;
+ public static final Register i0 = new Register(24, 24, "i0", CPU);
+ public static final Register i1 = new Register(25, 25, "i1", CPU);
+ public static final Register i2 = new Register(26, 26, "i2", CPU);
+ public static final Register i3 = new Register(27, 27, "i3", CPU);
+ public static final Register i4 = new Register(28, 28, "i4", CPU);
+ public static final Register i5 = new Register(29, 29, "i5", CPU);
+ public static final Register i6 = new Register(30, 30, "i6", CPU);
+ public static final Register i7 = new Register(31, 31, "i7", CPU);
public static final Register sp = o6;
public static final Register fp = i6;
- // @formatter:off
- public static final Register[] cpuRegisters = {
- r0, r1, r2, r3, r4, r5, r6, r7,
- r8, r9, r10, r11, r12, r13, r14, r15,
- r16, r17, r18, r19, r20, r21, r22, r23,
- r24, r25, r26, r27, r28, r29, r30, r31
- };
- // @formatter:on
-
- public static final RegisterCategory FPUs = new RegisterCategory("FPUs", cpuRegisters.length);
- public static final RegisterCategory FPUd = new RegisterCategory("FPUd", cpuRegisters.length + 32);
-
// Floating point registers
public static final Register f0 = new Register(32, 0, "f0", FPUs);
public static final Register f1 = new Register(33, 1, "f1", FPUs);
@@ -163,67 +122,111 @@
public static final Register f30 = new Register(62, 30, "f30", FPUs);
public static final Register f31 = new Register(63, 31, "f31", FPUs);
- public static final Register d0 = new Register(32, getDoubleEncoding(0), "d0", FPUs);
- public static final Register d2 = new Register(34, getDoubleEncoding(2), "d2", FPUs);
- public static final Register d4 = new Register(36, getDoubleEncoding(4), "d4", FPUs);
- public static final Register d6 = new Register(38, getDoubleEncoding(6), "d6", FPUs);
- public static final Register d8 = new Register(40, getDoubleEncoding(8), "d8", FPUs);
- public static final Register d10 = new Register(42, getDoubleEncoding(10), "d10", FPUs);
- public static final Register d12 = new Register(44, getDoubleEncoding(12), "d12", FPUs);
- public static final Register d14 = new Register(46, getDoubleEncoding(14), "d14", FPUs);
+ // Double precision registers
+ public static final Register d0 = new Register(64, getDoubleEncoding(0), "d0", FPUd);
+ public static final Register d2 = new Register(65, getDoubleEncoding(2), "d2", FPUd);
+ public static final Register d4 = new Register(66, getDoubleEncoding(4), "d4", FPUd);
+ public static final Register d6 = new Register(67, getDoubleEncoding(6), "d6", FPUd);
+ public static final Register d8 = new Register(68, getDoubleEncoding(8), "d8", FPUd);
+ public static final Register d10 = new Register(69, getDoubleEncoding(10), "d10", FPUd);
+ public static final Register d12 = new Register(70, getDoubleEncoding(12), "d12", FPUd);
+ public static final Register d14 = new Register(71, getDoubleEncoding(14), "d14", FPUd);
- public static final Register d16 = new Register(48, getDoubleEncoding(16), "d16", FPUs);
- public static final Register d18 = new Register(50, getDoubleEncoding(18), "d18", FPUs);
- public static final Register d20 = new Register(52, getDoubleEncoding(20), "d20", FPUs);
- public static final Register d22 = new Register(54, getDoubleEncoding(22), "d22", FPUs);
- public static final Register d24 = new Register(56, getDoubleEncoding(24), "d24", FPUs);
- public static final Register d26 = new Register(58, getDoubleEncoding(26), "d26", FPUs);
- public static final Register d28 = new Register(60, getDoubleEncoding(28), "d28", FPUs);
- public static final Register d30 = new Register(62, getDoubleEncoding(28), "d28", FPUs);
+ public static final Register d16 = new Register(72, getDoubleEncoding(16), "d16", FPUd);
+ public static final Register d18 = new Register(73, getDoubleEncoding(18), "d18", FPUd);
+ public static final Register d20 = new Register(74, getDoubleEncoding(20), "d20", FPUd);
+ public static final Register d22 = new Register(75, getDoubleEncoding(22), "d22", FPUd);
+ public static final Register d24 = new Register(76, getDoubleEncoding(24), "d24", FPUd);
+ public static final Register d26 = new Register(77, getDoubleEncoding(26), "d26", FPUd);
+ public static final Register d28 = new Register(78, getDoubleEncoding(28), "d28", FPUd);
+ public static final Register d30 = new Register(79, getDoubleEncoding(28), "d28", FPUd);
+
+ public static final Register d32 = new Register(80, getDoubleEncoding(32), "d32", FPUd);
+ public static final Register d34 = new Register(81, getDoubleEncoding(34), "d34", FPUd);
+ public static final Register d36 = new Register(82, getDoubleEncoding(36), "d36", FPUd);
+ public static final Register d38 = new Register(83, getDoubleEncoding(38), "d38", FPUd);
+ public static final Register d40 = new Register(84, getDoubleEncoding(40), "d40", FPUd);
+ public static final Register d42 = new Register(85, getDoubleEncoding(42), "d42", FPUd);
+ public static final Register d44 = new Register(86, getDoubleEncoding(44), "d44", FPUd);
+ public static final Register d46 = new Register(87, getDoubleEncoding(46), "d46", FPUd);
- public static final Register d32 = new Register(64, getDoubleEncoding(32), "d32", FPUd);
- public static final Register d34 = new Register(65, getDoubleEncoding(34), "d34", FPUd);
- public static final Register d36 = new Register(66, getDoubleEncoding(36), "d36", FPUd);
- public static final Register d38 = new Register(67, getDoubleEncoding(38), "d38", FPUd);
- public static final Register d40 = new Register(68, getDoubleEncoding(40), "d40", FPUd);
- public static final Register d42 = new Register(69, getDoubleEncoding(42), "d42", FPUd);
- public static final Register d44 = new Register(70, getDoubleEncoding(44), "d44", FPUd);
- public static final Register d46 = new Register(71, getDoubleEncoding(46), "d46", FPUd);
+ public static final Register d48 = new Register(88, getDoubleEncoding(48), "d48", FPUd);
+ public static final Register d50 = new Register(89, getDoubleEncoding(50), "d50", FPUd);
+ public static final Register d52 = new Register(90, getDoubleEncoding(52), "d52", FPUd);
+ public static final Register d54 = new Register(91, getDoubleEncoding(54), "d54", FPUd);
+ public static final Register d56 = new Register(92, getDoubleEncoding(56), "d56", FPUd);
+ public static final Register d58 = new Register(93, getDoubleEncoding(58), "d58", FPUd);
+ public static final Register d60 = new Register(94, getDoubleEncoding(60), "d60", FPUd);
+ public static final Register d62 = new Register(95, getDoubleEncoding(62), "d62", FPUd);
- public static final Register d48 = new Register(72, getDoubleEncoding(48), "d48", FPUd);
- public static final Register d50 = new Register(73, getDoubleEncoding(50), "d50", FPUd);
- public static final Register d52 = new Register(74, getDoubleEncoding(52), "d52", FPUd);
- public static final Register d54 = new Register(75, getDoubleEncoding(54), "d54", FPUd);
- public static final Register d56 = new Register(76, getDoubleEncoding(56), "d56", FPUd);
- public static final Register d58 = new Register(77, getDoubleEncoding(58), "d58", FPUd);
- public static final Register d60 = new Register(78, getDoubleEncoding(60), "d60", FPUd);
- public static final Register d62 = new Register(79, getDoubleEncoding(62), "d62", FPUd);
+ // Quad precision registers
+ public static final Register q0 = new Register(96, getQuadncoding(0), "q0", FPUq);
+ public static final Register q4 = new Register(97, getQuadncoding(4), "q4", FPUq);
+ public static final Register q8 = new Register(98, getQuadncoding(8), "q8", FPUq);
+ public static final Register q12 = new Register(99, getQuadncoding(12), "q12", FPUq);
+ public static final Register q16 = new Register(100, getQuadncoding(16), "q16", FPUq);
+ public static final Register q20 = new Register(101, getQuadncoding(20), "q20", FPUq);
+ public static final Register q24 = new Register(102, getQuadncoding(24), "q24", FPUq);
+ public static final Register q28 = new Register(103, getQuadncoding(28), "q28", FPUq);
+
+ public static final Register q32 = new Register(104, getQuadncoding(32), "q32", FPUq);
+ public static final Register q36 = new Register(105, getQuadncoding(36), "q36", FPUq);
+ public static final Register q40 = new Register(106, getQuadncoding(40), "q40", FPUq);
+ public static final Register q44 = new Register(107, getQuadncoding(44), "q44", FPUq);
+ public static final Register q48 = new Register(108, getQuadncoding(48), "q48", FPUq);
+ public static final Register q52 = new Register(109, getQuadncoding(52), "q52", FPUq);
+ public static final Register q56 = new Register(110, getQuadncoding(56), "q56", FPUq);
+ public static final Register q60 = new Register(111, getQuadncoding(60), "q60", FPUq);
// @formatter:off
- public static final Register[] fpuRegisters = {
+ public static final Register[] cpuRegisters = {
+ g0, g1, g2, g3, g4, g5, g6, g7,
+ o0, o1, o2, o3, o4, o5, o6, o7,
+ l0, l1, l2, l3, l4, l5, l6, l7,
+ i0, i1, i2, i3, i4, i5, i6, i7
+ };
+
+ public static final Register[] fpusRegisters = {
+ f0, f1, f2, f3, f4, f5, f6, f7,
+ f8, f9, f10, f11, f12, f13, f14, f15,
+ f16, f17, f18, f19, f20, f21, f22, f23,
+ f24, f25, f26, f27, f28, f29, f30, f31
+ };
+
+ public static final Register[] fpudRegisters = {
+ d0, d2, d4, d6, d8, d10, d12, d14,
+ d16, d18, d20, d22, d24, d26, d28, d30,
+ d32, d34, d36, d38, d40, d42, d44, d46,
+ d48, d50, d52, d54, d56, d58, d60, d62
+ };
+
+ public static final Register[] fpuqRegisters = {
+ q0, q4, q8, q12,
+ q16, q20, q24, q28,
+ q32, q36, q40, q44,
+ q48, q52, q56, q60,
+ };
+
+ public static final Register[] allRegisters = {
+ g0, g1, g2, g3, g4, g5, g6, g7,
+ o0, o1, o2, o3, o4, o5, o6, o7,
+ l0, l1, l2, l3, l4, l5, l6, l7,
+ i0, i1, i2, i3, i4, i5, i6, i7,
+
f0, f1, f2, f3, f4, f5, f6, f7,
f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23,
f24, f25, f26, f27, f28, f29, f30, f31,
- d32, d34, d36, d38, d40, d42, d44, d46,
- d48, d50, d52, d54, d56, d58, d60, d62
- };
- // @formatter:on
- // @formatter:off
- public static final Register[] allRegisters = {
- // CPU
- r0, r1, r2, r3, r4, r5, r6, r7,
- r8, r9, r10, r11, r12, r13, r14, r15,
- r16, r17, r18, r19, r20, r21, r22, r23,
- r24, r25, r26, r27, r28, r29, r30, r31,
- // FPU
- f0, f1, f2, f3, f4, f5, f6, f7,
- f8, f9, f10, f11, f12, f13, f14, f15,
- f16, f17, f18, f19, f20, f21, f22, f23,
- f24, f25, f26, f27, f28, f29, f30, f31,
+ d0, d2, d4, d6, d8, d10, d12, d14,
+ d16, d18, d20, d22, d24, d26, d28, d30,
d32, d34, d36, d38, d40, d42, d44, d46,
- d48, d50, d52, d54, d56, d58, d60, d62
+ d48, d50, d52, d54, d56, d58, d60, d62,
+
+ q0, q4, q8, q12,
+ q16, q20, q24, q28,
+ q32, q36, q40, q44,
+ q48, q52, q56, q60,
};
// @formatter:on
@@ -231,18 +234,6 @@
* Stack bias for stack and frame pointer loads.
*/
public static final int STACK_BIAS = 0x7ff;
- /**
- * In fact there are 64 single floating point registers, 32 of them could be accessed. TODO:
- * Improve handling of these float registers
- */
- public static final int FLOAT_REGISTER_COUNT = 64;
-
- /**
- * Alignment for valid memory access.
- */
- public static final int MEMORY_ACCESS_ALIGN = 4;
-
- public static final int INSTRUCTION_SIZE = 4;
/**
* Size to keep free for flushing the register-window to stack.
@@ -252,90 +243,87 @@
public final Set<CPUFeature> features;
public SPARC(Set<CPUFeature> features) {
- super("SPARC", JavaKind.Long, BIG_ENDIAN, false, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, r31.encoding + FLOAT_REGISTER_COUNT + 1, 8);
+ super("SPARC", SPARCKind.XWORD, BIG_ENDIAN, false, allRegisters, LOAD_LOAD | LOAD_STORE | STORE_STORE, 1, 8);
this.features = features;
}
@Override
- public boolean canStoreValue(RegisterCategory category, PlatformKind lirKind) {
- if (!(lirKind instanceof JavaKind)) {
- return false;
- }
+ public Register[] getAvailableValueRegisters() {
+ return allRegisters;
+ }
- JavaKind kind = (JavaKind) lirKind;
- if (category.equals(CPU)) {
- switch (kind) {
- case Boolean:
- case Byte:
- case Char:
- case Short:
- case Int:
- case Long:
- return true;
- }
- } else if (category.equals(FPUs) && kind.equals(JavaKind.Float)) {
- return true;
- } else if (category.equals(FPUd) && kind.equals(JavaKind.Double)) {
- return true;
+ @Override
+ public boolean canStoreValue(RegisterCategory category, PlatformKind kind) {
+ SPARCKind sparcKind = (SPARCKind) kind;
+ switch (sparcKind) {
+ case BYTE:
+ case HWORD:
+ case WORD:
+ case XWORD:
+ return CPU.equals(category);
+ case SINGLE:
+ case V32_BYTE:
+ case V32_HWORD:
+ return FPUs.equals(category);
+ case DOUBLE:
+ case V64_BYTE:
+ case V64_HWORD:
+ case V64_WORD:
+ case V64_SINGLE:
+ return FPUd.equals(category);
+ case QUAD:
+ return FPUq.equals(category);
+ default:
+ return false;
}
- return false;
}
@Override
public PlatformKind getLargestStorableKind(RegisterCategory category) {
if (category.equals(CPU)) {
- return JavaKind.Long;
+ return SPARCKind.XWORD;
} else if (category.equals(FPUd)) {
- return JavaKind.Double;
+ return SPARCKind.DOUBLE;
} else if (category.equals(FPUs)) {
- return JavaKind.Float;
+ return SPARCKind.SINGLE;
+ } else if (category.equals(FPUq)) {
+ return SPARCKind.QUAD;
} else {
- return JavaKind.Illegal;
+ throw new IllegalArgumentException("Unknown register category: " + category);
}
}
@Override
public PlatformKind getPlatformKind(JavaKind javaKind) {
- if (javaKind.isObject()) {
- return JavaKind.Long;
- } else {
- return javaKind;
+ switch (javaKind) {
+ case Boolean:
+ case Byte:
+ return SPARCKind.BYTE;
+ case Short:
+ case Char:
+ return SPARCKind.HWORD;
+ case Int:
+ return SPARCKind.WORD;
+ case Long:
+ case Object:
+ return SPARCKind.XWORD;
+ case Float:
+ return SPARCKind.SINGLE;
+ case Double:
+ return SPARCKind.DOUBLE;
+ default:
+ throw new IllegalArgumentException("Unknown JavaKind: " + javaKind);
}
}
- public static int spillSlotSize(TargetDescription td, PlatformKind kind) {
- return Math.max(td.getSizeInBytes(kind), MEMORY_ACCESS_ALIGN);
- }
-
- public static int getDoubleEncoding(int reg) {
+ private static int getDoubleEncoding(int reg) {
assert reg < 64 && ((reg & 1) == 0);
- // ignore v8 assertion for now
return (reg & 0x1e) | ((reg & 0x20) >> 5);
}
- public static boolean isCPURegister(Register r) {
- return r.getRegisterCategory().equals(CPU);
- }
-
- public static boolean isCPURegister(Register... regs) {
- for (Register reg : regs) {
- if (!isCPURegister(reg)) {
- return false;
- }
- }
- return true;
- }
-
- public static boolean isGlobalRegister(Register r) {
- return isCPURegister(r) && g0.number <= r.number && r.number <= g7.number;
- }
-
- public static boolean isSingleFloatRegister(Register r) {
- return r.name.startsWith("f");
- }
-
- public static boolean isDoubleFloatRegister(Register r) {
- return r.name.startsWith("d");
+ private static int getQuadncoding(int reg) {
+ assert reg < 64 && ((reg & 1) == 0);
+ return (reg & 0x1c) | ((reg & 0x20) >> 5);
}
public Set<CPUFeature> getFeatures() {
@@ -351,6 +339,24 @@
VIS2,
VIS3,
CBCOND,
- BLOCK_ZEROING
+ V8,
+ HARDWARE_MUL32,
+ HARDWARE_DIV32,
+ HARDWARE_FSMULD,
+ HARDWARE_POPC,
+ V9,
+ SUN4V,
+ BLK_INIT_INSTRUCTIONS,
+ FMAF,
+ FMAU,
+ SPARC64_FAMILY,
+ M_FAMILY,
+ T_FAMILY,
+ T1_MODEL,
+ SPARC5,
+ AES,
+ SHA1,
+ SHA256,
+ SHA512
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARCKind.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.sparc;
+
+import jdk.vm.ci.meta.PlatformKind;
+
+public enum SPARCKind implements PlatformKind {
+ BYTE(1),
+ HWORD(2),
+ WORD(4),
+ XWORD(8),
+ SINGLE(4),
+ DOUBLE(8),
+ QUAD(16),
+
+ V32_BYTE(4, BYTE),
+ V32_HWORD(4, HWORD),
+
+ V64_BYTE(8, BYTE),
+ V64_HWORD(8, HWORD),
+ V64_WORD(8, WORD),
+ V64_SINGLE(8, SINGLE);
+
+ private final int size;
+ private final int vectorLength;
+
+ private final SPARCKind scalar;
+ private final EnumKey<SPARCKind> key = new EnumKey<>(this);
+
+ private SPARCKind(int size) {
+ this.size = size;
+ this.scalar = this;
+ this.vectorLength = 1;
+ }
+
+ private SPARCKind(int size, SPARCKind scalar) {
+ this.size = size;
+ this.scalar = scalar;
+
+ assert size % scalar.size == 0;
+ this.vectorLength = size / scalar.size;
+ }
+
+ public SPARCKind getScalar() {
+ return scalar;
+ }
+
+ public int getSizeInBytes() {
+ return size;
+ }
+
+ public int getSizeInBits() {
+ return getSizeInBytes() * 8;
+ }
+
+ public int getVectorLength() {
+ return vectorLength;
+ }
+
+ public Key getKey() {
+ return key;
+ }
+
+ public boolean isInteger() {
+ switch (this) {
+ case BYTE:
+ case HWORD:
+ case WORD:
+ case XWORD:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isFloat() {
+ return !isInteger();
+ }
+
+ public char getTypeChar() {
+ switch (this) {
+ case BYTE:
+ return 'b';
+ case HWORD:
+ return 'h';
+ case WORD:
+ return 'w';
+ case XWORD:
+ return 'd';
+ case SINGLE:
+ return 'S';
+ case DOUBLE:
+ case V64_BYTE:
+ case V64_HWORD:
+ case V64_WORD:
+ return 'D';
+ default:
+ return '-';
+ }
+ }
+}
--- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os/aix/vm/os_aix.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -3811,7 +3811,7 @@
// able to use structured exception handling (thread-local exception filters)
// on, e.g., Win32.
void
-os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method,
+os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
JavaCallArguments* args, Thread* thread) {
f(value, method, args, thread);
}
--- a/hotspot/src/os/bsd/dtrace/libjvm_db.c Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os/bsd/dtrace/libjvm_db.c Wed Jul 05 21:00:20 2017 +0200
@@ -834,7 +834,7 @@
if (stream_bci == vf->bci) {
/* perfect match */
if (debug > 2)
- fprintf(stderr, "\t line_number_from_bci: END: exact line: %ld \n\n", vf->line);
+ fprintf(stderr, "\t line_number_from_bci: END: exact line: %d \n\n", vf->line);
vf->line = stream_line;
return PS_OK;
} else {
@@ -843,14 +843,14 @@
best_bci = stream_bci;
vf->line = stream_line;
if (debug > 2) {
- fprintf(stderr, "\t line_number_from_bci: best_bci: %ld, best_line: %ld\n",
+ fprintf(stderr, "\t line_number_from_bci: best_bci: %d, best_line: %d\n",
best_bci, vf->line);
}
}
}
}
if (debug > 2)
- fprintf(stderr, "\t line_number_from_bci: END: line: %ld \n\n", vf->line);
+ fprintf(stderr, "\t line_number_from_bci: END: line: %d \n\n", vf->line);
return PS_OK;
fail:
@@ -1002,7 +1002,7 @@
err = line_number_from_bci(N->J, vf);
CHECK_FAIL(err);
if (debug > 2) {
- fprintf(stderr, "\t scopeDesc_chain: method: %#8llx, line: %ld\n",
+ fprintf(stderr, "\t scopeDesc_chain: method: %#8llx, line: %d\n",
vf->method, vf->line);
}
}
@@ -1338,7 +1338,7 @@
jframe->bci = vf->bci;
jframe->line = vf->line;
if (debug) {
- fprintf(stderr, "\t Jget_vframe: method name: %s, line: %ld\n",
+ fprintf(stderr, "\t Jget_vframe: method name: %s, line: %d\n",
name, vf->line);
}
return PS_OK;
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -440,6 +440,10 @@
if (pslash != NULL) {
*pslash = '\0'; // Get rid of /{client|server|hotspot}.
}
+#ifdef STATIC_BUILD
+ strcat(buf, "/lib");
+#endif
+
Arguments::set_dll_dir(buf);
if (pslash != NULL) {
@@ -1388,6 +1392,9 @@
#ifdef __APPLE__
void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
+#ifdef STATIC_BUILD
+ return os::get_default_process_handle();
+#else
void * result= ::dlopen(filename, RTLD_LAZY);
if (result != NULL) {
// Successful loading
@@ -1399,9 +1406,13 @@
ebuf[ebuflen-1]='\0';
return NULL;
+#endif // STATIC_BUILD
}
#else
void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
+#ifdef STATIC_BUILD
+ return os::get_default_process_handle();
+#else
void * result= ::dlopen(filename, RTLD_LAZY);
if (result != NULL) {
// Successful loading
@@ -1574,6 +1585,7 @@
}
return NULL;
+#endif // STATIC_BUILD
}
#endif // !__APPLE__
@@ -3745,7 +3757,7 @@
// able to use structured exception handling (thread-local exception filters)
// on, e.g., Win32.
void os::os_exception_wrapper(java_call_t f, JavaValue* value,
- methodHandle* method, JavaCallArguments* args,
+ const methodHandle& method, JavaCallArguments* args,
Thread* thread) {
f(value, method, args, thread);
}
--- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -2794,7 +2794,7 @@
int os::Linux::sched_getcpu_syscall(void) {
- unsigned int cpu;
+ unsigned int cpu = 0;
int retval = -1;
#if defined(IA32)
@@ -4187,8 +4187,8 @@
sigaddset(&(actp->sa_mask), sig);
}
- sa_handler_t hand;
- sa_sigaction_t sa;
+ sa_handler_t hand = NULL;
+ sa_sigaction_t sa = NULL;
bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
// retrieve the chained handler
if (siginfo_flag_set) {
@@ -4393,7 +4393,7 @@
static const char* get_signal_handler_name(address handler,
char* buf, int buflen) {
- int offset;
+ int offset = 0;
bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
if (found) {
// skip directory names
@@ -4960,7 +4960,7 @@
// able to use structured exception handling (thread-local exception filters)
// on, e.g., Win32.
void
-os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method,
+os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
JavaCallArguments* args, Thread* thread) {
f(value, method, args, thread);
}
--- a/hotspot/src/os/solaris/dtrace/libjvm_db.c Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c Wed Jul 05 21:00:20 2017 +0200
@@ -834,7 +834,7 @@
if (stream_bci == vf->bci) {
/* perfect match */
if (debug > 2)
- fprintf(stderr, "\t line_number_from_bci: END: exact line: %ld \n\n", vf->line);
+ fprintf(stderr, "\t line_number_from_bci: END: exact line: %d \n\n", vf->line);
vf->line = stream_line;
return PS_OK;
} else {
@@ -843,14 +843,14 @@
best_bci = stream_bci;
vf->line = stream_line;
if (debug > 2) {
- fprintf(stderr, "\t line_number_from_bci: best_bci: %ld, best_line: %ld\n",
+ fprintf(stderr, "\t line_number_from_bci: best_bci: %d, best_line: %d\n",
best_bci, vf->line);
}
}
}
}
if (debug > 2)
- fprintf(stderr, "\t line_number_from_bci: END: line: %ld \n\n", vf->line);
+ fprintf(stderr, "\t line_number_from_bci: END: line: %d \n\n", vf->line);
return PS_OK;
fail:
@@ -1002,7 +1002,7 @@
err = line_number_from_bci(N->J, vf);
CHECK_FAIL(err);
if (debug > 2) {
- fprintf(stderr, "\t scopeDesc_chain: method: %#8llx, line: %ld\n",
+ fprintf(stderr, "\t scopeDesc_chain: method: %#8llx, line: %d\n",
vf->method, vf->line);
}
}
@@ -1338,7 +1338,7 @@
jframe->bci = vf->bci;
jframe->line = vf->line;
if (debug) {
- fprintf(stderr, "\t Jget_vframe: method name: %s, line: %ld\n",
+ fprintf(stderr, "\t Jget_vframe: method name: %s, line: %d\n",
name, vf->line);
}
return PS_OK;
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -3774,7 +3774,7 @@
// This does not do anything on Solaris. This is basically a hook for being
// able to use structured exception handling (thread-local exception filters) on, e.g., Win32.
void os::os_exception_wrapper(java_call_t f, JavaValue* value,
- methodHandle* method, JavaCallArguments* args,
+ const methodHandle& method, JavaCallArguments* args,
Thread* thread) {
f(value, method, args, thread);
}
--- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -65,6 +65,8 @@
}
inline void os::dll_unload(void *lib) { ::dlclose(lib); }
+inline const int os::default_file_open_flags() { return 0;}
+
inline DIR* os::opendir(const char* dirname) {
assert(dirname != NULL, "just checking");
return ::opendir(dirname);
--- a/hotspot/src/os_cpu/linux_x86/vm/copy_linux_x86.inline.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/copy_linux_x86.inline.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -30,7 +30,7 @@
(void)memmove(to, from, count * HeapWordSize);
#else
// Includes a zero-count check.
- intx temp;
+ intx temp = 0;
__asm__ volatile(" testl %6,%6 ;"
" jz 7f ;"
" cmpl %4,%5 ;"
@@ -88,7 +88,7 @@
}
#else
// Includes a zero-count check.
- intx temp;
+ intx temp = 0;
__asm__ volatile(" testl %6,%6 ;"
" jz 3f ;"
" cmpl $32,%6 ;"
@@ -145,7 +145,7 @@
(void)memmove(to, from, count);
#else
// Includes a zero-count check.
- intx temp;
+ intx temp = 0;
__asm__ volatile(" testl %6,%6 ;"
" jz 13f ;"
" cmpl %4,%5 ;"
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,7 +71,7 @@
extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
// Install a win32 structured exception handler around thread.
-void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread) {
+void os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread) {
__try {
#ifndef AMD64
--- a/hotspot/src/share/vm/adlc/formssel.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -607,6 +607,8 @@
( strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrIndexOf" )==0 ||
+ strcmp(_matrule->_rChild->_opType,"StrIndexOfChar" )==0 ||
+ strcmp(_matrule->_rChild->_opType,"HasNegatives" )==0 ||
strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ))
return true;
@@ -887,11 +889,16 @@
( strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
+ strcmp(_matrule->_rChild->_opType,"StrInflatedCopy" )==0 ||
+ strcmp(_matrule->_rChild->_opType,"StrCompressedCopy" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 ||
+ strcmp(_matrule->_rChild->_opType,"StrIndexOfChar")==0 ||
+ strcmp(_matrule->_rChild->_opType,"HasNegatives")==0 ||
strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) {
// String.(compareTo/equals/indexOf) and Arrays.equals
// and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray
// take 1 control and 1 memory edges.
+ // Also String.(compressedCopy/inflatedCopy).
return 2;
}
--- a/hotspot/src/share/vm/adlc/main.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/adlc/main.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -221,6 +221,7 @@
AD.addInclude(AD._CPP_file, "oops/method.hpp");
AD.addInclude(AD._CPP_file, "oops/oop.inline.hpp");
AD.addInclude(AD._CPP_file, "opto/cfgnode.hpp");
+ AD.addInclude(AD._CPP_file, "opto/intrinsicnode.hpp");
AD.addInclude(AD._CPP_file, "opto/locknode.hpp");
AD.addInclude(AD._CPP_file, "opto/opcodes.hpp");
AD.addInclude(AD._CPP_file, "opto/regalloc.hpp");
@@ -256,6 +257,7 @@
AD.addInclude(AD._DFA_file, "precompiled.hpp");
AD.addInclude(AD._DFA_file, "adfiles", get_basename(AD._HPP_file._name));
AD.addInclude(AD._DFA_file, "opto/cfgnode.hpp"); // Use PROB_MAX in predicate.
+ AD.addInclude(AD._DFA_file, "opto/intrinsicnode.hpp");
AD.addInclude(AD._DFA_file, "opto/matcher.hpp");
AD.addInclude(AD._DFA_file, "opto/opcodes.hpp");
AD.addInclude(AD._DFA_file, "opto/convertnode.hpp");
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -509,7 +509,7 @@
}
}
-void CodeBuffer::finalize_oop_references(methodHandle mh) {
+void CodeBuffer::finalize_oop_references(const methodHandle& mh) {
No_Safepoint_Verifier nsv;
GrowableArray<oop> oops;
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -541,7 +541,7 @@
bool insts_contains2(address pc) const { return _insts.contains2(pc); }
// Record any extra oops required to keep embedded metadata alive
- void finalize_oop_references(methodHandle method);
+ void finalize_oop_references(const methodHandle& method);
// Allocated size in all sections, when aligned and concatenated
// (this is the eventual state of the content in its final
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -639,7 +639,7 @@
if (l == r && !lt->is_float_kind()) {
// pattern: If (a cond a) => simplify to Goto
- BlockBegin* sux;
+ BlockBegin* sux = NULL;
switch (x->cond()) {
case If::eql: sux = x->sux_for(true); break;
case If::neq: sux = x->sux_for(false); break;
@@ -647,6 +647,7 @@
case If::leq: sux = x->sux_for(true); break;
case If::gtr: sux = x->sux_for(false); break;
case If::geq: sux = x->sux_for(true); break;
+ default: ShouldNotReachHere();
}
// If is a safepoint then the debug information should come from the state_before of the If.
set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
@@ -684,7 +685,7 @@
} else {
// two successors differ and two successors are the same => simplify to: If (x cmp y)
// determine new condition & successors
- If::Condition cond;
+ If::Condition cond = If::eql;
BlockBegin* tsux = NULL;
BlockBegin* fsux = NULL;
if (lss_sux == eql_sux) { cond = If::leq; tsux = lss_sux; fsux = gtr_sux; }
@@ -727,7 +728,9 @@
set_canonical(new IfInstanceOf(inst->klass(), inst->obj(), true, inst->state_before()->bci(), is_inst_sux, no_inst_sux));
}
}
- } else if (rt == objectNull && (l->as_NewInstance() || l->as_NewArray())) {
+ } else if (rt == objectNull &&
+ (l->as_NewInstance() || l->as_NewArray() ||
+ (UseNewCode && l->as_Local() && l->as_Local()->is_receiver()))) {
if (x->cond() == Instruction::eql) {
BlockBegin* sux = x->fsux();
set_canonical(new Goto(sux, x->state_before(), is_safepoint(x, sux)));
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@
return buffer_blob;
}
-bool Compiler::is_intrinsic_supported(methodHandle method) {
+bool Compiler::is_intrinsic_supported(const methodHandle& method) {
vmIntrinsics::ID id = method->intrinsic_id();
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
@@ -225,6 +225,8 @@
case vmIntrinsics::_updateByteBufferCRC32:
case vmIntrinsics::_compareAndSwapInt:
case vmIntrinsics::_compareAndSwapObject:
+ case vmIntrinsics::_getCharStringU:
+ case vmIntrinsics::_putCharStringU:
#ifdef TRACE_HAVE_INTRINSICS
case vmIntrinsics::_classID:
case vmIntrinsics::_threadID:
--- a/hotspot/src/share/vm/c1/c1_Compiler.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_Compiler.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,7 +57,7 @@
virtual void print_timers();
// Check if the C1 compiler supports an intrinsic for 'method'.
- virtual bool is_intrinsic_supported(methodHandle method);
+ virtual bool is_intrinsic_supported(const methodHandle& method);
// Size of the code buffer
static int code_buffer_size();
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -3089,7 +3089,7 @@
int idx = 0;
if (!method()->is_static()) {
// we should always see the receiver
- state->store_local(idx, new Local(method()->holder(), objectType, idx));
+ state->store_local(idx, new Local(method()->holder(), objectType, idx, true));
idx = 1;
}
@@ -3101,7 +3101,7 @@
// don't allow T_ARRAY to propagate into locals types
if (basic_type == T_ARRAY) basic_type = T_OBJECT;
ValueType* vt = as_ValueType(basic_type);
- state->store_local(idx, new Local(type, vt, idx));
+ state->store_local(idx, new Local(type, vt, idx, false));
idx += type->size();
}
@@ -3445,6 +3445,8 @@
case vmIntrinsics::_getAndSetInt :
case vmIntrinsics::_getAndSetLong :
case vmIntrinsics::_getAndSetObject : append_unsafe_get_and_set_obj(callee, false); return;
+ case vmIntrinsics::_getCharStringU : append_char_access(callee, false); return;
+ case vmIntrinsics::_putCharStringU : append_char_access(callee, true); return;
default:
break;
}
@@ -3823,8 +3825,8 @@
caller_state->truncate_stack(args_base);
assert(callee_state->stack_size() == 0, "callee stack must be empty");
- Value lock;
- BlockBegin* sync_handler;
+ Value lock = NULL;
+ BlockBegin* sync_handler = NULL;
// Inline the locking of the receiver if the callee is synchronized
if (callee->is_synchronized()) {
@@ -4179,6 +4181,30 @@
compilation()->set_has_unsafe_access(true);
}
+void GraphBuilder::append_char_access(ciMethod* callee, bool is_store) {
+ // This intrinsic accesses byte[] array as char[] array. Computing the offsets
+ // correctly requires matched array shapes.
+ assert (arrayOopDesc::base_offset_in_bytes(T_CHAR) == arrayOopDesc::base_offset_in_bytes(T_BYTE),
+ "sanity: byte[] and char[] bases agree");
+ assert (type2aelembytes(T_CHAR) == type2aelembytes(T_BYTE)*2,
+ "sanity: byte[] and char[] scales agree");
+
+ ValueStack* state_before = copy_state_indexed_access();
+ compilation()->set_has_access_indexed(true);
+ Values* args = state()->pop_arguments(callee->arg_size());
+ Value array = args->at(0);
+ Value index = args->at(1);
+ if (is_store) {
+ Value value = args->at(2);
+ Instruction* store = append(new StoreIndexed(array, index, NULL, T_CHAR, value, state_before));
+ store->set_flag(Instruction::NeedsRangeCheckFlag, false);
+ _memory->store_value(value);
+ } else {
+ Instruction* load = append(new LoadIndexed(array, index, NULL, T_CHAR, state_before));
+ load->set_flag(Instruction::NeedsRangeCheckFlag, false);
+ push(load->type(), load);
+ }
+}
void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool success) {
CompileLog* log = compilation()->log();
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -372,6 +372,7 @@
void append_unsafe_put_raw(ciMethod* callee, BasicType t);
void append_unsafe_CAS(ciMethod* callee);
void append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add);
+ void append_char_access(ciMethod* callee, bool is_store);
void print_inlining(ciMethod* callee, const char* msg = NULL, bool success = true);
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -701,19 +701,22 @@
LEAF(Local, Instruction)
private:
int _java_index; // the local index within the method to which the local belongs
+ bool _is_receiver; // if local variable holds the receiver: "this" for non-static methods
ciType* _declared_type;
public:
// creation
- Local(ciType* declared, ValueType* type, int index)
+ Local(ciType* declared, ValueType* type, int index, bool receiver)
: Instruction(type)
, _java_index(index)
, _declared_type(declared)
+ , _is_receiver(receiver)
{
NOT_PRODUCT(set_printable_bci(-1));
}
// accessors
int java_index() const { return _java_index; }
+ bool is_receiver() const { return _is_receiver; }
virtual ciType* declared_type() const { return _declared_type; }
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -161,8 +161,6 @@
// particular sparc uses this for delay slot filling.
void peephole(LIR_List* list);
- void emit_string_compare(LIR_Opr left, LIR_Opr right, LIR_Opr dst, CodeEmitInfo* info);
-
void return_op(LIR_Opr result);
// returns offset of poll instruction
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -3348,7 +3348,7 @@
}
void LIRGenerator::increment_event_counter(CodeEmitInfo* info, int bci, bool backedge) {
- int freq_log;
+ int freq_log = 0;
int level = compilation()->env()->comp_level();
if (level == CompLevel_limited_profile) {
freq_log = (backedge ? Tier2BackedgeNotifyFreqLog : Tier2InvokeNotifyFreqLog);
@@ -3394,7 +3394,7 @@
assert(level > CompLevel_simple, "Shouldn't be here");
int offset = -1;
- LIR_Opr counter_holder;
+ LIR_Opr counter_holder = NULL;
if (level == CompLevel_limited_profile) {
MethodCounters* counters_adr = method->ensure_method_counters();
if (counters_adr == NULL) {
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -414,7 +414,7 @@
}
static LIR_Condition lir_cond(If::Condition cond) {
- LIR_Condition l;
+ LIR_Condition l = lir_cond_unknown;
switch (cond) {
case If::eql: l = lir_cond_equal; break;
case If::neq: l = lir_cond_notEqual; break;
@@ -424,6 +424,7 @@
case If::gtr: l = lir_cond_greater; break;
case If::aeq: l = lir_cond_aboveEqual; break;
case If::beq: l = lir_cond_belowEqual; break;
+ default: fatal("You must pass valid If::Condition");
};
return l;
}
--- a/hotspot/src/share/vm/ci/ciArrayKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciArrayKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,7 @@
//
// Loaded array klass.
ciArrayKlass::ciArrayKlass(KlassHandle h_k) : ciKlass(h_k) {
- assert(get_Klass()->oop_is_array(), "wrong type");
+ assert(get_Klass()->is_array_klass(), "wrong type");
_dimension = get_ArrayKlass()->dimension();
}
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -366,11 +366,11 @@
return true;
}
- if (resolved_klass->oop_is_objArray()) {
+ if (resolved_klass->is_objArray_klass()) {
// Find the element klass, if this is an array.
resolved_klass = ObjArrayKlass::cast(resolved_klass)->bottom_klass();
}
- if (resolved_klass->oop_is_instance()) {
+ if (resolved_klass->is_instance_klass()) {
return Reflection::verify_class_access(accessing_klass->get_Klass(),
resolved_klass,
true);
@@ -381,7 +381,7 @@
// ------------------------------------------------------------------
// ciEnv::get_klass_by_name_impl
ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
- constantPoolHandle cpool,
+ const constantPoolHandle& cpool,
ciSymbol* name,
bool require_local) {
ASSERT_IN_VM;
@@ -503,7 +503,7 @@
// ciEnv::get_klass_by_index_impl
//
// Implementation of get_klass_by_index.
-ciKlass* ciEnv::get_klass_by_index_impl(constantPoolHandle cpool,
+ciKlass* ciEnv::get_klass_by_index_impl(const constantPoolHandle& cpool,
int index,
bool& is_accessible,
ciInstanceKlass* accessor) {
@@ -560,7 +560,7 @@
// ciEnv::get_klass_by_index
//
// Get a klass from the constant pool.
-ciKlass* ciEnv::get_klass_by_index(constantPoolHandle cpool,
+ciKlass* ciEnv::get_klass_by_index(const constantPoolHandle& cpool,
int index,
bool& is_accessible,
ciInstanceKlass* accessor) {
@@ -571,7 +571,7 @@
// ciEnv::get_constant_by_index_impl
//
// Implementation of get_constant_by_index().
-ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,
+ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool,
int pool_index, int cache_index,
ciInstanceKlass* accessor) {
bool ignore_will_link;
@@ -657,7 +657,7 @@
// Pull a constant out of the constant pool. How appropriate.
//
// Implementation note: this query is currently in no way cached.
-ciConstant ciEnv::get_constant_by_index(constantPoolHandle cpool,
+ciConstant ciEnv::get_constant_by_index(const constantPoolHandle& cpool,
int pool_index, int cache_index,
ciInstanceKlass* accessor) {
GUARDED_VM_ENTRY(return get_constant_by_index_impl(cpool, pool_index, cache_index, accessor);)
@@ -737,7 +737,7 @@
// ------------------------------------------------------------------
// ciEnv::get_method_by_index_impl
-ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
+ciMethod* ciEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
int index, Bytecodes::Code bc,
ciInstanceKlass* accessor) {
if (bc == Bytecodes::_invokedynamic) {
@@ -849,7 +849,7 @@
// ------------------------------------------------------------------
// ciEnv::get_method_by_index
-ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool,
+ciMethod* ciEnv::get_method_by_index(const constantPoolHandle& cpool,
int index, Bytecodes::Code bc,
ciInstanceKlass* accessor) {
GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);)
--- a/hotspot/src/share/vm/ci/ciEnv.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -120,34 +120,34 @@
bool require_local);
// Constant pool access.
- ciKlass* get_klass_by_index(constantPoolHandle cpool,
+ ciKlass* get_klass_by_index(const constantPoolHandle& cpool,
int klass_index,
bool& is_accessible,
ciInstanceKlass* loading_klass);
- ciConstant get_constant_by_index(constantPoolHandle cpool,
+ ciConstant get_constant_by_index(const constantPoolHandle& cpool,
int pool_index, int cache_index,
ciInstanceKlass* accessor);
ciField* get_field_by_index(ciInstanceKlass* loading_klass,
int field_index);
- ciMethod* get_method_by_index(constantPoolHandle cpool,
+ ciMethod* get_method_by_index(const constantPoolHandle& cpool,
int method_index, Bytecodes::Code bc,
ciInstanceKlass* loading_klass);
// Implementation methods for loading and constant pool access.
ciKlass* get_klass_by_name_impl(ciKlass* accessing_klass,
- constantPoolHandle cpool,
+ const constantPoolHandle& cpool,
ciSymbol* klass_name,
bool require_local);
- ciKlass* get_klass_by_index_impl(constantPoolHandle cpool,
+ ciKlass* get_klass_by_index_impl(const constantPoolHandle& cpool,
int klass_index,
bool& is_accessible,
ciInstanceKlass* loading_klass);
- ciConstant get_constant_by_index_impl(constantPoolHandle cpool,
+ ciConstant get_constant_by_index_impl(const constantPoolHandle& cpool,
int pool_index, int cache_index,
ciInstanceKlass* loading_klass);
ciField* get_field_by_index_impl(ciInstanceKlass* loading_klass,
int field_index);
- ciMethod* get_method_by_index_impl(constantPoolHandle cpool,
+ ciMethod* get_method_by_index_impl(const constantPoolHandle& cpool,
int method_index, Bytecodes::Code bc,
ciInstanceKlass* loading_klass);
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
ciInstanceKlass::ciInstanceKlass(KlassHandle h_k) :
ciKlass(h_k)
{
- assert(get_Klass()->oop_is_instance(), "wrong type");
+ assert(get_Klass()->is_instance_klass(), "wrong type");
assert(get_instanceKlass()->is_loaded(), "must be at least loaded");
InstanceKlass* ik = get_instanceKlass();
@@ -356,7 +356,7 @@
VM_ENTRY_MARK;
InstanceKlass* ik = get_instanceKlass();
Klass* up = ik->up_cast_abstract();
- assert(up->oop_is_instance(), "must be InstanceKlass");
+ assert(up->is_instance_klass(), "must be InstanceKlass");
if (ik == up) {
return NULL;
}
@@ -683,7 +683,7 @@
// Try to record related loaded classes
Klass* sub = ik->subklass();
while (sub != NULL) {
- if (sub->oop_is_instance()) {
+ if (sub->is_instance_klass()) {
out->print_cr("instanceKlass %s", sub->name()->as_quoted_ascii());
}
sub = sub->next_sibling();
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,7 @@
ciInstanceKlass(ciSymbol* name, jobject loader, jobject protection_domain);
InstanceKlass* get_instanceKlass() const {
- return (InstanceKlass*)get_Klass();
+ return InstanceKlass::cast(get_Klass());
}
oop loader();
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -744,7 +744,7 @@
#ifndef PRODUCT
if (TraceDependencies && target() != NULL && target() != root_m->get_Method()) {
tty->print("found a non-root unique target method");
- tty->print_cr(" context = %s", InstanceKlass::cast(actual_recv->get_Klass())->external_name());
+ tty->print_cr(" context = %s", actual_recv->get_Klass()->external_name());
tty->print(" method = ");
target->print_short_name(tty);
tty->cr();
@@ -790,7 +790,7 @@
methodHandle m;
// Only do exact lookup if receiver klass has been linked. Otherwise,
// the vtable has not been setup, and the LinkResolver will fail.
- if (h_recv->oop_is_array()
+ if (h_recv->is_array_klass()
||
InstanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) {
if (holder()->is_interface()) {
--- a/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
//
// Constructor for loaded object array klasses.
ciObjArrayKlass::ciObjArrayKlass(KlassHandle h_k) : ciArrayKlass(h_k) {
- assert(get_Klass()->oop_is_objArray(), "wrong type");
+ assert(get_Klass()->is_objArray_klass(), "wrong type");
Klass* element_Klass = get_ObjArrayKlass()->bottom_klass();
_base_element_klass = CURRENT_ENV->get_klass(element_Klass);
assert(_base_element_klass->is_instance_klass() ||
--- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -357,7 +357,7 @@
// Hold metadata from unloading by keeping it's holder alive.
if (_initialized && o->is_klass()) {
Klass* holder = ((Klass*)o);
- if (holder->oop_is_instance() && InstanceKlass::cast(holder)->is_anonymous()) {
+ if (holder->is_instance_klass() && InstanceKlass::cast(holder)->is_anonymous()) {
// Though ciInstanceKlass records class loader oop, it's not enough to keep
// VM anonymous classes alive (loader == NULL). Klass holder should be used instead.
// It is enough to record a ciObject, since cached elements are never removed
@@ -370,11 +370,11 @@
if (o->is_klass()) {
KlassHandle h_k(THREAD, (Klass*)o);
Klass* k = (Klass*)o;
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
return new (arena()) ciInstanceKlass(h_k);
- } else if (k->oop_is_objArray()) {
+ } else if (k->is_objArray_klass()) {
return new (arena()) ciObjArrayKlass(h_k);
- } else if (k->oop_is_typeArray()) {
+ } else if (k->is_typeArray_klass()) {
return new (arena()) ciTypeArrayKlass(h_k);
}
} else if (o->is_method()) {
@@ -414,6 +414,7 @@
metadata_owner_klass = m->as_method()->get_Method()->constants()->pool_holder();
} else {
fatal("Not implemented for other types of metadata");
+ return;
}
oop metadata_holder = metadata_owner_klass->klass_holder();
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -530,15 +530,15 @@
if (_imethod != NULL) {
return; // Replay Inlining
}
- Klass* k = method->method_holder();
- ((InstanceKlass*)k)->initialize(THREAD);
+ InstanceKlass* ik = method->method_holder();
+ ik->initialize(THREAD);
if (HAS_PENDING_EXCEPTION) {
oop throwable = PENDING_EXCEPTION;
java_lang_Throwable::print(throwable, tty);
tty->cr();
if (ReplayIgnoreInitErrors) {
CLEAR_PENDING_EXCEPTION;
- ((InstanceKlass*)k)->set_init_state(InstanceKlass::fully_initialized);
+ ik->set_init_state(InstanceKlass::fully_initialized);
} else {
return;
}
@@ -842,7 +842,7 @@
} else if (field_signature[0] == 'L') {
Symbol* klass_name = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
KlassHandle kelem = resolve_klass(field_signature, CHECK);
- oop value = ((InstanceKlass*)kelem())->allocate_instance(CHECK);
+ oop value = InstanceKlass::cast(kelem())->allocate_instance(CHECK);
java_mirror->obj_field_put(fd.offset(), value);
} else {
report_error("unhandled staticfield");
--- a/hotspot/src/share/vm/ci/ciSignature.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciSignature.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
// ------------------------------------------------------------------
// ciSignature::ciSignature
-ciSignature::ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* symbol) {
+ciSignature::ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* symbol) {
ASSERT_IN_VM;
EXCEPTION_CONTEXT;
_accessing_klass = accessing_klass;
--- a/hotspot/src/share/vm/ci/ciSignature.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciSignature.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
friend class ciBytecodeStream;
friend class ciObjectFactory;
- ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* signature);
+ ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* signature);
ciSignature(ciKlass* accessing_klass, ciSymbol* signature, ciMethodType* method_type);
void get_all_klasses();
--- a/hotspot/src/share/vm/ci/ciType.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciType.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@
}
ciType::ciType(KlassHandle k) : ciMetadata(k()) {
- _basic_type = k()->oop_is_array() ? T_ARRAY : T_OBJECT;
+ _basic_type = k()->is_array_klass() ? T_ARRAY : T_OBJECT;
}
--- a/hotspot/src/share/vm/ci/ciTypeArray.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciTypeArray.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,3 +46,13 @@
#endif //ASSERT
return c;
}
+
+// ------------------------------------------------------------------
+// ciTypeArray::byte_at
+//
+// Implementation of the byte_at method.
+jbyte ciTypeArray::byte_at(int index) {
+ VM_ENTRY_MARK;
+ assert(index >= 0 && index < length(), "out of range");
+ return get_typeArrayOop()->byte_at(index);
+}
--- a/hotspot/src/share/vm/ci/ciTypeArray.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciTypeArray.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,6 +56,9 @@
// array will never change.
jchar char_at(int index);
+ // Return byte at index.
+ jbyte byte_at(int index);
+
};
#endif // SHARE_VM_CI_CITYPEARRAY_HPP
--- a/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
// ------------------------------------------------------------------
// ciTypeArrayKlass::ciTypeArrayKlass
ciTypeArrayKlass::ciTypeArrayKlass(KlassHandle h_k) : ciArrayKlass(h_k) {
- assert(get_Klass()->oop_is_typeArray(), "wrong type");
+ assert(get_Klass()->is_typeArray_klass(), "wrong type");
assert(element_type() == get_TypeArrayKlass()->element_type(), "");
}
--- a/hotspot/src/share/vm/classfile/bytecodeAssembler.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/bytecodeAssembler.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -140,7 +140,7 @@
BytecodeCPEntry const& at(u2 index) const { return _entries.at(index); }
InstanceKlass* pool_holder() const {
- return InstanceKlass::cast(_orig->pool_holder());
+ return _orig->pool_holder();
}
u2 utf8(Symbol* sym) {
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -315,6 +315,7 @@
return NULL;
}
+#ifdef ASSERT
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED
void ClassFileParser::report_assert_property_failure(const char* msg, TRAPS) {
@@ -327,6 +328,7 @@
fatal(msg, index, _class_name->as_C_string());
}
PRAGMA_DIAG_POP
+#endif
constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
ClassFileStream* cfs = stream();
@@ -646,7 +648,7 @@
}
-void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
+void ClassFileParser::patch_constant_pool(const constantPoolHandle& cp, int index, Handle patch, TRAPS) {
BasicType patch_type = T_VOID;
switch (cp->tag_at(index).value()) {
@@ -822,7 +824,7 @@
debug_only(No_Safepoint_Verifier nsv;)
for (index = 0; index < length; index++) {
Klass* k = _local_interfaces->at(index);
- Symbol* name = InstanceKlass::cast(k)->name();
+ Symbol* name = k->name();
// If no duplicates, add (name, NULL) in hashtable interface_names.
if (!put_after_lookup(name, NULL, interface_names)) {
dup = true;
@@ -3175,8 +3177,9 @@
bool is_array = false;
if (_cp->tag_at(super_class_index).is_klass()) {
super_klass = instanceKlassHandle(THREAD, _cp->resolved_klass_at(super_class_index));
- if (_need_verify)
- is_array = super_klass->oop_is_array();
+ if (_need_verify) {
+ is_array = super_klass->is_array_klass();
+ }
} else if (_need_verify) {
is_array = (_cp->klass_name_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
}
@@ -3211,19 +3214,19 @@
// Field size and offset computation
int nonstatic_field_size = _super_klass() == NULL ? 0 : _super_klass()->nonstatic_field_size();
- int next_static_oop_offset;
- int next_static_double_offset;
- int next_static_word_offset;
- int next_static_short_offset;
- int next_static_byte_offset;
- int next_nonstatic_oop_offset;
- int next_nonstatic_double_offset;
- int next_nonstatic_word_offset;
- int next_nonstatic_short_offset;
- int next_nonstatic_byte_offset;
- int first_nonstatic_oop_offset;
- int next_nonstatic_field_offset;
- int next_nonstatic_padded_offset;
+ int next_static_oop_offset = 0;
+ int next_static_double_offset = 0;
+ int next_static_word_offset = 0;
+ int next_static_short_offset = 0;
+ int next_static_byte_offset = 0;
+ int next_nonstatic_oop_offset = 0;
+ int next_nonstatic_double_offset = 0;
+ int next_nonstatic_word_offset = 0;
+ int next_nonstatic_short_offset = 0;
+ int next_nonstatic_byte_offset = 0;
+ int first_nonstatic_oop_offset = 0;
+ int next_nonstatic_field_offset = 0;
+ int next_nonstatic_padded_offset = 0;
// Count the contended fields by type.
//
@@ -3376,14 +3379,14 @@
ShouldNotReachHere();
}
- int nonstatic_oop_space_count = 0;
- int nonstatic_word_space_count = 0;
- int nonstatic_short_space_count = 0;
- int nonstatic_byte_space_count = 0;
- int nonstatic_oop_space_offset;
- int nonstatic_word_space_offset;
- int nonstatic_short_space_offset;
- int nonstatic_byte_space_offset;
+ int nonstatic_oop_space_count = 0;
+ int nonstatic_word_space_count = 0;
+ int nonstatic_short_space_count = 0;
+ int nonstatic_byte_space_count = 0;
+ int nonstatic_oop_space_offset = 0;
+ int nonstatic_word_space_offset = 0;
+ int nonstatic_short_space_offset = 0;
+ int nonstatic_byte_space_offset = 0;
// Try to squeeze some of the fields into the gaps due to
// long/double alignment.
@@ -3455,7 +3458,7 @@
// contended instance fields are handled below
if (fs.is_contended() && !fs.access_flags().is_static()) continue;
- int real_offset;
+ int real_offset = 0;
FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
// pack the rest of the fields
@@ -3589,7 +3592,7 @@
// handle statics below
if (fs.access_flags().is_static()) continue;
- int real_offset;
+ int real_offset = 0;
FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
switch (atype) {
@@ -4111,7 +4114,7 @@
this_klass->set_should_verify_class(verify);
jint lh = Klass::instance_layout_helper(info.instance_size, false);
this_klass->set_layout_helper(lh);
- assert(this_klass->oop_is_instance(), "layout is correct");
+ assert(this_klass->is_instance_klass(), "layout is correct");
assert(this_klass->size_helper() == info.instance_size, "correct size_helper");
// Not yet: supers are done below to support the new subtype-checking fields
//this_klass->set_super(super_klass());
@@ -4315,13 +4318,13 @@
if (caller != NULL) {
tty->print("[Loaded %s by instance of %s]\n",
this_klass->external_name(),
- InstanceKlass::cast(caller)->external_name());
+ caller->external_name());
} else {
tty->print("[Loaded %s]\n", this_klass->external_name());
}
} else {
tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
- InstanceKlass::cast(class_loader->klass())->external_name());
+ class_loader->klass()->external_name());
}
}
@@ -4330,7 +4333,7 @@
// print out the superclass.
const char * from = this_klass()->external_name();
if (this_klass->java_super() != NULL) {
- tty->print("RESOLVE %s %s (super)\n", from, InstanceKlass::cast(this_klass->java_super())->external_name());
+ tty->print("RESOLVE %s %s (super)\n", from, this_klass->java_super()->external_name());
}
// print out each of the interface classes referred to by this class.
Array<Klass*>* local_interfaces = this_klass->local_interfaces();
@@ -4338,8 +4341,7 @@
int length = local_interfaces->length();
for (int i = 0; i < length; i++) {
Klass* k = local_interfaces->at(i);
- InstanceKlass* to_class = InstanceKlass::cast(k);
- const char * to = to_class->external_name();
+ const char * to = k->external_name();
tty->print("RESOLVE %s %s (interface)\n", from, to);
}
}
@@ -4411,7 +4413,7 @@
void ClassFileParser::print_field_layout(Symbol* name,
Array<u2>* fields,
- constantPoolHandle cp,
+ const constantPoolHandle& cp,
int instance_size,
int instance_fields_start,
int instance_fields_end,
@@ -4687,7 +4689,7 @@
vmSymbols::java_lang_IllegalAccessError(),
"class %s cannot access its superclass %s",
this_klass->external_name(),
- InstanceKlass::cast(super)->external_name()
+ super->external_name()
);
return;
}
@@ -4707,7 +4709,7 @@
vmSymbols::java_lang_IllegalAccessError(),
"class %s cannot access its superinterface %s",
this_klass->external_name(),
- InstanceKlass::cast(k)->external_name()
+ k->external_name()
);
return;
}
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -241,7 +241,7 @@
void print_field_layout(Symbol* name,
Array<u2>* fields,
- constantPoolHandle cp,
+ const constantPoolHandle& cp,
int instance_size,
int instance_fields_start,
int instance_fields_end,
@@ -319,8 +319,8 @@
if (!b) { classfile_parse_error(msg, CHECK); }
}
- void report_assert_property_failure(const char* msg, TRAPS);
- void report_assert_property_failure(const char* msg, int index, TRAPS);
+ void report_assert_property_failure(const char* msg, TRAPS) PRODUCT_RETURN;
+ void report_assert_property_failure(const char* msg, int index, TRAPS) PRODUCT_RETURN;
inline void assert_property(bool b, const char* msg, TRAPS) {
#ifdef ASSERT
@@ -403,7 +403,7 @@
assert(!has_cp_patch_at(index), "");
return patch;
}
- void patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS);
+ void patch_constant_pool(const constantPoolHandle& cp, int index, Handle patch, TRAPS);
// Wrapper for constantTag.is_klass_[or_]reference.
// In older versions of the VM, Klass*s cannot sneak into early phases of
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -140,7 +140,7 @@
void ClassLoaderData::methods_do(void f(Method*)) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
InstanceKlass::cast(k)->methods_do(f);
}
}
@@ -151,7 +151,7 @@
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
// Do not filter ArrayKlass oops here...
- if (k->oop_is_array() || (k->oop_is_instance() && InstanceKlass::cast(k)->is_loaded())) {
+ if (k->is_array_klass() || (k->is_instance_klass() && InstanceKlass::cast(k)->is_loaded())) {
klass_closure->do_klass(k);
}
}
@@ -159,7 +159,7 @@
void ClassLoaderData::classes_do(void f(InstanceKlass*)) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
f(InstanceKlass::cast(k));
}
assert(k != k->next_link(), "no loops!");
--- a/hotspot/src/share/vm/classfile/compactHashtable.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/compactHashtable.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -422,7 +422,7 @@
int HashtableTextDump::scan_string_prefix() {
// Expect /[0-9]+: /
- int utf8_length;
+ int utf8_length = 0;
get_num(':', &utf8_length);
if (*_p != ' ') {
corrupted(_p, "Wrong prefix format for string");
@@ -433,13 +433,13 @@
int HashtableTextDump::scan_symbol_prefix() {
// Expect /[0-9]+ (-|)[0-9]+: /
- int utf8_length;
+ int utf8_length = 0;
get_num(' ', &utf8_length);
- if (*_p == '-') {
- _p++;
+ if (*_p == '-') {
+ _p++;
}
int ref_num;
- (void)get_num(':', &ref_num);
+ get_num(':', &ref_num);
if (*_p != ' ') {
corrupted(_p, "Wrong prefix format for symbol");
}
--- a/hotspot/src/share/vm/classfile/dictionary.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
DictionaryEntry* entry = (DictionaryEntry*)Hashtable<Klass*, mtClass>::new_entry(hash, klass);
entry->set_loader_data(loader_data);
entry->set_pd_set(NULL);
- assert(klass->oop_is_instance(), "Must be");
+ assert(klass->is_instance_klass(), "Must be");
return entry;
}
@@ -78,7 +78,7 @@
bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {
#ifdef ASSERT
- if (protection_domain == InstanceKlass::cast(klass())->protection_domain()) {
+ if (protection_domain == klass()->protection_domain()) {
// Ensure this doesn't show up in the pd_set (invariant)
bool in_pd_set = false;
for (ProtectionDomainEntry* current = _pd_set;
@@ -96,7 +96,7 @@
}
#endif /* ASSERT */
- if (protection_domain == InstanceKlass::cast(klass())->protection_domain()) {
+ if (protection_domain == klass()->protection_domain()) {
// Succeeds trivially
return true;
}
@@ -275,7 +275,7 @@
probe != NULL;
probe = probe->next()) {
Klass* k = probe->klass();
- if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) {
+ if (probe->loader_data() == k->class_loader_data()) {
f(k);
}
}
@@ -290,7 +290,7 @@
probe != NULL;
probe = probe->next()) {
Klass* k = probe->klass();
- if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) {
+ if (probe->loader_data() == k->class_loader_data()) {
f(k, CHECK);
}
}
@@ -322,7 +322,7 @@
probe != NULL;
probe = probe->next()) {
Klass* k = probe->klass();
- if (probe->loader_data() == InstanceKlass::cast(k)->class_loader_data()) {
+ if (probe->loader_data() == k->class_loader_data()) {
// only take klass is we have the entry with the defining class loader
InstanceKlass::cast(k)->methods_do(f);
}
@@ -476,7 +476,7 @@
DictionaryEntry* p = master_list;
master_list = master_list->next();
p->set_next(NULL);
- Symbol* class_name = InstanceKlass::cast((Klass*)(p->klass()))->name();
+ Symbol* class_name = p->klass()->name();
// Since the null class loader data isn't copied to the CDS archive,
// compute the hash with NULL for loader data.
unsigned int hash = compute_hash(class_name, NULL);
@@ -723,7 +723,7 @@
Klass* e = probe->klass();
ClassLoaderData* loader_data = probe->loader_data();
bool is_defining_class =
- (loader_data == InstanceKlass::cast(e)->class_loader_data());
+ (loader_data == e->class_loader_data());
tty->print("%s%s", ((!details) || is_defining_class) ? " " : "^",
e->external_name());
@@ -756,7 +756,7 @@
probe = probe->next()) {
Klass* e = probe->klass();
ClassLoaderData* loader_data = probe->loader_data();
- guarantee(e->oop_is_instance(),
+ guarantee(e->is_instance_klass(),
"Verify of system dictionary failed");
// class loader must be present; a null class loader is the
// boostrap loader
--- a/hotspot/src/share/vm/classfile/dictionary.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -323,8 +323,7 @@
bool equals(Symbol* class_name, ClassLoaderData* loader_data) const {
Klass* klass = (Klass*)literal();
- return (InstanceKlass::cast(klass)->name() == class_name &&
- _loader_data == loader_data);
+ return (klass->name() == class_name && _loader_data == loader_data);
}
void print() {
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -114,17 +114,17 @@
// Helpful routine for computing field offsets at run time rather than hardcoding them
static void
compute_offset(int &dest_offset,
- Klass* klass_oop, Symbol* name_symbol, Symbol* signature_symbol,
+ Klass* klass, Symbol* name_symbol, Symbol* signature_symbol,
bool is_static = false, bool allow_super = false) {
fieldDescriptor fd;
- InstanceKlass* ik = InstanceKlass::cast(klass_oop);
+ InstanceKlass* ik = InstanceKlass::cast(klass);
if (!find_field(ik, name_symbol, signature_symbol, &fd, is_static, allow_super)) {
ResourceMark rm;
tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string());
#ifndef PRODUCT
- klass_oop->print();
+ ik->print();
tty->print_cr("all fields:");
- for (AllFieldStream fs(InstanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
+ for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
}
#endif //PRODUCT
@@ -136,10 +136,10 @@
// Same as above but for "optional" offsets that might not be present in certain JDK versions
static void
compute_optional_offset(int& dest_offset,
- Klass* klass_oop, Symbol* name_symbol, Symbol* signature_symbol,
+ Klass* klass, Symbol* name_symbol, Symbol* signature_symbol,
bool allow_super = false) {
fieldDescriptor fd;
- InstanceKlass* ik = InstanceKlass::cast(klass_oop);
+ InstanceKlass* ik = InstanceKlass::cast(klass);
if (find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) {
dest_offset = fd.offset();
}
@@ -147,9 +147,8 @@
int java_lang_String::value_offset = 0;
-int java_lang_String::offset_offset = 0;
-int java_lang_String::count_offset = 0;
int java_lang_String::hash_offset = 0;
+int java_lang_String::coder_offset = 0;
bool java_lang_String::initialized = false;
@@ -161,44 +160,85 @@
assert(!initialized, "offsets should be initialized only once");
Klass* k = SystemDictionary::String_klass();
- compute_offset(value_offset, k, vmSymbols::value_name(), vmSymbols::char_array_signature());
- compute_optional_offset(offset_offset, k, vmSymbols::offset_name(), vmSymbols::int_signature());
- compute_optional_offset(count_offset, k, vmSymbols::count_name(), vmSymbols::int_signature());
+ compute_offset(value_offset, k, vmSymbols::value_name(), vmSymbols::byte_array_signature());
compute_optional_offset(hash_offset, k, vmSymbols::hash_name(), vmSymbols::int_signature());
+ compute_optional_offset(coder_offset, k, vmSymbols::coder_name(), vmSymbols::byte_signature());
initialized = true;
}
-Handle java_lang_String::basic_create(int length, TRAPS) {
+class CompactStringsFixup : public FieldClosure {
+private:
+ bool _value;
+
+public:
+ CompactStringsFixup(bool value) : _value(value) {}
+
+ void do_field(fieldDescriptor* fd) {
+ if (fd->name() == vmSymbols::compact_strings_name()) {
+ oop mirror = fd->field_holder()->java_mirror();
+ assert(fd->field_holder() == SystemDictionary::String_klass(), "Should be String");
+ assert(mirror != NULL, "String must have mirror already");
+ mirror->bool_field_put(fd->offset(), _value);
+ }
+ }
+};
+
+void java_lang_String::set_compact_strings(bool value) {
+ CompactStringsFixup fix(value);
+ InstanceKlass::cast(SystemDictionary::String_klass())->do_local_static_fields(&fix);
+}
+
+Handle java_lang_String::basic_create(int length, bool is_latin1, TRAPS) {
assert(initialized, "Must be initialized");
+ assert(CompactStrings || !is_latin1, "Must be UTF16 without CompactStrings");
+
// Create the String object first, so there's a chance that the String
// and the char array it points to end up in the same cache line.
oop obj;
- obj = InstanceKlass::cast(SystemDictionary::String_klass())->allocate_instance(CHECK_NH);
+ obj = SystemDictionary::String_klass()->allocate_instance(CHECK_NH);
// Create the char array. The String object must be handlized here
// because GC can happen as a result of the allocation attempt.
Handle h_obj(THREAD, obj);
- typeArrayOop buffer;
- buffer = oopFactory::new_charArray(length, CHECK_NH);
+ int arr_length = is_latin1 ? length : length << 1; // 2 bytes per UTF16.
+ typeArrayOop buffer = oopFactory::new_byteArray(arr_length, CHECK_NH);;
// Point the String at the char array
obj = h_obj();
set_value(obj, buffer);
// No need to zero the offset, allocation zero'ed the entire String object
- assert(offset(obj) == 0, "initial String offset should be zero");
-//set_offset(obj, 0);
- set_count(obj, length);
-
+ set_coder(obj, is_latin1 ? CODER_LATIN1 : CODER_UTF16);
return h_obj;
}
Handle java_lang_String::create_from_unicode(jchar* unicode, int length, TRAPS) {
- Handle h_obj = basic_create(length, CHECK_NH);
+ bool is_latin1 = CompactStrings && UNICODE::is_latin1(unicode, length);
+ Handle h_obj = basic_create(length, is_latin1, CHECK_NH);
typeArrayOop buffer = value(h_obj());
- for (int index = 0; index < length; index++) {
- buffer->char_at_put(index, unicode[index]);
+ assert(TypeArrayKlass::cast(buffer->klass())->element_type() == T_BYTE, "only byte[]");
+ if (is_latin1) {
+ for (int index = 0; index < length; index++) {
+ buffer->byte_at_put(index, (jbyte)unicode[index]);
+ }
+ } else {
+ for (int index = 0; index < length; index++) {
+ buffer->char_at_put(index, unicode[index]);
+ }
}
+
+#ifdef ASSERT
+ {
+ ResourceMark rm;
+ char* expected = UNICODE::as_utf8(unicode, length);
+ char* actual = as_utf8_string(h_obj());
+ if (strcmp(expected, actual) != 0) {
+ tty->print_cr("Unicode conversion failure: %s --> %s", expected, actual);
+ ShouldNotReachHere();
+ }
+ }
+#endif
+
return h_obj;
}
@@ -211,11 +251,40 @@
if (utf8_str == NULL) {
return Handle();
}
- int length = UTF8::unicode_length(utf8_str);
- Handle h_obj = basic_create(length, CHECK_NH);
+ bool has_multibyte, is_latin1;
+ int length = UTF8::unicode_length(utf8_str, is_latin1, has_multibyte);
+ if (!CompactStrings) {
+ has_multibyte = true;
+ is_latin1 = false;
+ }
+
+ Handle h_obj = basic_create(length, is_latin1, CHECK_NH);
if (length > 0) {
- UTF8::convert_to_unicode(utf8_str, value(h_obj())->char_at_addr(0), length);
+ if (!has_multibyte) {
+ strncpy((char*)value(h_obj())->byte_at_addr(0), utf8_str, length);
+ } else if (is_latin1) {
+ UTF8::convert_to_unicode(utf8_str, value(h_obj())->byte_at_addr(0), length);
+ } else {
+ UTF8::convert_to_unicode(utf8_str, value(h_obj())->char_at_addr(0), length);
+ }
}
+
+#ifdef ASSERT
+ // This check is too strict because the input string is not necessarily valid UTF8.
+ // For example, it may be created with arbitrary content via jni_NewStringUTF.
+ /*
+ {
+ ResourceMark rm;
+ const char* expected = utf8_str;
+ char* actual = as_utf8_string(h_obj());
+ if (strcmp(expected, actual) != 0) {
+ tty->print_cr("String conversion failure: %s --> %s", expected, actual);
+ ShouldNotReachHere();
+ }
+ }
+ */
+#endif
+
return h_obj;
}
@@ -225,11 +294,39 @@
}
Handle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) {
- int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length());
- Handle h_obj = basic_create(length, CHECK_NH);
+ const char* utf8_str = (char*)symbol->bytes();
+ int utf8_len = symbol->utf8_length();
+
+ bool has_multibyte, is_latin1;
+ int length = UTF8::unicode_length(utf8_str, utf8_len, is_latin1, has_multibyte);
+ if (!CompactStrings) {
+ has_multibyte = true;
+ is_latin1 = false;
+ }
+
+ Handle h_obj = basic_create(length, is_latin1, CHECK_NH);
if (length > 0) {
- UTF8::convert_to_unicode((char*)symbol->bytes(), value(h_obj())->char_at_addr(0), length);
+ if (!has_multibyte) {
+ strncpy((char*)value(h_obj())->byte_at_addr(0), utf8_str, length);
+ } else if (is_latin1) {
+ UTF8::convert_to_unicode(utf8_str, value(h_obj())->byte_at_addr(0), length);
+ } else {
+ UTF8::convert_to_unicode(utf8_str, value(h_obj())->char_at_addr(0), length);
+ }
}
+
+#ifdef ASSERT
+ {
+ ResourceMark rm;
+ const char* expected = symbol->as_utf8();
+ char* actual = as_utf8_string(h_obj());
+ if (strncmp(expected, actual, utf8_len) != 0) {
+ tty->print_cr("Symbol conversion failure: %s --> %s", expected, actual);
+ ShouldNotReachHere();
+ }
+ }
+#endif
+
return h_obj;
}
@@ -261,7 +358,6 @@
// Converts a Java String to a native C string that can be used for
// native OS calls.
char* java_lang_String::as_platform_dependent_str(Handle java_string, TRAPS) {
-
typedef char* (*to_platform_string_fn_t)(JNIEnv*, jstring, bool*);
static to_platform_string_fn_t _to_platform_string_fn = NULL;
@@ -292,13 +388,15 @@
oop obj = java_string();
// Typical usage is to convert all '/' to '.' in string.
typeArrayOop value = java_lang_String::value(obj);
- int offset = java_lang_String::offset(obj);
int length = java_lang_String::length(obj);
+ bool is_latin1 = java_lang_String::is_latin1(obj);
// First check if any from_char exist
int index; // Declared outside, used later
for (index = 0; index < length; index++) {
- if (value->char_at(index + offset) == from_char) {
+ jchar c = !is_latin1 ? value->char_at(index) :
+ ((jchar) value->byte_at(index)) & 0xff;
+ if (c == from_char) {
break;
}
}
@@ -307,34 +405,66 @@
return java_string;
}
- // Create new UNICODE buffer. Must handlize value because GC
+ // Check if result string will be latin1
+ bool to_is_latin1 = false;
+
+ // Replacement char must be latin1
+ if (CompactStrings && UNICODE::is_latin1(to_char)) {
+ if (is_latin1) {
+ // Source string is latin1 as well
+ to_is_latin1 = true;
+ } else if (!UNICODE::is_latin1(from_char)) {
+ // We are replacing an UTF16 char. Scan string to
+ // check if result can be latin1 encoded.
+ to_is_latin1 = true;
+ for (index = 0; index < length; index++) {
+ jchar c = value->char_at(index);
+ if (c != from_char && !UNICODE::is_latin1(c)) {
+ to_is_latin1 = false;
+ break;
+ }
+ }
+ }
+ }
+
+ // Create new UNICODE (or byte) buffer. Must handlize value because GC
// may happen during String and char array creation.
typeArrayHandle h_value(THREAD, value);
- Handle string = basic_create(length, CHECK_NH);
-
+ Handle string = basic_create(length, to_is_latin1, CHECK_NH);
typeArrayOop from_buffer = h_value();
- typeArrayOop to_buffer = java_lang_String::value(string());
+ typeArrayOop to_buffer = java_lang_String::value(string());
// Copy contents
for (index = 0; index < length; index++) {
- jchar c = from_buffer->char_at(index + offset);
+ jchar c = (!is_latin1) ? from_buffer->char_at(index) :
+ ((jchar) from_buffer->byte_at(index)) & 0xff;
if (c == from_char) {
c = to_char;
}
- to_buffer->char_at_put(index, c);
+ if (!to_is_latin1) {
+ to_buffer->char_at_put(index, c);
+ } else {
+ to_buffer->byte_at_put(index, (jbyte) c);
+ }
}
return string;
}
jchar* java_lang_String::as_unicode_string(oop java_string, int& length, TRAPS) {
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
length = java_lang_String::length(java_string);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
jchar* result = NEW_RESOURCE_ARRAY_RETURN_NULL(jchar, length);
if (result != NULL) {
- for (int index = 0; index < length; index++) {
- result[index] = value->char_at(index + offset);
+ if (!is_latin1) {
+ for (int index = 0; index < length; index++) {
+ result[index] = value->char_at(index);
+ }
+ } else {
+ for (int index = 0; index < length; index++) {
+ result[index] = ((jchar) value->byte_at(index)) & 0xff;
+ }
}
} else {
THROW_MSG_0(vmSymbols::java_lang_OutOfMemoryError(), "could not allocate Unicode string");
@@ -348,21 +478,35 @@
if (length == 0) return 0;
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
- return java_lang_String::hash_code(value->char_at_addr(offset), length);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+
+ if (is_latin1) {
+ return java_lang_String::hash_code(value->byte_at_addr(0), length);
+ } else {
+ return java_lang_String::hash_code(value->char_at_addr(0), length);
+ }
}
char* java_lang_String::as_quoted_ascii(oop java_string) {
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
-
- jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
- if (base == NULL) return NULL;
-
- int result_length = UNICODE::quoted_ascii_length(base, length) + 1;
- char* result = NEW_RESOURCE_ARRAY(char, result_length);
- UNICODE::as_quoted_ascii(base, length, result, result_length);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+
+ if (length == 0) return NULL;
+
+ char* result;
+ int result_length;
+ if (!is_latin1) {
+ jchar* base = value->char_at_addr(0);
+ result_length = UNICODE::quoted_ascii_length(base, length) + 1;
+ result = NEW_RESOURCE_ARRAY(char, result_length);
+ UNICODE::as_quoted_ascii(base, length, result, result_length);
+ } else {
+ jbyte* base = value->byte_at_addr(0);
+ result_length = UNICODE::quoted_ascii_length(base, length) + 1;
+ result = NEW_RESOURCE_ARRAY(char, result_length);
+ UNICODE::as_quoted_ascii(base, length, result, result_length);
+ }
assert(result_length >= length + 1, "must not be shorter");
assert(result_length == (int)strlen(result) + 1, "must match");
return result;
@@ -370,89 +514,141 @@
unsigned int java_lang_String::hash_string(oop java_string) {
int length = java_lang_String::length(java_string);
- // Zero length string doesn't hash necessarily hash to zero.
+ // Zero length string doesn't necessarily hash to zero.
if (length == 0) {
- return StringTable::hash_string(NULL, 0);
+ return StringTable::hash_string((jchar*) NULL, 0);
}
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
- return StringTable::hash_string(value->char_at_addr(offset), length);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+ if (is_latin1) {
+ return StringTable::hash_string(value->byte_at_addr(0), length);
+ } else {
+ return StringTable::hash_string(value->char_at_addr(0), length);
+ }
}
Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) {
oop obj = java_string();
typeArrayOop value = java_lang_String::value(obj);
- int offset = java_lang_String::offset(obj);
int length = java_lang_String::length(obj);
- jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
- Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD);
- return sym;
+ bool is_latin1 = java_lang_String::is_latin1(obj);
+ if (!is_latin1) {
+ jchar* base = (length == 0) ? NULL : value->char_at_addr(0);
+ Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD);
+ return sym;
+ } else {
+ ResourceMark rm;
+ jbyte* position = (length == 0) ? NULL : value->byte_at_addr(0);
+ const char* base = UNICODE::as_utf8(position, length);
+ Symbol* sym = SymbolTable::lookup(base, length, THREAD);
+ return sym;
+ }
}
Symbol* java_lang_String::as_symbol_or_null(oop java_string) {
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
- jchar* base = (length == 0) ? NULL : value->char_at_addr(offset);
- return SymbolTable::probe_unicode(base, length);
-}
-
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+ if (!is_latin1) {
+ jchar* base = (length == 0) ? NULL : value->char_at_addr(0);
+ return SymbolTable::probe_unicode(base, length);
+ } else {
+ ResourceMark rm;
+ jbyte* position = (length == 0) ? NULL : value->byte_at_addr(0);
+ const char* base = UNICODE::as_utf8(position, length);
+ return SymbolTable::probe(base, length);
+ }
+}
int java_lang_String::utf8_length(oop java_string) {
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
- jchar* position = (length == 0) ? NULL : value->char_at_addr(offset);
- return UNICODE::utf8_length(position, length);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+ if (length == 0) {
+ return 0;
+ }
+ if (!is_latin1) {
+ return UNICODE::utf8_length(value->char_at_addr(0), length);
+ } else {
+ return UNICODE::utf8_length(value->byte_at_addr(0), length);
+ }
}
char* java_lang_String::as_utf8_string(oop java_string) {
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
- jchar* position = (length == 0) ? NULL : value->char_at_addr(offset);
- return UNICODE::as_utf8(position, length);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+ if (!is_latin1) {
+ jchar* position = (length == 0) ? NULL : value->char_at_addr(0);
+ return UNICODE::as_utf8(position, length);
+ } else {
+ jbyte* position = (length == 0) ? NULL : value->byte_at_addr(0);
+ return UNICODE::as_utf8(position, length);
+ }
}
char* java_lang_String::as_utf8_string(oop java_string, char* buf, int buflen) {
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
- jchar* position = (length == 0) ? NULL : value->char_at_addr(offset);
- return UNICODE::as_utf8(position, length, buf, buflen);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+ if (!is_latin1) {
+ jchar* position = (length == 0) ? NULL : value->char_at_addr(0);
+ return UNICODE::as_utf8(position, length, buf, buflen);
+ } else {
+ jbyte* position = (length == 0) ? NULL : value->byte_at_addr(0);
+ return UNICODE::as_utf8(position, length, buf, buflen);
+ }
}
char* java_lang_String::as_utf8_string(oop java_string, int start, int len) {
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
assert(start + len <= length, "just checking");
- jchar* position = value->char_at_addr(offset + start);
- return UNICODE::as_utf8(position, len);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+ if (!is_latin1) {
+ jchar* position = value->char_at_addr(start);
+ return UNICODE::as_utf8(position, len);
+ } else {
+ jbyte* position = value->byte_at_addr(start);
+ return UNICODE::as_utf8(position, len);
+ }
}
char* java_lang_String::as_utf8_string(oop java_string, int start, int len, char* buf, int buflen) {
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
assert(start + len <= length, "just checking");
- jchar* position = value->char_at_addr(offset + start);
- return UNICODE::as_utf8(position, len, buf, buflen);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+ if (!is_latin1) {
+ jchar* position = value->char_at_addr(start);
+ return UNICODE::as_utf8(position, len, buf, buflen);
+ } else {
+ jbyte* position = value->byte_at_addr(start);
+ return UNICODE::as_utf8(position, len, buf, buflen);
+ }
}
bool java_lang_String::equals(oop java_string, jchar* chars, int len) {
assert(java_string->klass() == SystemDictionary::String_klass(),
"must be java_string");
typeArrayOop value = java_lang_String::value(java_string);
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
if (length != len) {
return false;
}
- for (int i = 0; i < len; i++) {
- if (value->char_at(i + offset) != chars[i]) {
- return false;
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+ if (!is_latin1) {
+ for (int i = 0; i < len; i++) {
+ if (value->char_at(i) != chars[i]) {
+ return false;
+ }
+ }
+ } else {
+ for (int i = 0; i < len; i++) {
+ if ((((jchar) value->byte_at(i)) & 0xff) != chars[i]) {
+ return false;
+ }
}
}
return true;
@@ -464,17 +660,20 @@
assert(str2->klass() == SystemDictionary::String_klass(),
"must be java String");
typeArrayOop value1 = java_lang_String::value(str1);
- int offset1 = java_lang_String::offset(str1);
int length1 = java_lang_String::length(str1);
+ bool is_latin1 = java_lang_String::is_latin1(str1);
typeArrayOop value2 = java_lang_String::value(str2);
- int offset2 = java_lang_String::offset(str2);
int length2 = java_lang_String::length(str2);
-
- if (length1 != length2) {
+ bool is_latin2 = java_lang_String::is_latin1(str2);
+
+ if ((length1 != length2) || (is_latin1 != is_latin2)) {
+ // Strings of different size or with different
+ // coders are never equal.
return false;
}
- for (int i = 0; i < length1; i++) {
- if (value1->char_at(i + offset1) != value2->char_at(i + offset2)) {
+ int blength1 = value1->length();
+ for (int i = 0; i < value1->length(); i++) {
+ if (value1->byte_at(i) != value2->byte_at(i)) {
return false;
}
}
@@ -492,12 +691,13 @@
return;
}
- int offset = java_lang_String::offset(java_string);
int length = java_lang_String::length(java_string);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
st->print("\"");
for (int index = 0; index < length; index++) {
- st->print("%c", value->char_at(index + offset));
+ st->print("%c", (!is_latin1) ? value->char_at(index) :
+ ((jchar) value->byte_at(index)) & 0xff );
}
st->print("\"");
}
@@ -555,7 +755,7 @@
// If the offset was read from the shared archive, it was fixed up already
if (!k->is_shared()) {
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
// During bootstrap, java.lang.Class wasn't loaded so static field
// offsets were computed without the size added it. Go back and
// update all the static field offsets to included the size.
@@ -613,13 +813,13 @@
java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
// It might also have a component mirror. This mirror must already exist.
- if (k->oop_is_array()) {
+ if (k->is_array_klass()) {
Handle comp_mirror;
- if (k->oop_is_typeArray()) {
+ if (k->is_typeArray_klass()) {
BasicType type = TypeArrayKlass::cast(k())->element_type();
comp_mirror = Universe::java_mirror(type);
} else {
- assert(k->oop_is_objArray(), "Must be");
+ assert(k->is_objArray_klass(), "Must be");
Klass* element_klass = ObjArrayKlass::cast(k())->element_klass();
assert(element_klass != NULL, "Must have an element klass");
comp_mirror = element_klass->java_mirror();
@@ -631,7 +831,7 @@
set_component_mirror(mirror(), comp_mirror());
set_array_klass(comp_mirror(), k());
} else {
- assert(k->oop_is_instance(), "Must be");
+ assert(k->is_instance_klass(), "Must be");
initialize_mirror_fields(k, mirror, protection_domain, THREAD);
if (HAS_PENDING_EXCEPTION) {
@@ -770,7 +970,7 @@
name = vmSymbols::type_signature(primitive_type(java_class));
} else {
Klass* k = as_Klass(java_class);
- is_instance = k->oop_is_instance();
+ is_instance = k->is_instance_klass();
name = k->name();
}
if (name == NULL) {
@@ -793,7 +993,7 @@
name->increment_refcount();
} else {
Klass* k = as_Klass(java_class);
- if (!k->oop_is_instance()) {
+ if (!k->is_instance_klass()) {
name = k->name();
name->increment_refcount();
} else {
@@ -829,13 +1029,13 @@
Klass* java_lang_Class::array_klass(oop java_class) {
Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset));
- assert(k == NULL || k->is_klass() && k->oop_is_array(), "should be array klass");
+ assert(k == NULL || k->is_klass() && k->is_array_klass(), "should be array klass");
return k;
}
void java_lang_Class::set_array_klass(oop java_class, Klass* klass) {
- assert(klass->is_klass() && klass->oop_is_array(), "should be array klass");
+ assert(klass->is_klass() && klass->is_array_klass(), "should be array klass");
java_class->metadata_field_put(_array_klass_offset, klass);
}
@@ -1169,10 +1369,13 @@
// ("name as oop" accessor is not necessary)
-typeArrayOop java_lang_ThreadGroup::name(oop java_thread_group) {
+const char* java_lang_ThreadGroup::name(oop java_thread_group) {
oop name = java_thread_group->obj_field(_name_offset);
// ThreadGroup.name can be null
- return name == NULL ? (typeArrayOop)NULL : java_lang_String::value(name);
+ if (name != NULL) {
+ return java_lang_String::as_utf8_string(name);
+ }
+ return NULL;
}
int java_lang_ThreadGroup::nthreads(oop java_thread_group) {
@@ -1236,7 +1439,7 @@
}
oop java_lang_Throwable::unassigned_stacktrace() {
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Throwable_klass());
+ InstanceKlass* ik = SystemDictionary::Throwable_klass();
address addr = ik->static_field_addr(static_unassigned_stacktrace_offset);
if (UseCompressedOops) {
return oopDesc::load_decode_heap_oop((narrowOop *)addr);
@@ -1293,7 +1496,7 @@
ResourceMark rm;
Klass* k = throwable->klass();
assert(k != NULL, "just checking");
- st->print("%s", InstanceKlass::cast(k)->external_name());
+ st->print("%s", k->external_name());
oop msg = message(throwable);
if (msg != NULL) {
st->print(": %s", java_lang_String::as_utf8_string(msg));
@@ -1305,7 +1508,7 @@
ResourceMark rm;
Klass* k = throwable->klass();
assert(k != NULL, "just checking");
- st->print("%s", InstanceKlass::cast(k)->external_name());
+ st->print("%s", k->external_name());
oop msg = message(throwable);
if (msg != NULL) {
st->print(": %s", java_lang_String::as_utf8_string(msg));
@@ -1561,7 +1764,7 @@
st->print_cr("%s", buf);
}
-void java_lang_Throwable::print_stack_element(outputStream *st, methodHandle method, int bci) {
+void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) {
Handle mirror = method->method_holder()->java_mirror();
int method_id = method->orig_method_idnum();
int version = method->constants()->version();
@@ -1632,7 +1835,7 @@
}
}
-void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) {
+void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method, TRAPS) {
if (!StackTraceInThrowable) return;
ResourceMark rm(THREAD);
@@ -1763,7 +1966,7 @@
set_backtrace(throwable(), bt.backtrace());
}
-void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method) {
+void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method) {
// No-op if stack trace is disabled
if (!StackTraceInThrowable) {
return;
@@ -1945,7 +2148,7 @@
return element();
}
-oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
+oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) {
Handle mirror (THREAD, method->method_holder()->java_mirror());
int method_id = method->orig_method_idnum();
int cpref = method->name_index();
@@ -2506,7 +2709,7 @@
oop mirror = reflect->obj_field(_oop_offset);
Klass* k = java_lang_Class::as_Klass(mirror);
- assert(k->oop_is_instance(), "Must be");
+ assert(k->is_instance_klass(), "Must be");
// Get the constant pool back from the klass. Since class redefinition
// merges the new constant pool into the old, this is essentially the
@@ -2663,13 +2866,13 @@
// Support for java_lang_ref_Reference
HeapWord *java_lang_ref_Reference::pending_list_lock_addr() {
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass());
+ InstanceKlass* ik = SystemDictionary::Reference_klass();
address addr = ik->static_field_addr(static_lock_offset);
return (HeapWord*) addr;
}
oop java_lang_ref_Reference::pending_list_lock() {
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass());
+ InstanceKlass* ik = SystemDictionary::Reference_klass();
address addr = ik->static_field_addr(static_lock_offset);
if (UseCompressedOops) {
return oopDesc::load_decode_heap_oop((narrowOop *)addr);
@@ -2679,7 +2882,7 @@
}
HeapWord *java_lang_ref_Reference::pending_list_addr() {
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass());
+ InstanceKlass* ik = SystemDictionary::Reference_klass();
address addr = ik->static_field_addr(static_pending_offset);
// XXX This might not be HeapWord aligned, almost rather be char *.
return (HeapWord*)addr;
@@ -2702,13 +2905,13 @@
}
jlong java_lang_ref_SoftReference::clock() {
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::SoftReference_klass());
+ InstanceKlass* ik = SystemDictionary::SoftReference_klass();
jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
return *offset;
}
void java_lang_ref_SoftReference::set_clock(jlong value) {
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::SoftReference_klass());
+ InstanceKlass* ik = SystemDictionary::SoftReference_klass();
jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset);
*offset = value;
}
@@ -3033,7 +3236,7 @@
void java_security_AccessControlContext::compute_offsets() {
assert(_isPrivileged_offset == 0, "offsets should be initialized only once");
fieldDescriptor fd;
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::AccessControlContext_klass());
+ InstanceKlass* ik = SystemDictionary::AccessControlContext_klass();
if (!ik->find_local_field(vmSymbols::context_name(), vmSymbols::protectiondomain_signature(), &fd)) {
fatal("Invalid layout of java.security.AccessControlContext");
@@ -3066,9 +3269,9 @@
oop java_security_AccessControlContext::create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS) {
assert(_isPrivileged_offset != 0, "offsets should have been initialized");
// Ensure klass is initialized
- InstanceKlass::cast(SystemDictionary::AccessControlContext_klass())->initialize(CHECK_0);
+ SystemDictionary::AccessControlContext_klass()->initialize(CHECK_0);
// Allocate result
- oop result = InstanceKlass::cast(SystemDictionary::AccessControlContext_klass())->allocate_instance(CHECK_0);
+ oop result = SystemDictionary::AccessControlContext_klass()->allocate_instance(CHECK_0);
// Fill in values
result->obj_field_put(_context_offset, context());
result->obj_field_put(_privilegedContext_offset, privileged_context());
@@ -3190,7 +3393,7 @@
bool java_lang_System::has_security_manager() {
- InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::System_klass());
+ InstanceKlass* ik = SystemDictionary::System_klass();
address addr = ik->static_field_addr(static_security_offset);
if (UseCompressedOops) {
return oopDesc::load_decode_heap_oop((narrowOop *)addr) != NULL;
@@ -3541,14 +3744,13 @@
// java.lang.String
- CHECK_OFFSET("java/lang/String", java_lang_String, value, "[C");
- if (java_lang_String::has_offset_field()) {
- CHECK_OFFSET("java/lang/String", java_lang_String, offset, "I");
- CHECK_OFFSET("java/lang/String", java_lang_String, count, "I");
- }
+ CHECK_OFFSET("java/lang/String", java_lang_String, value, "[B");
if (java_lang_String::has_hash_field()) {
CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I");
}
+ if (java_lang_String::has_coder_field()) {
+ CHECK_OFFSET("java/lang/String", java_lang_String, coder, "B");
+ }
// java.lang.Class
@@ -3630,8 +3832,8 @@
#endif // PRODUCT
int InjectedField::compute_offset() {
- Klass* klass_oop = klass();
- for (AllFieldStream fs(InstanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
+ InstanceKlass* ik = InstanceKlass::cast(klass());
+ for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
if (!may_be_java && !fs.access_flags().is_internal()) {
// Only look at injected fields
continue;
@@ -3641,11 +3843,11 @@
}
}
ResourceMark rm;
- tty->print_cr("Invalid layout of %s at %s/%s%s", InstanceKlass::cast(klass_oop)->external_name(), name()->as_C_string(), signature()->as_C_string(), may_be_java ? " (may_be_java)" : "");
+ tty->print_cr("Invalid layout of %s at %s/%s%s", ik->external_name(), name()->as_C_string(), signature()->as_C_string(), may_be_java ? " (may_be_java)" : "");
#ifndef PRODUCT
- klass_oop->print();
+ ik->print();
tty->print_cr("all fields:");
- for (AllFieldStream fs(InstanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
+ for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
}
#endif //PRODUCT
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -53,28 +53,28 @@
class java_lang_String : AllStatic {
private:
static int value_offset;
- static int offset_offset;
- static int count_offset;
static int hash_offset;
+ static int coder_offset;
static bool initialized;
- static Handle basic_create(int length, TRAPS);
+ static Handle basic_create(int length, bool byte_arr, TRAPS);
- static void set_offset(oop string, int offset) {
+ static void set_coder(oop string, jbyte coder) {
assert(initialized, "Must be initialized");
- if (offset_offset > 0) {
- string->int_field_put(offset_offset, offset);
- }
- }
- static void set_count( oop string, int count) {
- assert(initialized, "Must be initialized");
- if (count_offset > 0) {
- string->int_field_put(count_offset, count);
+ if (coder_offset > 0) {
+ string->byte_field_put(coder_offset, coder);
}
}
public:
+
+ // Coders
+ enum Coder {
+ CODER_LATIN1 = 0,
+ CODER_UTF16 = 1
+ };
+
static void compute_offsets();
// Instance creation
@@ -86,37 +86,29 @@
static Handle create_from_platform_dependent_str(const char* str, TRAPS);
static Handle char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS);
- static bool has_offset_field() {
- assert(initialized, "Must be initialized");
- return (offset_offset > 0);
- }
-
- static bool has_count_field() {
- assert(initialized, "Must be initialized");
- return (count_offset > 0);
- }
-
static bool has_hash_field() {
assert(initialized, "Must be initialized");
return (hash_offset > 0);
}
+ static bool has_coder_field() {
+ assert(initialized, "Must be initialized");
+ return (coder_offset > 0);
+ }
+
+ static void set_compact_strings(bool value);
static int value_offset_in_bytes() {
assert(initialized && (value_offset > 0), "Must be initialized");
return value_offset;
}
- static int count_offset_in_bytes() {
- assert(initialized && (count_offset > 0), "Must be initialized");
- return count_offset;
- }
- static int offset_offset_in_bytes() {
- assert(initialized && (offset_offset > 0), "Must be initialized");
- return offset_offset;
- }
static int hash_offset_in_bytes() {
assert(initialized && (hash_offset > 0), "Must be initialized");
return hash_offset;
}
+ static int coder_offset_in_bytes() {
+ assert(initialized && (coder_offset > 0), "Must be initialized");
+ return coder_offset;
+ }
static void set_value_raw(oop string, typeArrayOop buffer) {
assert(initialized, "Must be initialized");
@@ -142,28 +134,30 @@
assert(is_instance(java_string), "must be java_string");
return java_string->int_field(hash_offset);
}
- static int offset(oop java_string) {
+ static bool is_latin1(oop java_string) {
assert(initialized, "Must be initialized");
assert(is_instance(java_string), "must be java_string");
- if (offset_offset > 0) {
- return java_string->int_field(offset_offset);
+ if (coder_offset > 0) {
+ jbyte coder = java_string->byte_field(coder_offset);
+ assert(CompactStrings || coder == CODER_UTF16, "Must be UTF16 without CompactStrings");
+ return coder == CODER_LATIN1;
} else {
- return 0;
+ return false;
}
}
static int length(oop java_string) {
assert(initialized, "Must be initialized");
assert(is_instance(java_string), "must be java_string");
- if (count_offset > 0) {
- return java_string->int_field(count_offset);
- } else {
- typeArrayOop value_array = ((typeArrayOop)java_string->obj_field(value_offset));
- if (value_array == NULL) {
- return 0;
- } else {
- return value_array->length();
- }
+ typeArrayOop value_array = ((typeArrayOop)java_string->obj_field(value_offset));
+ if (value_array == NULL) {
+ return 0;
}
+ int arr_length = value_array->length();
+ if (!is_latin1(java_string)) {
+ assert((arr_length & 1) == 0, "should be even for UTF16 string");
+ arr_length >>= 1; // convert number of bytes to number of elements
+ }
+ return arr_length;
}
static int utf8_length(oop java_string);
@@ -187,7 +181,7 @@
// hash P(31) from Kernighan & Ritchie
//
// For this reason, THIS ALGORITHM MUST MATCH String.hashCode().
- template <typename T> static unsigned int hash_code(T* s, int len) {
+ static unsigned int hash_code(const jchar* s, int len) {
unsigned int h = 0;
while (len-- > 0) {
h = 31*h + (unsigned int) *s;
@@ -195,7 +189,18 @@
}
return h;
}
+
+ static unsigned int hash_code(const jbyte* s, int len) {
+ unsigned int h = 0;
+ while (len-- > 0) {
+ h = 31*h + (((unsigned int) *s) & 0xFF);
+ s++;
+ }
+ return h;
+ }
+
static unsigned int hash_code(oop java_string);
+ static unsigned int latin1_hash_code(typeArrayOop value, int len);
// This is the string hash code used by the StringTable, which may be
// the same as String.hashCode or an alternate hash code.
@@ -451,7 +456,7 @@
// parent ThreadGroup
static oop parent(oop java_thread_group);
// name
- static typeArrayOop name(oop java_thread_group);
+ static const char* name(oop java_thread_group);
// ("name as oop" accessor is not necessary)
// Number of threads in group
static int nthreads(oop java_thread_group);
@@ -532,7 +537,7 @@
static Symbol* detail_message(oop throwable);
static void print_stack_element(outputStream *st, Handle mirror, int method,
int version, int bci, int cpref);
- static void print_stack_element(outputStream *st, methodHandle method, int bci);
+ static void print_stack_element(outputStream *st, const methodHandle& method, int bci);
static void print_stack_usage(Handle stream);
// Allocate space for backtrace (created but stack trace not filled in)
@@ -540,8 +545,8 @@
// Fill in current stack trace for throwable with preallocated backtrace (no GC)
static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable);
// Fill in current stack trace, can cause GC
- static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS);
- static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle());
+ static void fill_in_stack_trace(Handle throwable, const methodHandle& method, TRAPS);
+ static void fill_in_stack_trace(Handle throwable, const methodHandle& method = methodHandle());
// Programmatic access to stack trace
static oop get_stack_trace_element(oop throwable, int index, TRAPS);
static int get_stack_trace_depth(oop throwable, TRAPS);
@@ -1347,7 +1352,7 @@
// Create an instance of StackTraceElement
static oop create(Handle mirror, int method, int version, int bci, int cpref, TRAPS);
- static oop create(methodHandle method, int bci, TRAPS);
+ static oop create(const methodHandle& method, int bci, TRAPS);
// Debugging
friend class JavaClasses;
--- a/hotspot/src/share/vm/classfile/loaderConstraints.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -320,7 +320,7 @@
Handle loader) {
LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
if (p != NULL && p->klass() != NULL) {
- if (p->klass()->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) {
+ if (p->klass()->is_instance_klass() && !InstanceKlass::cast(p->klass())->is_loaded()) {
// Only return fully loaded classes. Classes found through the
// constraints might still be in the process of loading.
return NULL;
--- a/hotspot/src/share/vm/classfile/placeholders.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/placeholders.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -244,7 +244,7 @@
guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
"checking type of _loader");
guarantee(instance_klass() == NULL
- || instance_klass()->oop_is_instance(),
+ || instance_klass()->is_instance_klass(),
"checking type of instance_klass result");
}
--- a/hotspot/src/share/vm/classfile/placeholders.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/placeholders.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -220,7 +220,7 @@
}
SeenThread* actionToQueue(PlaceholderTable::classloadAction action) {
- SeenThread* queuehead;
+ SeenThread* queuehead = NULL;
switch (action) {
case PlaceholderTable::LOAD_INSTANCE:
queuehead = _loadInstanceThreadQ;
--- a/hotspot/src/share/vm/classfile/resolutionErrors.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/resolutionErrors.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
// add new entry to the table
void ResolutionErrorTable::add_entry(int index, unsigned int hash,
- constantPoolHandle pool, int cp_index,
+ const constantPoolHandle& pool, int cp_index,
Symbol* error, Symbol* message)
{
assert_locked_or_safepoint(SystemDictionary_lock);
@@ -44,7 +44,7 @@
// find entry in the table
ResolutionErrorEntry* ResolutionErrorTable::find_entry(int index, unsigned int hash,
- constantPoolHandle pool, int cp_index)
+ const constantPoolHandle& pool, int cp_index)
{
assert_locked_or_safepoint(SystemDictionary_lock);
--- a/hotspot/src/share/vm/classfile/resolutionErrors.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/resolutionErrors.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,15 +56,15 @@
}
void add_entry(int index, unsigned int hash,
- constantPoolHandle pool, int which, Symbol* error, Symbol* message);
+ const constantPoolHandle& pool, int which, Symbol* error, Symbol* message);
// find error given the constant pool and constant pool index
ResolutionErrorEntry* find_entry(int index, unsigned int hash,
- constantPoolHandle pool, int cp_index);
+ const constantPoolHandle& pool, int cp_index);
- unsigned int compute_hash(constantPoolHandle pool, int cp_index) {
+ unsigned int compute_hash(const constantPoolHandle& pool, int cp_index) {
return (unsigned int) pool->identity_hash() + cp_index;
}
--- a/hotspot/src/share/vm/classfile/stringTable.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/stringTable.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -94,11 +94,16 @@
CompactHashtable<oop, char> StringTable::_shared_table;
// Pick hashing algorithm
-unsigned int StringTable::hash_string(const jchar* s, int len) {
+template<typename T>
+unsigned int StringTable::hash_string(const T* s, int len) {
return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
java_lang_String::hash_code(s, len);
}
+// Explicit instantiation for all supported types.
+template unsigned int StringTable::hash_string<jchar>(const jchar* s, int len);
+template unsigned int StringTable::hash_string<jbyte>(const jbyte* s, int len);
+
oop StringTable::lookup_shared(jchar* name, int len) {
// java_lang_String::hash_code() was used to compute hash values in the shared table. Don't
// use the hash value from StringTable::hash_string() as it might use alternate hashcode.
@@ -409,17 +414,25 @@
for ( ; p != NULL; p = p->next()) {
oop s = p->literal();
typeArrayOop value = java_lang_String::value(s);
- int offset = java_lang_String::offset(s);
int length = java_lang_String::length(s);
+ bool is_latin1 = java_lang_String::is_latin1(s);
if (length <= 0) {
st->print("%d: ", length);
} else {
ResourceMark rm(THREAD);
- jchar* chars = (jchar*)value->char_at_addr(offset);
- int utf8_length = UNICODE::utf8_length(chars, length);
- char* utf8_string = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
- UNICODE::convert_to_utf8(chars, length, utf8_string);
+ int utf8_length;
+ char* utf8_string;
+
+ if (!is_latin1) {
+ jchar* chars = value->char_at_addr(0);
+ utf8_length = UNICODE::utf8_length(chars, length);
+ utf8_string = UNICODE::as_utf8(chars, length);
+ } else {
+ jbyte* bytes = value->byte_at_addr(0);
+ utf8_length = UNICODE::utf8_length(bytes, length);
+ utf8_string = UNICODE::as_utf8(bytes, length);
+ }
st->print("%d: ", utf8_length);
HashtableTextDump::put_utf8(st, utf8_string, utf8_length);
--- a/hotspot/src/share/vm/classfile/stringTable.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/stringTable.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -111,7 +111,7 @@
// Hashing algorithm, used as the hash value used by the
// StringTable for bucket selection and comparison (stored in the
// HashtableEntry structures). This is used in the String.intern() method.
- static unsigned int hash_string(const jchar* s, int len);
+ template<typename T> static unsigned int hash_string(const T* s, int len);
// Internal test.
static void test_alt_hash() PRODUCT_RETURN;
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -244,7 +244,7 @@
unsigned int SymbolTable::hash_symbol(const char* s, int len) {
return use_alternate_hashcode() ?
AltHashing::murmur3_32(seed(), (const jbyte*)s, len) :
- java_lang_String::hash_code(s, len);
+ java_lang_String::hash_code((const jbyte*)s, len);
}
@@ -371,7 +371,7 @@
}
}
-void SymbolTable::add(ClassLoaderData* loader_data, constantPoolHandle cp,
+void SymbolTable::add(ClassLoaderData* loader_data, const constantPoolHandle& cp,
int names_count,
const char** names, int* lengths, int* cp_indices,
unsigned int* hashValues, TRAPS) {
@@ -452,7 +452,7 @@
// This version of basic_add adds symbols in batch from the constant pool
// parsing.
-bool SymbolTable::basic_add(ClassLoaderData* loader_data, constantPoolHandle cp,
+bool SymbolTable::basic_add(ClassLoaderData* loader_data, const constantPoolHandle& cp,
int names_count,
const char** names, int* lengths,
int* cp_indices, unsigned int* hashValues,
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -100,12 +100,12 @@
Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue,
bool c_heap, TRAPS);
bool basic_add(ClassLoaderData* loader_data,
- constantPoolHandle cp, int names_count,
+ const constantPoolHandle& cp, int names_count,
const char** names, int* lengths, int* cp_indices,
unsigned int* hashValues, TRAPS);
static void new_symbols(ClassLoaderData* loader_data,
- constantPoolHandle cp, int names_count,
+ const constantPoolHandle& cp, int names_count,
const char** name, int* lengths,
int* cp_indices, unsigned int* hashValues,
TRAPS) {
@@ -165,12 +165,12 @@
// Look up the address of the literal in the SymbolTable for this Symbol*
static Symbol** lookup_symbol_addr(Symbol* sym);
- // jchar (utf16) version of lookups
+ // jchar (UTF16) version of lookups
static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
static void add(ClassLoaderData* loader_data,
- constantPoolHandle cp, int names_count,
+ const constantPoolHandle& cp, int names_count,
const char** names, int* lengths, int* cp_indices,
unsigned int* hashValues, TRAPS);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -88,10 +88,10 @@
oop SystemDictionary::_system_loader_lock_obj = NULL;
-Klass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
+InstanceKlass* SystemDictionary::_well_known_klasses[SystemDictionary::WKID_LIMIT]
= { NULL /*, NULL...*/ };
-Klass* SystemDictionary::_box_klasses[T_VOID+1] = { NULL /*, NULL...*/ };
+InstanceKlass* SystemDictionary::_box_klasses[T_VOID+1] = { NULL /*, NULL...*/ };
oop SystemDictionary::_java_system_loader = NULL;
@@ -99,7 +99,7 @@
bool SystemDictionary::_has_checkPackageAccess = false;
// lazily initialized klass variables
-Klass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL;
+InstanceKlass* volatile SystemDictionary::_abstract_ownable_synchronizer_klass = NULL;
// ----------------------------------------------------------------------------
@@ -357,7 +357,7 @@
// so we don't throw an exception here.
// see: nsk redefclass014 & java.lang.instrument Instrument032
if ((childk != NULL ) && (is_superclass) &&
- ((quicksuperk = InstanceKlass::cast(childk)->super()) != NULL) &&
+ ((quicksuperk = childk->super()) != NULL) &&
((quicksuperk->name() == class_name) &&
(quicksuperk->class_loader() == class_loader()))) {
@@ -1257,8 +1257,7 @@
}
// notify a class loaded from shared object
- ClassLoadingService::notify_class_loaded(InstanceKlass::cast(ik()),
- true /* shared class */);
+ ClassLoadingService::notify_class_loaded(ik(), true /* shared class */);
}
return ik;
}
@@ -1805,7 +1804,7 @@
Klass* k = resolve_or_fail(vmSymbols::java_util_concurrent_locks_AbstractOwnableSynchronizer(), true, CHECK);
// Force a fence to prevent any read before the write completes
OrderAccess::fence();
- _abstract_ownable_synchronizer_klass = k;
+ _abstract_ownable_synchronizer_klass = InstanceKlass::cast(k);
}
}
@@ -1846,14 +1845,16 @@
int info = wk_init_info[id - FIRST_WKID];
int sid = (info >> CEIL_LG_OPTION_LIMIT);
Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
- Klass** klassp = &_well_known_klasses[id];
+ InstanceKlass** klassp = &_well_known_klasses[id];
bool must_load = (init_opt < SystemDictionary::Opt);
if ((*klassp) == NULL) {
+ Klass* k;
if (must_load) {
- (*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class
+ k = resolve_or_fail(symbol, true, CHECK_0); // load required class
} else {
- (*klassp) = resolve_or_null(symbol, CHECK_0); // load optional klass
+ k = resolve_or_null(symbol, CHECK_0); // load optional klass
}
+ (*klassp) = (k == NULL) ? NULL : InstanceKlass::cast(k);
}
return ((*klassp) != NULL);
}
@@ -1966,7 +1967,8 @@
instanceKlassHandle k,
Handle class_loader, bool defining,
TRAPS) {
- const char *linkage_error = NULL;
+ const char *linkage_error1 = NULL;
+ const char *linkage_error2 = NULL;
{
Symbol* name = k->name();
ClassLoaderData *loader_data = class_loader_data(class_loader);
@@ -1981,10 +1983,10 @@
// system dictionary only holds instance classes, placeholders
// also holds array classes
- assert(check->oop_is_instance(), "noninstance in systemdictionary");
+ assert(check->is_instance_klass(), "noninstance in systemdictionary");
if ((defining == true) || (k() != check)) {
- linkage_error = "loader (instance of %s): attempted duplicate class "
- "definition for name: \"%s\"";
+ linkage_error1 = "loader (instance of ";
+ linkage_error2 = "): attempted duplicate class definition for name: \"";
} else {
return;
}
@@ -1995,10 +1997,10 @@
assert(ph_check == NULL || ph_check == name, "invalid symbol");
#endif
- if (linkage_error == NULL) {
+ if (linkage_error1 == NULL) {
if (constraints()->check_or_update(k, class_loader, name) == false) {
- linkage_error = "loader constraint violation: loader (instance of %s)"
- " previously initiated loading for a different type with name \"%s\"";
+ linkage_error1 = "loader constraint violation: loader (instance of ";
+ linkage_error2 = ") previously initiated loading for a different type with name \"";
}
}
}
@@ -2006,14 +2008,14 @@
// Throw error now if needed (cannot throw while holding
// SystemDictionary_lock because of rank ordering)
- if (linkage_error) {
+ if (linkage_error1) {
ResourceMark rm(THREAD);
const char* class_loader_name = loader_name(class_loader());
char* type_name = k->name()->as_C_string();
- size_t buflen = strlen(linkage_error) + strlen(class_loader_name) +
- strlen(type_name);
+ size_t buflen = strlen(linkage_error1) + strlen(class_loader_name) +
+ strlen(linkage_error2) + strlen(type_name) + 2; // +2 for '"' and null byte.
char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
- jio_snprintf(buf, buflen, linkage_error, class_loader_name, type_name);
+ jio_snprintf(buf, buflen, "%s%s%s%s\"", linkage_error1, class_loader_name, linkage_error2, type_name);
THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
}
}
@@ -2155,7 +2157,7 @@
// Add entry to resolution error table to record the error when the first
// attempt to resolve a reference to a class has failed.
-void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which,
+void SystemDictionary::add_resolution_error(const constantPoolHandle& pool, int which,
Symbol* error, Symbol* message) {
unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash);
@@ -2171,7 +2173,7 @@
}
// Lookup resolution error table. Returns error if found, otherwise NULL.
-Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which,
+Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, int which,
Symbol** message) {
unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash);
@@ -2387,13 +2389,13 @@
// Out of an abundance of caution, we do not include any other classes, not even for packages like java.util.
static bool is_always_visible_class(oop mirror) {
Klass* klass = java_lang_Class::as_Klass(mirror);
- if (klass->oop_is_objArray()) {
+ if (klass->is_objArray_klass()) {
klass = ObjArrayKlass::cast(klass)->bottom_klass(); // check element type
}
- if (klass->oop_is_typeArray()) {
+ if (klass->is_typeArray_klass()) {
return true; // primitive array
}
- assert(klass->oop_is_instance(), "%s", klass->external_name());
+ assert(klass->is_instance_klass(), "%s", klass->external_name());
return klass->is_public() &&
(InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::Object_klass()) || // java.lang
InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::MethodHandle_klass())); // java.lang.invoke
@@ -2457,9 +2459,9 @@
Klass* sel_klass = java_lang_Class::as_Klass(mirror);
mirror = NULL; // safety
// Emulate ConstantPool::verify_constant_pool_resolve.
- if (sel_klass->oop_is_objArray())
+ if (sel_klass->is_objArray_klass())
sel_klass = ObjArrayKlass::cast(sel_klass)->bottom_klass();
- if (sel_klass->oop_is_instance()) {
+ if (sel_klass->is_instance_klass()) {
KlassHandle sel_kh(THREAD, sel_klass);
LinkResolver::check_klass_accessability(accessing_klass, sel_kh, CHECK_(empty));
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -168,7 +168,7 @@
\
do_klass(StringBuffer_klass, java_lang_StringBuffer, Pre ) \
do_klass(StringBuilder_klass, java_lang_StringBuilder, Pre ) \
- do_klass(misc_Unsafe_klass, sun_misc_Unsafe, Pre ) \
+ do_klass(internal_Unsafe_klass, jdk_internal_misc_Unsafe, Pre ) \
\
/* support for CDS */ \
do_klass(ByteArrayInputStream_klass, java_io_ByteArrayInputStream, Pre ) \
@@ -403,15 +403,15 @@
static void initialize(TRAPS);
// Fast access to commonly used classes (preloaded)
- static Klass* check_klass(Klass* k) {
+ static InstanceKlass* check_klass(InstanceKlass* k) {
assert(k != NULL, "preloaded klass not initialized");
return k;
}
- static Klass* check_klass_Pre( Klass* k) { return check_klass(k); }
- static Klass* check_klass_Opt( Klass* k) { return k; }
+ static InstanceKlass* check_klass_Pre(InstanceKlass* k) { return check_klass(k); }
+ static InstanceKlass* check_klass_Opt(InstanceKlass* k) { return k; }
- JVMCI_ONLY(static Klass* check_klass_Jvmci(Klass* k) { return k; })
+ JVMCI_ONLY(static InstanceKlass* check_klass_Jvmci(InstanceKlass* k) { return k; })
static bool initialize_wk_klass(WKID id, int init_opt, TRAPS);
static void initialize_wk_klasses_until(WKID limit_id, WKID &start_id, TRAPS);
@@ -422,19 +422,19 @@
public:
#define WK_KLASS_DECLARE(name, symbol, option) \
- static Klass* name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); } \
- static Klass** name##_addr() { \
+ static InstanceKlass* name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); } \
+ static InstanceKlass** name##_addr() { \
return &SystemDictionary::_well_known_klasses[SystemDictionary::WK_KLASS_ENUM_NAME(name)]; \
}
WK_KLASSES_DO(WK_KLASS_DECLARE);
#undef WK_KLASS_DECLARE
- static Klass* well_known_klass(WKID id) {
+ static InstanceKlass* well_known_klass(WKID id) {
assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
return _well_known_klasses[id];
}
- static Klass** well_known_klass_addr(WKID id) {
+ static InstanceKlass** well_known_klass_addr(WKID id) {
assert(id >= (int)FIRST_WKID && id < (int)WKID_LIMIT, "oob");
return &_well_known_klasses[id];
}
@@ -442,7 +442,7 @@
// Local definition for direct access to the private array:
#define WK_KLASS(name) _well_known_klasses[SystemDictionary::WK_KLASS_ENUM_NAME(name)]
- static Klass* box_klass(BasicType t) {
+ static InstanceKlass* box_klass(BasicType t) {
assert((uint)t < T_VOID+1, "range check");
return check_klass(_box_klasses[t]);
}
@@ -450,7 +450,7 @@
// methods returning lazily loaded klasses
// The corresponding method to load the class must be called before calling them.
- static Klass* abstract_ownable_synchronizer_klass() { return check_klass(_abstract_ownable_synchronizer_klass); }
+ static InstanceKlass* abstract_ownable_synchronizer_klass() { return check_klass(_abstract_ownable_synchronizer_klass); }
static void load_abstract_ownable_synchronizer_klass(TRAPS);
@@ -547,10 +547,10 @@
// Record the error when the first attempt to resolve a reference from a constant
// pool entry to a class fails.
- static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error,
+ static void add_resolution_error(const constantPoolHandle& pool, int which, Symbol* error,
Symbol* message);
static void delete_resolution_error(ConstantPool* pool);
- static Symbol* find_resolution_error(constantPoolHandle pool, int which,
+ static Symbol* find_resolution_error(const constantPoolHandle& pool, int which,
Symbol** message);
protected:
@@ -700,13 +700,13 @@
TRAPS);
// Variables holding commonly used klasses (preloaded)
- static Klass* _well_known_klasses[];
+ static InstanceKlass* _well_known_klasses[];
// Lazily loaded klasses
- static Klass* volatile _abstract_ownable_synchronizer_klass;
+ static InstanceKlass* volatile _abstract_ownable_synchronizer_klass;
// table of box klasses (int_klass, etc.)
- static Klass* _box_klasses[T_VOID+1];
+ static InstanceKlass* _box_klasses[T_VOID+1];
static oop _java_system_loader;
--- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -184,7 +184,7 @@
if (HAS_PENDING_EXCEPTION) {
tty->print("Verification for %s has", klassName);
tty->print_cr(" exception pending %s ",
- InstanceKlass::cast(PENDING_EXCEPTION->klass())->external_name());
+ PENDING_EXCEPTION->klass()->external_name());
} else if (exception_name != NULL) {
tty->print_cr("Verification for %s failed", klassName);
}
@@ -605,7 +605,7 @@
}
}
-void ClassVerifier::verify_method(methodHandle m, TRAPS) {
+void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
HandleMark hm(THREAD);
_method = m; // initialize _method
if (VerboseVerification) {
@@ -1901,7 +1901,7 @@
}
void ClassVerifier::verify_cp_index(
- u2 bci, constantPoolHandle cp, int index, TRAPS) {
+ u2 bci, const constantPoolHandle& cp, int index, TRAPS) {
int nconstants = cp->length();
if ((index <= 0) || (index >= nconstants)) {
verify_error(ErrorContext::bad_cp_index(bci, index),
@@ -1912,7 +1912,7 @@
}
void ClassVerifier::verify_cp_type(
- u2 bci, int index, constantPoolHandle cp, unsigned int types, TRAPS) {
+ u2 bci, int index, const constantPoolHandle& cp, unsigned int types, TRAPS) {
// In some situations, bytecode rewriting may occur while we're verifying.
// In this case, a constant pool cache exists and some indices refer to that
@@ -1931,7 +1931,7 @@
}
void ClassVerifier::verify_cp_class_type(
- u2 bci, int index, constantPoolHandle cp, TRAPS) {
+ u2 bci, int index, const constantPoolHandle& cp, TRAPS) {
verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
constantTag tag = cp->tag_at(index);
if (!tag.is_klass() && !tag.is_unresolved_klass()) {
@@ -2023,7 +2023,7 @@
void ClassVerifier::verify_ldc(
int opcode, u2 index, StackMapFrame* current_frame,
- constantPoolHandle cp, u2 bci, TRAPS) {
+ const constantPoolHandle& cp, u2 bci, TRAPS) {
verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
constantTag tag = cp->tag_at(index);
unsigned int types;
@@ -2165,7 +2165,7 @@
void ClassVerifier::verify_field_instructions(RawBytecodeStream* bcs,
StackMapFrame* current_frame,
- constantPoolHandle cp,
+ const constantPoolHandle& cp,
bool allow_arrays,
TRAPS) {
u2 index = bcs->get_index_u2();
@@ -2477,7 +2477,7 @@
void ClassVerifier::verify_invoke_init(
RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
StackMapFrame* current_frame, u4 code_length, bool in_try_block,
- bool *this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table,
+ bool *this_uninit, const constantPoolHandle& cp, StackMapTable* stackmap_table,
TRAPS) {
u2 bci = bcs->bci();
VerificationType type = current_frame->pop_stack(
@@ -2613,7 +2613,7 @@
void ClassVerifier::verify_invoke_instructions(
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
bool in_try_block, bool *this_uninit, VerificationType return_type,
- constantPoolHandle cp, StackMapTable* stackmap_table, TRAPS) {
+ const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS) {
// Make sure the constant pool item is the right type
u2 index = bcs->get_index_u2();
Bytecodes::Code opcode = bcs->raw_code();
@@ -2878,7 +2878,7 @@
}
void ClassVerifier::verify_anewarray(
- u2 bci, u2 index, constantPoolHandle cp,
+ u2 bci, u2 index, const constantPoolHandle& cp,
StackMapFrame* current_frame, TRAPS) {
verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
current_frame->pop_stack(
--- a/hotspot/src/share/vm/classfile/verifier.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/verifier.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -262,14 +262,14 @@
ErrorContext _error_context; // contains information about an error
- void verify_method(methodHandle method, TRAPS);
+ void verify_method(const methodHandle& method, TRAPS);
char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
void verify_exception_handler_table(u4 code_length, char* code_data,
int& min, int& max, TRAPS);
void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
VerificationType cp_ref_index_to_type(
- int index, constantPoolHandle cp, TRAPS) {
+ int index, const constantPoolHandle& cp, TRAPS) {
return cp_index_to_type(cp->klass_ref_index_at(index), cp, THREAD);
}
@@ -277,10 +277,10 @@
instanceKlassHandle this_class, Klass* target_class,
Symbol* field_name, Symbol* field_sig, bool is_method);
- void verify_cp_index(u2 bci, constantPoolHandle cp, int index, TRAPS);
- void verify_cp_type(u2 bci, int index, constantPoolHandle cp,
+ void verify_cp_index(u2 bci, const constantPoolHandle& cp, int index, TRAPS);
+ void verify_cp_type(u2 bci, int index, const constantPoolHandle& cp,
unsigned int types, TRAPS);
- void verify_cp_class_type(u2 bci, int index, constantPoolHandle cp, TRAPS);
+ void verify_cp_class_type(u2 bci, int index, const constantPoolHandle& cp, TRAPS);
u2 verify_stackmap_table(
u2 stackmap_index, u2 bci, StackMapFrame* current_frame,
@@ -292,7 +292,7 @@
void verify_ldc(
int opcode, u2 index, StackMapFrame *current_frame,
- constantPoolHandle cp, u2 bci, TRAPS);
+ const constantPoolHandle& cp, u2 bci, TRAPS);
void verify_switch(
RawBytecodeStream* bcs, u4 code_length, char* code_data,
@@ -300,12 +300,12 @@
void verify_field_instructions(
RawBytecodeStream* bcs, StackMapFrame* current_frame,
- constantPoolHandle cp, bool allow_arrays, TRAPS);
+ const constantPoolHandle& cp, bool allow_arrays, TRAPS);
void verify_invoke_init(
RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
StackMapFrame* current_frame, u4 code_length, bool in_try_block,
- bool* this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table,
+ bool* this_uninit, const constantPoolHandle& cp, StackMapTable* stackmap_table,
TRAPS);
// Used by ends_in_athrow() to push all handlers that contain bci onto the
@@ -322,10 +322,10 @@
void verify_invoke_instructions(
RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
bool in_try_block, bool* this_uninit, VerificationType return_type,
- constantPoolHandle cp, StackMapTable* stackmap_table, TRAPS);
+ const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS);
VerificationType get_newarray_type(u2 index, u2 bci, TRAPS);
- void verify_anewarray(u2 bci, u2 index, constantPoolHandle cp,
+ void verify_anewarray(u2 bci, u2 index, const constantPoolHandle& cp,
StackMapFrame* current_frame, TRAPS);
void verify_return_value(
VerificationType return_type, VerificationType type, u2 offset,
@@ -406,7 +406,7 @@
int change_sig_to_verificationType(
SignatureStream* sig_type, VerificationType* inference_type, TRAPS);
- VerificationType cp_index_to_type(int index, constantPoolHandle cp, TRAPS) {
+ VerificationType cp_index_to_type(int index, const constantPoolHandle& cp, TRAPS) {
return VerificationType::reference_type(cp->klass_name_at(index));
}
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -417,7 +417,7 @@
}
}
-bool vmIntrinsics::is_disabled_by_flags(methodHandle method) {
+bool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) {
vmIntrinsics::ID id = method->intrinsic_id();
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
@@ -425,10 +425,26 @@
// the following switch statement.
if (!InlineNatives) {
switch (id) {
- case vmIntrinsics::_indexOf:
- case vmIntrinsics::_compareTo:
- case vmIntrinsics::_equals:
+ case vmIntrinsics::_indexOfL:
+ case vmIntrinsics::_indexOfU:
+ case vmIntrinsics::_indexOfUL:
+ case vmIntrinsics::_indexOfIL:
+ case vmIntrinsics::_indexOfIU:
+ case vmIntrinsics::_indexOfIUL:
+ case vmIntrinsics::_indexOfU_char:
+ case vmIntrinsics::_compareToL:
+ case vmIntrinsics::_compareToU:
+ case vmIntrinsics::_compareToLU:
+ case vmIntrinsics::_compareToUL:
+ case vmIntrinsics::_equalsL:
+ case vmIntrinsics::_equalsU:
case vmIntrinsics::_equalsC:
+ case vmIntrinsics::_getCharStringU:
+ case vmIntrinsics::_putCharStringU:
+ case vmIntrinsics::_compressStringC:
+ case vmIntrinsics::_compressStringB:
+ case vmIntrinsics::_inflateStringC:
+ case vmIntrinsics::_inflateStringB:
case vmIntrinsics::_getAndAddInt:
case vmIntrinsics::_getAndAddLong:
case vmIntrinsics::_getAndSetInt:
@@ -437,6 +453,7 @@
case vmIntrinsics::_loadFence:
case vmIntrinsics::_storeFence:
case vmIntrinsics::_fullFence:
+ case vmIntrinsics::_hasNegatives:
case vmIntrinsics::_Reference_get:
break;
default:
@@ -619,19 +636,31 @@
// intrinsic mechanism.
if (!InlineObjectCopy || !InlineArrayCopy) return true;
break;
- case vmIntrinsics::_compareTo:
+ case vmIntrinsics::_compareToL:
+ case vmIntrinsics::_compareToU:
+ case vmIntrinsics::_compareToLU:
+ case vmIntrinsics::_compareToUL:
if (!SpecialStringCompareTo) return true;
break;
- case vmIntrinsics::_indexOf:
+ case vmIntrinsics::_indexOfL:
+ case vmIntrinsics::_indexOfU:
+ case vmIntrinsics::_indexOfUL:
+ case vmIntrinsics::_indexOfIL:
+ case vmIntrinsics::_indexOfIU:
+ case vmIntrinsics::_indexOfIUL:
+ case vmIntrinsics::_indexOfU_char:
if (!SpecialStringIndexOf) return true;
break;
- case vmIntrinsics::_equals:
+ case vmIntrinsics::_equalsL:
+ case vmIntrinsics::_equalsU:
if (!SpecialStringEquals) return true;
break;
+ case vmIntrinsics::_equalsB:
case vmIntrinsics::_equalsC:
if (!SpecialArraysEquals) return true;
break;
case vmIntrinsics::_encodeISOArray:
+ case vmIntrinsics::_encodeByteISOArray:
if (!SpecialEncodeISOArray) return true;
break;
case vmIntrinsics::_getCallerClass:
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -53,6 +53,8 @@
template(java_lang_Object, "java/lang/Object") \
template(java_lang_Class, "java/lang/Class") \
template(java_lang_String, "java/lang/String") \
+ template(java_lang_StringLatin1, "java/lang/StringLatin1") \
+ template(java_lang_StringUTF16, "java/lang/StringUTF16") \
template(java_lang_Thread, "java/lang/Thread") \
template(java_lang_ThreadGroup, "java/lang/ThreadGroup") \
template(java_lang_Cloneable, "java/lang/Cloneable") \
@@ -381,9 +383,9 @@
template(park_event_name, "nativeParkEventPointer") \
template(cache_field_name, "cache") \
template(value_name, "value") \
- template(offset_name, "offset") \
- template(count_name, "count") \
template(hash_name, "hash") \
+ template(coder_name, "coder") \
+ template(compact_strings_name, "COMPACT_STRINGS") \
template(numberOfLeadingZeros_name, "numberOfLeadingZeros") \
template(numberOfTrailingZeros_name, "numberOfTrailingZeros") \
template(bitCount_name, "bitCount") \
@@ -837,22 +839,66 @@
\
do_intrinsic(_equalsC, java_util_Arrays, equals_name, equalsC_signature, F_S) \
do_signature(equalsC_signature, "([C[C)Z") \
+ do_intrinsic(_equalsB, java_util_Arrays, equals_name, equalsB_signature, F_S) \
+ do_signature(equalsB_signature, "([B[B)Z") \
\
- do_intrinsic(_compareTo, java_lang_String, compareTo_name, string_int_signature, F_R) \
+ do_intrinsic(_compressStringC, java_lang_StringUTF16, compress_name, encodeISOArray_signature, F_S) \
+ do_name( compress_name, "compress") \
+ do_intrinsic(_compressStringB, java_lang_StringUTF16, compress_name, indexOfI_signature, F_S) \
+ do_intrinsic(_inflateStringC, java_lang_StringLatin1, inflate_name, inflateC_signature, F_S) \
+ do_name( inflate_name, "inflate") \
+ do_signature(inflateC_signature, "([BI[CII)V") \
+ do_intrinsic(_inflateStringB, java_lang_StringLatin1, inflate_name, inflateB_signature, F_S) \
+ do_signature(inflateB_signature, "([BI[BII)V") \
+ do_intrinsic(_toBytesStringU, java_lang_StringUTF16, toBytes_name, toBytesU_signature, F_S) \
+ do_name( toBytes_name, "toBytes") \
+ do_signature(toBytesU_signature, "([CII)[B") \
+ do_intrinsic(_getCharsStringU, java_lang_StringUTF16, getCharsU_name, getCharsU_signature, F_S) \
+ do_name( getCharsU_name, "getChars") \
+ do_signature(getCharsU_signature, "([BII[CI)V") \
+ do_intrinsic(_getCharStringU, java_lang_StringUTF16, getChar_name, getCharStringU_signature, F_S) \
+ do_signature(getCharStringU_signature, "([BI)C") \
+ do_intrinsic(_putCharStringU, java_lang_StringUTF16, putChar_name, putCharStringU_signature, F_S) \
+ do_signature(putCharStringU_signature, "([BII)V") \
+ do_intrinsic(_compareToL, java_lang_StringLatin1,compareTo_name, compareTo_indexOf_signature, F_S) \
+ do_intrinsic(_compareToU, java_lang_StringUTF16, compareTo_name, compareTo_indexOf_signature, F_S) \
+ do_intrinsic(_compareToLU, java_lang_StringLatin1,compareToLU_name, compareTo_indexOf_signature, F_S) \
+ do_intrinsic(_compareToUL, java_lang_StringUTF16, compareToUL_name, compareTo_indexOf_signature, F_S) \
+ do_signature(compareTo_indexOf_signature, "([B[B)I") \
do_name( compareTo_name, "compareTo") \
- do_intrinsic(_indexOf, java_lang_String, indexOf_name, string_int_signature, F_R) \
+ do_name( compareToLU_name, "compareToUTF16") \
+ do_name( compareToUL_name, "compareToLatin1") \
+ do_intrinsic(_indexOfL, java_lang_StringLatin1,indexOf_name, compareTo_indexOf_signature, F_S) \
+ do_intrinsic(_indexOfU, java_lang_StringUTF16, indexOf_name, compareTo_indexOf_signature, F_S) \
+ do_intrinsic(_indexOfUL, java_lang_StringUTF16, indexOfUL_name, compareTo_indexOf_signature, F_S) \
+ do_intrinsic(_indexOfIL, java_lang_StringLatin1,indexOf_name, indexOfI_signature, F_S) \
+ do_intrinsic(_indexOfIU, java_lang_StringUTF16, indexOf_name, indexOfI_signature, F_S) \
+ do_intrinsic(_indexOfIUL, java_lang_StringUTF16, indexOfUL_name, indexOfI_signature, F_S) \
+ do_intrinsic(_indexOfU_char, java_lang_StringUTF16, indexOfChar_name, indexOfChar_signature, F_S) \
do_name( indexOf_name, "indexOf") \
- do_intrinsic(_equals, java_lang_String, equals_name, object_boolean_signature, F_R) \
+ do_name( indexOfChar_name, "indexOfChar") \
+ do_name( indexOfUL_name, "indexOfLatin1") \
+ do_signature(indexOfI_signature, "([BI[BII)I") \
+ do_signature(indexOfChar_signature, "([BIII)I") \
+ do_intrinsic(_equalsL, java_lang_StringLatin1,equals_name, equalsB_signature, F_S) \
+ do_intrinsic(_equalsU, java_lang_StringUTF16, equals_name, equalsB_signature, F_S) \
\
do_class(java_nio_Buffer, "java/nio/Buffer") \
do_intrinsic(_checkIndex, java_nio_Buffer, checkIndex_name, int_int_signature, F_R) \
do_name( checkIndex_name, "checkIndex") \
\
+ do_class(java_lang_StringCoding, "java/lang/StringCoding") \
+ do_intrinsic(_hasNegatives, java_lang_StringCoding, hasNegatives_name, hasNegatives_signature, F_S) \
+ do_name( hasNegatives_name, "hasNegatives") \
+ do_signature(hasNegatives_signature, "([BII)Z") \
+ \
do_class(sun_nio_cs_iso8859_1_Encoder, "sun/nio/cs/ISO_8859_1$Encoder") \
do_intrinsic(_encodeISOArray, sun_nio_cs_iso8859_1_Encoder, encodeISOArray_name, encodeISOArray_signature, F_S) \
do_name( encodeISOArray_name, "implEncodeISOArray") \
do_signature(encodeISOArray_signature, "([CI[BII)I") \
\
+ do_intrinsic(_encodeByteISOArray, java_lang_StringCoding, encodeISOArray_name, indexOfI_signature, F_S) \
+ \
do_class(java_math_BigInteger, "java/math/BigInteger") \
do_intrinsic(_multiplyToLen, java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_S) \
do_name( multiplyToLen_name, "implMultiplyToLen") \
@@ -942,24 +988,25 @@
do_intrinsic(_updateByteBufferAdler32, java_util_zip_Adler32, updateByteBuffer_A_name, updateByteBuffer_signature, F_SN) \
do_name( updateByteBuffer_A_name, "updateByteBuffer") \
\
- /* support for sun.misc.Unsafe */ \
- do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \
+ /* support for Unsafe */ \
+ do_class(sun_misc_Unsafe, "sun/misc/Unsafe") \
+ do_class(jdk_internal_misc_Unsafe, "jdk/internal/misc/Unsafe") \
\
- do_intrinsic(_allocateInstance, sun_misc_Unsafe, allocateInstance_name, allocateInstance_signature, F_RN) \
- do_name( allocateInstance_name, "allocateInstance") \
- do_signature(allocateInstance_signature, "(Ljava/lang/Class;)Ljava/lang/Object;") \
- do_intrinsic(_copyMemory, sun_misc_Unsafe, copyMemory_name, copyMemory_signature, F_RN) \
- do_name( copyMemory_name, "copyMemory") \
- do_signature(copyMemory_signature, "(Ljava/lang/Object;JLjava/lang/Object;JJ)V") \
- do_intrinsic(_loadFence, sun_misc_Unsafe, loadFence_name, loadFence_signature, F_RN) \
- do_name( loadFence_name, "loadFence") \
- do_alias( loadFence_signature, void_method_signature) \
- do_intrinsic(_storeFence, sun_misc_Unsafe, storeFence_name, storeFence_signature, F_RN) \
- do_name( storeFence_name, "storeFence") \
- do_alias( storeFence_signature, void_method_signature) \
- do_intrinsic(_fullFence, sun_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \
- do_name( fullFence_name, "fullFence") \
- do_alias( fullFence_signature, void_method_signature) \
+ do_intrinsic(_allocateInstance, jdk_internal_misc_Unsafe, allocateInstance_name, allocateInstance_signature, F_RN) \
+ do_name( allocateInstance_name, "allocateInstance") \
+ do_signature(allocateInstance_signature, "(Ljava/lang/Class;)Ljava/lang/Object;") \
+ do_intrinsic(_copyMemory, jdk_internal_misc_Unsafe, copyMemory_name, copyMemory_signature, F_RN) \
+ do_name( copyMemory_name, "copyMemory") \
+ do_signature(copyMemory_signature, "(Ljava/lang/Object;JLjava/lang/Object;JJ)V") \
+ do_intrinsic(_loadFence, jdk_internal_misc_Unsafe, loadFence_name, loadFence_signature, F_RN) \
+ do_name( loadFence_name, "loadFence") \
+ do_alias( loadFence_signature, void_method_signature) \
+ do_intrinsic(_storeFence, jdk_internal_misc_Unsafe, storeFence_name, storeFence_signature, F_RN) \
+ do_name( storeFence_name, "storeFence") \
+ do_alias( storeFence_signature, void_method_signature) \
+ do_intrinsic(_fullFence, jdk_internal_misc_Unsafe, fullFence_name, fullFence_signature, F_RN) \
+ do_name( fullFence_name, "fullFence") \
+ do_alias( fullFence_signature, void_method_signature) \
\
/* Custom branch frequencies profiling support for JSR292 */ \
do_class(java_lang_invoke_MethodHandleImpl, "java/lang/invoke/MethodHandleImpl") \
@@ -1000,24 +1047,24 @@
do_name(getFloat_name,"getFloat") do_name(putFloat_name,"putFloat") \
do_name(getDouble_name,"getDouble") do_name(putDouble_name,"putDouble") \
\
- do_intrinsic(_getObject, sun_misc_Unsafe, getObject_name, getObject_signature, F_RN) \
- do_intrinsic(_getBoolean, sun_misc_Unsafe, getBoolean_name, getBoolean_signature, F_RN) \
- do_intrinsic(_getByte, sun_misc_Unsafe, getByte_name, getByte_signature, F_RN) \
- do_intrinsic(_getShort, sun_misc_Unsafe, getShort_name, getShort_signature, F_RN) \
- do_intrinsic(_getChar, sun_misc_Unsafe, getChar_name, getChar_signature, F_RN) \
- do_intrinsic(_getInt, sun_misc_Unsafe, getInt_name, getInt_signature, F_RN) \
- do_intrinsic(_getLong, sun_misc_Unsafe, getLong_name, getLong_signature, F_RN) \
- do_intrinsic(_getFloat, sun_misc_Unsafe, getFloat_name, getFloat_signature, F_RN) \
- do_intrinsic(_getDouble, sun_misc_Unsafe, getDouble_name, getDouble_signature, F_RN) \
- do_intrinsic(_putObject, sun_misc_Unsafe, putObject_name, putObject_signature, F_RN) \
- do_intrinsic(_putBoolean, sun_misc_Unsafe, putBoolean_name, putBoolean_signature, F_RN) \
- do_intrinsic(_putByte, sun_misc_Unsafe, putByte_name, putByte_signature, F_RN) \
- do_intrinsic(_putShort, sun_misc_Unsafe, putShort_name, putShort_signature, F_RN) \
- do_intrinsic(_putChar, sun_misc_Unsafe, putChar_name, putChar_signature, F_RN) \
- do_intrinsic(_putInt, sun_misc_Unsafe, putInt_name, putInt_signature, F_RN) \
- do_intrinsic(_putLong, sun_misc_Unsafe, putLong_name, putLong_signature, F_RN) \
- do_intrinsic(_putFloat, sun_misc_Unsafe, putFloat_name, putFloat_signature, F_RN) \
- do_intrinsic(_putDouble, sun_misc_Unsafe, putDouble_name, putDouble_signature, F_RN) \
+ do_intrinsic(_getObject, jdk_internal_misc_Unsafe, getObject_name, getObject_signature, F_RN) \
+ do_intrinsic(_getBoolean, jdk_internal_misc_Unsafe, getBoolean_name, getBoolean_signature, F_RN) \
+ do_intrinsic(_getByte, jdk_internal_misc_Unsafe, getByte_name, getByte_signature, F_RN) \
+ do_intrinsic(_getShort, jdk_internal_misc_Unsafe, getShort_name, getShort_signature, F_RN) \
+ do_intrinsic(_getChar, jdk_internal_misc_Unsafe, getChar_name, getChar_signature, F_RN) \
+ do_intrinsic(_getInt, jdk_internal_misc_Unsafe, getInt_name, getInt_signature, F_RN) \
+ do_intrinsic(_getLong, jdk_internal_misc_Unsafe, getLong_name, getLong_signature, F_RN) \
+ do_intrinsic(_getFloat, jdk_internal_misc_Unsafe, getFloat_name, getFloat_signature, F_RN) \
+ do_intrinsic(_getDouble, jdk_internal_misc_Unsafe, getDouble_name, getDouble_signature, F_RN) \
+ do_intrinsic(_putObject, jdk_internal_misc_Unsafe, putObject_name, putObject_signature, F_RN) \
+ do_intrinsic(_putBoolean, jdk_internal_misc_Unsafe, putBoolean_name, putBoolean_signature, F_RN) \
+ do_intrinsic(_putByte, jdk_internal_misc_Unsafe, putByte_name, putByte_signature, F_RN) \
+ do_intrinsic(_putShort, jdk_internal_misc_Unsafe, putShort_name, putShort_signature, F_RN) \
+ do_intrinsic(_putChar, jdk_internal_misc_Unsafe, putChar_name, putChar_signature, F_RN) \
+ do_intrinsic(_putInt, jdk_internal_misc_Unsafe, putInt_name, putInt_signature, F_RN) \
+ do_intrinsic(_putLong, jdk_internal_misc_Unsafe, putLong_name, putLong_signature, F_RN) \
+ do_intrinsic(_putFloat, jdk_internal_misc_Unsafe, putFloat_name, putFloat_signature, F_RN) \
+ do_intrinsic(_putDouble, jdk_internal_misc_Unsafe, putDouble_name, putDouble_signature, F_RN) \
\
do_name(getObjectVolatile_name,"getObjectVolatile") do_name(putObjectVolatile_name,"putObjectVolatile") \
do_name(getBooleanVolatile_name,"getBooleanVolatile") do_name(putBooleanVolatile_name,"putBooleanVolatile") \
@@ -1029,38 +1076,38 @@
do_name(getFloatVolatile_name,"getFloatVolatile") do_name(putFloatVolatile_name,"putFloatVolatile") \
do_name(getDoubleVolatile_name,"getDoubleVolatile") do_name(putDoubleVolatile_name,"putDoubleVolatile") \
\
- do_intrinsic(_getObjectVolatile, sun_misc_Unsafe, getObjectVolatile_name, getObject_signature, F_RN) \
- do_intrinsic(_getBooleanVolatile, sun_misc_Unsafe, getBooleanVolatile_name, getBoolean_signature, F_RN) \
- do_intrinsic(_getByteVolatile, sun_misc_Unsafe, getByteVolatile_name, getByte_signature, F_RN) \
- do_intrinsic(_getShortVolatile, sun_misc_Unsafe, getShortVolatile_name, getShort_signature, F_RN) \
- do_intrinsic(_getCharVolatile, sun_misc_Unsafe, getCharVolatile_name, getChar_signature, F_RN) \
- do_intrinsic(_getIntVolatile, sun_misc_Unsafe, getIntVolatile_name, getInt_signature, F_RN) \
- do_intrinsic(_getLongVolatile, sun_misc_Unsafe, getLongVolatile_name, getLong_signature, F_RN) \
- do_intrinsic(_getFloatVolatile, sun_misc_Unsafe, getFloatVolatile_name, getFloat_signature, F_RN) \
- do_intrinsic(_getDoubleVolatile, sun_misc_Unsafe, getDoubleVolatile_name, getDouble_signature, F_RN) \
- do_intrinsic(_putObjectVolatile, sun_misc_Unsafe, putObjectVolatile_name, putObject_signature, F_RN) \
- do_intrinsic(_putBooleanVolatile, sun_misc_Unsafe, putBooleanVolatile_name, putBoolean_signature, F_RN) \
- do_intrinsic(_putByteVolatile, sun_misc_Unsafe, putByteVolatile_name, putByte_signature, F_RN) \
- do_intrinsic(_putShortVolatile, sun_misc_Unsafe, putShortVolatile_name, putShort_signature, F_RN) \
- do_intrinsic(_putCharVolatile, sun_misc_Unsafe, putCharVolatile_name, putChar_signature, F_RN) \
- do_intrinsic(_putIntVolatile, sun_misc_Unsafe, putIntVolatile_name, putInt_signature, F_RN) \
- do_intrinsic(_putLongVolatile, sun_misc_Unsafe, putLongVolatile_name, putLong_signature, F_RN) \
- do_intrinsic(_putFloatVolatile, sun_misc_Unsafe, putFloatVolatile_name, putFloat_signature, F_RN) \
- do_intrinsic(_putDoubleVolatile, sun_misc_Unsafe, putDoubleVolatile_name, putDouble_signature, F_RN) \
+ do_intrinsic(_getObjectVolatile, jdk_internal_misc_Unsafe, getObjectVolatile_name, getObject_signature, F_RN) \
+ do_intrinsic(_getBooleanVolatile, jdk_internal_misc_Unsafe, getBooleanVolatile_name, getBoolean_signature, F_RN) \
+ do_intrinsic(_getByteVolatile, jdk_internal_misc_Unsafe, getByteVolatile_name, getByte_signature, F_RN) \
+ do_intrinsic(_getShortVolatile, jdk_internal_misc_Unsafe, getShortVolatile_name, getShort_signature, F_RN) \
+ do_intrinsic(_getCharVolatile, jdk_internal_misc_Unsafe, getCharVolatile_name, getChar_signature, F_RN) \
+ do_intrinsic(_getIntVolatile, jdk_internal_misc_Unsafe, getIntVolatile_name, getInt_signature, F_RN) \
+ do_intrinsic(_getLongVolatile, jdk_internal_misc_Unsafe, getLongVolatile_name, getLong_signature, F_RN) \
+ do_intrinsic(_getFloatVolatile, jdk_internal_misc_Unsafe, getFloatVolatile_name, getFloat_signature, F_RN) \
+ do_intrinsic(_getDoubleVolatile, jdk_internal_misc_Unsafe, getDoubleVolatile_name, getDouble_signature, F_RN) \
+ do_intrinsic(_putObjectVolatile, jdk_internal_misc_Unsafe, putObjectVolatile_name, putObject_signature, F_RN) \
+ do_intrinsic(_putBooleanVolatile, jdk_internal_misc_Unsafe, putBooleanVolatile_name, putBoolean_signature, F_RN) \
+ do_intrinsic(_putByteVolatile, jdk_internal_misc_Unsafe, putByteVolatile_name, putByte_signature, F_RN) \
+ do_intrinsic(_putShortVolatile, jdk_internal_misc_Unsafe, putShortVolatile_name, putShort_signature, F_RN) \
+ do_intrinsic(_putCharVolatile, jdk_internal_misc_Unsafe, putCharVolatile_name, putChar_signature, F_RN) \
+ do_intrinsic(_putIntVolatile, jdk_internal_misc_Unsafe, putIntVolatile_name, putInt_signature, F_RN) \
+ do_intrinsic(_putLongVolatile, jdk_internal_misc_Unsafe, putLongVolatile_name, putLong_signature, F_RN) \
+ do_intrinsic(_putFloatVolatile, jdk_internal_misc_Unsafe, putFloatVolatile_name, putFloat_signature, F_RN) \
+ do_intrinsic(_putDoubleVolatile, jdk_internal_misc_Unsafe, putDoubleVolatile_name, putDouble_signature, F_RN) \
\
do_name(getShortUnaligned_name,"getShortUnaligned") do_name(putShortUnaligned_name,"putShortUnaligned") \
do_name(getCharUnaligned_name,"getCharUnaligned") do_name(putCharUnaligned_name,"putCharUnaligned") \
do_name(getIntUnaligned_name,"getIntUnaligned") do_name(putIntUnaligned_name,"putIntUnaligned") \
do_name(getLongUnaligned_name,"getLongUnaligned") do_name(putLongUnaligned_name,"putLongUnaligned") \
\
- do_intrinsic(_getShortUnaligned, sun_misc_Unsafe, getShortUnaligned_name, getShort_signature, F_R) \
- do_intrinsic(_getCharUnaligned, sun_misc_Unsafe, getCharUnaligned_name, getChar_signature, F_R) \
- do_intrinsic(_getIntUnaligned, sun_misc_Unsafe, getIntUnaligned_name, getInt_signature, F_R) \
- do_intrinsic(_getLongUnaligned, sun_misc_Unsafe, getLongUnaligned_name, getLong_signature, F_R) \
- do_intrinsic(_putShortUnaligned, sun_misc_Unsafe, putShortUnaligned_name, putShort_signature, F_R) \
- do_intrinsic(_putCharUnaligned, sun_misc_Unsafe, putCharUnaligned_name, putChar_signature, F_R) \
- do_intrinsic(_putIntUnaligned, sun_misc_Unsafe, putIntUnaligned_name, putInt_signature, F_R) \
- do_intrinsic(_putLongUnaligned, sun_misc_Unsafe, putLongUnaligned_name, putLong_signature, F_R) \
+ do_intrinsic(_getShortUnaligned, jdk_internal_misc_Unsafe, getShortUnaligned_name, getShort_signature, F_R) \
+ do_intrinsic(_getCharUnaligned, jdk_internal_misc_Unsafe, getCharUnaligned_name, getChar_signature, F_R) \
+ do_intrinsic(_getIntUnaligned, jdk_internal_misc_Unsafe, getIntUnaligned_name, getInt_signature, F_R) \
+ do_intrinsic(_getLongUnaligned, jdk_internal_misc_Unsafe, getLongUnaligned_name, getLong_signature, F_R) \
+ do_intrinsic(_putShortUnaligned, jdk_internal_misc_Unsafe, putShortUnaligned_name, putShort_signature, F_R) \
+ do_intrinsic(_putCharUnaligned, jdk_internal_misc_Unsafe, putCharUnaligned_name, putChar_signature, F_R) \
+ do_intrinsic(_putIntUnaligned, jdk_internal_misc_Unsafe, putIntUnaligned_name, putInt_signature, F_R) \
+ do_intrinsic(_putLongUnaligned, jdk_internal_misc_Unsafe, putLongUnaligned_name, putLong_signature, F_R) \
\
/* %%% these are redundant except perhaps for getAddress, but Unsafe has native methods for them */ \
do_signature(getByte_raw_signature, "(J)B") \
@@ -1082,66 +1129,67 @@
do_name( getAddress_name, "getAddress") \
do_name( putAddress_name, "putAddress") \
\
- do_intrinsic(_getByte_raw, sun_misc_Unsafe, getByte_name, getByte_raw_signature, F_RN) \
- do_intrinsic(_getShort_raw, sun_misc_Unsafe, getShort_name, getShort_raw_signature, F_RN) \
- do_intrinsic(_getChar_raw, sun_misc_Unsafe, getChar_name, getChar_raw_signature, F_RN) \
- do_intrinsic(_getInt_raw, sun_misc_Unsafe, getInt_name, long_int_signature, F_RN) \
- do_intrinsic(_getLong_raw, sun_misc_Unsafe, getLong_name, getLong_raw_signature, F_RN) \
- do_intrinsic(_getFloat_raw, sun_misc_Unsafe, getFloat_name, getFloat_raw_signature, F_RN) \
- do_intrinsic(_getDouble_raw, sun_misc_Unsafe, getDouble_name, getDouble_raw_signature, F_RN) \
- do_intrinsic(_getAddress_raw, sun_misc_Unsafe, getAddress_name, getAddress_raw_signature, F_RN) \
- do_intrinsic(_putByte_raw, sun_misc_Unsafe, putByte_name, putByte_raw_signature, F_RN) \
- do_intrinsic(_putShort_raw, sun_misc_Unsafe, putShort_name, putShort_raw_signature, F_RN) \
- do_intrinsic(_putChar_raw, sun_misc_Unsafe, putChar_name, putChar_raw_signature, F_RN) \
- do_intrinsic(_putInt_raw, sun_misc_Unsafe, putInt_name, putInt_raw_signature, F_RN) \
- do_intrinsic(_putLong_raw, sun_misc_Unsafe, putLong_name, putLong_raw_signature, F_RN) \
- do_intrinsic(_putFloat_raw, sun_misc_Unsafe, putFloat_name, putFloat_raw_signature, F_RN) \
- do_intrinsic(_putDouble_raw, sun_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_RN) \
- do_intrinsic(_putAddress_raw, sun_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_RN) \
+ do_intrinsic(_getByte_raw, jdk_internal_misc_Unsafe, getByte_name, getByte_raw_signature, F_R) \
+ do_intrinsic(_getShort_raw, jdk_internal_misc_Unsafe, getShort_name, getShort_raw_signature, F_R) \
+ do_intrinsic(_getChar_raw, jdk_internal_misc_Unsafe, getChar_name, getChar_raw_signature, F_R) \
+ do_intrinsic(_getInt_raw, jdk_internal_misc_Unsafe, getInt_name, long_int_signature, F_R) \
+ do_intrinsic(_getLong_raw, jdk_internal_misc_Unsafe, getLong_name, getLong_raw_signature, F_R) \
+ do_intrinsic(_getFloat_raw, jdk_internal_misc_Unsafe, getFloat_name, getFloat_raw_signature, F_R) \
+ do_intrinsic(_getDouble_raw, jdk_internal_misc_Unsafe, getDouble_name, getDouble_raw_signature, F_R) \
+ do_intrinsic(_getAddress_raw, jdk_internal_misc_Unsafe, getAddress_name, getAddress_raw_signature, F_R) \
+ do_intrinsic(_putByte_raw, jdk_internal_misc_Unsafe, putByte_name, putByte_raw_signature, F_R) \
+ do_intrinsic(_putShort_raw, jdk_internal_misc_Unsafe, putShort_name, putShort_raw_signature, F_R) \
+ do_intrinsic(_putChar_raw, jdk_internal_misc_Unsafe, putChar_name, putChar_raw_signature, F_R) \
+ do_intrinsic(_putInt_raw, jdk_internal_misc_Unsafe, putInt_name, putInt_raw_signature, F_R) \
+ do_intrinsic(_putLong_raw, jdk_internal_misc_Unsafe, putLong_name, putLong_raw_signature, F_R) \
+ do_intrinsic(_putFloat_raw, jdk_internal_misc_Unsafe, putFloat_name, putFloat_raw_signature, F_R) \
+ do_intrinsic(_putDouble_raw, jdk_internal_misc_Unsafe, putDouble_name, putDouble_raw_signature, F_R) \
+ do_intrinsic(_putAddress_raw, jdk_internal_misc_Unsafe, putAddress_name, putAddress_raw_signature, F_R) \
\
- do_intrinsic(_compareAndSwapObject, sun_misc_Unsafe, compareAndSwapObject_name, compareAndSwapObject_signature, F_RN) \
- do_name( compareAndSwapObject_name, "compareAndSwapObject") \
- do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \
- do_intrinsic(_compareAndSwapLong, sun_misc_Unsafe, compareAndSwapLong_name, compareAndSwapLong_signature, F_RN) \
- do_name( compareAndSwapLong_name, "compareAndSwapLong") \
- do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \
- do_intrinsic(_compareAndSwapInt, sun_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_RN) \
- do_name( compareAndSwapInt_name, "compareAndSwapInt") \
- do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \
- do_intrinsic(_putOrderedObject, sun_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_RN) \
- do_name( putOrderedObject_name, "putOrderedObject") \
- do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \
- do_intrinsic(_putOrderedLong, sun_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_RN) \
- do_name( putOrderedLong_name, "putOrderedLong") \
- do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \
- do_intrinsic(_putOrderedInt, sun_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_RN) \
- do_name( putOrderedInt_name, "putOrderedInt") \
- do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \
+ do_intrinsic(_compareAndSwapObject, jdk_internal_misc_Unsafe, compareAndSwapObject_name, compareAndSwapObject_signature, F_R) \
+ do_name( compareAndSwapObject_name, "compareAndSwapObject") \
+ do_signature(compareAndSwapObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \
+ do_intrinsic(_compareAndSwapLong, jdk_internal_misc_Unsafe, compareAndSwapLong_name, compareAndSwapLong_signature, F_R) \
+ do_name( compareAndSwapLong_name, "compareAndSwapLong") \
+ do_signature(compareAndSwapLong_signature, "(Ljava/lang/Object;JJJ)Z") \
+ do_intrinsic(_compareAndSwapInt, jdk_internal_misc_Unsafe, compareAndSwapInt_name, compareAndSwapInt_signature, F_R) \
+ do_name( compareAndSwapInt_name, "compareAndSwapInt") \
+ do_signature(compareAndSwapInt_signature, "(Ljava/lang/Object;JII)Z") \
+ do_intrinsic(_putOrderedObject, jdk_internal_misc_Unsafe, putOrderedObject_name, putOrderedObject_signature, F_R) \
+ do_name( putOrderedObject_name, "putOrderedObject") \
+ do_alias( putOrderedObject_signature, /*(LObject;JLObject;)V*/ putObject_signature) \
+ do_intrinsic(_putOrderedLong, jdk_internal_misc_Unsafe, putOrderedLong_name, putOrderedLong_signature, F_R) \
+ do_name( putOrderedLong_name, "putOrderedLong") \
+ do_alias( putOrderedLong_signature, /*(Ljava/lang/Object;JJ)V*/ putLong_signature) \
+ do_intrinsic(_putOrderedInt, jdk_internal_misc_Unsafe, putOrderedInt_name, putOrderedInt_signature, F_R) \
+ do_name( putOrderedInt_name, "putOrderedInt") \
+ do_alias( putOrderedInt_signature, /*(Ljava/lang/Object;JI)V*/ putInt_signature) \
\
- do_intrinsic(_getAndAddInt, sun_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \
- do_name( getAndAddInt_name, "getAndAddInt") \
- do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \
- do_intrinsic(_getAndAddLong, sun_misc_Unsafe, getAndAddLong_name, getAndAddLong_signature, F_R) \
- do_name( getAndAddLong_name, "getAndAddLong") \
- do_signature(getAndAddLong_signature, "(Ljava/lang/Object;JJ)J" ) \
- do_intrinsic(_getAndSetInt, sun_misc_Unsafe, getAndSetInt_name, getAndSetInt_signature, F_R) \
- do_name( getAndSetInt_name, "getAndSetInt") \
- do_alias( getAndSetInt_signature, /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature) \
- do_intrinsic(_getAndSetLong, sun_misc_Unsafe, getAndSetLong_name, getAndSetLong_signature, F_R) \
- do_name( getAndSetLong_name, "getAndSetLong") \
- do_alias( getAndSetLong_signature, /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature) \
- do_intrinsic(_getAndSetObject, sun_misc_Unsafe, getAndSetObject_name, getAndSetObject_signature, F_R)\
- do_name( getAndSetObject_name, "getAndSetObject") \
- do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
- \
- /* (2) Bytecode intrinsics */ \
- \
- do_intrinsic(_park, sun_misc_Unsafe, park_name, park_signature, F_RN) \
- do_name( park_name, "park") \
- do_signature(park_signature, "(ZJ)V") \
- do_intrinsic(_unpark, sun_misc_Unsafe, unpark_name, unpark_signature, F_RN) \
- do_name( unpark_name, "unpark") \
- do_alias( unpark_signature, /*(LObject;)V*/ object_void_signature) \
+ do_intrinsic(_getAndAddInt, jdk_internal_misc_Unsafe, getAndAddInt_name, getAndAddInt_signature, F_R) \
+ do_name( getAndAddInt_name, "getAndAddInt") \
+ do_signature(getAndAddInt_signature, "(Ljava/lang/Object;JI)I" ) \
+ do_intrinsic(_getAndAddLong, jdk_internal_misc_Unsafe, getAndAddLong_name, getAndAddLong_signature, F_R) \
+ do_name( getAndAddLong_name, "getAndAddLong") \
+ do_signature(getAndAddLong_signature, "(Ljava/lang/Object;JJ)J" ) \
+ do_intrinsic(_getAndSetInt, jdk_internal_misc_Unsafe, getAndSetInt_name, getAndSetInt_signature, F_R) \
+ do_name( getAndSetInt_name, "getAndSetInt") \
+ do_alias( getAndSetInt_signature, /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature) \
+ do_intrinsic(_getAndSetLong, jdk_internal_misc_Unsafe, getAndSetLong_name, getAndSetLong_signature, F_R) \
+ do_name( getAndSetLong_name, "getAndSetLong") \
+ do_alias( getAndSetLong_signature, /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature) \
+ do_intrinsic(_getAndSetObject, jdk_internal_misc_Unsafe, getAndSetObject_name, getAndSetObject_signature, F_R)\
+ do_name( getAndSetObject_name, "getAndSetObject") \
+ do_signature(getAndSetObject_signature, "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
+ \
+ /* (2) Bytecode intrinsics */ \
+ \
+ do_intrinsic(_park, jdk_internal_misc_Unsafe, park_name, park_signature, F_R) \
+ do_name( park_name, "park") \
+ do_signature(park_signature, "(ZJ)V") \
+ do_intrinsic(_unpark, jdk_internal_misc_Unsafe, unpark_name, unpark_signature, F_R) \
+ do_name( unpark_name, "unpark") \
+ do_alias( unpark_signature, /*(LObject;)V*/ object_void_signature) \
+ \
do_intrinsic(_StringBuilder_void, java_lang_StringBuilder, object_initializer_name, void_method_signature, F_R) \
do_intrinsic(_StringBuilder_int, java_lang_StringBuilder, object_initializer_name, int_void_signature, F_R) \
do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature, F_R) \
@@ -1406,7 +1454,7 @@
// Returns true if a compiler intrinsic is disabled by command-line flags
// and false otherwise.
- static bool is_disabled_by_flags(methodHandle method);
+ static bool is_disabled_by_flags(const methodHandle& method);
};
#endif // SHARE_VM_CLASSFILE_VMSYMBOLS_HPP
--- a/hotspot/src/share/vm/code/compiledIC.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/code/compiledIC.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -462,7 +462,7 @@
// is_optimized: Compiler has generated an optimized call (i.e., no inline
// cache) static_bound: The call can be static bound (i.e, no need to use
// inline cache)
-void CompiledIC::compute_monomorphic_entry(methodHandle method,
+void CompiledIC::compute_monomorphic_entry(const methodHandle& method,
KlassHandle receiver_klass,
bool is_optimized,
bool static_bound,
@@ -594,7 +594,7 @@
// Compute settings for a CompiledStaticCall. Since we might have to set
// the stub when calling to the interpreter, we need to return arguments.
-void CompiledStaticCall::compute_entry(methodHandle m, StaticCallInfo& info) {
+void CompiledStaticCall::compute_entry(const methodHandle& m, StaticCallInfo& info) {
nmethod* m_code = m->code();
info._callee = m;
if (m_code != NULL && m_code->is_in_use()) {
--- a/hotspot/src/share/vm/code/compiledIC.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/code/compiledIC.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -222,7 +222,7 @@
// allocation in the code cache fails.
bool set_to_megamorphic(CallInfo* call_info, Bytecodes::Code bytecode, TRAPS);
- static void compute_monomorphic_entry(methodHandle method, KlassHandle receiver_klass,
+ static void compute_monomorphic_entry(const methodHandle& method, KlassHandle receiver_klass,
bool is_optimized, bool static_bound, CompiledICInfo& info, TRAPS);
// Location
@@ -324,7 +324,7 @@
void set(const StaticCallInfo& info);
// Compute entry point given a method
- static void compute_entry(methodHandle m, StaticCallInfo& info);
+ static void compute_entry(const methodHandle& m, StaticCallInfo& info);
// Stub support
address find_stub();
--- a/hotspot/src/share/vm/code/debugInfoRec.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/code/debugInfoRec.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -324,7 +324,7 @@
// must call add_safepoint before: it sets PcDesc and this routine uses
// the last PcDesc set
void DebugInformationRecorder::describe_scope(int pc_offset,
- methodHandle methodH,
+ const methodHandle& methodH,
ciMethod* method,
int bci,
bool reexecute,
--- a/hotspot/src/share/vm/code/debugInfoRec.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/code/debugInfoRec.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@
// by add_non_safepoint, and the locals, expressions, and monitors
// must all be null.
void describe_scope(int pc_offset,
- methodHandle methodH,
+ const methodHandle& methodH,
ciMethod* method,
int bci,
bool reexecute,
--- a/hotspot/src/share/vm/code/dependencies.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/code/dependencies.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -151,7 +151,7 @@
}
void Dependencies::assert_leaf_type(Klass* ctxk) {
- if (ctxk->oop_is_array()) {
+ if (ctxk->is_array_klass()) {
// As a special case, support this assertion on an array type,
// which reduces to an assertion on its element type.
// Note that this cannot be done with assertions that
@@ -1084,10 +1084,10 @@
return true; // Must punt the assertion to true.
Klass* k = ctxk;
Method* lm = k->lookup_method(m->name(), m->signature());
- if (lm == NULL && k->oop_is_instance()) {
+ if (lm == NULL && k->is_instance_klass()) {
// It might be an interface method
- lm = ((InstanceKlass*)k)->lookup_method_in_ordered_interfaces(m->name(),
- m->signature());
+ lm = InstanceKlass::cast(k)->lookup_method_in_ordered_interfaces(m->name(),
+ m->signature());
}
if (lm == m)
// Method m is inherited into ctxk.
@@ -1135,7 +1135,7 @@
bool is_witness(Klass* k) {
if (doing_subtype_search()) {
return Dependencies::is_concrete_klass(k);
- } else if (!k->oop_is_instance()) {
+ } else if (!k->is_instance_klass()) {
return false; // no methods to find in an array type
} else {
// Search class hierarchy first.
@@ -1840,20 +1840,20 @@
Klass* k = str.klass();
switch (str.change_type()) {
case Change_new_type:
- tty->print_cr(" dependee = %s", InstanceKlass::cast(k)->external_name());
+ tty->print_cr(" dependee = %s", k->external_name());
break;
case Change_new_sub:
if (!WizardMode) {
++nsup;
} else {
- tty->print_cr(" context super = %s", InstanceKlass::cast(k)->external_name());
+ tty->print_cr(" context super = %s", k->external_name());
}
break;
case Change_new_impl:
if (!WizardMode) {
++nint;
} else {
- tty->print_cr(" context interface = %s", InstanceKlass::cast(k)->external_name());
+ tty->print_cr(" context interface = %s", k->external_name());
}
break;
}
@@ -1885,7 +1885,7 @@
case Change_new_sub:
// 6598190: brackets workaround Sun Studio C++ compiler bug 6629277
{
- _klass = InstanceKlass::cast(_klass)->super();
+ _klass = _klass->super();
if (_klass != NULL) {
return true;
}
@@ -1931,7 +1931,7 @@
}
bool KlassDepChange::involves_context(Klass* k) {
- if (k == NULL || !k->oop_is_instance()) {
+ if (k == NULL || !k->is_instance_klass()) {
return false;
}
InstanceKlass* ik = InstanceKlass::cast(k);
--- a/hotspot/src/share/vm/code/dependencies.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/code/dependencies.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -351,7 +351,7 @@
#if INCLUDE_JVMCI
private:
static void check_ctxk(Klass* ctxk) {
- assert(ctxk->oop_is_instance(), "java types only");
+ assert(ctxk->is_instance_klass(), "java types only");
}
static void check_ctxk_abstract(Klass* ctxk) {
check_ctxk(ctxk);
--- a/hotspot/src/share/vm/code/nmethod.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/code/nmethod.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -558,7 +558,7 @@
#endif
}
-nmethod* nmethod::new_native_nmethod(methodHandle method,
+nmethod* nmethod::new_native_nmethod(const methodHandle& method,
int compile_id,
CodeBuffer *code_buffer,
int vep_offset,
@@ -593,7 +593,7 @@
return nm;
}
-nmethod* nmethod::new_nmethod(methodHandle method,
+nmethod* nmethod::new_nmethod(const methodHandle& method,
int compile_id,
int entry_bci,
CodeOffsets* offsets,
@@ -1350,20 +1350,17 @@
// Unregister must be done before the state change
Universe::heap()->unregister_nmethod(this);
+ _state = unloaded;
+
#if INCLUDE_JVMCI
// The method can only be unloaded after the pointer to the installed code
// Java wrapper is no longer alive. Here we need to clear out this weak
// reference to the dead object. Nulling out the reference has to happen
// after the method is unregistered since the original value may be still
// tracked by the rset.
- if (_jvmci_installed_code != NULL) {
- InstalledCode::set_address(_jvmci_installed_code, 0);
- _jvmci_installed_code = NULL;
- }
+ maybe_invalidate_installed_code();
#endif
- _state = unloaded;
-
// Log the unloading.
log_state_change();
@@ -1525,12 +1522,8 @@
} else {
assert(state == not_entrant, "other cases may need to be handled differently");
}
-#if INCLUDE_JVMCI
- if (_jvmci_installed_code != NULL) {
- // Break the link between nmethod and InstalledCode such that the nmethod can subsequently be flushed safely.
- InstalledCode::set_address(_jvmci_installed_code, 0);
- }
-#endif
+
+ JVMCI_ONLY(maybe_invalidate_installed_code());
if (TraceCreateZombies) {
ResourceMark m;
@@ -1615,7 +1608,11 @@
// During GC the is_alive closure is non-NULL, and is used to
// determine liveness of dependees that need to be updated.
if (is_alive == NULL || klass->is_loader_alive(is_alive)) {
- InstanceKlass::cast(klass)->remove_dependent_nmethod(this);
+ // The GC defers deletion of this entry, since there might be multiple threads
+ // iterating over the _dependencies graph. Other call paths are single-threaded
+ // and may delete it immediately.
+ bool delete_immediately = is_alive == NULL;
+ InstanceKlass::cast(klass)->remove_dependent_nmethod(this, delete_immediately);
}
}
}
@@ -3004,7 +3001,7 @@
deps.print_dependency();
Klass* ctxk = deps.context_type();
if (ctxk != NULL) {
- if (ctxk->oop_is_instance() && ((InstanceKlass*)ctxk)->is_dependent_nmethod(this)) {
+ if (ctxk->is_instance_klass() && InstanceKlass::cast(ctxk)->is_dependent_nmethod(this)) {
tty->print_cr(" [nmethod<=klass]%s", ctxk->external_name());
}
}
@@ -3384,6 +3381,22 @@
#endif // !PRODUCT
#if INCLUDE_JVMCI
+void nmethod::maybe_invalidate_installed_code() {
+ if (_jvmci_installed_code != NULL) {
+ if (!is_alive()) {
+ // Break the link between nmethod and InstalledCode such that the nmethod
+ // can subsequently be flushed safely. The link must be maintained while
+ // the method could have live activations since invalidateInstalledCode
+ // might want to invalidate all existing activations.
+ InstalledCode::set_address(_jvmci_installed_code, 0);
+ InstalledCode::set_entryPoint(_jvmci_installed_code, 0);
+ _jvmci_installed_code = NULL;
+ } else if (is_not_entrant()) {
+ InstalledCode::set_entryPoint(_jvmci_installed_code, 0);
+ }
+ }
+}
+
char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) {
if (!this->is_compiled_by_jvmci()) {
return NULL;
--- a/hotspot/src/share/vm/code/nmethod.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/code/nmethod.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -307,7 +307,7 @@
public:
// create nmethod with entry_bci
- static nmethod* new_nmethod(methodHandle method,
+ static nmethod* new_nmethod(const methodHandle& method,
int compile_id,
int entry_bci,
CodeOffsets* offsets,
@@ -327,7 +327,7 @@
#endif
);
- static nmethod* new_native_nmethod(methodHandle method,
+ static nmethod* new_native_nmethod(const methodHandle& method,
int compile_id,
CodeBuffer *code_buffer,
int vep_offset,
@@ -603,6 +603,7 @@
oop jvmci_installed_code() { return _jvmci_installed_code ; }
char* jvmci_installed_code_name(char* buf, size_t buflen);
void set_jvmci_installed_code(oop installed_code) { _jvmci_installed_code = installed_code; }
+ void maybe_invalidate_installed_code();
oop speculation_log() { return _speculation_log ; }
void set_speculation_log(oop speculation_log) { _speculation_log = speculation_log; }
#endif
--- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -111,7 +111,7 @@
// Missing feature tests
virtual bool supports_native() { return true; }
virtual bool supports_osr () { return true; }
- virtual bool can_compile_method(methodHandle method) { return true; }
+ virtual bool can_compile_method(const methodHandle& method) { return true; }
// Determine if the current compiler provides an intrinsic
// for method 'method'. An intrinsic is available if:
@@ -138,7 +138,7 @@
// GraphBuilder::GraphBuilder() in src/share/vm/c1/c1_GraphBuilder.cpp
// for more details.
- virtual bool is_intrinsic_available(methodHandle method, DirectiveSet* directive) {
+ virtual bool is_intrinsic_available(const methodHandle& method, DirectiveSet* directive) {
return is_intrinsic_supported(method) &&
!directive->is_intrinsic_disabled(method) &&
!vmIntrinsics::is_disabled_by_flags(method);
@@ -152,7 +152,7 @@
// by default no intrinsics are supported by a compiler except
// the ones listed in the method. Overriding methods should conform
// to this behavior.
- virtual bool is_intrinsic_supported(methodHandle method) {
+ virtual bool is_intrinsic_supported(const methodHandle& method) {
return false;
}
@@ -162,6 +162,9 @@
bool is_jvmci() { return _type == jvmci; }
bool is_shark() { return _type == shark; }
+ // Extra tests to identify trivial methods for the tiered compilation policy.
+ virtual bool is_trivial(Method* method) { return false; }
+
// Customization
virtual void initialize () = 0;
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -790,10 +790,10 @@
// CompileBroker::compile_method
//
// Request compilation of a method.
-void CompileBroker::compile_method_base(methodHandle method,
+void CompileBroker::compile_method_base(const methodHandle& method,
int osr_bci,
int comp_level,
- methodHandle hot_method,
+ const methodHandle& hot_method,
int hot_count,
const char* comment,
Thread* thread) {
@@ -803,7 +803,7 @@
}
guarantee(!method->is_abstract(), "cannot compile abstract methods");
- assert(method->method_holder()->oop_is_instance(),
+ assert(method->method_holder()->is_instance_klass(),
"sanity check");
assert(!method->method_holder()->is_not_initialized(),
"method holder must be initialized");
@@ -993,12 +993,12 @@
}
-nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
+nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
int comp_level,
- methodHandle hot_method, int hot_count,
+ const methodHandle& hot_method, int hot_count,
const char* comment, Thread* THREAD) {
// make sure arguments make sense
- assert(method->method_holder()->oop_is_instance(), "not an instance method");
+ assert(method->method_holder()->is_instance_klass(), "not an instance method");
assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range");
assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods");
assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized");
@@ -1134,9 +1134,9 @@
// CompileBroker::compilation_is_complete
//
// See if compilation of this method is already complete.
-bool CompileBroker::compilation_is_complete(methodHandle method,
- int osr_bci,
- int comp_level) {
+bool CompileBroker::compilation_is_complete(const methodHandle& method,
+ int osr_bci,
+ int comp_level) {
bool is_osr = (osr_bci != standard_entry_bci);
if (is_osr) {
if (method->is_not_osr_compilable(comp_level)) {
@@ -1167,7 +1167,7 @@
* versa). This can be remedied by a full queue search to disambiguate
* cases. If it is deemed profitable, this may be done.
*/
-bool CompileBroker::compilation_is_in_queue(methodHandle method) {
+bool CompileBroker::compilation_is_in_queue(const methodHandle& method) {
return method->queued_for_compilation();
}
@@ -1175,7 +1175,7 @@
// CompileBroker::compilation_is_prohibited
//
// See if this compilation is not allowed.
-bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level) {
+bool CompileBroker::compilation_is_prohibited(const methodHandle& method, int osr_bci, int comp_level) {
bool is_native = method->is_native();
// Some compilers may not support the compilation of natives.
AbstractCompiler *comp = compiler(comp_level);
@@ -1222,7 +1222,7 @@
* and the ID is not within the specified range, the method is not compiled and 0 is returned.
* The function also allows to generate separate compilation IDs for OSR compilations.
*/
-int CompileBroker::assign_compile_id(methodHandle method, int osr_bci) {
+int CompileBroker::assign_compile_id(const methodHandle& method, int osr_bci) {
#ifdef ASSERT
bool is_osr = (osr_bci != standard_entry_bci);
int id;
@@ -1257,7 +1257,7 @@
// CompileBroker::assign_compile_id_unlocked
//
// Public wrapper for assign_compile_id that acquires the needed locks
-uint CompileBroker::assign_compile_id_unlocked(Thread* thread, methodHandle method, int osr_bci) {
+uint CompileBroker::assign_compile_id_unlocked(Thread* thread, const methodHandle& method, int osr_bci) {
MutexLocker locker(MethodCompileQueue_lock, thread);
return assign_compile_id(method, osr_bci);
}
@@ -1274,7 +1274,7 @@
// ------------------------------------------------------------------
// CompileBroker::preload_classes
-void CompileBroker::preload_classes(methodHandle method, TRAPS) {
+void CompileBroker::preload_classes(const methodHandle& method, TRAPS) {
// Move this code over from c1_Compiler.cpp
ShouldNotReachHere();
}
@@ -1285,15 +1285,15 @@
//
// Create a CompileTask object representing the current request for
// compilation. Add this task to the queue.
-CompileTask* CompileBroker::create_compile_task(CompileQueue* queue,
- int compile_id,
- methodHandle method,
- int osr_bci,
- int comp_level,
- methodHandle hot_method,
- int hot_count,
- const char* comment,
- bool blocking) {
+CompileTask* CompileBroker::create_compile_task(CompileQueue* queue,
+ int compile_id,
+ const methodHandle& method,
+ int osr_bci,
+ int comp_level,
+ const methodHandle& hot_method,
+ int hot_count,
+ const char* comment,
+ bool blocking) {
CompileTask* new_task = CompileTask::allocate();
new_task->initialize(compile_id, method, osr_bci, comp_level,
hot_method, hot_count, comment,
@@ -1891,7 +1891,7 @@
// CompileBroker::set_last_compile
//
// Record this compilation for debugging purposes.
-void CompileBroker::set_last_compile(CompilerThread* thread, methodHandle method, bool is_osr, int comp_level) {
+void CompileBroker::set_last_compile(CompilerThread* thread, const methodHandle& method, bool is_osr, int comp_level) {
ResourceMark rm;
char* method_name = method->name()->as_C_string();
strncpy(_last_method_compiled, method_name, CompileBroker::name_buffer_length);
@@ -2242,4 +2242,3 @@
st->cr();
#endif
}
-
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -145,7 +145,7 @@
// Compile type Information for print_last_compile() and CompilerCounters
enum { no_compile, normal_compile, osr_compile, native_compile };
- static int assign_compile_id (methodHandle method, int osr_bci);
+ static int assign_compile_id (const methodHandle& method, int osr_bci);
private:
@@ -218,33 +218,33 @@
static JavaThread* make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters, AbstractCompiler* comp, bool compiler_thread, TRAPS);
static void init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count);
- static bool compilation_is_complete (methodHandle method, int osr_bci, int comp_level);
- static bool compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level);
+ static bool compilation_is_complete (const methodHandle& method, int osr_bci, int comp_level);
+ static bool compilation_is_prohibited(const methodHandle& method, int osr_bci, int comp_level);
static bool is_compile_blocking();
- static void preload_classes (methodHandle method, TRAPS);
+ static void preload_classes (const methodHandle& method, TRAPS);
- static CompileTask* create_compile_task(CompileQueue* queue,
- int compile_id,
- methodHandle method,
- int osr_bci,
- int comp_level,
- methodHandle hot_method,
- int hot_count,
- const char* comment,
- bool blocking);
+ static CompileTask* create_compile_task(CompileQueue* queue,
+ int compile_id,
+ const methodHandle& method,
+ int osr_bci,
+ int comp_level,
+ const methodHandle& hot_method,
+ int hot_count,
+ const char* comment,
+ bool blocking);
static void wait_for_completion(CompileTask* task);
static void invoke_compiler_on_method(CompileTask* task);
static void post_compile(CompilerThread* thread, CompileTask* task, EventCompilation& event, bool success, ciEnv* ci_env);
- static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level);
+ static void set_last_compile(CompilerThread *thread, const methodHandle& method, bool is_osr, int comp_level);
static void push_jni_handle_block();
static void pop_jni_handle_block();
static void collect_statistics(CompilerThread* thread, elapsedTimer time, CompileTask* task);
- static void compile_method_base(methodHandle method,
+ static void compile_method_base(const methodHandle& method,
int osr_bci,
int comp_level,
- methodHandle hot_method,
+ const methodHandle& hot_method,
int hot_count,
const char* comment,
Thread* thread);
@@ -269,7 +269,7 @@
return NULL;
}
- static bool compilation_is_in_queue(methodHandle method);
+ static bool compilation_is_in_queue(const methodHandle& method);
static void print_compile_queues(outputStream* st);
static void print_directives(outputStream* st);
static int queue_size(int comp_level) {
@@ -278,15 +278,15 @@
}
static void compilation_init();
static void init_compiler_thread_log();
- static nmethod* compile_method(methodHandle method,
+ static nmethod* compile_method(const methodHandle& method,
int osr_bci,
int comp_level,
- methodHandle hot_method,
+ const methodHandle& hot_method,
int hot_count,
const char* comment, Thread* thread);
// Acquire any needed locks and assign a compile id
- static uint assign_compile_id_unlocked(Thread* thread, methodHandle method, int osr_bci);
+ static uint assign_compile_id_unlocked(Thread* thread, const methodHandle& method, int osr_bci);
static void compiler_thread_loop();
static uint get_compilation_id() { return _compilation_id; }
--- a/hotspot/src/share/vm/compiler/compileTask.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/compileTask.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -76,10 +76,10 @@
void CompileTask::initialize(int compile_id,
- methodHandle method,
+ const methodHandle& method,
int osr_bci,
int comp_level,
- methodHandle hot_method,
+ const methodHandle& hot_method,
int hot_count,
const char* comment,
bool is_blocking) {
--- a/hotspot/src/share/vm/compiler/compileTask.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/compileTask.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -71,8 +71,8 @@
_lock = new Monitor(Mutex::nonleaf+2, "CompileTaskLock");
}
- void initialize(int compile_id, methodHandle method, int osr_bci, int comp_level,
- methodHandle hot_method, int hot_count, const char* comment,
+ void initialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level,
+ const methodHandle& hot_method, int hot_count, const char* comment,
bool is_blocking);
static CompileTask* allocate();
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -317,7 +317,7 @@
}
template<typename T>
-bool CompilerOracle::has_option_value(methodHandle method, const char* option, T& value) {
+bool CompilerOracle::has_option_value(const methodHandle& method, const char* option, T& value) {
if (option_list != NULL) {
TypedMethodOptionMatcher* m = option_list->match(method, option, get_type_for<T>());
if (m != NULL) {
@@ -333,19 +333,19 @@
}
// Explicit instantiation for all OptionTypes supported.
-template bool CompilerOracle::has_option_value<intx>(methodHandle method, const char* option, intx& value);
-template bool CompilerOracle::has_option_value<uintx>(methodHandle method, const char* option, uintx& value);
-template bool CompilerOracle::has_option_value<bool>(methodHandle method, const char* option, bool& value);
-template bool CompilerOracle::has_option_value<ccstr>(methodHandle method, const char* option, ccstr& value);
-template bool CompilerOracle::has_option_value<double>(methodHandle method, const char* option, double& value);
+template bool CompilerOracle::has_option_value<intx>(const methodHandle& method, const char* option, intx& value);
+template bool CompilerOracle::has_option_value<uintx>(const methodHandle& method, const char* option, uintx& value);
+template bool CompilerOracle::has_option_value<bool>(const methodHandle& method, const char* option, bool& value);
+template bool CompilerOracle::has_option_value<ccstr>(const methodHandle& method, const char* option, ccstr& value);
+template bool CompilerOracle::has_option_value<double>(const methodHandle& method, const char* option, double& value);
-bool CompilerOracle::has_option_string(methodHandle method, const char* option) {
+bool CompilerOracle::has_option_string(const methodHandle& method, const char* option) {
bool value = false;
has_option_value(method, option, value);
return value;
}
-bool CompilerOracle::should_exclude(methodHandle method) {
+bool CompilerOracle::should_exclude(const methodHandle& method) {
if (check_predicate(ExcludeCommand, method)) {
return true;
}
@@ -355,15 +355,15 @@
return false;
}
-bool CompilerOracle::should_inline(methodHandle method) {
+bool CompilerOracle::should_inline(const methodHandle& method) {
return (check_predicate(InlineCommand, method));
}
-bool CompilerOracle::should_not_inline(methodHandle method) {
+bool CompilerOracle::should_not_inline(const methodHandle& method) {
return check_predicate(DontInlineCommand, method) || check_predicate(ExcludeCommand, method);
}
-bool CompilerOracle::should_print(methodHandle method) {
+bool CompilerOracle::should_print(const methodHandle& method) {
return check_predicate(PrintCommand, method);
}
@@ -371,13 +371,13 @@
return lists[PrintCommand] != NULL;
}
-bool CompilerOracle::should_log(methodHandle method) {
+bool CompilerOracle::should_log(const methodHandle& method) {
if (!LogCompilation) return false;
if (lists[LogCommand] == NULL) return true; // by default, log all
return (check_predicate(LogCommand, method));
}
-bool CompilerOracle::should_break_at(methodHandle method) {
+bool CompilerOracle::should_break_at(const methodHandle& method) {
return check_predicate(BreakCommand, method);
}
@@ -757,7 +757,7 @@
stream.cr();
}
-void CompilerOracle::append_exclude_to_file(methodHandle method) {
+void CompilerOracle::append_exclude_to_file(const methodHandle& method) {
assert(has_command_file(), "command file must be specified");
fileStream stream(fopen(cc_file(), "at"));
stream.print("exclude ");
--- a/hotspot/src/share/vm/compiler/compilerOracle.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/compilerOracle.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,31 +46,31 @@
static void parse_from_file();
// Tells whether we to exclude compilation of method
- static bool should_exclude(methodHandle method);
+ static bool should_exclude(const methodHandle& method);
static bool should_exclude_quietly() { return _quiet; }
// Tells whether we want to inline this method
- static bool should_inline(methodHandle method);
+ static bool should_inline(const methodHandle& method);
// Tells whether we want to disallow inlining of this method
- static bool should_not_inline(methodHandle method);
+ static bool should_not_inline(const methodHandle& method);
// Tells whether we should print the assembly for this method
- static bool should_print(methodHandle method);
+ static bool should_print(const methodHandle& method);
// Tells whether we should log the compilation data for this method
- static bool should_log(methodHandle method);
+ static bool should_log(const methodHandle& method);
// Tells whether to break when compiling method
- static bool should_break_at(methodHandle method);
+ static bool should_break_at(const methodHandle& method);
// Check to see if this method has option set for it
- static bool has_option_string(methodHandle method, const char * option);
+ static bool has_option_string(const methodHandle& method, const char * option);
// Check if method has option and value set. If yes, overwrite value and return true,
// otherwise leave value unchanged and return false.
template<typename T>
- static bool has_option_value(methodHandle method, const char* option, T& value);
+ static bool has_option_value(const methodHandle& method, const char* option, T& value);
// Fast check if there is any option available that compile control needs to know about
static bool has_any_option();
@@ -83,7 +83,7 @@
// For updating the oracle file
static void append_comment_to_file(const char* message);
- static void append_exclude_to_file(methodHandle method);
+ static void append_exclude_to_file(const methodHandle& method);
// Tells whether there are any methods to print for print_method_statistics()
static bool should_print_methods();
--- a/hotspot/src/share/vm/compiler/disassembler.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -86,6 +86,12 @@
os::jvm_path(buf, sizeof(buf));
int jvm_offset = -1;
int lib_offset = -1;
+#ifdef STATIC_BUILD
+ char* p = strrchr(buf, '/');
+ *p = '\0';
+ strcat(p, "/lib/");
+ lib_offset = jvm_offset = strlen(buf);
+#else
{
// Match "jvm[^/]*" in jvm_path.
const char* base = buf;
@@ -94,6 +100,7 @@
p = strstr(p ? p : base, "jvm");
if (p != NULL) jvm_offset = p - base;
}
+#endif
// Find the disassembler shared library.
// Search for several paths derived from libjvm, in this order:
// 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so (for compatibility)
--- a/hotspot/src/share/vm/compiler/methodMatcher.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/methodMatcher.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -306,7 +306,7 @@
}
}
-bool MethodMatcher::matches(methodHandle method) const {
+bool MethodMatcher::matches(const methodHandle& method) const {
Symbol* class_name = method->method_holder()->name();
Symbol* method_name = method->name();
Symbol* signature = method->signature();
@@ -362,7 +362,7 @@
return bm;
}
-bool BasicMatcher::match(methodHandle method) {
+bool BasicMatcher::match(const methodHandle& method) {
for (BasicMatcher* current = this; current != NULL; current = current->next()) {
if (current->matches(method)) {
return true;
@@ -391,7 +391,7 @@
return im;
}
-bool InlineMatcher::match(methodHandle method, int inline_action) {
+bool InlineMatcher::match(const methodHandle& method, int inline_action) {
for (InlineMatcher* current = this; current != NULL; current = current->next()) {
if (current->matches(method)) {
return (current->_inline_action == inline_action);
--- a/hotspot/src/share/vm/compiler/methodMatcher.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/methodMatcher.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -60,7 +60,7 @@
void init(Symbol* class_name, Mode class_mode, Symbol* method_name, Mode method_mode, Symbol* signature);
static void parse_method_pattern(char*& line, const char*& error_msg, MethodMatcher* m);
static void print_symbol(outputStream* st, Symbol* h, Mode mode);
- bool matches(methodHandle method) const;
+ bool matches(const methodHandle& method) const;
void print_base(outputStream* st);
private:
@@ -82,7 +82,7 @@
}
static BasicMatcher* parse_method_pattern(char* line, const char*& error_msg);
- bool match(methodHandle method);
+ bool match(const methodHandle& method);
void set_next(BasicMatcher* next) { _next = next; }
BasicMatcher* next() { return _next; }
@@ -113,7 +113,7 @@
public:
static InlineMatcher* parse_method_pattern(char* line, const char*& error_msg);
- bool match(methodHandle method, int inline_action);
+ bool match(const methodHandle& method, int inline_action);
void print(outputStream* st);
void set_next(InlineMatcher* next) { _next = next; }
InlineMatcher* next() { return _next; }
--- a/hotspot/src/share/vm/compiler/oopMap.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/compiler/oopMap.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -73,8 +73,8 @@
// Constructors
OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
- OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg,t); }
- OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg,t); set_content_reg(reg2); }
+ OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg, t); set_content_reg(VMRegImpl::Bad()); }
+ OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg, t); set_content_reg(reg2); }
OopMapValue (CompressedReadStream* stream) { read_from(stream); }
// Archiving
@@ -87,7 +87,7 @@
void read_from(CompressedReadStream* stream) {
set_value(stream->read_int());
- if(is_callee_saved() || is_derived_oop()) {
+ if (is_callee_saved() || is_derived_oop()) {
set_content_reg(VMRegImpl::as_VMReg(stream->read_int(), true));
}
}
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -73,11 +73,7 @@
}
// Constructor
-CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
- MemRegion mr, bool use_adaptive_freelists,
- FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
- _dictionaryChoice(dictionaryChoice),
- _adaptive_freelists(use_adaptive_freelists),
+CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr) :
_bt(bs, mr),
// free list locks are in the range of values taken by _lockRank
// This range currently is [_leaf+2, _leaf+3]
@@ -100,48 +96,17 @@
"FreeChunk is larger than expected");
_bt.set_space(this);
initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
- // We have all of "mr", all of which we place in the dictionary
- // as one big chunk. We'll need to decide here which of several
- // possible alternative dictionary implementations to use. For
- // now the choice is easy, since we have only one working
- // implementation, namely, the simple binary tree (splaying
- // temporarily disabled).
- switch (dictionaryChoice) {
- case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree:
- _dictionary = new AFLBinaryTreeDictionary(mr);
- break;
- case FreeBlockDictionary<FreeChunk>::dictionarySplayTree:
- case FreeBlockDictionary<FreeChunk>::dictionarySkipList:
- default:
- warning("dictionaryChoice: selected option not understood; using"
- " default BinaryTreeDictionary implementation instead.");
- }
+
+ _dictionary = new AFLBinaryTreeDictionary(mr);
+
assert(_dictionary != NULL, "CMS dictionary initialization");
// The indexed free lists are initially all empty and are lazily
// filled in on demand. Initialize the array elements to NULL.
initializeIndexedFreeListArray();
- // Not using adaptive free lists assumes that allocation is first
- // from the linAB's. Also a cms perm gen which can be compacted
- // has to have the klass's klassKlass allocated at a lower
- // address in the heap than the klass so that the klassKlass is
- // moved to its new location before the klass is moved.
- // Set the _refillSize for the linear allocation blocks
- if (!use_adaptive_freelists) {
- FreeChunk* fc = _dictionary->get_chunk(mr.word_size(),
- FreeBlockDictionary<FreeChunk>::atLeast);
- // The small linAB initially has all the space and will allocate
- // a chunk of any size.
- HeapWord* addr = (HeapWord*) fc;
- _smallLinearAllocBlock.set(addr, fc->size() ,
- 1024*SmallForLinearAlloc, fc->size());
- // Note that _unallocated_block is not updated here.
- // Allocations from the linear allocation block should
- // update it.
- } else {
- _smallLinearAllocBlock.set(0, 0, 1024*SmallForLinearAlloc,
- SmallForLinearAlloc);
- }
+ _smallLinearAllocBlock.set(0, 0, 1024*SmallForLinearAlloc,
+ SmallForLinearAlloc);
+
// CMSIndexedFreeListReplenish should be at least 1
CMSIndexedFreeListReplenish = MAX2((uintx)1, CMSIndexedFreeListReplenish);
_promoInfo.setSpace(this);
@@ -297,22 +262,7 @@
MemRegion mr(compaction_top(), end());
reset(mr);
// Now refill the linear allocation block(s) if possible.
- if (_adaptive_freelists) {
- refillLinearAllocBlocksIfNeeded();
- } else {
- // Place as much of mr in the linAB as we can get,
- // provided it was big enough to go into the dictionary.
- FreeChunk* fc = dictionary()->find_largest_dict();
- if (fc != NULL) {
- assert(fc->size() == mr.word_size(),
- "Why was the chunk broken up?");
- removeChunkFromDictionary(fc);
- HeapWord* addr = (HeapWord*) fc;
- _smallLinearAllocBlock.set(addr, fc->size() ,
- 1024*SmallForLinearAlloc, fc->size());
- // Note that _unallocated_block is not updated here.
- }
- }
+ refillLinearAllocBlocksIfNeeded();
}
// Walks the entire dictionary, returning a coterminal
@@ -445,8 +395,7 @@
// dump_memory_block(_smallLinearAllocBlock->_ptr, 128);
- st->print_cr(" _fitStrategy = %s, _adaptive_freelists = %s",
- _fitStrategy?"true":"false", _adaptive_freelists?"true":"false");
+ st->print_cr(" _fitStrategy = %s", BOOL_TO_STR(_fitStrategy));
}
void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st)
@@ -617,23 +566,9 @@
// Now, take this new chunk and add it to the free blocks.
// Note that the BOT has not yet been updated for this block.
size_t newFcSize = pointer_delta(value, prevEnd);
- // XXX This is REALLY UGLY and should be fixed up. XXX
- if (!_adaptive_freelists && _smallLinearAllocBlock._ptr == NULL) {
- // Mark the boundary of the new block in BOT
- _bt.mark_block(prevEnd, value);
- // put it all in the linAB
- MutexLockerEx x(parDictionaryAllocLock(),
- Mutex::_no_safepoint_check_flag);
- _smallLinearAllocBlock._ptr = prevEnd;
- _smallLinearAllocBlock._word_size = newFcSize;
- repairLinearAllocBlock(&_smallLinearAllocBlock);
- // Births of chunks put into a LinAB are not recorded. Births
- // of chunks as they are allocated out of a LinAB are.
- } else {
- // Add the block to the free lists, if possible coalescing it
- // with the last free block, and update the BOT and census data.
- addChunkToFreeListsAtEndRecordingStats(prevEnd, newFcSize);
- }
+ // Add the block to the free lists, if possible coalescing it
+ // with the last free block, and update the BOT and census data.
+ addChunkToFreeListsAtEndRecordingStats(prevEnd, newFcSize);
}
}
}
@@ -1177,11 +1112,7 @@
assert(size == adjustObjectSize(size),
"use adjustObjectSize() before calling into allocate()");
- if (_adaptive_freelists) {
- res = allocate_adaptive_freelists(size);
- } else { // non-adaptive free lists
- res = allocate_non_adaptive_freelists(size);
- }
+ res = allocate_adaptive_freelists(size);
if (res != NULL) {
// check that res does lie in this space!
@@ -1203,27 +1134,6 @@
return res;
}
-HeapWord* CompactibleFreeListSpace::allocate_non_adaptive_freelists(size_t size) {
- HeapWord* res = NULL;
- // try and use linear allocation for smaller blocks
- if (size < _smallLinearAllocBlock._allocation_size_limit) {
- // if successful, the following also adjusts block offset table
- res = getChunkFromSmallLinearAllocBlock(size);
- }
- // Else triage to indexed lists for smaller sizes
- if (res == NULL) {
- if (size < SmallForDictionary) {
- res = (HeapWord*) getChunkFromIndexedFreeList(size);
- } else {
- // else get it from the big dictionary; if even this doesn't
- // work we are out of luck.
- res = (HeapWord*)getChunkFromDictionaryExact(size);
- }
- }
-
- return res;
-}
-
HeapWord* CompactibleFreeListSpace::allocate_adaptive_freelists(size_t size) {
assert_lock_strong(freelistLock());
HeapWord* res = NULL;
@@ -1281,9 +1191,6 @@
// bigLAB or a smallLAB plus refilling a PromotionInfo object. MinChunkSize
// is added because the dictionary may over-allocate to avoid fragmentation.
size_t space = obj_size;
- if (!_adaptive_freelists) {
- space = MAX2(space, _smallLinearAllocBlock._refillSize);
- }
space += _promoInfo.refillSize() + 2 * MinChunkSize;
return space;
}
@@ -1698,11 +1605,7 @@
size_t size = fc->size();
_bt.verify_single_block((HeapWord*) fc, size);
_bt.verify_not_unallocated((HeapWord*) fc, size);
- if (_adaptive_freelists) {
- _indexedFreeList[size].return_chunk_at_tail(fc);
- } else {
- _indexedFreeList[size].return_chunk_at_head(fc);
- }
+ _indexedFreeList[size].return_chunk_at_tail(fc);
#ifndef PRODUCT
if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
_indexedFreeList[size].verify_stats();
@@ -1931,10 +1834,6 @@
void
CompactibleFreeListSpace::gc_epilogue() {
assert_locked();
- if (PrintGCDetails && Verbose && !_adaptive_freelists) {
- if (_smallLinearAllocBlock._word_size == 0)
- warning("CompactibleFreeListSpace(epilogue):: Linear allocation failure");
- }
assert(_promoInfo.noPromotions(), "_promoInfo inconsistency");
_promoInfo.stopTrackingPromotions();
repairLinearAllocationBlocks();
@@ -2060,13 +1959,6 @@
}
}
-// Support for concurrent collection policy decisions.
-bool CompactibleFreeListSpace::should_concurrent_collect() const {
- // In the future we might want to add in fragmentation stats --
- // including erosion of the "mountain" into this decision as well.
- return !adaptive_freelists() && linearAllocationWouldFail();
-}
-
// Support for compaction
void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) {
scan_and_forward(this, cp);
--- a/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/cms/compactibleFreeListSpace.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -138,15 +138,13 @@
// Linear allocation blocks
LinearAllocBlock _smallLinearAllocBlock;
- FreeBlockDictionary<FreeChunk>::DictionaryChoice _dictionaryChoice;
AFLBinaryTreeDictionary* _dictionary; // Pointer to dictionary for large size blocks
// Indexed array for small size blocks
AdaptiveFreeList<FreeChunk> _indexedFreeList[IndexSetSize];
// Allocation strategy
- bool _fitStrategy; // Use best fit strategy
- bool _adaptive_freelists; // Use adaptive freelists
+ bool _fitStrategy; // Use best fit strategy
// This is an address close to the largest free chunk in the heap.
// It is currently assumed to be at the end of the heap. Free
@@ -204,10 +202,6 @@
// strategy that attempts to keep the needed number of chunks in each
// indexed free lists.
HeapWord* allocate_adaptive_freelists(size_t size);
- // Allocate from the linear allocation buffers first. This allocation
- // strategy assumes maximal coalescing can maintain chunks large enough
- // to be used as linear allocation buffers.
- HeapWord* allocate_non_adaptive_freelists(size_t size);
// Gets a chunk from the linear allocation block (LinAB). If there
// is not enough space in the LinAB, refills it.
@@ -333,9 +327,7 @@
public:
// Constructor
- CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr,
- bool use_adaptive_freelists,
- FreeBlockDictionary<FreeChunk>::DictionaryChoice);
+ CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr);
// Accessors
bool bestFitFirst() { return _fitStrategy == FreeBlockBestFitFirst; }
FreeBlockDictionary<FreeChunk>* dictionary() const { return _dictionary; }
@@ -349,8 +341,6 @@
// chunk exists, return NULL.
FreeChunk* find_chunk_at_end();
- bool adaptive_freelists() const { return _adaptive_freelists; }
-
void set_collector(CMSCollector* collector) { _collector = collector; }
// Support for parallelization of rescan and marking.
@@ -536,9 +526,6 @@
void addChunkAndRepairOffsetTable(HeapWord* chunk, size_t size,
bool coalesced);
- // Support for decisions regarding concurrent collection policy.
- bool should_concurrent_collect() const;
-
// Support for compaction.
void prepare_for_compaction(CompactPoint* cp);
void adjust_pointers();
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -190,9 +190,7 @@
};
ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
- ReservedSpace rs, size_t initial_byte_size,
- CardTableRS* ct, bool use_adaptive_freelists,
- FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
+ ReservedSpace rs, size_t initial_byte_size, CardTableRS* ct) :
CardGeneration(rs, initial_byte_size, ct),
_dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))),
_did_compact(false)
@@ -208,9 +206,7 @@
_numWordsAllocated = 0;
)
- _cmsSpace = new CompactibleFreeListSpace(_bts, MemRegion(bottom, end),
- use_adaptive_freelists,
- dictionaryChoice);
+ _cmsSpace = new CompactibleFreeListSpace(_bts, MemRegion(bottom, end));
NOT_PRODUCT(debug_cms_space = _cmsSpace;)
_cmsSpace->_old_gen = this;
@@ -1312,13 +1308,6 @@
}
return true;
}
- if (_cmsSpace->should_concurrent_collect()) {
- if (PrintGCDetails && Verbose) {
- gclog_or_tty->print(" %s: collect because cmsSpace says so ",
- short_name());
- }
- return true;
- }
return false;
}
@@ -1766,9 +1755,8 @@
MutexLockerEx hl(Heap_lock, safepoint_check);
FreelistLocker fll(this);
MutexLockerEx x(CGC_lock, safepoint_check);
- if (_foregroundGCIsActive || !UseAsyncConcMarkSweepGC) {
- // The foreground collector is active or we're
- // not using asynchronous collections. Skip this
+ if (_foregroundGCIsActive) {
+ // The foreground collector is. Skip this
// background collection.
assert(!_foregroundGCShouldWait, "Should be clear");
return;
@@ -1795,7 +1783,7 @@
}
// Used for PrintGC
- size_t prev_used;
+ size_t prev_used = 0;
if (PrintGC && Verbose) {
prev_used = _cmsGen->used();
}
@@ -5214,9 +5202,8 @@
verify_work_stacks_empty();
// Restore evacuated mark words, if any, used for overflow list links
- if (!CMSOverflowEarlyRestoration) {
- restore_preserved_marks_if_any();
- }
+ restore_preserved_marks_if_any();
+
verify_overflow_empty();
}
@@ -6186,17 +6173,8 @@
assert(_mark_stack->isEmpty(), "post-condition (eager drainage)");
assert(_collector->overflow_list_is_empty(),
"overflow list was drained above");
- // We could restore evacuated mark words, if any, used for
- // overflow list links here because the overflow list is
- // provably empty here. That would reduce the maximum
- // size requirements for preserved_{oop,mark}_stack.
- // But we'll just postpone it until we are all done
- // so we can just stream through.
- if (!_concurrent_precleaning && CMSOverflowEarlyRestoration) {
- _collector->restore_preserved_marks_if_any();
- assert(_collector->no_preserved_marks(), "No preserved marks");
- }
- assert(!CMSOverflowEarlyRestoration || _collector->no_preserved_marks(),
+
+ assert(_collector->no_preserved_marks(),
"All preserved marks should have been restored above");
}
}
@@ -7372,14 +7350,6 @@
set_freeFinger(freeFinger);
set_freeRangeInFreeLists(freeRangeInFreeLists);
- if (CMSTestInFreeList) {
- if (freeRangeInFreeLists) {
- FreeChunk* fc = (FreeChunk*) freeFinger;
- assert(fc->is_free(), "A chunk on the free list should be free.");
- assert(fc->size() > 0, "Free range should have a size");
- assert(_sp->verify_chunk_in_free_list(fc), "Chunk is not in free lists");
- }
- }
}
// Note that the sweeper runs concurrently with mutators. Thus,
@@ -7532,12 +7502,7 @@
void SweepClosure::do_already_free_chunk(FreeChunk* fc) {
const size_t size = fc->size();
- // Chunks that cannot be coalesced are not in the
- // free lists.
- if (CMSTestInFreeList && !fc->cantCoalesce()) {
- assert(_sp->verify_chunk_in_free_list(fc),
- "free chunk should be in free lists");
- }
+
// a chunk that is already free, should not have been
// marked in the bit map
HeapWord* const addr = (HeapWord*) fc;
@@ -7550,57 +7515,8 @@
// See the definition of cantCoalesce().
if (!fc->cantCoalesce()) {
// This chunk can potentially be coalesced.
- if (_sp->adaptive_freelists()) {
- // All the work is done in
- do_post_free_or_garbage_chunk(fc, size);
- } else { // Not adaptive free lists
- // this is a free chunk that can potentially be coalesced by the sweeper;
- if (!inFreeRange()) {
- // if the next chunk is a free block that can't be coalesced
- // it doesn't make sense to remove this chunk from the free lists
- FreeChunk* nextChunk = (FreeChunk*)(addr + size);
- assert((HeapWord*)nextChunk <= _sp->end(), "Chunk size out of bounds?");
- if ((HeapWord*)nextChunk < _sp->end() && // There is another free chunk to the right ...
- nextChunk->is_free() && // ... which is free...
- nextChunk->cantCoalesce()) { // ... but can't be coalesced
- // nothing to do
- } else {
- // Potentially the start of a new free range:
- // Don't eagerly remove it from the free lists.
- // No need to remove it if it will just be put
- // back again. (Also from a pragmatic point of view
- // if it is a free block in a region that is beyond
- // any allocated blocks, an assertion will fail)
- // Remember the start of a free run.
- initialize_free_range(addr, true);
- // end - can coalesce with next chunk
- }
- } else {
- // the midst of a free range, we are coalescing
- print_free_block_coalesced(fc);
- if (CMSTraceSweeper) {
- gclog_or_tty->print(" -- pick up free block " PTR_FORMAT " (" SIZE_FORMAT ")\n", p2i(fc), size);
- }
- // remove it from the free lists
- _sp->removeFreeChunkFromFreeLists(fc);
- set_lastFreeRangeCoalesced(true);
- // If the chunk is being coalesced and the current free range is
- // in the free lists, remove the current free range so that it
- // will be returned to the free lists in its entirety - all
- // the coalesced pieces included.
- if (freeRangeInFreeLists()) {
- FreeChunk* ffc = (FreeChunk*) freeFinger();
- assert(ffc->size() == pointer_delta(addr, freeFinger()),
- "Size of free range is inconsistent with chunk size.");
- if (CMSTestInFreeList) {
- assert(_sp->verify_chunk_in_free_list(ffc),
- "free range is not in free lists");
- }
- _sp->removeFreeChunkFromFreeLists(ffc);
- set_freeRangeInFreeLists(false);
- }
- }
- }
+ // All the work is done in
+ do_post_free_or_garbage_chunk(fc, size);
// Note that if the chunk is not coalescable (the else arm
// below), we unconditionally flush, without needing to do
// a "lookahead," as we do below.
@@ -7626,46 +7542,11 @@
HeapWord* const addr = (HeapWord*) fc;
const size_t size = CompactibleFreeListSpace::adjustObjectSize(oop(addr)->size());
- if (_sp->adaptive_freelists()) {
- // Verify that the bit map has no bits marked between
- // addr and purported end of just dead object.
- _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
-
- do_post_free_or_garbage_chunk(fc, size);
- } else {
- if (!inFreeRange()) {
- // start of a new free range
- assert(size > 0, "A free range should have a size");
- initialize_free_range(addr, false);
- } else {
- // this will be swept up when we hit the end of the
- // free range
- if (CMSTraceSweeper) {
- gclog_or_tty->print(" -- pick up garbage " PTR_FORMAT " (" SIZE_FORMAT ")\n", p2i(fc), size);
- }
- // If the chunk is being coalesced and the current free range is
- // in the free lists, remove the current free range so that it
- // will be returned to the free lists in its entirety - all
- // the coalesced pieces included.
- if (freeRangeInFreeLists()) {
- FreeChunk* ffc = (FreeChunk*)freeFinger();
- assert(ffc->size() == pointer_delta(addr, freeFinger()),
- "Size of free range is inconsistent with chunk size.");
- if (CMSTestInFreeList) {
- assert(_sp->verify_chunk_in_free_list(ffc),
- "free range is not in free lists");
- }
- _sp->removeFreeChunkFromFreeLists(ffc);
- set_freeRangeInFreeLists(false);
- }
- set_lastFreeRangeCoalesced(true);
- }
- // this will be swept up when we hit the end of the free range
-
- // Verify that the bit map has no bits marked between
- // addr and purported end of just dead object.
- _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
- }
+ // Verify that the bit map has no bits marked between
+ // addr and purported end of just dead object.
+ _bitMap->verifyNoOneBitsInRange(addr + 1, addr + size);
+ do_post_free_or_garbage_chunk(fc, size);
+
assert(_limit >= addr + size,
"A freshly garbage chunk can't possibly straddle over _limit");
if (inFreeRange()) lookahead_and_flush(fc, size);
@@ -7727,11 +7608,7 @@
// do_post_free_or_garbage_chunk() should only be called in the case
// of the adaptive free list allocator.
const bool fcInFreeLists = fc->is_free();
- assert(_sp->adaptive_freelists(), "Should only be used in this case.");
assert((HeapWord*)fc <= _limit, "sweep invariant");
- if (CMSTestInFreeList && fcInFreeLists) {
- assert(_sp->verify_chunk_in_free_list(fc), "free chunk is not in free lists");
- }
if (CMSTraceSweeper) {
gclog_or_tty->print_cr(" -- pick up another chunk at " PTR_FORMAT " (" SIZE_FORMAT ")", p2i(fc), chunkSize);
@@ -7739,7 +7616,7 @@
HeapWord* const fc_addr = (HeapWord*) fc;
- bool coalesce;
+ bool coalesce = false;
const size_t left = pointer_delta(fc_addr, freeFinger());
const size_t right = chunkSize;
switch (FLSCoalescePolicy) {
@@ -7784,10 +7661,6 @@
FreeChunk* const ffc = (FreeChunk*)freeFinger();
assert(ffc->size() == pointer_delta(fc_addr, freeFinger()),
"Size of free range is inconsistent with chunk size.");
- if (CMSTestInFreeList) {
- assert(_sp->verify_chunk_in_free_list(ffc),
- "Chunk is not in free lists");
- }
_sp->coalDeath(ffc->size());
_sp->removeFreeChunkFromFreeLists(ffc);
set_freeRangeInFreeLists(false);
@@ -7856,12 +7729,6 @@
assert(size > 0,
"A zero sized chunk cannot be added to the free lists.");
if (!freeRangeInFreeLists()) {
- if (CMSTestInFreeList) {
- FreeChunk* fc = (FreeChunk*) chunk;
- fc->set_size(size);
- assert(!_sp->verify_chunk_in_free_list(fc),
- "chunk should not be in free lists yet");
- }
if (CMSTraceSweeper) {
gclog_or_tty->print_cr(" -- add free block " PTR_FORMAT " (" SIZE_FORMAT ") to free lists",
p2i(chunk), size);
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1076,10 +1076,7 @@
void assert_correct_size_change_locking();
public:
- ConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size,
- CardTableRS* ct,
- bool use_adaptive_freelists,
- FreeBlockDictionary<FreeChunk>::DictionaryChoice);
+ ConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size, CardTableRS* ct);
// Accessors
CMSCollector* collector() const { return _collector; }
@@ -1121,12 +1118,6 @@
// over-rides
MemRegion used_region_at_save_marks() const;
- // Does a "full" (forced) collection invoked on this generation collect
- // the young generation as well?
- virtual bool full_collects_young_generation() const {
- return !ScavengeBeforeFullGC;
- }
-
// Adjust quantities in the generation affected by
// the compaction.
void reset_after_compaction();
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepThread.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -79,9 +79,6 @@
static void makeSurrogateLockerThread(TRAPS);
static SurrogateLockerThread* slt() { return _slt; }
- // Tester
- bool is_ConcurrentGC_thread() const { return true; }
-
static void threads_do(ThreadClosure* tc);
// Printing
--- a/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/cms/vmCMSOperations.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -138,7 +138,6 @@
: VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */)
{
assert(FullGCCount_lock != NULL, "Error");
- assert(UseAsyncConcMarkSweepGC, "Else will hang caller");
}
~VM_GenCollectFullConcurrent() {}
virtual VMOp_Type type() const { return VMOp_GenCollectFullConcurrent; }
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -30,7 +30,8 @@
#include "runtime/java.hpp"
ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h) :
- _threads(NULL), _n_threads(0),
+ _threads(NULL),
+ _sample_thread(NULL),
_hot_card_cache(g1h)
{
// Ergonomically select initial concurrent refinement parameters
@@ -58,12 +59,10 @@
return NULL;
}
cg1r->_n_worker_threads = thread_num();
- // We need one extra thread to do the young gen rset size sampling.
- cg1r->_n_threads = cg1r->_n_worker_threads + 1;
cg1r->reset_threshold_step();
- cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_threads, mtGC);
+ cg1r->_threads = NEW_C_HEAP_ARRAY_RETURN_NULL(ConcurrentG1RefineThread*, cg1r->_n_worker_threads, mtGC);
if (cg1r->_threads == NULL) {
*ecode = JNI_ENOMEM;
vm_shutdown_during_initialization("Could not allocate an array for ConcurrentG1RefineThread");
@@ -73,7 +72,7 @@
uint worker_id_offset = DirtyCardQueueSet::num_par_ids();
ConcurrentG1RefineThread *next = NULL;
- for (uint i = cg1r->_n_threads - 1; i != UINT_MAX; i--) {
+ for (uint i = cg1r->_n_worker_threads - 1; i != UINT_MAX; i--) {
ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(cg1r, next, refine_closure, worker_id_offset, i);
assert(t != NULL, "Conc refine should have been created");
if (t->osthread() == NULL) {
@@ -86,6 +85,14 @@
cg1r->_threads[i] = t;
next = t;
}
+
+ cg1r->_sample_thread = new G1YoungRemSetSamplingThread();
+ if (cg1r->_sample_thread->osthread() == NULL) {
+ *ecode = JNI_ENOMEM;
+ vm_shutdown_during_initialization("Could not create G1YoungRemSetSamplingThread");
+ return NULL;
+ }
+
*ecode = JNI_OK;
return cg1r;
}
@@ -103,44 +110,36 @@
}
void ConcurrentG1Refine::stop() {
- if (_threads != NULL) {
- for (uint i = 0; i < _n_threads; i++) {
- _threads[i]->stop();
- }
+ for (uint i = 0; i < _n_worker_threads; i++) {
+ _threads[i]->stop();
}
+ _sample_thread->stop();
}
void ConcurrentG1Refine::reinitialize_threads() {
reset_threshold_step();
- if (_threads != NULL) {
- for (uint i = 0; i < _n_threads; i++) {
- _threads[i]->initialize();
- }
+ for (uint i = 0; i < _n_worker_threads; i++) {
+ _threads[i]->initialize();
}
}
ConcurrentG1Refine::~ConcurrentG1Refine() {
- if (_threads != NULL) {
- for (uint i = 0; i < _n_threads; i++) {
- delete _threads[i];
- }
- FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
+ for (uint i = 0; i < _n_worker_threads; i++) {
+ delete _threads[i];
}
+ FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
+
+ delete _sample_thread;
}
void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
- if (_threads != NULL) {
- for (uint i = 0; i < _n_threads; i++) {
- tc->do_thread(_threads[i]);
- }
- }
+ worker_threads_do(tc);
+ tc->do_thread(_sample_thread);
}
void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
- if (_threads != NULL) {
- for (uint i = 0; i < worker_thread_num(); i++) {
- tc->do_thread(_threads[i]);
- }
+ for (uint i = 0; i < worker_thread_num(); i++) {
+ tc->do_thread(_threads[i]);
}
}
@@ -149,12 +148,10 @@
}
void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
- for (uint i = 0; i < _n_threads; ++i) {
+ for (uint i = 0; i < _n_worker_threads; ++i) {
_threads[i]->print_on(st);
st->cr();
}
+ _sample_thread->print_on(st);
+ st->cr();
}
-
-ConcurrentG1RefineThread * ConcurrentG1Refine::sampling_thread() const {
- return _threads[worker_thread_num()];
-}
--- a/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1Refine.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -26,6 +26,7 @@
#define SHARE_VM_GC_G1_CONCURRENTG1REFINE_HPP
#include "gc/g1/g1HotCardCache.hpp"
+#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
#include "memory/allocation.hpp"
#include "runtime/thread.hpp"
#include "utilities/globalDefinitions.hpp"
@@ -39,8 +40,9 @@
class DirtyCardQueue;
class ConcurrentG1Refine: public CHeapObj<mtGC> {
+ G1YoungRemSetSamplingThread* _sample_thread;
+
ConcurrentG1RefineThread** _threads;
- uint _n_threads;
uint _n_worker_threads;
/*
* The value of the update buffer queue length falls into one of 3 zones:
@@ -91,8 +93,8 @@
// Iterate over all worker refinement threads
void worker_threads_do(ThreadClosure * tc);
- // The RS sampling thread
- ConcurrentG1RefineThread * sampling_thread() const;
+ // The RS sampling thread has nothing to do with refinement, but is here for now.
+ G1YoungRemSetSamplingThread * sampling_thread() const { return _sample_thread; }
static uint thread_num();
@@ -106,7 +108,6 @@
int yellow_zone() const { return _yellow_zone; }
int red_zone() const { return _red_zone; }
- uint total_thread_num() const { return _n_threads; }
uint worker_thread_num() const { return _n_worker_threads; }
int thread_threshold_step() const { return _thread_threshold_step; }
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -50,9 +50,8 @@
// Each thread has its own monitor. The i-th thread is responsible for signaling
// to thread i+1 if the number of buffers in the queue exceeds a threshold for this
// thread. Monitors are also used to wake up the threads during termination.
- // The 0th worker in notified by mutator threads and has a special monitor.
- // The last worker is used for young gen rset size sampling.
- if (worker_id > 0) {
+ // The 0th (primary) worker is notified by mutator threads and has a special monitor.
+ if (!is_primary()) {
_monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true,
Monitor::_safepoint_check_never);
} else {
@@ -66,61 +65,11 @@
}
void ConcurrentG1RefineThread::initialize() {
- if (_worker_id < cg1r()->worker_thread_num()) {
- // Current thread activation threshold
- _threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
- cg1r()->yellow_zone());
- // A thread deactivates once the number of buffer reached a deactivation threshold
- _deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone());
- } else {
- set_active(true);
- }
-}
-
-void ConcurrentG1RefineThread::sample_young_list_rs_lengths() {
- SuspendibleThreadSetJoiner sts_join;
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- G1CollectorPolicy* g1p = g1h->g1_policy();
- if (g1p->adaptive_young_list_length()) {
- int regions_visited = 0;
- g1h->young_list()->rs_length_sampling_init();
- while (g1h->young_list()->rs_length_sampling_more()) {
- g1h->young_list()->rs_length_sampling_next();
- ++regions_visited;
-
- // we try to yield every time we visit 10 regions
- if (regions_visited == 10) {
- if (sts_join.should_yield()) {
- sts_join.yield();
- // we just abandon the iteration
- break;
- }
- regions_visited = 0;
- }
- }
-
- g1p->revise_young_list_target_length_if_necessary();
- }
-}
-
-void ConcurrentG1RefineThread::run_young_rs_sampling() {
- DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
- _vtime_start = os::elapsedVTime();
- while(!_should_terminate) {
- sample_young_list_rs_lengths();
-
- if (os::supports_vtime()) {
- _vtime_accum = (os::elapsedVTime() - _vtime_start);
- } else {
- _vtime_accum = 0.0;
- }
-
- MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
- if (_should_terminate) {
- break;
- }
- _monitor->wait(Mutex::_no_safepoint_check_flag, G1ConcRefinementServiceIntervalMillis);
- }
+ // Current thread activation threshold
+ _threshold = MIN2<int>(cg1r()->thread_threshold_step() * (_worker_id + 1) + cg1r()->green_zone(),
+ cg1r()->yellow_zone());
+ // A thread deactivates once the number of buffer reached a deactivation threshold
+ _deactivation_threshold = MAX2<int>(_threshold - cg1r()->thread_threshold_step(), cg1r()->green_zone());
}
void ConcurrentG1RefineThread::wait_for_completed_buffers() {
@@ -133,12 +82,12 @@
bool ConcurrentG1RefineThread::is_active() {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
- return _worker_id > 0 ? _active : dcqs.process_completed_buffers();
+ return is_primary() ? dcqs.process_completed_buffers() : _active;
}
void ConcurrentG1RefineThread::activate() {
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
- if (_worker_id > 0) {
+ if (!is_primary()) {
if (G1TraceConcRefinement) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
gclog_or_tty->print_cr("G1-Refine-activated worker %d, on threshold %d, current %d",
@@ -154,7 +103,7 @@
void ConcurrentG1RefineThread::deactivate() {
MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
- if (_worker_id > 0) {
+ if (!is_primary()) {
if (G1TraceConcRefinement) {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
gclog_or_tty->print_cr("G1-Refine-deactivated worker %d, off threshold %d, current %d",
@@ -171,25 +120,24 @@
initialize_in_thread();
wait_for_universe_init();
- if (_worker_id >= cg1r()->worker_thread_num()) {
- run_young_rs_sampling();
- terminate();
- return;
- }
+ run_service();
+
+ terminate();
+}
+void ConcurrentG1RefineThread::run_service() {
_vtime_start = os::elapsedVTime();
+
while (!_should_terminate) {
- DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-
// Wait for work
wait_for_completed_buffers();
-
if (_should_terminate) {
break;
}
{
SuspendibleThreadSetJoiner sts_join;
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
do {
int curr_buffer_num = (int)dcqs.completed_buffers_num();
@@ -199,7 +147,7 @@
dcqs.set_completed_queue_padding(0);
}
- if (_worker_id > 0 && curr_buffer_num <= _deactivation_threshold) {
+ if (!is_primary() && curr_buffer_num <= _deactivation_threshold) {
// If the number of the buffer has fallen below our threshold
// we should deactivate. The predecessor will reactivate this
// thread should the number of the buffers cross the threshold again.
@@ -225,8 +173,10 @@
_vtime_accum = 0.0;
}
}
- assert(_should_terminate, "just checking");
- terminate();
+
+ if (G1TraceConcRefinement) {
+ gclog_or_tty->print_cr("G1-Refine-stop");
+ }
}
void ConcurrentG1RefineThread::stop() {
@@ -236,10 +186,7 @@
_should_terminate = true;
}
- {
- MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
- _monitor->notify();
- }
+ stop_service();
{
MutexLockerEx mu(Terminator_lock);
@@ -247,8 +194,9 @@
Terminator_lock->wait();
}
}
- if (G1TraceConcRefinement) {
- gclog_or_tty->print_cr("G1-Refine-stop");
- }
}
+void ConcurrentG1RefineThread::stop_service() {
+ MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ _monitor->notify();
+}
\ No newline at end of file
--- a/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/concurrentG1RefineThread.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -31,14 +31,14 @@
class CardTableEntryClosure;
class ConcurrentG1Refine;
-// The G1 Concurrent Refinement Thread (could be several in the future).
-
+// One or more G1 Concurrent Refinement Threads may be active if concurrent
+// refinement is in progress.
class ConcurrentG1RefineThread: public ConcurrentGCThread {
friend class VMStructs;
friend class G1CollectedHeap;
double _vtime_start; // Initial virtual time.
- double _vtime_accum; // Initial virtual time.
+ double _vtime_accum; // Accumulated virtual time.
uint _worker_id;
uint _worker_id_offset;
@@ -59,8 +59,6 @@
// This thread deactivation threshold
int _deactivation_threshold;
- void sample_young_list_rs_lengths();
- void run_young_rs_sampling();
void wait_for_completed_buffers();
void set_active(bool x) { _active = x; }
@@ -68,6 +66,11 @@
void activate();
void deactivate();
+ bool is_primary() { return (_worker_id == 0); }
+
+ void run_service();
+ void stop_service();
+
public:
virtual void run();
// Constructor
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -92,15 +92,31 @@
}
}
+// Marking pauses can be scheduled flexibly, so we might delay marking to meet MMU.
+void ConcurrentMarkThread::delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark) {
+ if (g1_policy->adaptive_young_list_length()) {
+ double now = os::elapsedTime();
+ double prediction_ms = remark ? g1_policy->predict_remark_time_ms()
+ : g1_policy->predict_cleanup_time_ms();
+ G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
+ jlong sleep_time_ms = mmu_tracker->when_ms(now, prediction_ms);
+ os::sleep(this, sleep_time_ms, false);
+ }
+}
void ConcurrentMarkThread::run() {
initialize_in_thread();
+ wait_for_universe_init();
+
+ run_service();
+
+ terminate();
+}
+
+void ConcurrentMarkThread::run_service() {
_vtime_start = os::elapsedVTime();
- wait_for_universe_init();
G1CollectedHeap* g1h = G1CollectedHeap::heap();
G1CollectorPolicy* g1_policy = g1h->g1_policy();
- G1MMUTracker *mmu_tracker = g1_policy->mmu_tracker();
- Thread *current_thread = Thread::current();
while (!_should_terminate) {
// wait until started is set.
@@ -141,12 +157,7 @@
double mark_end_sec = os::elapsedTime();
_vtime_mark_accum += (mark_end_time - cycle_start);
if (!cm()->has_aborted()) {
- if (g1_policy->adaptive_young_list_length()) {
- double now = os::elapsedTime();
- double remark_prediction_ms = g1_policy->predict_remark_time_ms();
- jlong sleep_time_ms = mmu_tracker->when_ms(now, remark_prediction_ms);
- os::sleep(current_thread, sleep_time_ms, false);
- }
+ delay_to_keep_mmu(g1_policy, true /* remark */);
cm_log(G1Log::fine(), true, "[GC concurrent-mark-end, %1.7lf secs]", mark_end_sec - mark_start_sec);
@@ -167,12 +178,7 @@
_vtime_accum = (end_time - _vtime_start);
if (!cm()->has_aborted()) {
- if (g1_policy->adaptive_young_list_length()) {
- double now = os::elapsedTime();
- double cleanup_prediction_ms = g1_policy->predict_cleanup_time_ms();
- jlong sleep_time_ms = mmu_tracker->when_ms(now, cleanup_prediction_ms);
- os::sleep(current_thread, sleep_time_ms, false);
- }
+ delay_to_keep_mmu(g1_policy, false /* cleanup */);
CMCleanUp cl_cl(_cm);
VM_CGC_Operation op(&cl_cl, "GC cleanup", false /* needs_pll */);
@@ -272,9 +278,6 @@
g1h->register_concurrent_cycle_end();
}
}
- assert(_should_terminate, "just checking");
-
- terminate();
}
void ConcurrentMarkThread::stop() {
@@ -283,10 +286,7 @@
_should_terminate = true;
}
- {
- MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag);
- CGC_lock->notify_all();
- }
+ stop_service();
{
MutexLockerEx ml(Terminator_lock);
@@ -296,6 +296,11 @@
}
}
+void ConcurrentMarkThread::stop_service() {
+ MutexLockerEx ml(CGC_lock, Mutex::_no_safepoint_check_flag);
+ CGC_lock->notify_all();
+}
+
void ConcurrentMarkThread::sleepBeforeNextCycle() {
// We join here because we don't want to do the "shouldConcurrentMark()"
// below while the world is otherwise stopped.
--- a/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/concurrentMarkThread.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -27,11 +27,11 @@
#include "gc/shared/concurrentGCThread.hpp"
-// The Concurrent Mark GC Thread (could be several in the future).
-// This is copied from the Concurrent Mark Sweep GC Thread
-// Still under construction.
+// The Concurrent Mark GC Thread triggers the parallel CMConcurrentMarkingTasks
+// as well as handling various marking cleanup.
class ConcurrentMark;
+class G1CollectorPolicy;
class ConcurrentMarkThread: public ConcurrentGCThread {
friend class VMStructs;
@@ -57,6 +57,10 @@
volatile State _state;
void sleepBeforeNextCycle();
+ void delay_to_keep_mmu(G1CollectorPolicy* g1_policy, bool remark);
+
+ void run_service();
+ void stop_service();
static SurrogateLockerThread* _slt;
@@ -67,9 +71,9 @@
static void makeSurrogateLockerThread(TRAPS);
static SurrogateLockerThread* slt() { return _slt; }
- // Total virtual time so far.
+ // Total virtual time so far for this thread and concurrent marking tasks.
double vtime_accum();
- // Marking virtual time so far
+ // Marking virtual time so far this thread and concurrent marking tasks.
double vtime_mark_accum();
ConcurrentMark* cm() { return _cm; }
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1716,7 +1716,7 @@
return NULL;
}
-bool G1CollectedHeap::expand(size_t expand_bytes) {
+bool G1CollectedHeap::expand(size_t expand_bytes, double* expand_time_ms) {
size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
aligned_expand_bytes = align_size_up(aligned_expand_bytes,
HeapRegion::GrainBytes);
@@ -1733,10 +1733,14 @@
return false;
}
+ double expand_heap_start_time_sec = os::elapsedTime();
uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes);
assert(regions_to_expand > 0, "Must expand by at least one region");
uint expanded_by = _hrm.expand_by(regions_to_expand);
+ if (expand_time_ms != NULL) {
+ *expand_time_ms = (os::elapsedTime() - expand_heap_start_time_sec) * MILLIUNITS;
+ }
if (expanded_by > 0) {
size_t actual_expand_bytes = expanded_by * HeapRegion::GrainBytes;
@@ -3930,9 +3934,13 @@
_allocator->init_gc_alloc_regions(evacuation_info);
G1ParScanThreadStateSet per_thread_states(this, workers()->active_workers(), g1_policy()->young_cset_region_length());
+ pre_evacuate_collection_set();
+
// Actually do the work...
evacuate_collection_set(evacuation_info, &per_thread_states);
+ post_evacuate_collection_set(evacuation_info, &per_thread_states);
+
const size_t* surviving_young_words = per_thread_states.surviving_young_words();
free_collection_set(g1_policy()->collection_set(), evacuation_info, surviving_young_words);
@@ -3997,9 +4005,11 @@
size_t bytes_before = capacity();
// No need for an ergo verbose message here,
// expansion_amount() does this when it returns a value > 0.
- if (!expand(expand_bytes)) {
+ double expand_ms;
+ if (!expand(expand_bytes, &expand_ms)) {
// We failed to expand the heap. Cannot do anything about it.
}
+ g1_policy()->phase_times()->record_expand_heap_time(expand_ms);
}
}
@@ -4584,20 +4594,16 @@
Klass* klass;
do {
klass =_klass_iterator.next_klass();
- } while (klass != NULL && !klass->oop_is_instance());
-
- return (InstanceKlass*)klass;
+ } while (klass != NULL && !klass->is_instance_klass());
+
+ // this can be null so don't call InstanceKlass::cast
+ return static_cast<InstanceKlass*>(klass);
}
public:
void clean_klass(InstanceKlass* ik) {
- ik->clean_implementors_list(_is_alive);
- ik->clean_method_data(_is_alive);
-
- // G1 specific cleanup work that has
- // been moved here to be done in parallel.
- ik->clean_dependent_nmethods();
+ ik->clean_weak_instanceklass_links(_is_alive);
}
void work() {
@@ -5164,27 +5170,29 @@
g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
}
-void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
+void G1CollectedHeap::pre_evacuate_collection_set() {
_expand_heap_after_alloc_failure = true;
_evacuation_failed = false;
- // Should G1EvacuationFailureALot be in effect for this GC?
- NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
-
- g1_rem_set()->prepare_for_oops_into_collection_set_do();
-
// Disable the hot card cache.
G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
hot_card_cache->reset_hot_cache_claimed_index();
hot_card_cache->set_use_cache(false);
- const uint n_workers = workers()->active_workers();
+}
+
+void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
+ g1_rem_set()->prepare_for_oops_into_collection_set_do();
+
+ // Should G1EvacuationFailureALot be in effect for this GC?
+ NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
double start_par_time_sec = os::elapsedTime();
double end_par_time_sec;
{
+ const uint n_workers = workers()->active_workers();
G1RootProcessor root_processor(this, n_workers);
G1ParTask g1_par_task(this, per_thread_states, _task_queues, &root_processor, n_workers);
// InitialMark needs claim bits to keep track of the marked-through CLDs.
@@ -5234,21 +5242,8 @@
phase_times->record_string_dedup_fixup_time(fixup_time_ms);
}
- _allocator->release_gc_alloc_regions(evacuation_info);
g1_rem_set()->cleanup_after_oops_into_collection_set_do();
- per_thread_states->flush();
-
- record_obj_copy_mem_stats();
-
- // Reset and re-enable the hot card cache.
- // Note the counts for the cards in the regions in the
- // collection set are reset when the collection set is freed.
- hot_card_cache->reset_hot_cache();
- hot_card_cache->set_use_cache(true);
-
- purge_code_root_memory();
-
if (evacuation_failed()) {
remove_self_forwarding_pointers();
@@ -5266,6 +5261,23 @@
// cards). We need these updates logged to update any
// RSets.
enqueue_discovered_references(per_thread_states);
+}
+
+void G1CollectedHeap::post_evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
+ _allocator->release_gc_alloc_regions(evacuation_info);
+
+ per_thread_states->flush();
+
+ record_obj_copy_mem_stats();
+
+ // Reset and re-enable the hot card cache.
+ // Note the counts for the cards in the regions in the
+ // collection set are reset when the collection set is freed.
+ G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
+ hot_card_cache->reset_hot_cache();
+ hot_card_cache->set_use_cache(true);
+
+ purge_code_root_memory();
redirty_logged_cards();
#if defined(COMPILER2) || INCLUDE_JVMCI
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -538,7 +538,7 @@
// Returns true if the heap was expanded by the requested amount;
// false otherwise.
// (Rounds up to a HeapRegion boundary.)
- bool expand(size_t expand_bytes);
+ bool expand(size_t expand_bytes, double* expand_time_ms = NULL);
// Returns the PLAB statistics for a given destination.
inline G1EvacStats* alloc_buffer_stats(InCSetState dest);
@@ -728,7 +728,10 @@
bool do_collection_pause_at_safepoint(double target_pause_time_ms);
// Actually do the work of evacuating the collection set.
- void evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states);
+ virtual void evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states);
+
+ void pre_evacuate_collection_set();
+ void post_evacuate_collection_set(EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* pss);
// Print the header for the per-thread termination statistics.
static void print_termination_stats_hdr(outputStream* const st);
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -431,7 +431,7 @@
}
_free_regions_at_end_of_collection = _g1->num_free_regions();
- update_young_list_target_length();
+ update_young_list_max_and_target_length();
// We may immediately start allocating regions and placing them on the
// collection set list. Initialize the per-collection set info
start_incremental_cset_building();
@@ -507,13 +507,24 @@
return _young_gen_sizer->max_desired_young_length();
}
+void G1CollectorPolicy::update_young_list_max_and_target_length() {
+ update_young_list_max_and_target_length(get_new_prediction(_rs_lengths_seq));
+}
+
+void G1CollectorPolicy::update_young_list_max_and_target_length(size_t rs_lengths) {
+ update_young_list_target_length(rs_lengths);
+ update_max_gc_locker_expansion();
+}
+
void G1CollectorPolicy::update_young_list_target_length(size_t rs_lengths) {
- if (rs_lengths == (size_t) -1) {
- // if it's set to the default value (-1), we should predict it;
- // otherwise, use the given value.
- rs_lengths = (size_t) get_new_prediction(_rs_lengths_seq);
- }
+ _young_list_target_length = bounded_young_list_target_length(rs_lengths);
+}
+void G1CollectorPolicy::update_young_list_target_length() {
+ update_young_list_target_length(get_new_prediction(_rs_lengths_seq));
+}
+
+uint G1CollectorPolicy::bounded_young_list_target_length(size_t rs_lengths) const {
// Calculate the absolute and desired min bounds.
// This is how many young regions we already have (currently: the survivors).
@@ -544,7 +555,6 @@
base_min_length,
desired_min_length,
desired_max_length);
- _rs_lengths_prediction = rs_lengths;
} else {
// Don't calculate anything and let the code below bound it to
// the desired_min_length, i.e., do the next GC as soon as
@@ -569,9 +579,8 @@
assert(young_list_target_length > recorded_survivor_regions(),
"we should be able to allocate at least one eden region");
assert(young_list_target_length >= absolute_min_length, "post-condition");
- _young_list_target_length = young_list_target_length;
- update_max_gc_locker_expansion();
+ return young_list_target_length;
}
uint
@@ -695,11 +704,21 @@
if (rs_lengths > _rs_lengths_prediction) {
// add 10% to avoid having to recalculate often
size_t rs_lengths_prediction = rs_lengths * 1100 / 1000;
- update_young_list_target_length(rs_lengths_prediction);
+ update_rs_lengths_prediction(rs_lengths_prediction);
+
+ update_young_list_max_and_target_length(rs_lengths_prediction);
}
}
+void G1CollectorPolicy::update_rs_lengths_prediction() {
+ update_rs_lengths_prediction(get_new_prediction(_rs_lengths_seq));
+}
+void G1CollectorPolicy::update_rs_lengths_prediction(size_t prediction) {
+ if (collector_state()->gcs_are_young() && adaptive_young_list_length()) {
+ _rs_lengths_prediction = prediction;
+ }
+}
HeapWord* G1CollectorPolicy::mem_allocate_work(size_t size,
bool is_tlab,
@@ -801,7 +820,8 @@
_free_regions_at_end_of_collection = _g1->num_free_regions();
// Reset survivors SurvRateGroup.
_survivor_surv_rate_group->reset();
- update_young_list_target_length();
+ update_young_list_max_and_target_length();
+ update_rs_lengths_prediction();
_collectionSetChooser->clear();
}
@@ -879,6 +899,10 @@
}
}
+double G1CollectorPolicy::average_time_ms(G1GCPhaseTimes::GCParPhases phase) const {
+ return phase_times()->average_time_ms(phase);
+}
+
bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) {
if (_g1->concurrent_mark()->cmThread()->during_cycle()) {
return false;
@@ -1049,16 +1073,16 @@
if (update_stats) {
double cost_per_card_ms = 0.0;
- double cost_scan_hcc = phase_times()->average_time_ms(G1GCPhaseTimes::ScanHCC);
+ double cost_scan_hcc = average_time_ms(G1GCPhaseTimes::ScanHCC);
if (_pending_cards > 0) {
- cost_per_card_ms = (phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS) - cost_scan_hcc) / (double) _pending_cards;
+ cost_per_card_ms = (average_time_ms(G1GCPhaseTimes::UpdateRS) - cost_scan_hcc) / (double) _pending_cards;
_cost_per_card_ms_seq->add(cost_per_card_ms);
}
_cost_scan_hcc_seq->add(cost_scan_hcc);
double cost_per_entry_ms = 0.0;
if (cards_scanned > 10) {
- cost_per_entry_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ScanRS) / (double) cards_scanned;
+ cost_per_entry_ms = average_time_ms(G1GCPhaseTimes::ScanRS) / (double) cards_scanned;
if (collector_state()->last_gc_was_young()) {
_cost_per_entry_ms_seq->add(cost_per_entry_ms);
} else {
@@ -1100,7 +1124,7 @@
double cost_per_byte_ms = 0.0;
if (copied_bytes > 0) {
- cost_per_byte_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ObjCopy) / (double) copied_bytes;
+ cost_per_byte_ms = average_time_ms(G1GCPhaseTimes::ObjCopy) / (double) copied_bytes;
if (collector_state()->in_marking_window()) {
_cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
} else {
@@ -1109,8 +1133,8 @@
}
double all_other_time_ms = pause_time_ms -
- (phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS) + phase_times()->average_time_ms(G1GCPhaseTimes::ScanRS) +
- phase_times()->average_time_ms(G1GCPhaseTimes::ObjCopy) + phase_times()->average_time_ms(G1GCPhaseTimes::Termination));
+ (average_time_ms(G1GCPhaseTimes::UpdateRS) + average_time_ms(G1GCPhaseTimes::ScanRS) +
+ average_time_ms(G1GCPhaseTimes::ObjCopy) + average_time_ms(G1GCPhaseTimes::Termination));
double young_other_time_ms = 0.0;
if (young_cset_region_length() > 0) {
@@ -1147,12 +1171,13 @@
collector_state()->set_in_marking_window(new_in_marking_window);
collector_state()->set_in_marking_window_im(new_in_marking_window_im);
_free_regions_at_end_of_collection = _g1->num_free_regions();
- update_young_list_target_length();
+ update_young_list_max_and_target_length();
+ update_rs_lengths_prediction();
// Note that _mmu_tracker->max_gc_time() returns the time in seconds.
double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
- double scan_hcc_time_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ScanHCC);
+ double scan_hcc_time_ms = average_time_ms(G1GCPhaseTimes::ScanHCC);
if (update_rs_time_goal_ms < scan_hcc_time_ms) {
ergo_verbose2(ErgoTiming,
@@ -1167,7 +1192,7 @@
} else {
update_rs_time_goal_ms -= scan_hcc_time_ms;
}
- adjust_concurrent_refinement(phase_times()->average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms,
+ adjust_concurrent_refinement(average_time_ms(G1GCPhaseTimes::UpdateRS) - scan_hcc_time_ms,
phase_times()->sum_thread_work_items(G1GCPhaseTimes::UpdateRS),
update_rs_time_goal_ms);
--- a/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1CollectorPolicy.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -27,6 +27,7 @@
#include "gc/g1/collectionSetChooser.hpp"
#include "gc/g1/g1CollectorState.hpp"
+#include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1InCSetState.hpp"
#include "gc/g1/g1MMUTracker.hpp"
#include "gc/g1/g1Predictions.hpp"
@@ -39,7 +40,6 @@
class HeapRegion;
class CollectionSetChooser;
-class G1GCPhaseTimes;
// TraceYoungGenTime collects data on _both_ young and mixed evacuation pauses
// (the latter may contain non-young regions - i.e. regions that are
@@ -378,6 +378,9 @@
double accum_yg_surv_rate_pred(int age) const;
+protected:
+ virtual double average_time_ms(G1GCPhaseTimes::GCParPhases phase) const;
+
private:
// Statistics kept per GC stoppage, pause or full.
TruncatedSeq* _recent_prev_end_times_for_all_gcs_sec;
@@ -465,12 +468,16 @@
double _mark_remark_start_sec;
double _mark_cleanup_start_sec;
+ void update_young_list_max_and_target_length();
+ void update_young_list_max_and_target_length(size_t rs_lengths);
+
// Update the young list target length either by setting it to the
// desired fixed value or by calculating it using G1's pause
// prediction model. If no rs_lengths parameter is passed, predict
// the RS lengths using the prediction model, otherwise use the
// given rs_lengths as the prediction.
- void update_young_list_target_length(size_t rs_lengths = (size_t) -1);
+ void update_young_list_target_length();
+ void update_young_list_target_length(size_t rs_lengths);
// Calculate and return the minimum desired young list target
// length. This is the minimum desired young list length according
@@ -493,6 +500,11 @@
uint desired_min_length,
uint desired_max_length) const;
+ uint bounded_young_list_target_length(size_t rs_lengths) const;
+
+ void update_rs_lengths_prediction();
+ void update_rs_lengths_prediction(size_t prediction);
+
// Calculate and return chunk size (in number of regions) for parallel
// concurrent mark cleanup.
uint calculate_parallel_work_chunk_size(uint n_workers, uint n_regions) const;
--- a/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1EvacStats.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -104,9 +104,12 @@
// Latch the result
_desired_net_plab_sz = plab_sz;
if (PrintPLAB) {
- gclog_or_tty->print_cr(" (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ") ", cur_plab_sz, plab_sz);
+ gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT " desired_plab_sz = " SIZE_FORMAT ") ", cur_plab_sz, plab_sz);
}
}
+ if (PrintPLAB) {
+ gclog_or_tty->cr();
+ }
// Clear accumulators for next round.
reset();
}
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -28,6 +28,7 @@
#include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1Log.hpp"
#include "gc/g1/g1StringDedup.hpp"
+#include "gc/g1/workerDataArray.inline.hpp"
#include "memory/allocation.hpp"
#include "runtime/os.hpp"
@@ -86,165 +87,6 @@
}
};
-template <class T>
-class WorkerDataArray : public CHeapObj<mtGC> {
- friend class G1GCParPhasePrinter;
- T* _data;
- uint _length;
- const char* _title;
- bool _print_sum;
- int _log_level;
- uint _indent_level;
- bool _enabled;
-
- WorkerDataArray<size_t>* _thread_work_items;
-
- NOT_PRODUCT(T uninitialized();)
-
- // We are caching the sum and average to only have to calculate them once.
- // This is not done in an MT-safe way. It is intended to allow single
- // threaded code to call sum() and average() multiple times in any order
- // without having to worry about the cost.
- bool _has_new_data;
- T _sum;
- T _min;
- T _max;
- double _average;
-
- public:
- WorkerDataArray(uint length, const char* title, bool print_sum, int log_level, uint indent_level) :
- _title(title), _length(0), _print_sum(print_sum), _log_level(log_level), _indent_level(indent_level),
- _has_new_data(true), _thread_work_items(NULL), _enabled(true) {
- assert(length > 0, "Must have some workers to store data for");
- _length = length;
- _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
- }
-
- ~WorkerDataArray() {
- FREE_C_HEAP_ARRAY(T, _data);
- }
-
- void link_thread_work_items(WorkerDataArray<size_t>* thread_work_items) {
- _thread_work_items = thread_work_items;
- }
-
- WorkerDataArray<size_t>* thread_work_items() { return _thread_work_items; }
-
- void set(uint worker_i, T value) {
- assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
- assert(_data[worker_i] == WorkerDataArray<T>::uninitialized(), "Overwriting data for worker %d in %s", worker_i, _title);
- _data[worker_i] = value;
- _has_new_data = true;
- }
-
- void set_thread_work_item(uint worker_i, size_t value) {
- assert(_thread_work_items != NULL, "No sub count");
- _thread_work_items->set(worker_i, value);
- }
-
- T get(uint worker_i) {
- assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
- assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), "No data added for worker %d", worker_i);
- return _data[worker_i];
- }
-
- void add(uint worker_i, T value) {
- assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
- assert(_data[worker_i] != WorkerDataArray<T>::uninitialized(), "No data to add to for worker %d", worker_i);
- _data[worker_i] += value;
- _has_new_data = true;
- }
-
- double average(uint active_threads){
- calculate_totals(active_threads);
- return _average;
- }
-
- T sum(uint active_threads) {
- calculate_totals(active_threads);
- return _sum;
- }
-
- T minimum(uint active_threads) {
- calculate_totals(active_threads);
- return _min;
- }
-
- T maximum(uint active_threads) {
- calculate_totals(active_threads);
- return _max;
- }
-
- void reset() PRODUCT_RETURN;
- void verify(uint active_threads) PRODUCT_RETURN;
-
- void set_enabled(bool enabled) { _enabled = enabled; }
-
- int log_level() { return _log_level; }
-
- private:
-
- void calculate_totals(uint active_threads){
- if (!_has_new_data) {
- return;
- }
-
- _sum = (T)0;
- _min = _data[0];
- _max = _min;
- assert(active_threads <= _length, "Wrong number of active threads");
- for (uint i = 0; i < active_threads; ++i) {
- T val = _data[i];
- _sum += val;
- _min = MIN2(_min, val);
- _max = MAX2(_max, val);
- }
- _average = (double)_sum / (double)active_threads;
- _has_new_data = false;
- }
-};
-
-
-#ifndef PRODUCT
-
-template <>
-size_t WorkerDataArray<size_t>::uninitialized() {
- return (size_t)-1;
-}
-
-template <>
-double WorkerDataArray<double>::uninitialized() {
- return -1.0;
-}
-
-template <class T>
-void WorkerDataArray<T>::reset() {
- for (uint i = 0; i < _length; i++) {
- _data[i] = WorkerDataArray<T>::uninitialized();
- }
- if (_thread_work_items != NULL) {
- _thread_work_items->reset();
- }
-}
-
-template <class T>
-void WorkerDataArray<T>::verify(uint active_threads) {
- if (!_enabled) {
- return;
- }
-
- assert(active_threads <= _length, "Wrong number of active threads");
- for (uint i = 0; i < active_threads; i++) {
- assert(_data[i] != WorkerDataArray<T>::uninitialized(),
- "Invalid data for worker %u in '%s'", i, _title);
- }
- if (_thread_work_items != NULL) {
- _thread_work_items->verify(active_threads);
- }
-}
-
-#endif
-
G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
_max_gc_threads(max_gc_threads)
{
@@ -298,6 +140,7 @@
assert(active_gc_threads > 0, "The number of threads must be > 0");
assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max number of threads");
_active_gc_threads = active_gc_threads;
+ _cur_expand_heap_time_ms = 0.0;
for (int i = 0; i < GCParPhasesSentinel; i++) {
_gc_par_phases[i]->reset();
@@ -363,6 +206,9 @@
// current value of "other time"
misc_time_ms += _cur_clear_ct_time_ms;
+ // Remove expand heap time from "other time"
+ misc_time_ms += _cur_expand_heap_time_ms;
+
return misc_time_ms;
}
@@ -536,6 +382,8 @@
}
}
print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
+ print_stats(1, "Expand Heap After Collection", _cur_expand_heap_time_ms);
+
double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
print_stats(1, "Other", misc_time_ms);
if (_cur_verify_before_time_ms > 0.0) {
--- a/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1GCPhaseTimes.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -92,6 +92,7 @@
double _cur_string_dedup_fixup_time_ms;
double _cur_clear_ct_time_ms;
+ double _cur_expand_heap_time_ms;
double _cur_ref_proc_time_ms;
double _cur_ref_enq_time_ms;
@@ -155,6 +156,10 @@
_cur_clear_ct_time_ms = ms;
}
+ void record_expand_heap_time(double ms) {
+ _cur_expand_heap_time_ms = ms;
+ }
+
void record_par_time(double ms) {
_cur_collection_par_time_ms = ms;
}
@@ -252,6 +257,10 @@
return _cur_clear_ct_time_ms;
}
+ double cur_expand_heap_time_ms() {
+ return _cur_expand_heap_time_ms;
+ }
+
double root_region_scan_wait_time_ms() {
return _root_region_scan_wait_time_ms;
}
--- a/hotspot/src/share/vm/gc/g1/g1MMUTracker.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1MMUTracker.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -29,11 +29,23 @@
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
-// Keeps track of the GC work and decides when it is OK to do GC work
+// Two major user controls over G1 behavior are setting a pause time goal (MaxGCPauseMillis),
+// over a time slice (GCPauseIntervalMillis). This defines the Minimum Mutator
+// Utilisation (MMU) goal.
+//
+// * Definitions *
+// Mutator Utilisation:
+// - for a given time slice duration "ts",
+// - mutator utilisation is the following fraction:
+// non_gc_time / ts
+//
+// Minimum Mutator Utilisation (MMU):
+// - the worst mutator utilisation across all time slices.
+//
+// G1MMUTracker keeps track of the GC work and decides when it is OK to do GC work
// and for how long so that the MMU invariants are maintained.
-
-/***** ALL TIMES ARE IN SECS!!!!!!! *****/
-
+//
+// ***** ALL TIMES ARE IN SECS!!!!!!! *****
// this is the "interface"
class G1MMUTracker: public CHeapObj<mtGC> {
protected:
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupTable.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupTable.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -198,10 +198,11 @@
_table = new G1StringDedupTable(_min_size);
}
-void G1StringDedupTable::add(typeArrayOop value, unsigned int hash, G1StringDedupEntry** list) {
+void G1StringDedupTable::add(typeArrayOop value, bool latin1, unsigned int hash, G1StringDedupEntry** list) {
G1StringDedupEntry* entry = _entry_cache->alloc();
entry->set_obj(value);
entry->set_hash(hash);
+ entry->set_latin1(latin1);
entry->set_next(*list);
*list = entry;
_entries++;
@@ -226,15 +227,15 @@
bool G1StringDedupTable::equals(typeArrayOop value1, typeArrayOop value2) {
return (value1 == value2 ||
(value1->length() == value2->length() &&
- (!memcmp(value1->base(T_CHAR),
- value2->base(T_CHAR),
- value1->length() * sizeof(jchar)))));
+ (!memcmp(value1->base(T_BYTE),
+ value2->base(T_BYTE),
+ value1->length() * sizeof(jbyte)))));
}
-typeArrayOop G1StringDedupTable::lookup(typeArrayOop value, unsigned int hash,
+typeArrayOop G1StringDedupTable::lookup(typeArrayOop value, bool latin1, unsigned int hash,
G1StringDedupEntry** list, uintx &count) {
for (G1StringDedupEntry* entry = *list; entry != NULL; entry = entry->next()) {
- if (entry->hash() == hash) {
+ if (entry->hash() == hash && entry->latin1() == latin1) {
typeArrayOop existing_value = entry->obj();
if (equals(value, existing_value)) {
// Match found
@@ -248,13 +249,13 @@
return NULL;
}
-typeArrayOop G1StringDedupTable::lookup_or_add_inner(typeArrayOop value, unsigned int hash) {
+typeArrayOop G1StringDedupTable::lookup_or_add_inner(typeArrayOop value, bool latin1, unsigned int hash) {
size_t index = hash_to_index(hash);
G1StringDedupEntry** list = bucket(index);
uintx count = 0;
// Lookup in list
- typeArrayOop existing_value = lookup(value, hash, list, count);
+ typeArrayOop existing_value = lookup(value, latin1, hash, list, count);
// Check if rehash is needed
if (count > _rehash_threshold) {
@@ -263,7 +264,7 @@
if (existing_value == NULL) {
// Not found, add new entry
- add(value, hash, list);
+ add(value, latin1, hash, list);
// Update statistics
_entries_added++;
@@ -272,15 +273,24 @@
return existing_value;
}
-unsigned int G1StringDedupTable::hash_code(typeArrayOop value) {
+unsigned int G1StringDedupTable::hash_code(typeArrayOop value, bool latin1) {
unsigned int hash;
int length = value->length();
- const jchar* data = (jchar*)value->base(T_CHAR);
-
- if (use_java_hash()) {
- hash = java_lang_String::hash_code(data, length);
+ if (latin1) {
+ const jbyte* data = (jbyte*)value->base(T_BYTE);
+ if (use_java_hash()) {
+ hash = java_lang_String::hash_code(data, length);
+ } else {
+ hash = AltHashing::murmur3_32(_table->_hash_seed, data, length);
+ }
} else {
- hash = AltHashing::murmur3_32(_table->_hash_seed, data, length);
+ length /= sizeof(jchar) / sizeof(jbyte); // Convert number of bytes to number of chars
+ const jchar* data = (jchar*)value->base(T_CHAR);
+ if (use_java_hash()) {
+ hash = java_lang_String::hash_code(data, length);
+ } else {
+ hash = AltHashing::murmur3_32(_table->_hash_seed, data, length);
+ }
}
return hash;
@@ -299,6 +309,7 @@
return;
}
+ bool latin1 = java_lang_String::is_latin1(java_string);
unsigned int hash = 0;
if (use_java_hash()) {
@@ -308,7 +319,7 @@
if (hash == 0) {
// Compute hash
- hash = hash_code(value);
+ hash = hash_code(value, latin1);
stat.inc_hashed();
if (use_java_hash() && hash != 0) {
@@ -317,7 +328,7 @@
}
}
- typeArrayOop existing_value = lookup_or_add(value, hash);
+ typeArrayOop existing_value = lookup_or_add(value, latin1, hash);
if (existing_value == value) {
// Same value, already known
stat.inc_known();
@@ -459,7 +470,8 @@
// destination partitions. finish_rehash() will do a single
// threaded transfer of all entries.
typeArrayOop value = (typeArrayOop)*p;
- unsigned int hash = hash_code(value);
+ bool latin1 = (*entry)->latin1();
+ unsigned int hash = hash_code(value, latin1);
(*entry)->set_hash(hash);
}
@@ -523,7 +535,8 @@
guarantee(G1CollectedHeap::heap()->is_in_reserved(value), "Object must be on the heap");
guarantee(!value->is_forwarded(), "Object must not be forwarded");
guarantee(value->is_typeArray(), "Object must be a typeArrayOop");
- unsigned int hash = hash_code(value);
+ bool latin1 = (*entry)->latin1();
+ unsigned int hash = hash_code(value, latin1);
guarantee((*entry)->hash() == hash, "Table entry has inorrect hash");
guarantee(_table->hash_to_index(hash) == bucket, "Table entry has incorrect index");
entry = (*entry)->next_addr();
@@ -536,10 +549,12 @@
G1StringDedupEntry** entry1 = _table->bucket(bucket);
while (*entry1 != NULL) {
typeArrayOop value1 = (*entry1)->obj();
+ bool latin1_1 = (*entry1)->latin1();
G1StringDedupEntry** entry2 = (*entry1)->next_addr();
while (*entry2 != NULL) {
typeArrayOop value2 = (*entry2)->obj();
- guarantee(!equals(value1, value2), "Table entries must not have identical arrays");
+ bool latin1_2 = (*entry2)->latin1();
+ guarantee(latin1_1 != latin1_2 || !equals(value1, value2), "Table entries must not have identical arrays");
entry2 = (*entry2)->next_addr();
}
entry1 = (*entry1)->next_addr();
--- a/hotspot/src/share/vm/gc/g1/g1StringDedupTable.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/g1StringDedupTable.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -40,12 +40,14 @@
private:
G1StringDedupEntry* _next;
unsigned int _hash;
+ bool _latin1;
typeArrayOop _obj;
public:
G1StringDedupEntry() :
_next(NULL),
_hash(0),
+ _latin1(false),
_obj(NULL) {
}
@@ -69,6 +71,14 @@
_hash = hash;
}
+ bool latin1() {
+ return _latin1;
+ }
+
+ void set_latin1(bool latin1) {
+ _latin1 = latin1;
+ }
+
typeArrayOop obj() {
return _obj;
}
@@ -152,7 +162,7 @@
}
// Adds a new table entry to the given hash bucket.
- void add(typeArrayOop value, unsigned int hash, G1StringDedupEntry** list);
+ void add(typeArrayOop value, bool latin1, unsigned int hash, G1StringDedupEntry** list);
// Removes the given table entry from the table.
void remove(G1StringDedupEntry** pentry, uint worker_id);
@@ -162,20 +172,20 @@
// Returns an existing character array in the given hash bucket, or NULL
// if no matching character array exists.
- typeArrayOop lookup(typeArrayOop value, unsigned int hash,
+ typeArrayOop lookup(typeArrayOop value, bool latin1, unsigned int hash,
G1StringDedupEntry** list, uintx &count);
// Returns an existing character array in the table, or inserts a new
// table entry if no matching character array exists.
- typeArrayOop lookup_or_add_inner(typeArrayOop value, unsigned int hash);
+ typeArrayOop lookup_or_add_inner(typeArrayOop value, bool latin1, unsigned int hash);
// Thread safe lookup or add of table entry
- static typeArrayOop lookup_or_add(typeArrayOop value, unsigned int hash) {
+ static typeArrayOop lookup_or_add(typeArrayOop value, bool latin1, unsigned int hash) {
// Protect the table from concurrent access. Also note that this lock
// acts as a fence for _table, which could have been replaced by a new
// instance if the table was resized or rehashed.
MutexLockerEx ml(StringDedupTable_lock, Mutex::_no_safepoint_check_flag);
- return _table->lookup_or_add_inner(value, hash);
+ return _table->lookup_or_add_inner(value, latin1, hash);
}
// Returns true if the hashtable is currently using a Java compatible
@@ -188,7 +198,7 @@
// Computes the hash code for the given character array, using the
// currently active hash function and hash seed.
- static unsigned int hash_code(typeArrayOop value);
+ static unsigned int hash_code(typeArrayOop value, bool latin1);
static uintx unlink_or_oops_do(G1StringDedupUnlinkOrOopsDoClosure* cl,
size_t partition_begin,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1CollectorPolicy.hpp"
+#include "gc/g1/g1YoungRemSetSamplingThread.hpp"
+#include "gc/g1/suspendibleThreadSet.hpp"
+#include "runtime/mutexLocker.hpp"
+
+void G1YoungRemSetSamplingThread::run() {
+ initialize_in_thread();
+ wait_for_universe_init();
+
+ run_service();
+
+ terminate();
+}
+
+void G1YoungRemSetSamplingThread::stop() {
+ // it is ok to take late safepoints here, if needed
+ {
+ MutexLockerEx mu(Terminator_lock);
+ _should_terminate = true;
+ }
+
+ stop_service();
+
+ {
+ MutexLockerEx mu(Terminator_lock);
+ while (!_has_terminated) {
+ Terminator_lock->wait();
+ }
+ }
+}
+
+G1YoungRemSetSamplingThread::G1YoungRemSetSamplingThread() : ConcurrentGCThread() {
+ _monitor = new Monitor(Mutex::nonleaf,
+ "G1YoungRemSetSamplingThread monitor",
+ true,
+ Monitor::_safepoint_check_never);
+
+ create_and_start();
+
+ set_name("G1 Young RemSet Sampling");
+}
+
+void G1YoungRemSetSamplingThread::sleep_before_next_cycle() {
+ MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ if (!_should_terminate) {
+ intx waitms = G1ConcRefinementServiceIntervalMillis; // 300, really should be?
+ _monitor->wait(Mutex::_no_safepoint_check_flag, waitms);
+ }
+}
+
+void G1YoungRemSetSamplingThread::run_service() {
+ double vtime_start = os::elapsedVTime();
+
+ while (!_should_terminate) {
+ sample_young_list_rs_lengths();
+
+ if (os::supports_vtime()) {
+ _vtime_accum = (os::elapsedVTime() - vtime_start);
+ } else {
+ _vtime_accum = 0.0;
+ }
+
+ sleep_before_next_cycle();
+ }
+}
+
+void G1YoungRemSetSamplingThread::stop_service() {
+ MutexLockerEx x(_monitor, Mutex::_no_safepoint_check_flag);
+ _monitor->notify();
+}
+
+void G1YoungRemSetSamplingThread::sample_young_list_rs_lengths() {
+ SuspendibleThreadSetJoiner sts;
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ G1CollectorPolicy* g1p = g1h->g1_policy();
+ if (g1p->adaptive_young_list_length()) {
+ int regions_visited = 0;
+ g1h->young_list()->rs_length_sampling_init();
+ while (g1h->young_list()->rs_length_sampling_more()) {
+ g1h->young_list()->rs_length_sampling_next();
+ ++regions_visited;
+
+ // we try to yield every time we visit 10 regions
+ if (regions_visited == 10) {
+ if (sts.should_yield()) {
+ sts.yield();
+ // we just abandon the iteration
+ break;
+ }
+ regions_visited = 0;
+ }
+ }
+
+ g1p->revise_young_list_target_length_if_necessary();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1YoungRemSetSamplingThread.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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_VM_GC_G1_G1YOUNGREMSETSAMPLINGTHREAD_HPP
+#define SHARE_VM_GC_G1_G1YOUNGREMSETSAMPLINGTHREAD_HPP
+
+#include "gc/shared/concurrentGCThread.hpp"
+
+// The G1YoungRemSetSamplingThread is used to re-assess the validity of
+// the prediction for the remembered set lengths of the young generation.
+//
+// At the end of the GC G1 determines the length of the young gen based on
+// how much time the next GC can take, and when the next GC may occur
+// according to the MMU.
+//
+// The assumption is that a significant part of the GC is spent on scanning
+// the remembered sets (and many other components), so this thread constantly
+// reevaluates the prediction for the remembered set scanning costs, and potentially
+// G1CollectorPolicy resizes the young gen. This may do a premature GC or even
+// increase the young gen size to keep pause time length goal.
+class G1YoungRemSetSamplingThread: public ConcurrentGCThread {
+private:
+ Monitor* _monitor;
+
+ void sample_young_list_rs_lengths();
+
+ void run_service();
+ void stop_service();
+
+ void sleep_before_next_cycle();
+
+ double _vtime_accum; // Accumulated virtual time.
+
+public:
+ G1YoungRemSetSamplingThread();
+ double vtime_accum() { return _vtime_accum; }
+
+ virtual void run();
+ void stop();
+};
+
+#endif /* SHARE_VM_GC_G1_G1YOUNGREMSETSAMPLINGTHREAD_HPP */
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -660,7 +660,7 @@
void print_object(outputStream* out, oop obj) {
#ifdef PRODUCT
Klass* k = obj->klass();
- const char* class_name = InstanceKlass::cast(k)->external_name();
+ const char* class_name = k->external_name();
out->print_cr("class name %s", class_name);
#else // PRODUCT
obj->print_on(out);
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -563,7 +563,7 @@
assert(_n_fine_entries == _max_fine_entries, "Precondition");
PerRegionTable* max = NULL;
jint max_occ = 0;
- PerRegionTable** max_prev;
+ PerRegionTable** max_prev = NULL;
size_t max_ind;
size_t i = _fine_eviction_start;
@@ -599,6 +599,7 @@
}
guarantee(max != NULL, "Since _n_fine_entries > 0");
+ guarantee(max_prev != NULL, "Since max != NULL.");
// Set the corresponding coarse bit.
size_t max_hrm_index = (size_t) max->hr()->hrm_index();
@@ -1138,7 +1139,7 @@
void HeapRegionRemSet::print_recorded() {
int cur_evnt = 0;
- Event cur_evnt_kind;
+ Event cur_evnt_kind = Event_illegal;
int cur_evnt_ind = 0;
if (_n_recorded_events > 0) {
cur_evnt_kind = _recorded_events[cur_evnt];
--- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -222,7 +222,7 @@
public:
enum Event {
- Event_EvacStart, Event_EvacEnd, Event_RSUpdateEnd
+ Event_EvacStart, Event_EvacEnd, Event_RSUpdateEnd, Event_illegal
};
private:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/g1/workerDataArray.inline.hpp"
+
+#ifndef PRODUCT
+void WorkerDataArray_test() {
+ const uint length = 3;
+ const char* title = "Test array";
+ const bool print_sum = false;
+ const int log_level = 3;
+ const uint indent_level = 2;
+
+ WorkerDataArray<size_t> array(length, title, print_sum, log_level, indent_level);
+ assert(strncmp(array.title(), title, strlen(title)) == 0 , "Expected titles to match");
+ assert(array.should_print_sum() == print_sum, "Expected should_print_sum to match print_sum");
+ assert(array.log_level() == log_level, "Expected log levels to match");
+ assert(array.indentation() == indent_level, "Expected indentation to match");
+
+ const size_t expected[length] = {5, 3, 7};
+ for (uint i = 0; i < length; i++) {
+ array.set(i, expected[i]);
+ }
+ for (uint i = 0; i < length; i++) {
+ assert(array.get(i) == expected[i], "Expected elements to match");
+ }
+
+ assert(array.sum(length) == (5 + 3 + 7), "Expected sums to match");
+ assert(array.minimum(length) == 3, "Expected mininum to match");
+ assert(array.maximum(length) == 7, "Expected maximum to match");
+ assert(array.diff(length) == (7 - 3), "Expected diffs to match");
+ assert(array.average(length) == 5, "Expected averages to match");
+
+ for (uint i = 0; i < length; i++) {
+ array.add(i, 1);
+ }
+ for (uint i = 0; i < length; i++) {
+ assert(array.get(i) == expected[i] + 1, "Expected add to increment values");
+ }
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+
+template <class T>
+class WorkerDataArray : public CHeapObj<mtGC> {
+ friend class G1GCParPhasePrinter;
+ T* _data;
+ uint _length;
+ const char* _title;
+ bool _print_sum;
+ int _log_level;
+ uint _indent_level;
+ bool _enabled;
+
+ WorkerDataArray<size_t>* _thread_work_items;
+
+ NOT_PRODUCT(inline T uninitialized() const;)
+
+ void set_all(T value);
+
+ public:
+ WorkerDataArray(uint length,
+ const char* title,
+ bool print_sum,
+ int log_level,
+ uint indent_level);
+
+ ~WorkerDataArray();
+
+ void link_thread_work_items(WorkerDataArray<size_t>* thread_work_items);
+ void set_thread_work_item(uint worker_i, size_t value);
+ WorkerDataArray<size_t>* thread_work_items() const {
+ return _thread_work_items;
+ }
+
+ void set(uint worker_i, T value);
+ T get(uint worker_i) const;
+
+ void add(uint worker_i, T value);
+
+ double average(uint active_threads) const;
+ T sum(uint active_threads) const;
+ T minimum(uint active_threads) const;
+ T maximum(uint active_threads) const;
+ T diff(uint active_threads) const;
+
+ uint indentation() const {
+ return _indent_level;
+ }
+
+ const char* title() const {
+ return _title;
+ }
+
+ bool should_print_sum() const {
+ return _print_sum;
+ }
+
+ int log_level() const {
+ return _log_level;
+ }
+
+ void clear();
+ void set_enabled(bool enabled) {
+ _enabled = enabled;
+ }
+
+ void reset() PRODUCT_RETURN;
+ void verify(uint active_threads) const PRODUCT_RETURN;
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc/g1/workerDataArray.inline.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include "gc/g1/workerDataArray.hpp"
+#include "memory/allocation.inline.hpp"
+
+template <typename T>
+WorkerDataArray<T>::WorkerDataArray(uint length,
+ const char* title,
+ bool print_sum,
+ int log_level,
+ uint indent_level) :
+ _title(title),
+ _length(0),
+ _print_sum(print_sum),
+ _log_level(log_level),
+ _indent_level(indent_level),
+ _thread_work_items(NULL),
+ _enabled(true) {
+ assert(length > 0, "Must have some workers to store data for");
+ _length = length;
+ _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
+ reset();
+}
+
+template <typename T>
+void WorkerDataArray<T>::set(uint worker_i, T value) {
+ assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
+ assert(_data[worker_i] == uninitialized(), "Overwriting data for worker %d in %s", worker_i, _title);
+ _data[worker_i] = value;
+}
+
+template <typename T>
+T WorkerDataArray<T>::get(uint worker_i) const {
+ assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
+ assert(_data[worker_i] != uninitialized(), "No data added for worker %d", worker_i);
+ return _data[worker_i];
+}
+
+template <typename T>
+WorkerDataArray<T>::~WorkerDataArray() {
+ FREE_C_HEAP_ARRAY(T, _data);
+}
+
+template <typename T>
+void WorkerDataArray<T>::link_thread_work_items(WorkerDataArray<size_t>* thread_work_items) {
+ _thread_work_items = thread_work_items;
+}
+
+template <typename T>
+void WorkerDataArray<T>::set_thread_work_item(uint worker_i, size_t value) {
+ assert(_thread_work_items != NULL, "No sub count");
+ _thread_work_items->set(worker_i, value);
+}
+
+template <typename T>
+void WorkerDataArray<T>::add(uint worker_i, T value) {
+ assert(worker_i < _length, "Worker %d is greater than max: %d", worker_i, _length);
+ assert(_data[worker_i] != uninitialized(), "No data to add to for worker %d", worker_i);
+ _data[worker_i] += value;
+}
+
+template <typename T>
+double WorkerDataArray<T>::average(uint active_threads) const {
+ return sum(active_threads) / (double) active_threads;
+}
+
+template <typename T>
+T WorkerDataArray<T>::sum(uint active_threads) const {
+ T s = get(0);
+ for (uint i = 1; i < active_threads; ++i) {
+ s += get(i);
+ }
+ return s;
+}
+
+template <typename T>
+T WorkerDataArray<T>::minimum(uint active_threads) const {
+ T min = get(0);
+ for (uint i = 1; i < active_threads; ++i) {
+ min = MIN2(min, get(i));
+ }
+ return min;
+}
+
+template <typename T>
+T WorkerDataArray<T>::maximum(uint active_threads) const {
+ T max = get(0);
+ for (uint i = 1; i < active_threads; ++i) {
+ max = MAX2(max, get(i));
+ }
+ return max;
+}
+
+template <typename T>
+T WorkerDataArray<T>::diff(uint active_threads) const {
+ return maximum(active_threads) - minimum(active_threads);
+}
+
+template <typename T>
+void WorkerDataArray<T>::clear() {
+ set_all(0);
+}
+
+template <typename T>
+void WorkerDataArray<T>::set_all(T value) {
+ for (uint i = 0; i < _length; i++) {
+ _data[i] = value;
+ }
+}
+
+#ifndef PRODUCT
+template <typename T>
+void WorkerDataArray<T>::reset() {
+ set_all(uninitialized());
+ if (_thread_work_items != NULL) {
+ _thread_work_items->reset();
+ }
+}
+
+template <typename T>
+void WorkerDataArray<T>::verify(uint active_threads) const {
+ if (!_enabled) {
+ return;
+ }
+
+ assert(active_threads <= _length, "Wrong number of active threads");
+ for (uint i = 0; i < active_threads; i++) {
+ assert(_data[i] != uninitialized(),
+ "Invalid data for worker %u in '%s'", i, _title);
+ }
+ if (_thread_work_items != NULL) {
+ _thread_work_items->verify(active_threads);
+ }
+}
+
+template <>
+inline size_t WorkerDataArray<size_t>::uninitialized() const {
+ return (size_t)-1;
+}
+
+template <>
+inline double WorkerDataArray<double>::uninitialized() const {
+ return -1.0;
+}
+#endif
--- a/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/parallel/psCompactionManager.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -200,7 +200,7 @@
// by calling follow_class_loader explicitly. For non-anonymous classes
// the call to follow_class_loader is made when the class loader itself
// is handled.
- if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
+ if (klass->is_instance_klass() && InstanceKlass::cast(klass)->is_anonymous()) {
cm->follow_class_loader(klass->class_loader_data());
} else {
cm->follow_klass(klass);
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -383,7 +383,7 @@
size_t old_size = gch->old_gen()->capacity();
size_t new_size_before = _virtual_space.committed_size();
- size_t min_new_size = spec()->init_size();
+ size_t min_new_size = initial_size();
size_t max_new_size = reserved().byte_size();
assert(min_new_size <= new_size_before &&
new_size_before <= max_new_size,
--- a/hotspot/src/share/vm/gc/serial/tenuredGeneration.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/serial/tenuredGeneration.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -66,13 +66,6 @@
const char* name() const { return "tenured generation"; }
const char* short_name() const { return "Tenured"; }
- // Does a "full" (forced) collection invoked on this generation collect
- // the young generation as well? Note that this is a hack to allow the
- // collection of the young gen first if the flag is set.
- virtual bool full_collects_young_generation() const {
- return !ScavengeBeforeFullGC;
- }
-
size_t unsafe_max_alloc_nogc() const;
size_t contiguous_available() const;
--- a/hotspot/src/share/vm/gc/shared/cardGeneration.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/cardGeneration.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -208,8 +208,7 @@
const double min_tmp = used_after_gc / maximum_used_percentage;
size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx));
// Don't shrink less than the initial generation size
- minimum_desired_capacity = MAX2(minimum_desired_capacity,
- spec()->init_size());
+ minimum_desired_capacity = MAX2(minimum_desired_capacity, initial_size());
assert(used_after_gc <= minimum_desired_capacity, "sanity check");
if (PrintGC && Verbose) {
@@ -262,8 +261,7 @@
const double minimum_used_percentage = 1.0 - maximum_free_percentage;
const double max_tmp = used_after_gc / minimum_used_percentage;
size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
- maximum_desired_capacity = MAX2(maximum_desired_capacity,
- spec()->init_size());
+ maximum_desired_capacity = MAX2(maximum_desired_capacity, initial_size());
if (PrintGC && Verbose) {
gclog_or_tty->print_cr(" "
" maximum_free_percentage: %6.2f"
@@ -299,20 +297,20 @@
}
if (PrintGC && Verbose) {
gclog_or_tty->print_cr(" "
- " shrinking:"
- " initSize: %.1fK"
- " maximum_desired_capacity: %.1fK",
- spec()->init_size() / (double) K,
- maximum_desired_capacity / (double) K);
+ " shrinking:"
+ " initSize: %.1fK"
+ " maximum_desired_capacity: %.1fK",
+ initial_size() / (double) K,
+ maximum_desired_capacity / (double) K);
gclog_or_tty->print_cr(" "
- " shrink_bytes: %.1fK"
- " current_shrink_factor: " SIZE_FORMAT
- " new shrink factor: " SIZE_FORMAT
- " _min_heap_delta_bytes: %.1fK",
- shrink_bytes / (double) K,
- current_shrink_factor,
- _shrink_factor,
- _min_heap_delta_bytes / (double) K);
+ " shrink_bytes: %.1fK"
+ " current_shrink_factor: " SIZE_FORMAT
+ " new shrink factor: " SIZE_FORMAT
+ " _min_heap_delta_bytes: %.1fK",
+ shrink_bytes / (double) K,
+ current_shrink_factor,
+ _shrink_factor,
+ _min_heap_delta_bytes / (double) K);
}
}
}
--- a/hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/concurrentGCThread.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -66,6 +66,7 @@
}
void ConcurrentGCThread::terminate() {
+ assert(_should_terminate, "Should only be called on terminate request.");
// Signal that it is terminated
{
MutexLockerEx mu(Terminator_lock,
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -460,10 +460,9 @@
bool prepared_for_verification = false;
bool collected_old = false;
- bool old_collects_young = complete &&
- _old_gen->full_collects_young_generation();
- if (!old_collects_young &&
- _young_gen->should_collect(full, size, is_tlab)) {
+ bool old_collects_young = complete && !ScavengeBeforeFullGC;
+
+ if (!old_collects_young && _young_gen->should_collect(full, size, is_tlab)) {
if (run_verification && VerifyGCLevel <= 0 && VerifyBeforeGC) {
prepare_for_verify();
prepared_for_verification = true;
@@ -1107,10 +1106,6 @@
_young_gen->prepare_for_compaction(&cp);
}
-GCStats* GenCollectedHeap::gc_stats(Generation* gen) const {
- return gen->gc_stats();
-}
-
void GenCollectedHeap::verify(bool silent, VerifyOption option /* ignored */) {
if (!silent) {
gclog_or_tty->print("%s", _old_gen->name());
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -126,8 +126,6 @@
WorkGang* workers() const { return _workers; }
- GCStats* gc_stats(Generation* generation) const;
-
// Returns JNI_OK on success
virtual jint initialize();
--- a/hotspot/src/share/vm/gc/shared/generation.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/generation.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -58,12 +58,12 @@
(HeapWord*)_virtual_space.high_boundary());
}
-GenerationSpec* Generation::spec() {
+size_t Generation::initial_size() {
GenCollectedHeap* gch = GenCollectedHeap::heap();
if (gch->is_young_gen(this)) {
- return gch->gen_policy()->young_gen_spec();
+ return gch->gen_policy()->young_gen_spec()->init_size();
}
- return gch->gen_policy()->old_gen_spec();
+ return gch->gen_policy()->old_gen_spec()->init_size();
}
size_t Generation::max_capacity() const {
--- a/hotspot/src/share/vm/gc/shared/generation.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/generation.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -141,14 +141,14 @@
}
virtual Generation::Name kind() { return Generation::Other; }
- GenerationSpec* spec();
// This properly belongs in the collector, but for now this
// will do.
virtual bool refs_discovery_is_atomic() const { return true; }
virtual bool refs_discovery_is_mt() const { return false; }
- // Space enquiries (results in bytes)
+ // Space inquiries (results in bytes)
+ size_t initial_size();
virtual size_t capacity() const = 0; // The maximum number of object bytes the
// generation can currently hold.
virtual size_t used() const = 0; // The number of used bytes in the gen.
@@ -309,10 +309,6 @@
// do nothing.
virtual void par_oop_since_save_marks_iterate_done(int thread_num) {}
- // This generation will collect all younger generations
- // during a full collection.
- virtual bool full_collects_young_generation() const { return false; }
-
// This generation does in-place marking, meaning that mark words
// are mutated during the marking phase and presumably reinitialized
// to a canonical value after the GC. This is currently used by the
@@ -403,7 +399,7 @@
// that was most recently collected. This allows the generation to
// decide what statistics are valid to collect. For example, the
// generation can decide to gather the amount of promoted data if
- // the collection of the younger generations has completed.
+ // the collection of the young generation has completed.
GCStats* gc_stats() const { return _gc_stats; }
virtual void update_gc_stats(Generation* current_generation, bool full) {}
--- a/hotspot/src/share/vm/gc/shared/generationSpec.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/generationSpec.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -58,9 +58,7 @@
// else registers with an existing CMSCollector
ConcurrentMarkSweepGeneration* g = NULL;
- g = new ConcurrentMarkSweepGeneration(rs,
- init_size(), remset, UseCMSAdaptiveFreeLists,
- (FreeBlockDictionary<FreeChunk>::DictionaryChoice)CMSDictionaryChoice);
+ g = new ConcurrentMarkSweepGeneration(rs, init_size(), remset);
g->initialize_performance_counters();
--- a/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/gc/shared/referenceProcessor.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -373,7 +373,8 @@
// so that the References are not considered active.
while (obj != next_d) {
obj = next_d;
- assert(obj->is_instanceRef(), "should be reference object");
+ assert(obj->is_instance(), "should be an instance object");
+ assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
next_d = java_lang_ref_Reference::discovered(obj);
if (TraceReferenceGC && PrintGCDetails) {
gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -194,7 +194,7 @@
bool is_bottom_frame);
// Runtime support
- static bool is_not_reached( methodHandle method, int bci);
+ static bool is_not_reached(const methodHandle& method, int bci);
// Safepoint support
static void notice_safepoints() { ShouldNotReachHere(); } // stops the thread when reaching a safepoint
static void ignore_safepoints() { ShouldNotReachHere(); } // ignores safepoints
--- a/hotspot/src/share/vm/interpreter/bytecode.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecode.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -179,7 +179,7 @@
protected:
const methodHandle _method; // method containing the bytecode
- Bytecode_member_ref(methodHandle method, int bci) : Bytecode(method(), method()->bcp_from(bci)), _method(method) {}
+ Bytecode_member_ref(const methodHandle& method, int bci) : Bytecode(method(), method()->bcp_from(bci)), _method(method) {}
methodHandle method() const { return _method; }
ConstantPool* constants() const { return _method->constants(); }
@@ -201,10 +201,10 @@
class Bytecode_invoke: public Bytecode_member_ref {
protected:
// Constructor that skips verification
- Bytecode_invoke(methodHandle method, int bci, bool unused) : Bytecode_member_ref(method, bci) {}
+ Bytecode_invoke(const methodHandle& method, int bci, bool unused) : Bytecode_member_ref(method, bci) {}
public:
- Bytecode_invoke(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); }
+ Bytecode_invoke(const methodHandle& method, int bci) : Bytecode_member_ref(method, bci) { verify(); }
void verify() const;
// Attributes
@@ -232,10 +232,10 @@
private:
// Helper to skip verification. Used is_valid() to check if the result is really an invoke
- inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci);
+ inline friend Bytecode_invoke Bytecode_invoke_check(const methodHandle& method, int bci);
};
-inline Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci) {
+inline Bytecode_invoke Bytecode_invoke_check(const methodHandle& method, int bci) {
return Bytecode_invoke(method, bci, false);
}
@@ -243,7 +243,7 @@
// Abstraction for all field accesses (put/get field/static)
class Bytecode_field: public Bytecode_member_ref {
public:
- Bytecode_field(methodHandle method, int bci) : Bytecode_member_ref(method, bci) { verify(); }
+ Bytecode_field(const methodHandle& method, int bci) : Bytecode_member_ref(method, bci) { verify(); }
// Testers
bool is_getfield() const { return java_code() == Bytecodes::_getfield; }
@@ -316,7 +316,7 @@
int raw_index() const;
public:
- Bytecode_loadconstant(methodHandle method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); }
+ Bytecode_loadconstant(const methodHandle& method, int bci): Bytecode(method(), method->bcp_from(bci)), _method(method) { verify(); }
void verify() const {
assert(_method.not_null(), "must supply method");
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -2148,11 +2148,8 @@
if (!constants->tag_at(index).is_unresolved_klass()) {
// Make sure klass is initialized and doesn't have a finalizer
Klass* entry = constants->slot_at(index).get_klass();
- assert(entry->is_klass(), "Should be resolved klass");
- Klass* k_entry = (Klass*) entry;
- assert(k_entry->oop_is_instance(), "Should be InstanceKlass");
- InstanceKlass* ik = (InstanceKlass*) k_entry;
- if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) {
+ InstanceKlass* ik = InstanceKlass::cast(entry);
+ if (ik->is_initialized() && ik->can_be_fastpath_allocated() ) {
size_t obj_size = ik->size_helper();
oop result = NULL;
// If the TLAB isn't pre-zeroed then we'll have to do it
@@ -2609,9 +2606,9 @@
- klass: {other class}
but using InstanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure
- because rcvr->klass()->oop_is_instance() == 0
+ because rcvr->klass()->is_instance_klass() == 0
However it seems to have a vtable in the right location. Huh?
-
+ Because vtables have the same offset for ArrayKlass and InstanceKlass.
*/
callee = (Method*) rcvrKlass->start_of_vtable()[ cache->f2_as_index()];
// Profile virtual call.
--- a/hotspot/src/share/vm/interpreter/bytecodeStream.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeStream.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,7 +63,7 @@
bool _is_raw; // false in 'cooked' BytecodeStream
// Construction
- BaseBytecodeStream(methodHandle method) : _method(method) {
+ BaseBytecodeStream(const methodHandle& method) : _method(method) {
set_interval(0, _method->code_size());
_is_raw = false;
}
@@ -118,7 +118,7 @@
class RawBytecodeStream: public BaseBytecodeStream {
public:
// Construction
- RawBytecodeStream(methodHandle method) : BaseBytecodeStream(method) {
+ RawBytecodeStream(const methodHandle& method) : BaseBytecodeStream(method) {
_is_raw = true;
}
@@ -169,7 +169,7 @@
public:
// Construction
- BytecodeStream(methodHandle method) : BaseBytecodeStream(method) { }
+ BytecodeStream(const methodHandle& method) : BaseBytecodeStream(method) { }
// Iteration
Bytecodes::Code next() {
--- a/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -84,7 +84,7 @@
// This method is called while executing the raw bytecodes, so none of
// the adjustments that BytecodeStream performs applies.
- void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
+ void trace(const methodHandle& method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
ResourceMark rm;
if (_current_method != method()) {
// Note 1: This code will not work as expected with true MT/MP.
@@ -126,7 +126,7 @@
// Used for Method*::print_codes(). The input bcp comes from
// BytecodeStream, which will skip wide bytecodes.
- void trace(methodHandle method, address bcp, outputStream* st) {
+ void trace(const methodHandle& method, address bcp, outputStream* st) {
_current_method = method();
ResourceMark rm;
Bytecodes::Code code = Bytecodes::code_at(method(), bcp);
@@ -166,7 +166,7 @@
}
-void BytecodeTracer::trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
+void BytecodeTracer::trace(const methodHandle& method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) {
if (TraceBytecodes && BytecodeCounter::counter_value() >= TraceBytecodesAt) {
ttyLocker ttyl; // 5065316: keep the following output coherent
// The ttyLocker also prevents races between two threads
@@ -185,7 +185,7 @@
}
}
-void BytecodeTracer::trace(methodHandle method, address bcp, outputStream* st) {
+void BytecodeTracer::trace(const methodHandle& method, address bcp, outputStream* st) {
ttyLocker ttyl; // 5065316: keep the following output coherent
_closure->trace(method, bcp, st);
}
@@ -390,7 +390,6 @@
}
-PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
void BytecodePrinter::print_attributes(int bci, outputStream* st) {
// Show attributes of pre-rewritten codes
Bytecodes::Code code = Bytecodes::java_code(raw_code());
@@ -512,15 +511,11 @@
}
st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ",
default_dest, lo, hi);
- int first = true;
- for (int ll = lo; ll <= hi; ll++, first = false) {
+ const char *comma = "";
+ for (int ll = lo; ll <= hi; ll++) {
int idx = ll - lo;
- const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" :
- ", %d:" INT32_FORMAT " (delta: %d)";
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
- st->print(format, ll, dest[idx], dest[idx]-bci);
-PRAGMA_DIAG_POP
+ st->print("%s %d:" INT32_FORMAT " (delta: %d)", comma, ll, dest[idx], dest[idx]-bci);
+ comma = ",";
}
st->cr();
}
@@ -536,14 +531,10 @@
dest[i] = bci + get_int();
};
st->print(" %d %d ", default_dest, len);
- bool first = true;
- for (int ll = 0; ll < len; ll++, first = false) {
- const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT :
- ", " INT32_FORMAT ":" INT32_FORMAT ;
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
- st->print(format, key[ll], dest[ll]);
-PRAGMA_DIAG_POP
+ const char *comma = "";
+ for (int ll = 0; ll < len; ll++) {
+ st->print("%s " INT32_FORMAT ":" INT32_FORMAT, comma, key[ll], dest[ll]);
+ comma = ",";
}
st->cr();
}
--- a/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,8 +46,8 @@
static BytecodeClosure* closure() { return _closure; }
static void set_closure(BytecodeClosure* closure) { _closure = closure; }
- static void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st = tty);
- static void trace(methodHandle method, address bcp, outputStream* st = tty);
+ static void trace(const methodHandle& method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st = tty);
+ static void trace(const methodHandle& method, address bcp, outputStream* st = tty);
};
@@ -55,8 +55,8 @@
class BytecodeClosure {
public:
- virtual void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) = 0;
- virtual void trace(methodHandle method, address bcp, outputStream* st) = 0;
+ virtual void trace(const methodHandle& method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) = 0;
+ virtual void trace(const methodHandle& method, address bcp, outputStream* st) = 0;
};
#endif // SHARE_VM_INTERPRETER_BYTECODETRACER_HPP
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -320,7 +320,7 @@
// Return true if the interpreter can prove that the given bytecode has
// not yet been executed (in Java semantics, not in actual operation).
-bool AbstractInterpreter::is_not_reached(methodHandle method, int bci) {
+bool AbstractInterpreter::is_not_reached(const methodHandle& method, int bci) {
Bytecodes::Code code = method()->code_at(bci);
if (!Bytecodes::must_rewrite(code)) {
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -480,7 +480,7 @@
} while (should_repeat == true);
#if INCLUDE_JVMCI
- if (UseJVMCICompiler && h_method->method_data() != NULL) {
+ if (EnableJVMCI && h_method->method_data() != NULL) {
ResourceMark rm(thread);
ProfileData* pdata = h_method->method_data()->allocate_bci_to_data(current_bci, NULL);
if (pdata != NULL && pdata->is_BitData()) {
@@ -1192,7 +1192,7 @@
return handler;
}
-void SignatureHandlerLibrary::add(methodHandle method) {
+void SignatureHandlerLibrary::add(const methodHandle& method) {
if (method->signature_handler() == NULL) {
// use slow signature handler if we can't do better
int handler_index = -1;
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -218,7 +218,7 @@
static void pd_set_handler(address handler);
public:
- static void add(methodHandle method);
+ static void add(const methodHandle& method);
static void add(uint64_t fingerprint, address handler);
};
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -237,7 +237,7 @@
//------------------------------------------------------------------------------------------------------------------------
// Implementation of LinkInfo
-LinkInfo::LinkInfo(constantPoolHandle pool, int index, TRAPS) {
+LinkInfo::LinkInfo(const constantPoolHandle& pool, int index, TRAPS) {
// resolve klass
Klass* result = pool->klass_ref_at(index, CHECK);
_resolved_klass = KlassHandle(THREAD, result);
@@ -302,17 +302,19 @@
// Ignore overpasses so statics can be found during resolution
Method* result = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
- if (klass->oop_is_array()) {
+ if (klass->is_array_klass()) {
// Only consider klass and super klass for arrays
return methodHandle(THREAD, result);
}
+ InstanceKlass* ik = InstanceKlass::cast(klass());
+
// JDK 8, JVMS 5.4.3.4: Interface method resolution should
// ignore static and non-public methods of java.lang.Object,
// like clone, finalize, registerNatives.
if (in_imethod_resolve &&
result != NULL &&
- klass->is_interface() &&
+ ik->is_interface() &&
(result->is_static() || !result->is_public()) &&
result->method_holder() == SystemDictionary::Object_klass()) {
result = NULL;
@@ -321,11 +323,11 @@
// Before considering default methods, check for an overpass in the
// current class if a method has not been found.
if (result == NULL) {
- result = InstanceKlass::cast(klass())->find_method(name, signature);
+ result = ik->find_method(name, signature);
}
if (result == NULL) {
- Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
+ Array<Method*>* default_methods = ik->default_methods();
if (default_methods != NULL) {
result = InstanceKlass::find_method(default_methods, name, signature);
}
@@ -353,7 +355,7 @@
result = super_klass->uncached_lookup_method(name, signature, Klass::find_overpass);
}
- if (klass->oop_is_array()) {
+ if (klass->is_array_klass()) {
// Only consider klass and super klass for arrays
return methodHandle(THREAD, result);
}
@@ -374,21 +376,21 @@
int vtable_index = Method::invalid_vtable_index;
Symbol* name = resolved_method->name();
Symbol* signature = resolved_method->signature();
+ InstanceKlass* ik = InstanceKlass::cast(klass());
// First check in default method array
- if (!resolved_method->is_abstract() &&
- (InstanceKlass::cast(klass())->default_methods() != NULL)) {
- int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(),
+ if (!resolved_method->is_abstract() && ik->default_methods() != NULL) {
+ int index = InstanceKlass::find_method_index(ik->default_methods(),
name, signature, Klass::find_overpass,
Klass::find_static, Klass::find_private);
if (index >= 0 ) {
- vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
+ vtable_index = ik->default_vtable_indices()->at(index);
}
}
if (vtable_index == Method::invalid_vtable_index) {
// get vtable_index for miranda methods
ResourceMark rm;
- klassVtable *vt = InstanceKlass::cast(klass())->vtable();
+ klassVtable *vt = ik->vtable();
vtable_index = vt->index_of_miranda(name, signature);
}
return vtable_index;
@@ -529,7 +531,7 @@
// to be false (so we'll short-circuit out of these tests).
if (sel_method->name() == vmSymbols::clone_name() &&
sel_klass() == SystemDictionary::Object_klass() &&
- resolved_klass->oop_is_array()) {
+ resolved_klass->is_array_klass()) {
// We need to change "protected" to "public".
assert(flags.is_protected(), "clone not protected?");
jint new_flags = flags.as_int();
@@ -559,7 +561,7 @@
}
methodHandle LinkResolver::resolve_method_statically(Bytecodes::Code code,
- constantPoolHandle pool, int index, TRAPS) {
+ const constantPoolHandle& pool, int index, TRAPS) {
// This method is used only
// (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
// and
@@ -682,7 +684,7 @@
// 2. lookup method in resolved klass and its super klasses
methodHandle resolved_method = lookup_method_in_klasses(link_info, true, false, CHECK_NULL);
- if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // not found in the class hierarchy
+ if (resolved_method.is_null() && !resolved_klass->is_array_klass()) { // not found in the class hierarchy
// 3. lookup method in all the interfaces implemented by the resolved klass
resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
@@ -742,7 +744,7 @@
// JDK8: also look for static methods
methodHandle resolved_method = lookup_method_in_klasses(link_info, false, true, CHECK_NULL);
- if (resolved_method.is_null() && !resolved_klass->oop_is_array()) {
+ if (resolved_method.is_null() && !resolved_klass->is_array_klass()) {
// lookup method in all the super-interfaces
resolved_method = lookup_method_in_interfaces(link_info, CHECK_NULL);
}
@@ -816,7 +818,7 @@
}
}
-void LinkResolver::resolve_field_access(fieldDescriptor& fd, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
+void LinkResolver::resolve_field_access(fieldDescriptor& fd, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
LinkInfo link_info(pool, index, CHECK);
resolve_field(fd, link_info, byte, true, CHECK);
}
@@ -1442,7 +1444,7 @@
//------------------------------------------------------------------------------------------------------------------------
// ConstantPool entries
-void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
+void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, Bytecodes::Code byte, TRAPS) {
switch (byte) {
case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break;
case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break;
@@ -1454,20 +1456,20 @@
return;
}
-void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
+void LinkResolver::resolve_invokestatic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
LinkInfo link_info(pool, index, CHECK);
resolve_static_call(result, link_info, /*initialize_class*/true, CHECK);
}
-void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
+void LinkResolver::resolve_invokespecial(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
LinkInfo link_info(pool, index, CHECK);
resolve_special_call(result, link_info, CHECK);
}
void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
- constantPoolHandle pool, int index,
+ const constantPoolHandle& pool, int index,
TRAPS) {
LinkInfo link_info(pool, index, CHECK);
@@ -1476,14 +1478,14 @@
}
-void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
+void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, const constantPoolHandle& pool, int index, TRAPS) {
LinkInfo link_info(pool, index, CHECK);
KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
resolve_interface_call(result, recv, recvrKlass, link_info, true, CHECK);
}
-void LinkResolver::resolve_invokehandle(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
+void LinkResolver::resolve_invokehandle(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
// This guy is reached from InterpreterRuntime::resolve_invokehandle.
LinkInfo link_info(pool, index, CHECK);
if (TraceMethodHandles) {
@@ -1528,7 +1530,7 @@
}
}
-void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
+void LinkResolver::resolve_invokedynamic(CallInfo& result, const constantPoolHandle& pool, int index, TRAPS) {
Symbol* method_name = pool->name_ref_at(index);
Symbol* method_signature = pool->signature_ref_at(index);
KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder());
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -136,7 +136,7 @@
KlassHandle _current_klass; // class that owns the constant pool
bool _check_access;
public:
- LinkInfo(constantPoolHandle pool, int index, TRAPS);
+ LinkInfo(const constantPoolHandle& pool, int index, TRAPS);
// Condensed information from other call sites within the vm.
LinkInfo(KlassHandle resolved_klass, Symbol* name, Symbol* signature,
KlassHandle current_klass, bool check_access = true) :
@@ -226,17 +226,17 @@
// runtime resolving from constant pool
static void resolve_invokestatic (CallInfo& result,
- constantPoolHandle pool, int index, TRAPS);
+ const constantPoolHandle& pool, int index, TRAPS);
static void resolve_invokespecial (CallInfo& result,
- constantPoolHandle pool, int index, TRAPS);
+ const constantPoolHandle& pool, int index, TRAPS);
static void resolve_invokevirtual (CallInfo& result, Handle recv,
- constantPoolHandle pool, int index, TRAPS);
+ const constantPoolHandle& pool, int index, TRAPS);
static void resolve_invokeinterface(CallInfo& result, Handle recv,
- constantPoolHandle pool, int index, TRAPS);
+ const constantPoolHandle& pool, int index, TRAPS);
static void resolve_invokedynamic (CallInfo& result,
- constantPoolHandle pool, int index, TRAPS);
+ const constantPoolHandle& pool, int index, TRAPS);
static void resolve_invokehandle (CallInfo& result,
- constantPoolHandle pool, int index, TRAPS);
+ const constantPoolHandle& pool, int index, TRAPS);
public:
// constant pool resolving
static void check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS);
@@ -244,11 +244,11 @@
// static resolving calls (will not run any Java code);
// used only from Bytecode_invoke::static_target
static methodHandle resolve_method_statically(Bytecodes::Code code,
- constantPoolHandle pool,
+ const constantPoolHandle& pool,
int index, TRAPS);
static void resolve_field_access(fieldDescriptor& result,
- constantPoolHandle pool,
+ const constantPoolHandle& pool,
int index, Bytecodes::Code byte, TRAPS);
static void resolve_field(fieldDescriptor& result, const LinkInfo& link_info,
Bytecodes::Code access_kind,
@@ -293,7 +293,7 @@
// runtime resolving from constant pool
static void resolve_invoke(CallInfo& result, Handle recv,
- constantPoolHandle pool, int index,
+ const constantPoolHandle& pool, int index,
Bytecodes::Code byte, TRAPS);
private:
static void trace_method_resolution(const char* prefix, KlassHandle klass,
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -426,7 +426,7 @@
}
}
-inline unsigned int OopMapCache::hash_value_for(methodHandle method, int bci) const {
+inline unsigned int OopMapCache::hash_value_for(const methodHandle& method, int bci) const {
// We use method->code_size() rather than method->identity_hash() below since
// the mark may not be present if a pointer to the method is already reversed.
return ((unsigned int) bci)
@@ -477,7 +477,7 @@
}
}
-void OopMapCache::lookup(methodHandle method,
+void OopMapCache::lookup(const methodHandle& method,
int bci,
InterpreterOopMap* entry_for) const {
MutexLocker x(&_mut);
@@ -558,7 +558,7 @@
return;
}
-void OopMapCache::compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry) {
+void OopMapCache::compute_one_oop_map(const methodHandle& method, int bci, InterpreterOopMap* entry) {
// Due to the invariants above it's tricky to allocate a temporary OopMapCacheEntry on the stack
OopMapCacheEntry* tmp = NEW_C_HEAP_ARRAY(OopMapCacheEntry, 1, mtClass);
tmp->initialize();
--- a/hotspot/src/share/vm/interpreter/oopMapCache.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -116,7 +116,7 @@
void set_expression_stack_size(int sz) { _expression_stack_size = sz; }
// Lookup
- bool match(methodHandle method, int bci) const { return _method == method() && _bci == bci; }
+ bool match(const methodHandle& method, int bci) const { return _method == method() && _bci == bci; }
bool is_empty() const;
// Initialization
@@ -151,7 +151,7 @@
OopMapCacheEntry* _array;
- unsigned int hash_value_for(methodHandle method, int bci) const;
+ unsigned int hash_value_for(const methodHandle& method, int bci) const;
OopMapCacheEntry* entry_at(int i) const;
mutable Mutex _mut;
@@ -167,10 +167,10 @@
// Returns the oopMap for (method, bci) in parameter "entry".
// Returns false if an oop map was not found.
- void lookup(methodHandle method, int bci, InterpreterOopMap* entry) const;
+ void lookup(const methodHandle& method, int bci, InterpreterOopMap* entry) const;
// Compute an oop map without updating the cache or grabbing any locks (for debugging)
- static void compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry);
+ static void compute_one_oop_map(const methodHandle& method, int bci, InterpreterOopMap* entry);
// Returns total no. of bytes allocated as part of OopMapCache's
static long memory_usage() PRODUCT_RETURN0;
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -509,7 +509,7 @@
// (That's all, folks.)
}
-Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS)
+Rewriter::Rewriter(instanceKlassHandle klass, const constantPoolHandle& cpool, Array<Method*>* methods, TRAPS)
: _klass(klass),
_pool(cpool),
_methods(methods)
--- a/hotspot/src/share/vm/interpreter/rewriter.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/rewriter.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -185,7 +185,7 @@
}
// All the work goes in here:
- Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS);
+ Rewriter(instanceKlassHandle klass, const constantPoolHandle& cpool, Array<Method*>* methods, TRAPS);
void compute_index_maps();
void make_constant_pool_cache(TRAPS);
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -562,7 +562,7 @@
if (StopInterpreterAt > 0) stop_interpreter_at();
__ verify_FPU(1, t->tos_in());
#endif // !PRODUCT
- int step;
+ int step = 0;
if (!t->does_dispatch()) {
step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
if (tos_out == ilgl) tos_out = t->tos_out();
--- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -142,42 +142,38 @@
return map;
}
-static void record_metadata_reference(oop obj, jlong prim, jboolean compressed, OopRecorder* oop_recorder) {
+Metadata* CodeInstaller::record_metadata_reference(Handle& constant) {
+ oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
- if (compressed) {
- assert(Klass::decode_klass((narrowKlass) prim) == klass, "%s @ " INTPTR_FORMAT " != " PTR64_FORMAT, klass->name()->as_C_string(), p2i(klass), prim);
- } else {
- assert((Klass*) prim == klass, "%s @ " INTPTR_FORMAT " != " PTR64_FORMAT, klass->name()->as_C_string(), p2i(klass), prim);
- }
- int index = oop_recorder->find_index(klass);
- TRACE_jvmci_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
+ assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed klass pointer %s @ " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass));
+ int index = _oop_recorder->find_index(klass);
+ TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
+ return klass;
} else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj);
- assert(!compressed, "unexpected compressed method pointer %s @ " INTPTR_FORMAT " = " PTR64_FORMAT, method->name()->as_C_string(), p2i(method), prim);
- int index = oop_recorder->find_index(method);
- TRACE_jvmci_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string());
+ assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed method pointer %s @ " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method));
+ int index = _oop_recorder->find_index(method);
+ TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string());
+ return method;
} else {
- assert(java_lang_String::is_instance(obj),
- "unexpected metadata reference (%s) for constant " JLONG_FORMAT " (" PTR64_FORMAT ")", obj->klass()->name()->as_C_string(), prim, prim);
+ fatal("unexpected metadata reference for constant of type %s", obj->klass()->name()->as_C_string());
+ return NULL;
}
}
-// Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectTypeImpl.klass()).
-static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) {
- if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
- oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
- jlong prim = HotSpotMetaspaceConstantImpl::primitive(constant);
- assert(obj != NULL, "must have an object");
- assert(prim != 0, "must have a primitive value");
+#ifdef _LP64
+narrowKlass CodeInstaller::record_narrow_metadata_reference(Handle& constant) {
+ oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
+ assert(HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected uncompressed pointer");
+ assert(obj->is_a(HotSpotResolvedObjectTypeImpl::klass()), "unexpected compressed pointer of type %s", obj->klass()->name()->as_C_string());
- record_metadata_reference(obj, prim, false, oop_recorder);
- }
+ Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
+ int index = _oop_recorder->find_index(klass);
+ TRACE_jvmci_3("narrowKlass[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
+ return Klass::encode_klass(klass);
}
-
-static void record_metadata_in_patch(Handle& constant, OopRecorder* oop_recorder) {
- record_metadata_reference(HotSpotMetaspaceConstantImpl::metaspaceObject(constant), HotSpotMetaspaceConstantImpl::primitive(constant), HotSpotMetaspaceConstantImpl::compressed(constant), oop_recorder);
-}
+#endif
Location::Type CodeInstaller::get_oop_type(oop value) {
oop lirKind = Value::lirKind(value);
@@ -253,7 +249,6 @@
}
return value;
} else if (value->is_a(JavaConstant::klass())) {
- record_metadata_in_constant(value, _oop_recorder);
if (value->is_a(PrimitiveConstant::klass())) {
if (value->is_a(RawConstant::klass())) {
jlong prim = PrimitiveConstant::primitive(value);
@@ -379,14 +374,15 @@
}
}
}
- objArrayHandle methods = HotSpotCompiledCode::methods(compiled_code);
- if (!methods.is_null()) {
- int length = methods->length();
- for (int i = 0; i < length; ++i) {
- Handle method_handle = methods->obj_at(i);
- methodHandle method = getMethodFromHotSpotMethod(method_handle());
-
- _dependencies->assert_evol_method(method());
+ if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
+ objArrayHandle methods = HotSpotCompiledCode::methods(compiled_code);
+ if (!methods.is_null()) {
+ int length = methods->length();
+ for (int i = 0; i < length; ++i) {
+ Handle method_handle = methods->obj_at(i);
+ methodHandle method = getMethodFromHotSpotMethod(method_handle());
+ _dependencies->assert_evol_method(method());
+ }
}
}
}
@@ -543,7 +539,7 @@
}
int CodeInstaller::estimate_stubs_size() {
- // Return size for all stubs.
+ // Estimate the number of static call stubs that might be emitted.
int static_call_stubs = 0;
objArrayOop sites = this->sites();
for (int i = 0; i < sites->length(); i++) {
@@ -564,6 +560,7 @@
// perform data and call relocation on the CodeBuffer
JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer) {
+ HandleMark hm;
objArrayHandle sites = this->sites();
int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo));
@@ -606,14 +603,22 @@
Handle reference = CompilationResult_DataPatch::reference(patch);
assert(reference->is_a(CompilationResult_ConstantReference::klass()), "patch in data section must be a ConstantReference");
Handle constant = CompilationResult_ConstantReference::constant(reference);
+ address dest = _constants->start() + CompilationResult_Site::pcOffset(patch);
if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
- record_metadata_in_patch(constant, _oop_recorder);
+ if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
+#ifdef _LP64
+ *((narrowKlass*) dest) = record_narrow_metadata_reference(constant);
+#else
+ fatal("unexpected compressed Klass* in 32-bit mode");
+#endif
+ } else {
+ *((Metadata**) dest) = record_metadata_reference(constant);
+ }
} else if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
Handle obj = HotSpotObjectConstantImpl::object(constant);
jobject value = JNIHandles::make_local(obj());
int oop_index = _oop_recorder->find_index(value);
- address dest = _constants->start() + CompilationResult_Site::pcOffset(patch);
if (HotSpotObjectConstantImpl::compressed(constant)) {
#ifdef _LP64
_constants->relocate(dest, oop_Relocation::spec(oop_index), relocInfo::narrow_oop_in_const);
@@ -960,7 +965,7 @@
if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
pd_patch_OopConstant(pc_offset, constant);
} else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
- record_metadata_in_patch(constant, _oop_recorder);
+ pd_patch_MetaspaceConstant(pc_offset, constant);
} else if (constant->is_a(HotSpotSentinelConstant::klass())) {
fatal("sentinel constant unsupported");
} else {
@@ -1014,6 +1019,7 @@
case POLL_RETURN_FAR:
pd_relocate_poll(pc, id);
break;
+ case CARD_TABLE_SHIFT:
case CARD_TABLE_ADDRESS:
case HEAP_TOP_ADDRESS:
case HEAP_END_ADDRESS:
--- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -107,10 +107,11 @@
POLL_FAR = 13,
POLL_RETURN_FAR = 14,
CARD_TABLE_ADDRESS = 15,
- HEAP_TOP_ADDRESS = 16,
- HEAP_END_ADDRESS = 17,
- NARROW_KLASS_BASE_ADDRESS = 18,
- CRC_TABLE_ADDRESS = 19,
+ CARD_TABLE_SHIFT = 16,
+ HEAP_TOP_ADDRESS = 17,
+ HEAP_END_ADDRESS = 18,
+ NARROW_KLASS_BASE_ADDRESS = 19,
+ CRC_TABLE_ADDRESS = 20,
INVOKE_INVALID = -1
};
@@ -155,8 +156,8 @@
jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method);
void pd_patch_OopConstant(int pc_offset, Handle& constant);
+ void pd_patch_MetaspaceConstant(int pc_offset, Handle& constant);
void pd_patch_DataSectionReference(int pc_offset, int data_offset);
- void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst);
void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination);
void pd_relocate_JavaMethod(oop method, jint pc_offset);
void pd_relocate_poll(address pc, jint mark);
@@ -170,11 +171,10 @@
objArrayOop comments() { return (objArrayOop) JNIHandles::resolve(_comments_handle); }
#endif
- void record_resolved(oop obj);
-
oop word_kind() { return (oop) JNIHandles::resolve(_word_kind_handle); }
public:
+
CodeInstaller() : _arena(mtCompiler) {}
JVMCIEnv::CodeInstallResult gather_metadata(Handle target, Handle& compiled_code, CodeMetadata& metadata);
@@ -191,6 +191,11 @@
ScopeValue* get_scope_value(oop value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second);
MonitorValue* get_monitor_value(oop value, GrowableArray<ScopeValue*>* objects);
+ Metadata* record_metadata_reference(Handle& constant);
+#ifdef _LP64
+ narrowKlass record_narrow_metadata_reference(Handle& constant);
+#endif
+
// extract the fields of the CompilationResult
void initialize_fields(oop target, oop target_method);
void initialize_dependencies(oop target_method, OopRecorder* oop_recorder);
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,10 @@
}
void JVMCICompiler::bootstrap() {
+ if (Arguments::mode() == Arguments::_int) {
+ // Nothing to do in -Xint mode
+ return;
+ }
#ifndef PRODUCT
// We turn off CompileTheWorld so that compilation requests are not
// ignored during bootstrap or that JVMCI can be compiled by C1/C2.
@@ -72,7 +76,7 @@
}
jlong start = os::javaTimeMillis();
- Array<Method*>* objectMethods = InstanceKlass::cast(SystemDictionary::Object_klass())->methods();
+ Array<Method*>* objectMethods = SystemDictionary::Object_klass()->methods();
// Initialize compile queue with a selected set of methods.
int len = objectMethods->length();
for (int i = 0; i < len; i++) {
@@ -125,22 +129,40 @@
Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_ABORT);
JavaValue method_result(T_OBJECT);
- {
+ JavaCallArguments args;
+ args.push_long((jlong) (address) method());
+ JavaCalls::call_static(&method_result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(),
+ vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
+
+ if (!HAS_PENDING_EXCEPTION) {
+ JavaValue result(T_VOID);
JavaCallArguments args;
- args.push_long((jlong) (address) method());
- JavaCalls::call_static(&method_result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, CHECK_ABORT);
+ args.push_oop(receiver);
+ args.push_oop((oop)method_result.get_jobject());
+ args.push_int(entry_bci);
+ args.push_long((jlong) (address) env);
+ args.push_int(env->task()->compile_id());
+ JavaCalls::call_special(&result, receiver->klass(),
+ vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
}
- JavaValue result(T_VOID);
- JavaCallArguments args;
- args.push_oop(receiver);
- args.push_oop((oop)method_result.get_jobject());
- args.push_int(entry_bci);
- args.push_long((jlong) (address) env);
- args.push_int(env->task()->compile_id());
- JavaCalls::call_special(&result, receiver->klass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, CHECK_ABORT);
+ // An uncaught exception was thrown during compilation. Generally these
+ // should be handled by the Java code in some useful way but if they leak
+ // through to here report them instead of dying or silently ignoring them.
+ if (HAS_PENDING_EXCEPTION) {
+ Handle throwable = PENDING_EXCEPTION;
+ CLEAR_PENDING_EXCEPTION;
- _methodsCompiled++;
+ JVMCIRuntime::call_printStackTrace(throwable, THREAD);
+ if (HAS_PENDING_EXCEPTION) {
+ CLEAR_PENDING_EXCEPTION;
+ }
+
+ // Something went wrong so disable compilation at this level
+ method->set_not_compilable(CompLevel_full_optimization);
+ } else {
+ _methodsCompiled++;
+ }
}
@@ -149,6 +171,13 @@
ShouldNotReachHere();
}
+bool JVMCICompiler::is_trivial(Method* method) {
+ if (_bootstrapping) {
+ return false;
+ }
+ return JVMCIRuntime::treat_as_trivial(method);
+}
+
// Print compilation timers and statistics
void JVMCICompiler::print_timers() {
print_compilation_timers();
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -73,6 +73,8 @@
void compile_method(methodHandle target, int entry_bci, JVMCIEnv* env);
+ virtual bool is_trivial(Method* method);
+
// Print compilation timers and statistics
virtual void print_timers();
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -60,7 +60,7 @@
#define C2V_END }
-oop CompilerToVM::get_jvmci_method(methodHandle method, TRAPS) {
+oop CompilerToVM::get_jvmci_method(const methodHandle& method, TRAPS) {
if (method() != NULL) {
JavaValue result(T_OBJECT);
JavaCallArguments args;
@@ -84,6 +84,24 @@
return NULL;
}
+void CompilerToVM::invalidate_installed_code(Handle installedCode, TRAPS) {
+ if (installedCode() == NULL) {
+ THROW(vmSymbols::java_lang_NullPointerException());
+ }
+ jlong nativeMethod = InstalledCode::address(installedCode);
+ nmethod* nm = (nmethod*)nativeMethod;
+ assert(nm == NULL || nm->jvmci_installed_code() == installedCode(), "sanity check");
+ if (nm != NULL && nm->is_alive()) {
+ // The nmethod state machinery maintains the link between the
+ // HotSpotInstalledCode and nmethod* so as long as the nmethod appears to be
+ // alive assume there is work to do and deoptimize the nmethod.
+ nm->mark_for_deoptimization();
+ VM_Deoptimize op;
+ VMThread::execute(&op);
+ }
+ InstalledCode::set_address(installedCode, 0);
+}
+
extern "C" {
extern VMStructEntry* gHotSpotVMStructs;
extern uint64_t gHotSpotVMStructEntryTypeNameOffset;
@@ -538,8 +556,8 @@
if (!method->method_holder()->is_interface()) {
THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string()));
}
- if (!InstanceKlass::cast(klass)->is_initialized()) {
- THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be initialized", klass->external_name()));
+ if (!InstanceKlass::cast(klass)->is_linked()) {
+ THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be linked", klass->external_name()));
}
return LinkResolver::vtable_index_of_interface_method(klass, method);
C2V_END
@@ -549,7 +567,7 @@
Klass* caller_klass = CompilerToVM::asKlass(caller_jvmci_type);
Method* method = CompilerToVM::asMethod(jvmci_method);
- if (recv_klass->oop_is_array() || (InstanceKlass::cast(recv_klass)->is_linked())) {
+ if (recv_klass->is_array_klass() || (InstanceKlass::cast(recv_klass)->is_linked())) {
Klass* holder_klass = method->method_holder();
Symbol* method_name = method->name();
Symbol* method_signature = method->signature();
@@ -670,8 +688,13 @@
} else {
if (!installed_code_handle.is_null()) {
assert(installed_code_handle->is_a(InstalledCode::klass()), "wrong type");
+ CompilerToVM::invalidate_installed_code(installed_code_handle, CHECK_0);
InstalledCode::set_address(installed_code_handle, (jlong) cb);
- InstalledCode::set_version(installed_code_handle, InstalledCode::version(installed_code_handle) + 1);
+ if (cb->is_nmethod()) {
+ InstalledCode::set_entryPoint(installed_code_handle, (jlong) cb->as_nmethod_or_null()->verified_entry_point());
+ } else {
+ InstalledCode::set_entryPoint(installed_code_handle, (jlong) cb->code_begin());
+ }
if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) {
HotSpotInstalledCode::set_size(installed_code_handle, cb->size());
HotSpotInstalledCode::set_codeStart(installed_code_handle, (jlong) cb->code_begin());
@@ -782,10 +805,19 @@
stats->_osr.reset();
C2V_END
-C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv *jniEnv, jobject, jlong codeBlob))
+C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv *jniEnv, jobject, jobject installedCode))
ResourceMark rm;
HandleMark hm;
+ if (installedCode == NULL) {
+ THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(), "installedCode is null");
+ }
+
+ jlong codeBlob = InstalledCode::address(installedCode);
+ if (codeBlob == 0L) {
+ return NULL;
+ }
+
CodeBlob* cb = (CodeBlob*) (address) codeBlob;
if (cb == NULL) {
return NULL;
@@ -936,15 +968,9 @@
C2V_END
-C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv*, jobject, jobject hotspotInstalledCode))
- jlong nativeMethod = InstalledCode::address(hotspotInstalledCode);
- nmethod* m = (nmethod*)nativeMethod;
- if (m != NULL && !m->is_not_entrant()) {
- m->mark_for_deoptimization();
- VM_Deoptimize op;
- VMThread::execute(&op);
- }
- InstalledCode::set_address(hotspotInstalledCode, 0);
+C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv*, jobject, jobject installed_code))
+ Handle installed_code_handle = JNIHandles::resolve(installed_code);
+ CompilerToVM::invalidate_installed_code(installed_code_handle, CHECK);
C2V_END
C2V_VMENTRY(jobject, readUncompressedOop, (JNIEnv*, jobject, jlong addr))
@@ -991,7 +1017,8 @@
objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
for (int i = 0; i < methods_oop->length(); i++) {
- if (CompilerToVM::asMethod(methods_oop->obj_at(i)) == method) {
+ oop resolved = methods_oop->obj_at(i);
+ if (resolved->is_a(HotSpotResolvedJavaMethodImpl::klass()) && CompilerToVM::asMethod(resolved) == method) {
return true;
}
}
@@ -1284,11 +1311,29 @@
tty->flush();
C2V_END
+C2V_VMENTRY(int, methodDataProfileDataSize, (JNIEnv*, jobject, jlong metaspace_method_data, jint position))
+ ResourceMark rm;
+ MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data);
+ ProfileData* profile_data = mdo->data_at(position);
+ if (mdo->is_valid(profile_data)) {
+ return profile_data->size_in_bytes();
+ }
+ DataLayout* data = mdo->extra_data_base();
+ DataLayout* end = mdo->extra_data_limit();
+ for (;; data = mdo->next_extra(data)) {
+ assert(data < end, "moved past end of extra data");
+ profile_data = data->data_in();
+ if (mdo->dp_to_di(profile_data->dp()) == position) {
+ return profile_data->size_in_bytes();
+ }
+ }
+ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Invalid profile data position %d", position));
+C2V_END
+
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
-#define SPECULATION_LOG "Ljdk/vm/ci/meta/SpeculationLog;"
#define STRING "Ljava/lang/String;"
#define OBJECT "Ljava/lang/Object;"
#define CLASS "Ljava/lang/Class;"
@@ -1300,8 +1345,10 @@
#define HS_RESOLVED_KLASS "Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;"
#define HS_CONSTANT_POOL "Ljdk/vm/ci/hotspot/HotSpotConstantPool;"
#define HS_COMPILED_CODE "Ljdk/vm/ci/hotspot/HotSpotCompiledCode;"
+#define HS_CONFIG "Ljdk/vm/ci/hotspot/HotSpotVMConfig;"
#define HS_METADATA "Ljdk/vm/ci/hotspot/HotSpotMetaData;"
#define HS_STACK_FRAME_REF "Ljdk/vm/ci/hotspot/HotSpotStackFrameReference;"
+#define HS_SPECULATION_LOG "Ljdk/vm/ci/hotspot/HotSpotSpeculationLog;"
#define METASPACE_METHOD_DATA "J"
JNINativeMethod CompilerToVM::methods[] = {
@@ -1339,12 +1386,12 @@
{CC"getResolvedJavaMethod", CC"(Ljava/lang/Object;J)"HS_RESOLVED_METHOD, FN_PTR(getResolvedJavaMethod)},
{CC"getConstantPool", CC"(Ljava/lang/Object;J)"HS_CONSTANT_POOL, FN_PTR(getConstantPool)},
{CC"getResolvedJavaType", CC"(Ljava/lang/Object;JZ)"HS_RESOLVED_KLASS, FN_PTR(getResolvedJavaType)},
- {CC"initializeConfiguration", CC"()J", FN_PTR(initializeConfiguration)},
- {CC"installCode", CC"("TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE SPECULATION_LOG")I", FN_PTR(installCode)},
+ {CC"initializeConfiguration", CC"("HS_CONFIG")J", FN_PTR(initializeConfiguration)},
+ {CC"installCode", CC"("TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG")I", FN_PTR(installCode)},
{CC"getMetadata", CC"("TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA")I", FN_PTR(getMetadata)},
{CC"notifyCompilationStatistics", CC"(I"HS_RESOLVED_METHOD"ZIJJ"INSTALLED_CODE")V", FN_PTR(notifyCompilationStatistics)},
{CC"resetCompilationStatistics", CC"()V", FN_PTR(resetCompilationStatistics)},
- {CC"disassembleCodeBlob", CC"(J)"STRING, FN_PTR(disassembleCodeBlob)},
+ {CC"disassembleCodeBlob", CC"("INSTALLED_CODE")"STRING, FN_PTR(disassembleCodeBlob)},
{CC"executeInstalledCode", CC"(["OBJECT INSTALLED_CODE")"OBJECT, FN_PTR(executeInstalledCode)},
{CC"getLineNumberTable", CC"("HS_RESOLVED_METHOD")[J", FN_PTR(getLineNumberTable)},
{CC"getLocalVariableTableStart", CC"("HS_RESOLVED_METHOD")J", FN_PTR(getLocalVariableTableStart)},
@@ -1357,11 +1404,12 @@
{CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)},
{CC"hasCompiledCodeForOSR", CC"("HS_RESOLVED_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)},
{CC"getSymbol", CC"(J)"STRING, FN_PTR(getSymbol)},
- {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF "["HS_RESOLVED_METHOD"I)"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)},
+ {CC"getNextStackFrame", CC"("HS_STACK_FRAME_REF "["RESOLVED_METHOD"I)"HS_STACK_FRAME_REF, FN_PTR(getNextStackFrame)},
{CC"materializeVirtualObjects", CC"("HS_STACK_FRAME_REF"Z)V", FN_PTR(materializeVirtualObjects)},
{CC"shouldDebugNonSafepoints", CC"()Z", FN_PTR(shouldDebugNonSafepoints)},
{CC"writeDebugOutput", CC"([BII)V", FN_PTR(writeDebugOutput)},
{CC"flushDebugOutput", CC"()V", FN_PTR(flushDebugOutput)},
+ {CC"methodDataProfileDataSize", CC"(JI)I", FN_PTR(methodDataProfileDataSize)},
};
int CompilerToVM::methods_count() {
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -94,9 +94,11 @@
return (MethodData*) (address) metaspaceMethodData;
}
- static oop get_jvmci_method(methodHandle method, TRAPS);
+ static oop get_jvmci_method(const methodHandle& method, TRAPS);
static oop get_jvmci_type(KlassHandle klass, TRAPS);
+
+ static void invalidate_installed_code(Handle installedCode, TRAPS);
};
class JavaArgumentUnboxer : public SignatureIterator {
--- a/hotspot/src/share/vm/jvmci/jvmciEnv.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciEnv.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,18 +64,18 @@
// Note: the logic of this method should mirror the logic of
// constantPoolOopDesc::verify_constant_pool_resolve.
bool JVMCIEnv::check_klass_accessibility(KlassHandle accessing_klass, KlassHandle resolved_klass) {
- if (accessing_klass->oop_is_objArray()) {
+ if (accessing_klass->is_objArray_klass()) {
accessing_klass = ObjArrayKlass::cast(accessing_klass())->bottom_klass();
}
- if (!accessing_klass->oop_is_instance()) {
+ if (!accessing_klass->is_instance_klass()) {
return true;
}
- if (resolved_klass->oop_is_objArray()) {
+ if (resolved_klass->is_objArray_klass()) {
// Find the element klass, if this is an array.
resolved_klass = ObjArrayKlass::cast(resolved_klass())->bottom_klass();
}
- if (resolved_klass->oop_is_instance()) {
+ if (resolved_klass->is_instance_klass()) {
return Reflection::verify_class_access(accessing_klass(), resolved_klass(), true);
}
return true;
@@ -83,7 +83,7 @@
// ------------------------------------------------------------------
KlassHandle JVMCIEnv::get_klass_by_name_impl(KlassHandle& accessing_klass,
- constantPoolHandle& cpool,
+ const constantPoolHandle& cpool,
Symbol* sym,
bool require_local) {
JVMCI_EXCEPTION_CONTEXT;
@@ -174,7 +174,7 @@
// ------------------------------------------------------------------
// Implementation of get_klass_by_index.
-KlassHandle JVMCIEnv::get_klass_by_index_impl(constantPoolHandle& cpool,
+KlassHandle JVMCIEnv::get_klass_by_index_impl(const constantPoolHandle& cpool,
int index,
bool& is_accessible,
KlassHandle& accessor) {
@@ -215,7 +215,7 @@
// ------------------------------------------------------------------
// Get a klass from the constant pool.
-KlassHandle JVMCIEnv::get_klass_by_index(constantPoolHandle& cpool,
+KlassHandle JVMCIEnv::get_klass_by_index(const constantPoolHandle& cpool,
int index,
bool& is_accessible,
KlassHandle& accessor) {
@@ -312,7 +312,7 @@
// ------------------------------------------------------------------
-methodHandle JVMCIEnv::get_method_by_index_impl(constantPoolHandle& cpool,
+methodHandle JVMCIEnv::get_method_by_index_impl(const constantPoolHandle& cpool,
int index, Bytecodes::Code bc,
instanceKlassHandle& accessor) {
if (bc == Bytecodes::_invokedynamic) {
@@ -383,9 +383,9 @@
// For the case of <array>.clone(), the method holder can be an ArrayKlass*
// instead of an InstanceKlass*. For that case simply pretend that the
// declared holder is Object.clone since that's where the call will bottom out.
- if (method_holder->oop_is_instance()) {
+ if (method_holder->is_instance_klass()) {
return instanceKlassHandle(method_holder());
- } else if (method_holder->oop_is_array()) {
+ } else if (method_holder->is_array_klass()) {
return instanceKlassHandle(SystemDictionary::Object_klass());
} else {
ShouldNotReachHere();
@@ -395,7 +395,7 @@
// ------------------------------------------------------------------
-methodHandle JVMCIEnv::get_method_by_index(constantPoolHandle& cpool,
+methodHandle JVMCIEnv::get_method_by_index(const constantPoolHandle& cpool,
int index, Bytecodes::Code bc,
instanceKlassHandle& accessor) {
ResourceMark rm;
@@ -494,12 +494,12 @@
MethodData* mdp = method()->method_data();
if (mdp != NULL) {
mdp->inc_decompile_count();
+#ifdef ASSERT
if (mdp->decompile_count() > (uint)PerMethodRecompilationCutoff) {
- // TODO (chaeubl) enable this in the fastdebug build only once we are more stable
ResourceMark m;
tty->print_cr("WARN: endless recompilation of %s. Method was set to not compilable.", method()->name_and_sig_as_C_string());
- //ShouldNotReachHere();
}
+#endif
}
// All buffers in the CodeBuffer are allocated in the CodeCache.
--- a/hotspot/src/share/vm/jvmci/jvmciEnv.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciEnv.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -83,13 +83,13 @@
bool require_local);
// Constant pool access.
- static KlassHandle get_klass_by_index(constantPoolHandle& cpool,
+ static KlassHandle get_klass_by_index(const constantPoolHandle& cpool,
int klass_index,
bool& is_accessible,
KlassHandle& loading_klass);
static void get_field_by_index(instanceKlassHandle& loading_klass, fieldDescriptor& fd,
int field_index);
- static methodHandle get_method_by_index(constantPoolHandle& cpool,
+ static methodHandle get_method_by_index(const constantPoolHandle& cpool,
int method_index, Bytecodes::Code bc,
instanceKlassHandle& loading_klass);
@@ -106,16 +106,16 @@
// Implementation methods for loading and constant pool access.
static KlassHandle get_klass_by_name_impl(KlassHandle& accessing_klass,
- constantPoolHandle& cpool,
+ const constantPoolHandle& cpool,
Symbol* klass_name,
bool require_local);
- static KlassHandle get_klass_by_index_impl(constantPoolHandle& cpool,
+ static KlassHandle get_klass_by_index_impl(const constantPoolHandle& cpool,
int klass_index,
bool& is_accessible,
KlassHandle& loading_klass);
static void get_field_by_index_impl(instanceKlassHandle& loading_klass, fieldDescriptor& fd,
int field_index);
- static methodHandle get_method_by_index_impl(constantPoolHandle& cpool,
+ static methodHandle get_method_by_index_impl(const constantPoolHandle& cpool,
int method_index, Bytecodes::Code bc,
instanceKlassHandle& loading_klass);
--- a/hotspot/src/share/vm/jvmci/jvmciJavaClasses.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -71,7 +71,6 @@
void JVMCIJavaClasses::compute_offsets() {
COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
- guarantee(InstalledCode::_address_offset == sizeof(oopDesc), "codeBlob must be first field!");
}
#define EMPTY0
--- a/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -65,6 +65,7 @@
end_class \
start_class(InstalledCode) \
long_field(InstalledCode, address) \
+ long_field(InstalledCode, entryPoint) \
long_field(InstalledCode, version) \
oop_field(InstalledCode, name, "Ljava/lang/String;") \
end_class \
@@ -215,8 +216,7 @@
boolean_field(HotSpotObjectConstantImpl, compressed) \
end_class \
start_class(HotSpotMetaspaceConstantImpl) \
- long_field(HotSpotMetaspaceConstantImpl, primitive) \
- oop_field(HotSpotMetaspaceConstantImpl, metaspaceObject, "Ljava/lang/Object;") \
+ oop_field(HotSpotMetaspaceConstantImpl, metaspaceObject, "Ljdk/vm/ci/hotspot/MetaspaceWrapperObject;") \
boolean_field(HotSpotMetaspaceConstantImpl, compressed) \
end_class \
start_class(HotSpotSentinelConstant) \
@@ -261,11 +261,11 @@
end_class \
start_class(StackLockValue) \
oop_field(StackLockValue, owner, "Ljdk/vm/ci/meta/JavaValue;") \
- oop_field(StackLockValue, slot, "Ljdk/vm/ci/code/StackSlotValue;") \
+ oop_field(StackLockValue, slot, "Ljdk/vm/ci/meta/AllocatableValue;") \
boolean_field(StackLockValue, eliminated) \
end_class \
- start_class(SpeculationLog) \
- oop_field(SpeculationLog, lastFailed, "Ljava/lang/Object;") \
+ start_class(HotSpotSpeculationLog) \
+ oop_field(HotSpotSpeculationLog, lastFailed, "Ljava/lang/Object;") \
end_class \
start_class(HotSpotStackFrameReference) \
oop_field(HotSpotStackFrameReference, compilerToVM, "Ljdk/vm/ci/hotspot/CompilerToVM;") \
@@ -292,9 +292,11 @@
start_class(HotSpotConstantPool) \
long_field(HotSpotConstantPool, metaspaceConstantPool) \
end_class \
+ start_class(HotSpotJVMCIRuntime) \
+ objArrayOop_field(HotSpotJVMCIRuntime, trivialPrefixes, "[Ljava/lang/String;") \
+ end_class \
/* end*/
-
#define START_CLASS(name) \
class name : AllStatic { \
private: \
@@ -306,7 +308,7 @@
} \
static void compute_offsets(); \
public: \
- static InstanceKlass* klass() { return SystemDictionary::name##_klass() == NULL ? NULL : InstanceKlass::cast(SystemDictionary::name##_klass()); }
+ static InstanceKlass* klass() { return SystemDictionary::name##_klass(); }
#define END_CLASS };
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -52,6 +52,8 @@
const char* JVMCIRuntime::_compiler = NULL;
int JVMCIRuntime::_options_count = 0;
SystemProperty** JVMCIRuntime::_options = NULL;
+int JVMCIRuntime::_trivial_prefixes_count = 0;
+char** JVMCIRuntime::_trivial_prefixes = NULL;
bool JVMCIRuntime::_shutdown_called = false;
static const char* OPTION_PREFIX = "jvmci.option.";
@@ -124,7 +126,7 @@
// (This may have to change if this code changes!)
assert(array_klass->is_klass(), "not a class");
oop obj;
- if (array_klass->oop_is_typeArray()) {
+ if (array_klass->is_typeArray_klass()) {
BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type();
obj = oopFactory::new_typeArray(elt_type, length, CHECK);
} else {
@@ -433,12 +435,13 @@
}
JRT_END
-JRT_LEAF(void, JVMCIRuntime::log_object(JavaThread* thread, oopDesc* obj, jint flags))
- bool string = mask_bits_are_true(flags, LOG_OBJECT_STRING);
- bool addr = mask_bits_are_true(flags, LOG_OBJECT_ADDRESS);
- bool newline = mask_bits_are_true(flags, LOG_OBJECT_NEWLINE);
- if (!string) {
- if (!addr && obj->is_oop_or_null(true)) {
+JRT_LEAF(void, JVMCIRuntime::log_object(JavaThread* thread, oopDesc* obj, bool as_string, bool newline))
+ ttyLocker ttyl;
+
+ if (obj == NULL) {
+ tty->print("NULL");
+ } else if (obj->is_oop_or_null(true) && (!as_string || !java_lang_String::is_instance(obj))) {
+ if (obj->is_oop_or_null(true)) {
char buf[O_BUFLEN];
tty->print("%s@" INTPTR_FORMAT, obj->klass()->name()->as_C_string(buf, O_BUFLEN), p2i(obj));
} else {
@@ -628,10 +631,10 @@
static bool jvmci_options_file_exists() {
const char* home = Arguments::get_java_home();
- size_t path_len = strlen(home) + strlen("/lib/jvmci/options") + 1;
+ size_t path_len = strlen(home) + strlen("/lib/jvmci.options") + 1;
char path[JVM_MAXPATHLEN];
char sep = os::file_separator()[0];
- jio_snprintf(path, JVM_MAXPATHLEN, "%s%clib%cjvmci%coptions", home, sep, sep, sep);
+ jio_snprintf(path, JVM_MAXPATHLEN, "%s%clib%cjvmci.options", home, sep, sep);
struct stat st;
return os::stat(path, &st) == 0;
}
@@ -656,7 +659,8 @@
for (int i = 0; i < _options_count; i++) {
SystemProperty* prop = _options[i];
oop name = java_lang_String::create_oop_from_str(prop->key() + OPTION_PREFIX_LEN, CHECK);
- oop value = java_lang_String::create_oop_from_str(prop->value(), CHECK);
+ const char* prop_value = prop->value() != NULL ? prop->value() : "";
+ oop value = java_lang_String::create_oop_from_str(prop_value, CHECK);
options->obj_at_put(i * 2, name);
options->obj_at_put((i * 2) + 1, value);
}
@@ -682,6 +686,20 @@
Handle result = callStatic("jdk/vm/ci/hotspot/HotSpotJVMCIRuntime",
"runtime",
"()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;", NULL, CHECK);
+ objArrayOop trivial_prefixes = HotSpotJVMCIRuntime::trivialPrefixes(result);
+ if (trivial_prefixes != NULL) {
+ char** prefixes = NEW_C_HEAP_ARRAY(char*, trivial_prefixes->length(), mtCompiler);
+ for (int i = 0; i < trivial_prefixes->length(); i++) {
+ oop str = trivial_prefixes->obj_at(i);
+ if (str == NULL) {
+ THROW(vmSymbols::java_lang_NullPointerException());
+ } else {
+ prefixes[i] = strdup(java_lang_String::as_utf8_string(str));
+ }
+ }
+ _trivial_prefixes = prefixes;
+ _trivial_prefixes_count = trivial_prefixes->length();
+ }
_HotSpotJVMCIRuntime_initialized = true;
_HotSpotJVMCIRuntime_instance = JNIHandles::make_global(result());
}
@@ -877,15 +895,27 @@
_compiler = compiler;
}
-jint JVMCIRuntime::save_options(SystemProperty* props) {
+void JVMCIRuntime::maybe_print_flags(TRAPS) {
+ if (_options != NULL) {
+ for (int i = 0; i < _options_count; i++) {
+ SystemProperty* p = _options[i];
+ const char* name = p->key() + OPTION_PREFIX_LEN;
+ if (strcmp(name, "PrintFlags") == 0 || strcmp(name, "ShowFlags") == 0) {
+ JVMCIRuntime::initialize_well_known_classes(CHECK);
+ HandleMark hm;
+ ResourceMark rm;
+ JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK);
+ return;
+ }
+ }
+ }
+}
+
+void JVMCIRuntime::save_options(SystemProperty* props) {
int count = 0;
SystemProperty* first = NULL;
for (SystemProperty* p = props; p != NULL; p = p->next()) {
if (strncmp(p->key(), OPTION_PREFIX, OPTION_PREFIX_LEN) == 0) {
- if (p->value() == NULL || strlen(p->value()) == 0) {
- jio_fprintf(defaultStream::output_stream(), "JVMCI option %s must have non-zero length value\n", p->key());
- return JNI_ERR;
- }
if (first == NULL) {
first = p;
}
@@ -905,7 +935,6 @@
}
assert (insert_pos - _options == count, "must be");
}
- return JNI_OK;
}
void JVMCIRuntime::shutdown() {
@@ -921,6 +950,20 @@
}
}
+bool JVMCIRuntime::treat_as_trivial(Method* method) {
+ if (_HotSpotJVMCIRuntime_initialized) {
+ oop loader = method->method_holder()->class_loader();
+ if (loader == NULL) {
+ for (int i = 0; i < _trivial_prefixes_count; i++) {
+ if (method->method_holder()->name()->starts_with(_trivial_prefixes[i])) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
void JVMCIRuntime::call_printStackTrace(Handle exception, Thread* thread) {
assert(exception->is_a(SystemDictionary::Throwable_klass()), "Throwable instance expected");
JavaValue result(T_VOID);
@@ -949,18 +992,18 @@
void JVMCIRuntime::parse_lines(char* path, ParseClosure* closure, bool warnStatFailure) {
struct stat st;
- if (os::stat(path, &st) == 0 && (st.st_mode & S_IFREG) == S_IFREG) { // exists & is regular file
- int file_handle = os::open(path, 0, 0);
+ if (::stat(path, &st) == 0 && (st.st_mode & S_IFREG) == S_IFREG) { // exists & is regular file
+ int file_handle = ::open(path, os::default_file_open_flags(), 0);
if (file_handle != -1) {
char* buffer = NEW_C_HEAP_ARRAY(char, st.st_size + 1, mtInternal);
int num_read;
- num_read = (int) os::read(file_handle, (char*) buffer, st.st_size);
+ num_read = (int) ::read(file_handle, (char*) buffer, st.st_size);
if (num_read == -1) {
warning("Error reading file %s due to %s", path, strerror(errno));
} else if (num_read != st.st_size) {
warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, (size_t) st.st_size, path);
}
- os::close(file_handle);
+ ::close(file_handle);
closure->set_filename(path);
if (num_read == st.st_size) {
buffer[num_read] = '\0';
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -54,24 +54,6 @@
void set_filename(char* path) {_filename = path; _lineNo = 0;}
};
-#define CHECK_ABORT THREAD); \
- if (HAS_PENDING_EXCEPTION) { \
- char buf[256]; \
- jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
- JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
- return; \
- } \
- (void)(0
-
-#define CHECK_ABORT_(result) THREAD); \
- if (HAS_PENDING_EXCEPTION) { \
- char buf[256]; \
- jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
- JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
- return result; \
- } \
- (void)(0
-
class JVMCIRuntime: public AllStatic {
private:
static jobject _HotSpotJVMCIRuntime_instance;
@@ -81,6 +63,9 @@
static int _options_count;
static SystemProperty** _options;
+ static int _trivial_prefixes_count;
+ static char** _trivial_prefixes;
+
static bool _shutdown_called;
/**
@@ -108,9 +93,14 @@
* when JVMCI is initialized.
*
* @param props the head of the system property list
- * @return JNI_ERR if a JVMCI option has a zero length value, JNI_OK otherwise
*/
- static jint save_options(SystemProperty* props);
+ static void save_options(SystemProperty* props);
+
+ /**
+ * If either the PrintFlags or ShowFlags JVMCI option is present,
+ * then JVMCI is initialized to show the help message.
+ */
+ static void maybe_print_flags(TRAPS);
static bool is_HotSpotJVMCIRuntime_initialized() { return _HotSpotJVMCIRuntime_initialized; }
@@ -150,6 +140,7 @@
return _shutdown_called;
}
+ static bool treat_as_trivial(Method* method);
static void parse_lines(char* path, ParseClosure* closure, bool warnStatFailure);
/**
@@ -162,6 +153,24 @@
*/
static void call_printStackTrace(Handle exception, Thread* thread);
+#define CHECK_ABORT THREAD); \
+ if (HAS_PENDING_EXCEPTION) { \
+ char buf[256]; \
+ jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
+ JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
+ return; \
+ } \
+ (void)(0
+
+#define CHECK_ABORT_(result) THREAD); \
+ if (HAS_PENDING_EXCEPTION) { \
+ char buf[256]; \
+ jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
+ JVMCIRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \
+ return result; \
+ } \
+ (void)(0
+
static BasicType kindToBasicType(jchar ch);
// The following routines are all called from compiled JVMCI code
@@ -183,13 +192,11 @@
static oopDesc* load_and_clear_exception(JavaThread* thread);
static void log_printf(JavaThread* thread, oopDesc* format, jlong v1, jlong v2, jlong v3);
static void log_primitive(JavaThread* thread, jchar typeChar, jlong value, jboolean newline);
- // Note: Must be kept in sync with constants in com.oracle.graal.replacements.Log
- enum {
- LOG_OBJECT_NEWLINE = 0x01,
- LOG_OBJECT_STRING = 0x02,
- LOG_OBJECT_ADDRESS = 0x04
- };
- static void log_object(JavaThread* thread, oopDesc* msg, jint flags);
+ // Print the passed in object, optionally followed by a newline. If
+ // as_string is true and the object is a java.lang.String then it
+ // printed as a string, otherwise the type of the object is printed
+ // followed by its address.
+ static void log_object(JavaThread* thread, oopDesc* object, bool as_string, bool newline);
static void write_barrier_pre(JavaThread* thread, oopDesc* obj);
static void write_barrier_post(JavaThread* thread, void* card);
static jboolean validate_object(JavaThread* thread, oopDesc* parent, oopDesc* child);
--- a/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -47,6 +47,8 @@
do_klass(HotSpotOopMap_klass, jdk_vm_ci_hotspot_HotSpotOopMap, Jvmci) \
do_klass(HotSpotConstantPool_klass, jdk_vm_ci_hotspot_HotSpotConstantPool, Jvmci) \
do_klass(HotSpotJVMCIMetaAccessContext_klass, jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext, Jvmci) \
+ do_klass(HotSpotJVMCIRuntime_klass, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime, Jvmci) \
+ do_klass(HotSpotSpeculationLog_klass, jdk_vm_ci_hotspot_HotSpotSpeculationLog, Jvmci) \
do_klass(Assumptions_ConcreteMethod_klass, jdk_vm_ci_meta_Assumptions_ConcreteMethod, Jvmci) \
do_klass(Assumptions_NoFinalizableSubclass_klass, jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass, Jvmci) \
do_klass(Assumptions_ConcreteSubtype_klass, jdk_vm_ci_meta_Assumptions_ConcreteSubtype, Jvmci) \
@@ -74,7 +76,6 @@
do_klass(StackSlot_klass, jdk_vm_ci_code_StackSlot, Jvmci) \
do_klass(StackLockValue_klass, jdk_vm_ci_code_StackLockValue, Jvmci) \
do_klass(VirtualObject_klass, jdk_vm_ci_code_VirtualObject, Jvmci) \
- do_klass(SpeculationLog_klass, jdk_vm_ci_meta_SpeculationLog, Jvmci) \
do_klass(JavaConstant_klass, jdk_vm_ci_meta_JavaConstant, Jvmci) \
do_klass(PrimitiveConstant_klass, jdk_vm_ci_meta_PrimitiveConstant, Jvmci) \
do_klass(RawConstant_klass, jdk_vm_ci_meta_RawConstant, Jvmci) \
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -70,6 +70,20 @@
declare_constant(CompilerToVM::KLASS_TAG) \
declare_constant(CompilerToVM::SYMBOL_TAG) \
\
+ declare_constant(BitData::exception_seen_flag) \
+ declare_constant(BitData::null_seen_flag) \
+ declare_constant(CounterData::count_off) \
+ declare_constant(JumpData::taken_off_set) \
+ declare_constant(JumpData::displacement_off_set) \
+ declare_constant(ReceiverTypeData::nonprofiled_count_off_set) \
+ declare_constant(ReceiverTypeData::receiver_type_row_cell_count) \
+ declare_constant(ReceiverTypeData::receiver0_offset) \
+ declare_constant(ReceiverTypeData::count0_offset) \
+ declare_constant(BranchData::not_taken_off_set) \
+ declare_constant(ArrayData::array_len_off_set) \
+ declare_constant(ArrayData::array_start_off_set) \
+ declare_constant(MultiBranchData::per_case_cell_count) \
+ \
declare_constant(CodeInstaller::VERIFIED_ENTRY) \
declare_constant(CodeInstaller::UNVERIFIED_ENTRY) \
declare_constant(CodeInstaller::OSR_ENTRY) \
@@ -84,6 +98,7 @@
declare_constant(CodeInstaller::POLL_RETURN_NEAR) \
declare_constant(CodeInstaller::POLL_FAR) \
declare_constant(CodeInstaller::POLL_RETURN_FAR) \
+ declare_constant(CodeInstaller::CARD_TABLE_SHIFT) \
declare_constant(CodeInstaller::CARD_TABLE_ADDRESS) \
declare_constant(CodeInstaller::HEAP_TOP_ADDRESS) \
declare_constant(CodeInstaller::HEAP_END_ADDRESS) \
--- a/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -48,6 +48,8 @@
template(jdk_vm_ci_hotspot_HotSpotOopMap, "jdk/vm/ci/hotspot/HotSpotOopMap") \
template(jdk_vm_ci_hotspot_HotSpotConstantPool, "jdk/vm/ci/hotspot/HotSpotConstantPool") \
template(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext, "jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext") \
+ template(jdk_vm_ci_hotspot_HotSpotJVMCIRuntime, "jdk/vm/ci/hotspot/HotSpotJVMCIRuntime") \
+ template(jdk_vm_ci_hotspot_HotSpotSpeculationLog, "jdk/vm/ci/hotspot/HotSpotSpeculationLog") \
template(jdk_vm_ci_meta_JavaConstant, "jdk/vm/ci/meta/JavaConstant") \
template(jdk_vm_ci_meta_PrimitiveConstant, "jdk/vm/ci/meta/PrimitiveConstant") \
template(jdk_vm_ci_meta_RawConstant, "jdk/vm/ci/meta/RawConstant") \
@@ -61,7 +63,6 @@
template(jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass, "jdk/vm/ci/meta/Assumptions$NoFinalizableSubclass") \
template(jdk_vm_ci_meta_Assumptions_ConcreteMethod, "jdk/vm/ci/meta/Assumptions$ConcreteMethod") \
template(jdk_vm_ci_meta_Assumptions_CallSiteTargetValue, "jdk/vm/ci/meta/Assumptions$CallSiteTargetValue") \
- template(jdk_vm_ci_meta_SpeculationLog, "jdk/vm/ci/meta/SpeculationLog") \
template(jdk_vm_ci_code_Architecture, "jdk/vm/ci/code/Architecture") \
template(jdk_vm_ci_code_TargetDescription, "jdk/vm/ci/code/TargetDescription") \
template(jdk_vm_ci_code_CompilationResult_Call, "jdk/vm/ci/code/CompilationResult$Call") \
--- a/hotspot/src/share/vm/memory/allocation.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/memory/allocation.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -66,7 +66,7 @@
}
void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) throw() {
- address res;
+ address res = NULL;
switch (type) {
case C_HEAP:
res = (address)AllocateHeap(size, flags, CALLER_PC);
@@ -88,8 +88,8 @@
void* ResourceObj::operator new(size_t size, const std::nothrow_t& nothrow_constant,
allocation_type type, MEMFLAGS flags) throw() {
- //should only call this with std::nothrow, use other operator new() otherwise
- address res;
+ // should only call this with std::nothrow, use other operator new() otherwise
+ address res = NULL;
switch (type) {
case C_HEAP:
res = (address)AllocateHeap(size, flags, CALLER_PC, AllocFailStrategy::RETURN_NULL);
--- a/hotspot/src/share/vm/memory/filemap.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/memory/filemap.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -168,6 +168,7 @@
_version = _current_version;
_alignment = alignment;
_obj_alignment = ObjectAlignmentInBytes;
+ _compact_strings = CompactStrings;
_narrow_oop_mode = Universe::narrow_oop_mode();
_narrow_oop_shift = Universe::narrow_oop_shift();
_max_heap_size = MaxHeapSize;
@@ -900,6 +901,13 @@
_obj_alignment, ObjectAlignmentInBytes);
return false;
}
+ if (_compact_strings != CompactStrings) {
+ FileMapInfo::fail_continue("The shared archive file's CompactStrings setting (%s)"
+ " does not equal the current CompactStrings setting (%s).",
+ _compact_strings ? "enabled" : "disabled",
+ CompactStrings ? "enabled" : "disabled");
+ return false;
+ }
return true;
}
--- a/hotspot/src/share/vm/memory/filemap.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/memory/filemap.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -95,6 +95,7 @@
size_t _alignment; // how shared archive should be aligned
int _obj_alignment; // value of ObjectAlignmentInBytes
int _narrow_oop_shift; // compressed oop encoding shift
+ bool _compact_strings; // value of CompactStrings
uintx _max_heap_size; // java max heap size during dumping
Universe::NARROW_OOP_MODE _narrow_oop_mode; // compressed oop encoding mode
int _narrow_klass_shift; // save narrow klass base and shift
--- a/hotspot/src/share/vm/memory/heapInspection.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -286,7 +286,6 @@
return true;
}
-PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
void KlassInfoHisto::print_title(outputStream* st, bool csv_format,
bool selected[], int width_table[],
const char *name_table[]) {
@@ -298,11 +297,10 @@
st->print(",ClassName");
} else {
st->print("Index Super");
- for (int c=0; c<KlassSizeStats::_num_columns; c++) {
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
- if (selected[c]) {st->print(str_fmt(width_table[c]), name_table[c]);}
-PRAGMA_DIAG_POP
+ for (int c = 0; c < KlassSizeStats::_num_columns; c++) {
+ if (selected[c]) {
+ st->print("%*s", width_table[c], name_table[c]);
+ }
}
st->print(" ClassName");
}
@@ -321,7 +319,7 @@
void do_cinfo(KlassInfoEntry* cie) {
// ignore array classes
- if (cie->klass()->oop_is_instance()) {
+ if (cie->klass()->is_instance_klass()) {
_elements->append(cie);
}
}
@@ -348,8 +346,7 @@
for(int i = 0; i < elements.length(); i++) {
KlassInfoEntry* cie = elements.at(i);
- const InstanceKlass* k = (InstanceKlass*)cie->klass();
- Klass* super = ((InstanceKlass*)k)->java_super();
+ Klass* super = cie->klass()->super();
// Set the index for the class.
cie->set_index(i + 1);
@@ -544,8 +541,8 @@
} else {
int super_index = -1;
// Print the stats for this class.
- if (k->oop_is_instance()) {
- Klass* super = ((InstanceKlass*)k)->java_super();
+ if (k->is_instance_klass()) {
+ Klass* super = k->super();
if (super) {
KlassInfoEntry* super_e = _cit->lookup(super);
if (super_e) {
@@ -608,18 +605,12 @@
case KlassSizeStats::_index_inst_size:
case KlassSizeStats::_index_inst_count:
case KlassSizeStats::_index_method_count:
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
- st->print(str_fmt(width_table[c]), "-");
-PRAGMA_DIAG_POP
+ st->print("%*s", width_table[c], "-");
break;
default:
{
double perc = (double)(100) * (double)(colsum_table[c]) / (double)sz_sum._total_bytes;
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
- st->print(perc_fmt(width_table[c]), perc);
-PRAGMA_DIAG_POP
+ st->print("%*.1f%%", width_table[c]-1, perc);
}
}
}
--- a/hotspot/src/share/vm/memory/heapInspection.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/memory/heapInspection.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -313,32 +313,13 @@
return HeapWordSize * x->size();
}
- // returns a format string to print a julong with the given width. E.g,
- // printf(num_fmt(6), julong(10)) would print out the number 10 with 4
- // leading spaces.
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED
-
static void print_julong(outputStream* st, int width, julong n) {
int num_spaces = width - julong_width(n);
if (num_spaces > 0) {
- st->print(str_fmt(num_spaces), "");
+ st->print("%*s", num_spaces, "");
}
st->print(JULONG_FORMAT, n);
}
-PRAGMA_DIAG_POP
-
- static char* perc_fmt(int width) {
- static char buf[32];
- jio_snprintf(buf, sizeof(buf), "%%%d.1f%%%%", width-1);
- return buf;
- }
-
- static char* str_fmt(int width) {
- static char buf[32];
- jio_snprintf(buf, sizeof(buf), "%%%ds", width);
- return buf;
- }
static int julong_width(julong n) {
if (n == 0) {
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -90,7 +90,7 @@
static GrowableArray<Klass*>* _global_klass_objects;
static void collect_classes(Klass* k) {
_global_klass_objects->append_if_missing(k);
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
// Add in the array classes too
InstanceKlass* ik = InstanceKlass::cast(k);
ik->array_klasses_do(collect_classes);
@@ -126,7 +126,7 @@
static void rewrite_nofast_bytecodes_and_calculate_fingerprints() {
for (int i = 0; i < _global_klass_objects->length(); i++) {
Klass* k = _global_klass_objects->at(i);
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(k);
for (int i = 0; i < ik->methods()->length(); i++) {
Method* m = ik->methods()->at(i);
@@ -199,9 +199,9 @@
int n = _global_klass_objects->length();
for (int i = 0; i < n; i++) {
Klass* obj = _global_klass_objects->at(i);
- // Note oop_is_instance() is a virtual call. After patching vtables
+ // Note is_instance_klass() is a virtual call in debug. After patching vtables
// all virtual calls on the dummy vtables will restore the original!
- if (obj->oop_is_instance()) {
+ if (obj->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(obj);
*(void**)ik = find_matching_vtbl_ptr(vtbl_list, new_vtable_start, ik);
ConstantPool* cp = ik->constants();
@@ -482,12 +482,12 @@
int num_type_array = 0, num_obj_array = 0, num_inst = 0;
for (int i = 0; i < _global_klass_objects->length(); i++) {
Klass* k = _global_klass_objects->at(i);
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
num_inst ++;
- } else if (k->oop_is_objArray()) {
+ } else if (k->is_objArray_klass()) {
num_obj_array ++;
} else {
- assert(k->oop_is_typeArray(), "sanity");
+ assert(k->is_typeArray_klass(), "sanity");
num_type_array ++;
}
}
@@ -540,7 +540,7 @@
NOT_PRODUCT(SystemDictionary::verify();)
- // Copy the the symbol table, string table, and the system dictionary to the shared
+ // Copy the symbol table, string table, and the system dictionary to the shared
// space in usable form. Copy the hashtable
// buckets first [read-write], then copy the linked lists of entries
// [read-only].
@@ -679,8 +679,8 @@
void MetaspaceShared::link_one_shared_class(Klass* obj, TRAPS) {
Klass* k = obj;
- if (k->oop_is_instance()) {
- InstanceKlass* ik = (InstanceKlass*) k;
+ if (k->is_instance_klass()) {
+ InstanceKlass* ik = InstanceKlass::cast(k);
// Link the class to cause the bytecodes to be rewritten and the
// cpcache to be created. Class verification is done according
// to -Xverify setting.
@@ -690,7 +690,7 @@
}
void MetaspaceShared::check_one_shared_class(Klass* k) {
- if (k->oop_is_instance() && InstanceKlass::cast(k)->check_sharing_error_state()) {
+ if (k->is_instance_klass() && InstanceKlass::cast(k)->check_sharing_error_state()) {
_check_classes_made_progress = true;
}
}
--- a/hotspot/src/share/vm/memory/oopFactory.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/memory/oopFactory.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -81,10 +81,9 @@
objArrayOop oopFactory::new_objArray(Klass* klass, int length, TRAPS) {
assert(klass->is_klass(), "must be instance class");
- if (klass->oop_is_array()) {
- return ((ArrayKlass*)klass)->allocate_arrayArray(1, length, THREAD);
+ if (klass->is_array_klass()) {
+ return ArrayKlass::cast(klass)->allocate_arrayArray(1, length, THREAD);
} else {
- assert (klass->oop_is_instance(), "new object array with klass not an InstanceKlass");
- return ((InstanceKlass*)klass)->allocate_objArray(1, length, THREAD);
+ return InstanceKlass::cast(klass)->allocate_objArray(1, length, THREAD);
}
}
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -409,7 +409,7 @@
int i = 0;
while (i < size) {
// Allocate dummy in old generation
- oop dummy = InstanceKlass::cast(SystemDictionary::Object_klass())->allocate_instance(CHECK);
+ oop dummy = SystemDictionary::Object_klass()->allocate_instance(CHECK);
dummy_array->obj_at_put(i++, dummy);
}
{
@@ -484,8 +484,8 @@
_mirrors[T_LONG] = _long_mirror;
_mirrors[T_SHORT] = _short_mirror;
_mirrors[T_VOID] = _void_mirror;
- //_mirrors[T_OBJECT] = InstanceKlass::cast(_object_klass)->java_mirror();
- //_mirrors[T_ARRAY] = InstanceKlass::cast(_object_klass)->java_mirror();
+ //_mirrors[T_OBJECT] = _object_klass->java_mirror();
+ //_mirrors[T_ARRAY] = _object_klass->java_mirror();
}
void Universe::fixup_mirrors(TRAPS) {
@@ -545,9 +545,8 @@
Klass* ko = k_h();
klassVtable* vt = ko->vtable();
if (vt) vt->initialize_vtable(false, CHECK);
- if (ko->oop_is_instance()) {
- InstanceKlass* ik = (InstanceKlass*)ko;
- for (KlassHandle s_h(THREAD, ik->subklass());
+ if (ko->is_instance_klass()) {
+ for (KlassHandle s_h(THREAD, ko->subklass());
s_h() != NULL;
s_h = KlassHandle(THREAD, s_h()->next_sibling())) {
reinitialize_vtable_of(s_h, CHECK);
@@ -998,8 +997,8 @@
// Setup static method for registering finalizers
// The finalizer klass must be linked before looking up the method, in
// case it needs to get rewritten.
- InstanceKlass::cast(SystemDictionary::Finalizer_klass())->link_class(CHECK_false);
- Method* m = InstanceKlass::cast(SystemDictionary::Finalizer_klass())->find_method(
+ SystemDictionary::Finalizer_klass()->link_class(CHECK_false);
+ Method* m = SystemDictionary::Finalizer_klass()->find_method(
vmSymbols::register_method_name(),
vmSymbols::register_method_signature());
if (m == NULL || !m->is_static()) {
@@ -1009,8 +1008,8 @@
Universe::_finalizer_register_cache->init(
SystemDictionary::Finalizer_klass(), m);
- InstanceKlass::cast(SystemDictionary::misc_Unsafe_klass())->link_class(CHECK_false);
- m = InstanceKlass::cast(SystemDictionary::misc_Unsafe_klass())->find_method(
+ SystemDictionary::internal_Unsafe_klass()->link_class(CHECK_false);
+ m = SystemDictionary::internal_Unsafe_klass()->find_method(
vmSymbols::throwIllegalAccessError_name(),
vmSymbols::void_method_signature());
if (m != NULL && !m->is_static()) {
@@ -1020,11 +1019,11 @@
return false; // initialization failed (cannot throw exception yet)
}
Universe::_throw_illegal_access_error_cache->init(
- SystemDictionary::misc_Unsafe_klass(), m);
+ SystemDictionary::internal_Unsafe_klass(), m);
// Setup method for registering loaded classes in class loader vector
- InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false);
- m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature());
+ SystemDictionary::ClassLoader_klass()->link_class(CHECK_false);
+ m = SystemDictionary::ClassLoader_klass()->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature());
if (m == NULL || m->is_static()) {
tty->print_cr("Unable to link/verify ClassLoader.addClass method");
return false; // initialization failed (cannot throw exception yet)
@@ -1033,8 +1032,8 @@
SystemDictionary::ClassLoader_klass(), m);
// Setup method for checking protection domain
- InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->link_class(CHECK_false);
- m = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->
+ SystemDictionary::ProtectionDomain_klass()->link_class(CHECK_false);
+ m = SystemDictionary::ProtectionDomain_klass()->
find_method(vmSymbols::impliesCreateAccessControlContext_name(),
vmSymbols::void_boolean_signature());
// Allow NULL which should only happen with bootstrapping.
--- a/hotspot/src/share/vm/oops/arrayKlass.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/arrayKlass.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -50,7 +50,7 @@
public:
// Testing operation
- bool oop_is_array_slow() const { return true; }
+ DEBUG_ONLY(bool is_array_klass_slow() const { return true; })
// Instance variables
int dimension() const { return _dimension; }
@@ -86,8 +86,8 @@
// Casting from Klass*
static ArrayKlass* cast(Klass* k) {
- assert(k->oop_is_array(), "cast to ArrayKlass");
- return (ArrayKlass*) k;
+ assert(k->is_array_klass(), "cast to ArrayKlass");
+ return static_cast<ArrayKlass*>(k);
}
GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots);
--- a/hotspot/src/share/vm/oops/constantPool.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -178,7 +178,7 @@
return (i < 0) ? _no_index_sentinel : i;
}
-void ConstantPool::trace_class_resolution(constantPoolHandle this_cp, KlassHandle k) {
+void ConstantPool::trace_class_resolution(const constantPoolHandle& this_cp, KlassHandle k) {
ResourceMark rm;
int line_number = -1;
const char * source_file = NULL;
@@ -198,16 +198,16 @@
if (source_file != NULL) {
tty->print("RESOLVE %s %s %s:%d\n",
this_cp->pool_holder()->external_name(),
- InstanceKlass::cast(k())->external_name(), source_file, line_number);
+ k->external_name(), source_file, line_number);
} else {
tty->print("RESOLVE %s %s\n",
this_cp->pool_holder()->external_name(),
- InstanceKlass::cast(k())->external_name());
+ k->external_name());
}
}
}
-Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which,
+Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int which,
bool save_resolution_error, TRAPS) {
assert(THREAD->is_Java_thread(), "must be a Java thread");
@@ -269,7 +269,7 @@
ClassLoaderData* this_key = this_cp->pool_holder()->class_loader_data();
this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
- if (TraceClassResolution && !k->oop_is_array()) {
+ if (TraceClassResolution && !k->is_array_klass()) {
// skip resolving the constant pool so that this code gets
// called the next time some bytecodes refer to this class.
trace_class_resolution(this_cp, k);
@@ -288,7 +288,7 @@
// by compiler and exception handling. Also used to avoid classloads for
// instanceof operations. Returns NULL if the class has not been loaded or
// if the verification of constant pool failed
-Klass* ConstantPool::klass_at_if_loaded(constantPoolHandle this_cp, int which) {
+Klass* ConstantPool::klass_at_if_loaded(const constantPoolHandle& this_cp, int which) {
CPSlot entry = this_cp->slot_at(which);
if (entry.is_resolved()) {
assert(entry.get_klass()->is_klass(), "must be");
@@ -321,12 +321,12 @@
}
-Klass* ConstantPool::klass_ref_at_if_loaded(constantPoolHandle this_cp, int which) {
+Klass* ConstantPool::klass_ref_at_if_loaded(const constantPoolHandle& this_cp, int which) {
return klass_at_if_loaded(this_cp, this_cp->klass_ref_index_at(which));
}
-Method* ConstantPool::method_at_if_loaded(constantPoolHandle cpool,
+Method* ConstantPool::method_at_if_loaded(const constantPoolHandle& cpool,
int which) {
if (cpool->cache() == NULL) return NULL; // nothing to load yet
int cache_index = decode_cpcache_index(which, true);
@@ -342,14 +342,14 @@
}
-bool ConstantPool::has_appendix_at_if_loaded(constantPoolHandle cpool, int which) {
+bool ConstantPool::has_appendix_at_if_loaded(const constantPoolHandle& cpool, int which) {
if (cpool->cache() == NULL) return false; // nothing to load yet
int cache_index = decode_cpcache_index(which, true);
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
return e->has_appendix();
}
-oop ConstantPool::appendix_at_if_loaded(constantPoolHandle cpool, int which) {
+oop ConstantPool::appendix_at_if_loaded(const constantPoolHandle& cpool, int which) {
if (cpool->cache() == NULL) return NULL; // nothing to load yet
int cache_index = decode_cpcache_index(which, true);
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
@@ -357,14 +357,14 @@
}
-bool ConstantPool::has_method_type_at_if_loaded(constantPoolHandle cpool, int which) {
+bool ConstantPool::has_method_type_at_if_loaded(const constantPoolHandle& cpool, int which) {
if (cpool->cache() == NULL) return false; // nothing to load yet
int cache_index = decode_cpcache_index(which, true);
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
return e->has_method_type();
}
-oop ConstantPool::method_type_at_if_loaded(constantPoolHandle cpool, int which) {
+oop ConstantPool::method_type_at_if_loaded(const constantPoolHandle& cpool, int which) {
if (cpool->cache() == NULL) return NULL; // nothing to load yet
int cache_index = decode_cpcache_index(which, true);
ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
@@ -434,15 +434,15 @@
}
-void ConstantPool::verify_constant_pool_resolve(constantPoolHandle this_cp, KlassHandle k, TRAPS) {
- if (k->oop_is_instance() || k->oop_is_objArray()) {
+void ConstantPool::verify_constant_pool_resolve(const constantPoolHandle& this_cp, KlassHandle k, TRAPS) {
+ if (k->is_instance_klass() || k->is_objArray_klass()) {
instanceKlassHandle holder (THREAD, this_cp->pool_holder());
- Klass* elem = k->oop_is_instance() ? k() : ObjArrayKlass::cast(k())->bottom_klass();
+ Klass* elem = k->is_instance_klass() ? k() : ObjArrayKlass::cast(k())->bottom_klass();
KlassHandle element (THREAD, elem);
// The element type could be a typeArray - we only need the access check if it is
// an reference to another class
- if (element->oop_is_instance()) {
+ if (element->is_instance_klass()) {
LinkResolver::check_klass_accessability(holder, element, CHECK);
}
}
@@ -502,7 +502,7 @@
}
-void ConstantPool::resolve_string_constants_impl(constantPoolHandle this_cp, TRAPS) {
+void ConstantPool::resolve_string_constants_impl(const constantPoolHandle& this_cp, TRAPS) {
for (int index = 1; index < this_cp->length(); index++) { // Index 0 is unused
if (this_cp->tag_at(index).is_string()) {
this_cp->string_at(index, CHECK);
@@ -526,7 +526,7 @@
return true;
}
-Symbol* ConstantPool::exception_message(constantPoolHandle this_cp, int which, constantTag tag, oop pending_exception) {
+Symbol* ConstantPool::exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) {
// Dig out the detailed message to reuse if possible
Symbol* message = java_lang_Throwable::detail_message(pending_exception);
if (message != NULL) {
@@ -554,7 +554,7 @@
return message;
}
-void ConstantPool::throw_resolution_error(constantPoolHandle this_cp, int which, TRAPS) {
+void ConstantPool::throw_resolution_error(const constantPoolHandle& this_cp, int which, TRAPS) {
Symbol* message = NULL;
Symbol* error = SystemDictionary::find_resolution_error(this_cp, which, &message);
assert(error != NULL && message != NULL, "checking");
@@ -565,7 +565,7 @@
// If resolution for Class, MethodHandle or MethodType fails, save the exception
// in the resolution error table, so that the same exception is thrown again.
-void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int which,
+void ConstantPool::save_and_throw_exception(const constantPoolHandle& this_cp, int which,
constantTag tag, TRAPS) {
Symbol* error = PENDING_EXCEPTION->klass()->name();
@@ -603,7 +603,7 @@
// Called to resolve constants in the constant pool and return an oop.
// Some constant pool entries cache their resolved oop. This is also
// called to create oops from constants to use in arguments for invokedynamic
-oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index, int cache_index, TRAPS) {
+oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, int index, int cache_index, TRAPS) {
oop result_oop = NULL;
Handle throw_exception;
@@ -756,7 +756,7 @@
}
-oop ConstantPool::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_cp, int index, TRAPS) {
+oop ConstantPool::resolve_bootstrap_specifier_at_impl(const constantPoolHandle& this_cp, int index, TRAPS) {
assert(this_cp->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool");
Handle bsm;
@@ -794,7 +794,7 @@
return info();
}
-oop ConstantPool::string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS) {
+oop ConstantPool::string_at_impl(const constantPoolHandle& this_cp, int which, int obj_index, TRAPS) {
// If the string has already been interned, this entry will be non-null
oop str = this_cp->resolved_references()->obj_at(obj_index);
if (str != NULL) return str;
@@ -830,7 +830,7 @@
// Compare this constant pool's entry at index1 to the constant pool
// cp2's entry at index2.
-bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2,
+bool ConstantPool::compare_entry_to(int index1, const constantPoolHandle& cp2,
int index2, TRAPS) {
// The error tags are equivalent to non-error tags when comparing
@@ -1056,7 +1056,7 @@
// Extend the operands array with the length and size of the ext_cp operands.
// Used in RedefineClasses for CP merge.
-void ConstantPool::extend_operands(constantPoolHandle ext_cp, TRAPS) {
+void ConstantPool::extend_operands(const constantPoolHandle& ext_cp, TRAPS) {
int delta_len = operand_array_length(ext_cp->operands());
if (delta_len == 0) {
return; // nothing to do
@@ -1096,8 +1096,8 @@
} // end shrink_operands()
-void ConstantPool::copy_operands(constantPoolHandle from_cp,
- constantPoolHandle to_cp,
+void ConstantPool::copy_operands(const constantPoolHandle& from_cp,
+ const constantPoolHandle& to_cp,
TRAPS) {
int from_oplen = operand_array_length(from_cp->operands());
@@ -1160,8 +1160,8 @@
// Copy this constant pool's entries at start_i to end_i (inclusive)
// to the constant pool to_cp's entries starting at to_i. A total of
// (end_i - start_i) + 1 entries are copied.
-void ConstantPool::copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i,
- constantPoolHandle to_cp, int to_i, TRAPS) {
+void ConstantPool::copy_cp_to_impl(const constantPoolHandle& from_cp, int start_i, int end_i,
+ const constantPoolHandle& to_cp, int to_i, TRAPS) {
int dest_i = to_i; // leave original alone for debug purposes
@@ -1191,8 +1191,8 @@
// Copy this constant pool's entry at from_i to the constant pool
// to_cp's entry at to_i.
-void ConstantPool::copy_entry_to(constantPoolHandle from_cp, int from_i,
- constantPoolHandle to_cp, int to_i,
+void ConstantPool::copy_entry_to(const constantPoolHandle& from_cp, int from_i,
+ const constantPoolHandle& to_cp, int to_i,
TRAPS) {
int tag = from_cp->tag_at(from_i).value();
@@ -1339,7 +1339,7 @@
// constant pool's entry at pattern_i. Returns the index of a
// matching entry or zero (0) if there is no matching entry.
int ConstantPool::find_matching_entry(int pattern_i,
- constantPoolHandle search_cp, TRAPS) {
+ const constantPoolHandle& search_cp, TRAPS) {
// index zero (0) is not used
for (int i = 1; i < search_cp->length(); i++) {
@@ -1355,7 +1355,7 @@
// Compare this constant pool's bootstrap specifier at idx1 to the constant pool
// cp2's bootstrap specifier at idx2.
-bool ConstantPool::compare_operand_to(int idx1, constantPoolHandle cp2, int idx2, TRAPS) {
+bool ConstantPool::compare_operand_to(int idx1, const constantPoolHandle& cp2, int idx2, TRAPS) {
int k1 = operand_bootstrap_method_ref_index_at(idx1);
int k2 = cp2->operand_bootstrap_method_ref_index_at(idx2);
bool match = compare_entry_to(k1, cp2, k2, CHECK_false);
@@ -1382,7 +1382,7 @@
// this constant pool's bootstrap specifier at pattern_i index.
// Return the index of a matching bootstrap specifier or (-1) if there is no match.
int ConstantPool::find_matching_operand(int pattern_i,
- constantPoolHandle search_cp, int search_len, TRAPS) {
+ const constantPoolHandle& search_cp, int search_len, TRAPS) {
for (int i = 0; i < search_len; i++) {
bool found = compare_operand_to(pattern_i, search_cp, i, CHECK_(-1));
if (found) {
@@ -1843,7 +1843,7 @@
if (cp->tag_at(i).is_unresolved_klass()) {
// This will force loading of the class
Klass* klass = cp->klass_at(i, CHECK);
- if (klass->oop_is_instance()) {
+ if (klass->is_instance_klass()) {
// Force initialization of class
InstanceKlass::cast(klass)->initialize(CHECK);
}
--- a/hotspot/src/share/vm/oops/constantPool.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -604,15 +604,15 @@
return offset;
}
// Compare a bootsrap specifier in the operands arrays
- bool compare_operand_to(int bootstrap_specifier_index1, constantPoolHandle cp2,
+ bool compare_operand_to(int bootstrap_specifier_index1, const constantPoolHandle& cp2,
int bootstrap_specifier_index2, TRAPS);
// Find a bootsrap specifier in the operands array
- int find_matching_operand(int bootstrap_specifier_index, constantPoolHandle search_cp,
+ int find_matching_operand(int bootstrap_specifier_index, const constantPoolHandle& search_cp,
int operands_cur_len, TRAPS);
// Resize the operands array with delta_len and delta_size
void resize_operands(int delta_len, int delta_size, TRAPS);
// Extend the operands array with the length and size of the ext_cp operands
- void extend_operands(constantPoolHandle ext_cp, TRAPS);
+ void extend_operands(const constantPoolHandle& ext_cp, TRAPS);
// Shrink the operands array to a smaller array with new_len length
void shrink_operands(int new_len, TRAPS);
@@ -735,13 +735,13 @@
friend class SystemDictionary;
// Used by compiler to prevent classloading.
- static Method* method_at_if_loaded (constantPoolHandle this_cp, int which);
- static bool has_appendix_at_if_loaded (constantPoolHandle this_cp, int which);
- static oop appendix_at_if_loaded (constantPoolHandle this_cp, int which);
- static bool has_method_type_at_if_loaded (constantPoolHandle this_cp, int which);
- static oop method_type_at_if_loaded (constantPoolHandle this_cp, int which);
- static Klass* klass_at_if_loaded (constantPoolHandle this_cp, int which);
- static Klass* klass_ref_at_if_loaded (constantPoolHandle this_cp, int which);
+ static Method* method_at_if_loaded (const constantPoolHandle& this_cp, int which);
+ static bool has_appendix_at_if_loaded (const constantPoolHandle& this_cp, int which);
+ static oop appendix_at_if_loaded (const constantPoolHandle& this_cp, int which);
+ static bool has_method_type_at_if_loaded (const constantPoolHandle& this_cp, int which);
+ static oop method_type_at_if_loaded (const constantPoolHandle& this_cp, int which);
+ static Klass* klass_at_if_loaded (const constantPoolHandle& this_cp, int which);
+ static Klass* klass_ref_at_if_loaded (const constantPoolHandle& this_cp, int which);
// Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
// future by other Java code. These take constant pool indices rather than
@@ -797,38 +797,38 @@
}
// Performs the LinkResolver checks
- static void verify_constant_pool_resolve(constantPoolHandle this_cp, KlassHandle klass, TRAPS);
+ static void verify_constant_pool_resolve(const constantPoolHandle& this_cp, KlassHandle klass, TRAPS);
// Implementation of methods that needs an exposed 'this' pointer, in order to
// handle GC while executing the method
- static Klass* klass_at_impl(constantPoolHandle this_cp, int which,
+ static Klass* klass_at_impl(const constantPoolHandle& this_cp, int which,
bool save_resolution_error, TRAPS);
- static oop string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS);
+ static oop string_at_impl(const constantPoolHandle& this_cp, int which, int obj_index, TRAPS);
- static void trace_class_resolution(constantPoolHandle this_cp, KlassHandle k);
+ static void trace_class_resolution(const constantPoolHandle& this_cp, KlassHandle k);
// Resolve string constants (to prevent allocation during compilation)
- static void resolve_string_constants_impl(constantPoolHandle this_cp, TRAPS);
+ static void resolve_string_constants_impl(const constantPoolHandle& this_cp, TRAPS);
- static oop resolve_constant_at_impl(constantPoolHandle this_cp, int index, int cache_index, TRAPS);
- static oop resolve_bootstrap_specifier_at_impl(constantPoolHandle this_cp, int index, TRAPS);
+ static oop resolve_constant_at_impl(const constantPoolHandle& this_cp, int index, int cache_index, TRAPS);
+ static oop resolve_bootstrap_specifier_at_impl(const constantPoolHandle& this_cp, int index, TRAPS);
// Exception handling
- static void throw_resolution_error(constantPoolHandle this_cp, int which, TRAPS);
- static Symbol* exception_message(constantPoolHandle this_cp, int which, constantTag tag, oop pending_exception);
- static void save_and_throw_exception(constantPoolHandle this_cp, int which, constantTag tag, TRAPS);
+ static void throw_resolution_error(const constantPoolHandle& this_cp, int which, TRAPS);
+ static Symbol* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception);
+ static void save_and_throw_exception(const constantPoolHandle& this_cp, int which, constantTag tag, TRAPS);
public:
// Merging ConstantPool* support:
- bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
- void copy_cp_to(int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS) {
+ bool compare_entry_to(int index1, const constantPoolHandle& cp2, int index2, TRAPS);
+ void copy_cp_to(int start_i, int end_i, const constantPoolHandle& to_cp, int to_i, TRAPS) {
constantPoolHandle h_this(THREAD, this);
copy_cp_to_impl(h_this, start_i, end_i, to_cp, to_i, THREAD);
}
- static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS);
- static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
- static void copy_operands(constantPoolHandle from_cp, constantPoolHandle to_cp, TRAPS);
- int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS);
+ static void copy_cp_to_impl(const constantPoolHandle& from_cp, int start_i, int end_i, const constantPoolHandle& to_cp, int to_i, TRAPS);
+ static void copy_entry_to(const constantPoolHandle& from_cp, int from_i, const constantPoolHandle& to_cp, int to_i, TRAPS);
+ static void copy_operands(const constantPoolHandle& from_cp, const constantPoolHandle& to_cp, TRAPS);
+ int find_matching_entry(int pattern_i, const constantPoolHandle& search_cp, TRAPS);
int version() const { return _saved._version; }
void set_version(int version) { _saved._version = version; }
void increment_and_save_version(int version) {
--- a/hotspot/src/share/vm/oops/cpCache.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/cpCache.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -246,7 +246,7 @@
set_direct_or_vtable_call(invoke_code, method, index);
}
-void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, methodHandle method, int index) {
+void ConstantPoolCacheEntry::set_itable_call(Bytecodes::Code invoke_code, const methodHandle& method, int index) {
assert(method->method_holder()->verify_itable_index(index), "");
assert(invoke_code == Bytecodes::_invokeinterface, "");
InstanceKlass* interf = method->method_holder();
@@ -261,15 +261,15 @@
}
-void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool, const CallInfo &call_info) {
+void ConstantPoolCacheEntry::set_method_handle(const constantPoolHandle& cpool, const CallInfo &call_info) {
set_method_handle_common(cpool, Bytecodes::_invokehandle, call_info);
}
-void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool, const CallInfo &call_info) {
+void ConstantPoolCacheEntry::set_dynamic_call(const constantPoolHandle& cpool, const CallInfo &call_info) {
set_method_handle_common(cpool, Bytecodes::_invokedynamic, call_info);
}
-void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
+void ConstantPoolCacheEntry::set_method_handle_common(const constantPoolHandle& cpool,
Bytecodes::Code invoke_code,
const CallInfo &call_info) {
// NOTE: This CPCE can be the subject of data races.
@@ -361,7 +361,7 @@
}
}
-Method* ConstantPoolCacheEntry::method_if_resolved(constantPoolHandle cpool) {
+Method* ConstantPoolCacheEntry::method_if_resolved(const constantPoolHandle& cpool) {
// Decode the action of set_method and set_interface_call
Bytecodes::Code invoke_code = bytecode_1();
if (invoke_code != (Bytecodes::Code)0) {
@@ -394,7 +394,7 @@
int holder_index = cpool->uncached_klass_ref_index_at(constant_pool_index());
if (cpool->tag_at(holder_index).is_klass()) {
Klass* klass = cpool->resolved_klass_at(holder_index);
- if (!klass->oop_is_instance())
+ if (!klass->is_instance_klass())
klass = SystemDictionary::Object_klass();
return InstanceKlass::cast(klass)->method_at_vtable(f2_as_index());
}
@@ -406,7 +406,7 @@
}
-oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
+oop ConstantPoolCacheEntry::appendix_if_resolved(const constantPoolHandle& cpool) {
if (!has_appendix())
return NULL;
const int ref_index = f2_as_index() + _indy_resolved_references_appendix_offset;
@@ -415,7 +415,7 @@
}
-oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
+oop ConstantPoolCacheEntry::method_type_if_resolved(const constantPoolHandle& cpool) {
if (!has_method_type())
return NULL;
const int ref_index = f2_as_index() + _indy_resolved_references_method_type_offset;
--- a/hotspot/src/share/vm/oops/cpCache.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/cpCache.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -246,17 +246,17 @@
void set_itable_call(
Bytecodes::Code invoke_code, // the bytecode used; must be invokeinterface
- methodHandle method, // the resolved interface method
+ const methodHandle& method, // the resolved interface method
int itable_index // index into itable for the method
);
void set_method_handle(
- constantPoolHandle cpool, // holding constant pool (required for locking)
+ const constantPoolHandle& cpool, // holding constant pool (required for locking)
const CallInfo &call_info // Call link information
);
void set_dynamic_call(
- constantPoolHandle cpool, // holding constant pool (required for locking)
+ const constantPoolHandle& cpool, // holding constant pool (required for locking)
const CallInfo &call_info // Call link information
);
@@ -276,7 +276,7 @@
// resolution logic needs to make slightly different assessments about the
// number and types of arguments.
void set_method_handle_common(
- constantPoolHandle cpool, // holding constant pool (required for locking)
+ const constantPoolHandle& cpool, // holding constant pool (required for locking)
Bytecodes::Code invoke_code, // _invokehandle or _invokedynamic
const CallInfo &call_info // Call link information
);
@@ -291,9 +291,9 @@
_indy_resolved_references_entries
};
- Method* method_if_resolved(constantPoolHandle cpool);
- oop appendix_if_resolved(constantPoolHandle cpool);
- oop method_type_if_resolved(constantPoolHandle cpool);
+ Method* method_if_resolved(const constantPoolHandle& cpool);
+ oop appendix_if_resolved(const constantPoolHandle& cpool);
+ oop method_type_if_resolved(const constantPoolHandle& cpool);
void set_parameter_size(int value);
--- a/hotspot/src/share/vm/oops/fieldInfo.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/fieldInfo.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -176,7 +176,7 @@
return (_shorts[low_packed_offset] & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET;
}
- Symbol* name(constantPoolHandle cp) const {
+ Symbol* name(const constantPoolHandle& cp) const {
int index = name_index();
if (is_internal()) {
return lookup_symbol(index);
@@ -184,7 +184,7 @@
return cp->symbol_at(index);
}
- Symbol* signature(constantPoolHandle cp) const {
+ Symbol* signature(const constantPoolHandle& cp) const {
int index = signature_index();
if (is_internal()) {
return lookup_symbol(index);
--- a/hotspot/src/share/vm/oops/fieldStreams.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/fieldStreams.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,7 @@
return num_fields;
}
- FieldStreamBase(Array<u2>* fields, constantPoolHandle constants, int start, int limit) {
+ FieldStreamBase(Array<u2>* fields, const constantPoolHandle& constants, int start, int limit) {
_fields = fields;
_constants = constants;
_index = start;
@@ -91,7 +91,7 @@
}
}
- FieldStreamBase(Array<u2>* fields, constantPoolHandle constants) {
+ FieldStreamBase(Array<u2>* fields, const constantPoolHandle& constants) {
_fields = fields;
_constants = constants;
_index = 0;
@@ -251,7 +251,7 @@
class AllFieldStream : public FieldStreamBase {
public:
- AllFieldStream(Array<u2>* fields, constantPoolHandle constants): FieldStreamBase(fields, constants) {}
+ AllFieldStream(Array<u2>* fields, const constantPoolHandle& constants): FieldStreamBase(fields, constants) {}
AllFieldStream(InstanceKlass* k): FieldStreamBase(k->fields(), k->constants()) {}
AllFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants()) {}
};
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -222,7 +222,7 @@
}
}
-void RetTable::compute_ret_table(methodHandle method) {
+void RetTable::compute_ret_table(const methodHandle& method) {
BytecodeStream i(method);
Bytecodes::Code bytecode;
@@ -2039,7 +2039,7 @@
//
// ============ Main Entry Point ===========
//
-GenerateOopMap::GenerateOopMap(methodHandle method) {
+GenerateOopMap::GenerateOopMap(const methodHandle& method) {
// We have to initialize all variables here, that can be queried directly
_method = method;
_max_locals=0;
--- a/hotspot/src/share/vm/oops/generateOopMap.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/generateOopMap.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,7 +78,7 @@
void add_jsr(int return_bci, int target_bci); // Adds entry to list
public:
RetTable() { _first = NULL; }
- void compute_ret_table(methodHandle method);
+ void compute_ret_table(const methodHandle& method);
void update_ret_table(int bci, int delta);
RetTableEntry* find_jsrs_for_target(int targBci);
};
@@ -462,7 +462,7 @@
friend class RelocCallback;
public:
- GenerateOopMap(methodHandle method);
+ GenerateOopMap(const methodHandle& method);
// Compute the map.
void compute_map(TRAPS);
@@ -537,7 +537,7 @@
#endif
public:
- ResolveOopMapConflicts(methodHandle method) : GenerateOopMap(method) { _must_clear_locals = false; };
+ ResolveOopMapConflicts(const methodHandle& method) : GenerateOopMap(method) { _must_clear_locals = false; };
methodHandle do_potential_rewrite(TRAPS);
bool must_clear_locals() const { return _must_clear_locals; }
@@ -562,7 +562,7 @@
int stack_top) {}
virtual void fill_init_vars (GrowableArray<intptr_t> *init_vars) {}
public:
- GeneratePairingInfo(methodHandle method) : GenerateOopMap(method) {};
+ GeneratePairingInfo(const methodHandle& method) : GenerateOopMap(method) {};
// Call compute_map(CHECK) to generate info.
};
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -742,7 +742,7 @@
// A class could already be verified, since it has been reflected upon.
this_k->link_class(CHECK);
- DTRACE_CLASSINIT_PROBE(required, InstanceKlass::cast(this_k()), -1);
+ DTRACE_CLASSINIT_PROBE(required, this_k(), -1);
bool wait = false;
@@ -765,19 +765,19 @@
// Step 3
if (this_k->is_being_initialized() && this_k->is_reentrant_initialization(self)) {
- DTRACE_CLASSINIT_PROBE_WAIT(recursive, InstanceKlass::cast(this_k()), -1,wait);
+ DTRACE_CLASSINIT_PROBE_WAIT(recursive, this_k(), -1,wait);
return;
}
// Step 4
if (this_k->is_initialized()) {
- DTRACE_CLASSINIT_PROBE_WAIT(concurrent, InstanceKlass::cast(this_k()), -1,wait);
+ DTRACE_CLASSINIT_PROBE_WAIT(concurrent, this_k(), -1,wait);
return;
}
// Step 5
if (this_k->is_in_error_state()) {
- DTRACE_CLASSINIT_PROBE_WAIT(erroneous, InstanceKlass::cast(this_k()), -1,wait);
+ DTRACE_CLASSINIT_PROBE_WAIT(erroneous, this_k(), -1,wait);
ResourceMark rm(THREAD);
const char* desc = "Could not initialize class ";
const char* className = this_k->external_name();
@@ -810,7 +810,7 @@
this_k->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads
CLEAR_PENDING_EXCEPTION; // ignore any exception thrown, superclass initialization error is thrown below
}
- DTRACE_CLASSINIT_PROBE_WAIT(super__failed, InstanceKlass::cast(this_k()), -1,wait);
+ DTRACE_CLASSINIT_PROBE_WAIT(super__failed, this_k(), -1,wait);
THROW_OOP(e());
}
}
@@ -826,7 +826,7 @@
{
assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
JavaThread* jt = (JavaThread*)THREAD;
- DTRACE_CLASSINIT_PROBE_WAIT(clinit, InstanceKlass::cast(this_k()), -1,wait);
+ DTRACE_CLASSINIT_PROBE_WAIT(clinit, this_k(), -1,wait);
// Timer includes any side effects of class initialization (resolution,
// etc), but not recursive entry into call_class_initializer().
PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
@@ -860,7 +860,7 @@
// JVMTI internal flag reset is needed in order to report ExceptionInInitializerError
JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
}
- DTRACE_CLASSINIT_PROBE_WAIT(error, InstanceKlass::cast(this_k()), -1,wait);
+ DTRACE_CLASSINIT_PROBE_WAIT(error, this_k(), -1,wait);
if (e->is_a(SystemDictionary::Error_klass())) {
THROW_OOP(e());
} else {
@@ -870,7 +870,7 @@
&args);
}
}
- DTRACE_CLASSINIT_PROBE_WAIT(end, InstanceKlass::cast(this_k()), -1,wait);
+ DTRACE_CLASSINIT_PROBE_WAIT(end, this_k(), -1,wait);
}
@@ -907,7 +907,7 @@
// Filter out subclasses whose supers already implement me.
// (Note: CHA must walk subclasses of direct implementors
// in order to locate indirect implementors.)
- Klass* sk = InstanceKlass::cast(k)->super();
+ Klass* sk = k->super();
if (sk != NULL && InstanceKlass::cast(sk)->implements_interface(this))
// We only need to check one immediate superclass, since the
// implements_interface query looks at transitive_interfaces.
@@ -955,8 +955,7 @@
GrowableArray<Klass*>* InstanceKlass::compute_secondary_supers(int num_extra_slots) {
// The secondaries are the implemented interfaces.
- InstanceKlass* ik = InstanceKlass::cast(this);
- Array<Klass*>* interfaces = ik->transitive_interfaces();
+ Array<Klass*>* interfaces = transitive_interfaces();
int num_secondaries = num_extra_slots + interfaces->length();
if (num_secondaries == 0) {
// Must share this for correct bootstrapping!
@@ -1141,7 +1140,7 @@
}
-void InstanceKlass::mask_for(methodHandle method, int bci,
+void InstanceKlass::mask_for(const methodHandle& method, int bci,
InterpreterOopMap* entry_for) {
// Dirty read, then double-check under a lock.
if (_oop_map_cache == NULL) {
@@ -1532,7 +1531,7 @@
if (method != NULL) {
return method;
}
- klass = InstanceKlass::cast(klass)->super();
+ klass = klass->super();
overpass_local_mode = skip_overpass; // Always ignore overpass methods in superclasses
}
return NULL;
@@ -1541,13 +1540,13 @@
#ifdef ASSERT
// search through class hierarchy and return true if this class or
// one of the superclasses was redefined
-bool InstanceKlass::has_redefined_this_or_super() const {
- const InstanceKlass* klass = this;
+bool InstanceKlass::has_redefined_this_or_super() {
+ Klass* klass = this;
while (klass != NULL) {
- if (klass->has_been_redefined()) {
+ if (InstanceKlass::cast(klass)->has_been_redefined()) {
return true;
}
- klass = InstanceKlass::cast(klass->super());
+ klass = klass->super();
}
return false;
}
@@ -1645,7 +1644,7 @@
// locking has to be done very carefully to avoid deadlocks
// and/or other cache consistency problems.
//
-jmethodID InstanceKlass::get_jmethod_id(instanceKlassHandle ik_h, methodHandle method_h) {
+jmethodID InstanceKlass::get_jmethod_id(instanceKlassHandle ik_h, const methodHandle& method_h) {
size_t idnum = (size_t)method_h->method_idnum();
jmethodID* jmeths = ik_h->methods_jmethod_ids_acquire();
size_t length = 0;
@@ -1907,18 +1906,33 @@
// Decrement count of the nmethod in the dependency list and remove
// the bucket completely when the count goes to 0. This method must
// find a corresponding bucket otherwise there's a bug in the
-// recording of dependencies. Returns true if the bucket is ready for reclamation.
-//
-bool nmethodBucket::remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm) {
+// recording of dependencies. Returns true if the bucket was deleted,
+// or marked ready for reclaimation.
+bool nmethodBucket::remove_dependent_nmethod(nmethodBucket** deps, nmethod* nm, bool delete_immediately) {
assert_locked_or_safepoint(CodeCache_lock);
- for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
+ nmethodBucket* first = *deps;
+ nmethodBucket* last = NULL;
+
+ for (nmethodBucket* b = first; b != NULL; b = b->next()) {
if (nm == b->get_nmethod()) {
int val = b->decrement();
guarantee(val >= 0, "Underflow: %d", val);
- return (val == 0);
+ if (val == 0) {
+ if (delete_immediately) {
+ if (last == NULL) {
+ *deps = b->next();
+ } else {
+ last->set_next(b->next());
+ }
+ delete b;
+ }
+ }
+ return true;
}
+ last = b;
}
+
#ifdef ASSERT
tty->print_raw_cr("### can't find dependent nmethod");
nm->print();
@@ -1927,6 +1941,12 @@
return false;
}
+// Convenience overload, for callers that don't want to delete the nmethodBucket entry.
+bool nmethodBucket::remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm) {
+ nmethodBucket** deps_addr = &deps;
+ return remove_dependent_nmethod(deps_addr, nm, false /* Don't delete */);
+}
+
//
// Reclaim all unused buckets. Returns new head of the list.
//
@@ -2013,10 +2033,10 @@
_dependencies = nmethodBucket::add_dependent_nmethod(_dependencies, nm);
}
-void InstanceKlass::remove_dependent_nmethod(nmethod* nm) {
+void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) {
assert_locked_or_safepoint(CodeCache_lock);
- if (nmethodBucket::remove_dependent_nmethod(_dependencies, nm)) {
+ if (nmethodBucket::remove_dependent_nmethod(&_dependencies, nm, delete_immediately)) {
set_has_unloaded_dependent(true);
}
}
@@ -2031,6 +2051,13 @@
}
#endif //PRODUCT
+void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) {
+ clean_implementors_list(is_alive);
+ clean_method_data(is_alive);
+
+ clean_dependent_nmethods();
+}
+
void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
assert(class_loader_data()->is_alive(is_alive), "this klass should be live");
if (is_interface()) {
@@ -2297,32 +2324,18 @@
// different verisons of is_same_class_package
bool InstanceKlass::is_same_class_package(Klass* class2) {
- Klass* class1 = this;
- oop classloader1 = InstanceKlass::cast(class1)->class_loader();
- Symbol* classname1 = class1->name();
-
- if (class2->oop_is_objArray()) {
+ if (class2->is_objArray_klass()) {
class2 = ObjArrayKlass::cast(class2)->bottom_klass();
}
- oop classloader2;
- if (class2->oop_is_instance()) {
- classloader2 = InstanceKlass::cast(class2)->class_loader();
- } else {
- assert(class2->oop_is_typeArray(), "should be type array");
- classloader2 = NULL;
- }
+ oop classloader2 = class2->class_loader();
Symbol* classname2 = class2->name();
- return InstanceKlass::is_same_class_package(classloader1, classname1,
+ return InstanceKlass::is_same_class_package(class_loader(), name(),
classloader2, classname2);
}
bool InstanceKlass::is_same_class_package(oop classloader2, Symbol* classname2) {
- Klass* class1 = this;
- oop classloader1 = InstanceKlass::cast(class1)->class_loader();
- Symbol* classname1 = class1->name();
-
- return InstanceKlass::is_same_class_package(classloader1, classname1,
+ return InstanceKlass::is_same_class_package(class_loader(), name(),
classloader2, classname2);
}
@@ -2385,7 +2398,7 @@
// Assumes name-signature match
// "this" is InstanceKlass of super_method which must exist
// note that the InstanceKlass of the method in the targetclassname has not always been created yet
-bool InstanceKlass::is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS) {
+bool InstanceKlass::is_override(const methodHandle& super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS) {
// Private methods can not be overridden
if (super_method->is_private()) {
return false;
@@ -2411,7 +2424,7 @@
bool InstanceKlass::is_same_package_member_impl(instanceKlassHandle class1,
Klass* class2_oop, TRAPS) {
if (class2_oop == class1()) return true;
- if (!class2_oop->oop_is_instance()) return false;
+ if (!class2_oop->is_instance_klass()) return false;
instanceKlassHandle class2(THREAD, class2_oop);
// must be in same package before we try anything else
@@ -2882,7 +2895,8 @@
((InstanceKlass*)this)->do_local_static_fields(&print_static_field);
st->print_cr(BULLET"---- non-static fields (%d words):", nonstatic_field_size());
FieldPrinter print_nonstatic_field(st);
- ((InstanceKlass*)this)->do_nonstatic_fields(&print_nonstatic_field);
+ InstanceKlass* ik = const_cast<InstanceKlass*>(this);
+ ik->do_nonstatic_fields(&print_nonstatic_field);
st->print(BULLET"non-static oop maps: ");
OopMapBlock* map = start_of_nonstatic_oop_maps();
@@ -2921,12 +2935,10 @@
if (this == SystemDictionary::String_klass()) {
typeArrayOop value = java_lang_String::value(obj);
- juint offset = java_lang_String::offset(obj);
juint length = java_lang_String::length(obj);
if (value != NULL &&
value->is_typeArray() &&
- offset <= (juint) value->length() &&
- offset + length <= (juint) value->length()) {
+ length <= (juint) value->length()) {
st->print(BULLET"string: ");
java_lang_String::print(obj, st);
st->cr();
@@ -2953,7 +2965,7 @@
st->print_cr(BULLET"fake entry for oop_size: %d", java_lang_Class::oop_size(obj));
st->print_cr(BULLET"fake entry for static_oop_field_count: %d", java_lang_Class::static_oop_field_count(obj));
Klass* real_klass = java_lang_Class::as_Klass(obj);
- if (real_klass != NULL && real_klass->oop_is_instance()) {
+ if (real_klass != NULL && real_klass->is_instance_klass()) {
InstanceKlass::cast(real_klass)->do_local_static_fields(&print_field);
}
} else if (this == SystemDictionary::MethodType_klass()) {
@@ -3546,3 +3558,199 @@
unsigned char * InstanceKlass::get_cached_class_file_bytes() {
return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
}
+
+
+/////////////// Unit tests ///////////////
+
+#ifndef PRODUCT
+
+class TestNmethodBucketContext {
+ public:
+ nmethod* _nmethodLast;
+ nmethod* _nmethodMiddle;
+ nmethod* _nmethodFirst;
+
+ nmethodBucket* _bucketLast;
+ nmethodBucket* _bucketMiddle;
+ nmethodBucket* _bucketFirst;
+
+ nmethodBucket* _bucketList;
+
+ TestNmethodBucketContext() {
+ CodeCache_lock->lock_without_safepoint_check();
+
+ _nmethodLast = reinterpret_cast<nmethod*>(0x8 * 0);
+ _nmethodMiddle = reinterpret_cast<nmethod*>(0x8 * 1);
+ _nmethodFirst = reinterpret_cast<nmethod*>(0x8 * 2);
+
+ _bucketLast = new nmethodBucket(_nmethodLast, NULL);
+ _bucketMiddle = new nmethodBucket(_nmethodMiddle, _bucketLast);
+ _bucketFirst = new nmethodBucket(_nmethodFirst, _bucketMiddle);
+
+ _bucketList = _bucketFirst;
+ }
+
+ ~TestNmethodBucketContext() {
+ delete _bucketLast;
+ delete _bucketMiddle;
+ delete _bucketFirst;
+
+ CodeCache_lock->unlock();
+ }
+};
+
+class TestNmethodBucket {
+ public:
+ static void testRemoveDependentNmethodFirstDeleteImmediately() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodFirst, true /* delete */);
+
+ assert(c._bucketList == c._bucketMiddle, "check");
+ assert(c._bucketList->next() == c._bucketLast, "check");
+ assert(c._bucketList->next()->next() == NULL, "check");
+
+ // Cleanup before context is deleted.
+ c._bucketFirst = NULL;
+ }
+
+ static void testRemoveDependentNmethodMiddleDeleteImmediately() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodMiddle, true /* delete */);
+
+ assert(c._bucketList == c._bucketFirst, "check");
+ assert(c._bucketList->next() == c._bucketLast, "check");
+ assert(c._bucketList->next()->next() == NULL, "check");
+
+ // Cleanup before context is deleted.
+ c._bucketMiddle = NULL;
+ }
+
+ static void testRemoveDependentNmethodLastDeleteImmediately() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodLast, true /* delete */);
+
+ assert(c._bucketList == c._bucketFirst, "check");
+ assert(c._bucketList->next() == c._bucketMiddle, "check");
+ assert(c._bucketList->next()->next() == NULL, "check");
+
+ // Cleanup before context is deleted.
+ c._bucketLast = NULL;
+ }
+
+ static void testRemoveDependentNmethodFirstDeleteDeferred() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodFirst, false /* delete */);
+
+ assert(c._bucketList == c._bucketFirst, "check");
+ assert(c._bucketList->next() == c._bucketMiddle, "check");
+ assert(c._bucketList->next()->next() == c._bucketLast, "check");
+ assert(c._bucketList->next()->next()->next() == NULL, "check");
+
+ assert(c._bucketFirst->count() == 0, "check");
+ assert(c._bucketMiddle->count() == 1, "check");
+ assert(c._bucketLast->count() == 1, "check");
+ }
+
+ static void testRemoveDependentNmethodMiddleDeleteDeferred() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodMiddle, false /* delete */);
+
+ assert(c._bucketList == c._bucketFirst, "check");
+ assert(c._bucketList->next() == c._bucketMiddle, "check");
+ assert(c._bucketList->next()->next() == c._bucketLast, "check");
+ assert(c._bucketList->next()->next()->next() == NULL, "check");
+
+ assert(c._bucketFirst->count() == 1, "check");
+ assert(c._bucketMiddle->count() == 0, "check");
+ assert(c._bucketLast->count() == 1, "check");
+ }
+
+ static void testRemoveDependentNmethodLastDeleteDeferred() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodLast, false /* delete */);
+
+ assert(c._bucketList == c._bucketFirst, "check");
+ assert(c._bucketList->next() == c._bucketMiddle, "check");
+ assert(c._bucketList->next()->next() == c._bucketLast, "check");
+ assert(c._bucketList->next()->next()->next() == NULL, "check");
+
+ assert(c._bucketFirst->count() == 1, "check");
+ assert(c._bucketMiddle->count() == 1, "check");
+ assert(c._bucketLast->count() == 0, "check");
+ }
+
+ static void testRemoveDependentNmethodConvenienceFirst() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodFirst);
+
+ assert(c._bucketList == c._bucketFirst, "check");
+ assert(c._bucketList->next() == c._bucketMiddle, "check");
+ assert(c._bucketList->next()->next() == c._bucketLast, "check");
+ assert(c._bucketList->next()->next()->next() == NULL, "check");
+
+ assert(c._bucketFirst->count() == 0, "check");
+ assert(c._bucketMiddle->count() == 1, "check");
+ assert(c._bucketLast->count() == 1, "check");
+ }
+
+ static void testRemoveDependentNmethodConvenienceMiddle() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodMiddle);
+
+ assert(c._bucketList == c._bucketFirst, "check");
+ assert(c._bucketList->next() == c._bucketMiddle, "check");
+ assert(c._bucketList->next()->next() == c._bucketLast, "check");
+ assert(c._bucketList->next()->next()->next() == NULL, "check");
+
+ assert(c._bucketFirst->count() == 1, "check");
+ assert(c._bucketMiddle->count() == 0, "check");
+ assert(c._bucketLast->count() == 1, "check");
+ }
+
+ static void testRemoveDependentNmethodConvenienceLast() {
+ TestNmethodBucketContext c;
+
+ nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodLast);
+
+ assert(c._bucketList == c._bucketFirst, "check");
+ assert(c._bucketList->next() == c._bucketMiddle, "check");
+ assert(c._bucketList->next()->next() == c._bucketLast, "check");
+ assert(c._bucketList->next()->next()->next() == NULL, "check");
+
+ assert(c._bucketFirst->count() == 1, "check");
+ assert(c._bucketMiddle->count() == 1, "check");
+ assert(c._bucketLast->count() == 0, "check");
+ }
+
+ static void testRemoveDependentNmethod() {
+ testRemoveDependentNmethodFirstDeleteImmediately();
+ testRemoveDependentNmethodMiddleDeleteImmediately();
+ testRemoveDependentNmethodLastDeleteImmediately();
+
+ testRemoveDependentNmethodFirstDeleteDeferred();
+ testRemoveDependentNmethodMiddleDeleteDeferred();
+ testRemoveDependentNmethodLastDeleteDeferred();
+
+ testRemoveDependentNmethodConvenienceFirst();
+ testRemoveDependentNmethodConvenienceMiddle();
+ testRemoveDependentNmethodConvenienceLast();
+ }
+
+ static void test() {
+ testRemoveDependentNmethod();
+ }
+};
+
+void TestNmethodBucket_test() {
+ TestNmethodBucket::test();
+}
+
+#endif
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -414,7 +414,7 @@
};
// method override check
- bool is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS);
+ bool is_override(const methodHandle& super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS);
// package
bool is_same_class_package(Klass* class2);
@@ -780,7 +780,7 @@
// jmethodID support
static jmethodID get_jmethod_id(instanceKlassHandle ik_h,
- methodHandle method_h);
+ const methodHandle& method_h);
static jmethodID get_jmethod_id_fetch_or_update(instanceKlassHandle ik_h,
size_t idnum, jmethodID new_id, jmethodID* new_jmeths,
jmethodID* to_dealloc_id_p,
@@ -827,7 +827,7 @@
// OopMapCache support
OopMapCache* oop_map_cache() { return _oop_map_cache; }
void set_oop_map_cache(OopMapCache *cache) { _oop_map_cache = cache; }
- void mask_for(methodHandle method, int bci, InterpreterOopMap* entry);
+ void mask_for(const methodHandle& method, int bci, InterpreterOopMap* entry);
// JNI identifier support (for static fields - for jni performance)
JNIid* jni_ids() { return _jni_ids; }
@@ -837,7 +837,7 @@
// maintenance of deoptimization dependencies
int mark_dependent_nmethods(DepChange& changes);
void add_dependent_nmethod(nmethod* nm);
- void remove_dependent_nmethod(nmethod* nm);
+ void remove_dependent_nmethod(nmethod* nm, bool delete_immediately);
// On-stack replacement support
nmethod* osr_nmethods_head() const { return _osr_nmethods_head; };
@@ -862,7 +862,7 @@
#ifdef ASSERT
// check whether this class or one of its superclasses was redefined
- bool has_redefined_this_or_super() const;
+ bool has_redefined_this_or_super();
#endif
// Access to the implementor of an interface.
@@ -908,7 +908,9 @@
bool compute_is_subtype_of(Klass* k);
bool can_be_primary_super_slow() const;
int oop_size(oop obj) const { return size_helper(); }
- bool oop_is_instance_slow() const { return true; }
+ // slow because it's a virtual call and used for verifying the layout_helper.
+ // Using the layout_helper bits, we can call is_instance_klass without a virtual call.
+ DEBUG_ONLY(bool is_instance_klass_slow() const { return true; })
// Iterators
void do_local_static_fields(FieldClosure* cl);
@@ -922,7 +924,8 @@
// Casting from Klass*
static InstanceKlass* cast(Klass* k) {
- assert(k == NULL || k->oop_is_instance(), "cast to InstanceKlass");
+ assert(k != NULL, "k should not be null");
+ assert(k->is_instance_klass(), "cast to InstanceKlass");
return static_cast<InstanceKlass*>(k);
}
@@ -1021,6 +1024,7 @@
void adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed);
#endif // INCLUDE_JVMTI
+ void clean_weak_instanceklass_links(BoolObjectClosure* is_alive);
void clean_implementors_list(BoolObjectClosure* is_alive);
void clean_method_data(BoolObjectClosure* is_alive);
void clean_dependent_nmethods();
@@ -1349,6 +1353,7 @@
static int mark_dependent_nmethods(nmethodBucket* deps, DepChange& changes);
static nmethodBucket* add_dependent_nmethod(nmethodBucket* deps, nmethod* nm);
+ static bool remove_dependent_nmethod(nmethodBucket** deps, nmethod* nm, bool delete_immediately);
static bool remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm);
static nmethodBucket* clean_dependent_nmethods(nmethodBucket* deps);
#ifndef PRODUCT
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -40,7 +40,7 @@
int InstanceMirrorKlass::_offset_of_static_fields = 0;
int InstanceMirrorKlass::instance_size(KlassHandle k) {
- if (k() != NULL && k->oop_is_instance()) {
+ if (k() != NULL && k->is_instance_klass()) {
return align_object_size(size_helper() + InstanceKlass::cast(k())->static_field_size());
}
return size_helper();
@@ -65,7 +65,7 @@
int InstanceMirrorKlass::compute_static_oop_field_count(oop obj) {
Klass* k = java_lang_Class::as_Klass(obj);
- if (k != NULL && k->oop_is_instance()) {
+ if (k != NULL && k->is_instance_klass()) {
return InstanceKlass::cast(k)->static_oop_field_count();
}
return 0;
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.inline.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.inline.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -60,7 +60,7 @@
Klass* klass = java_lang_Class::as_Klass(obj);
// We'll get NULL for primitive mirrors.
if (klass != NULL) {
- if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
+ if (klass->is_instance_klass() && InstanceKlass::cast(klass)->is_anonymous()) {
// An anonymous class doesn't have its own class loader, so when handling
// the java mirror for an anonymous class we need to make sure its class
// loader data is claimed, this is done by calling do_cld explicitly.
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -82,8 +82,9 @@
// Verify next field
oop next = java_lang_ref_Reference::next(obj);
if (next != NULL) {
- guarantee(next->is_oop(), "next field verify failed");
- guarantee(next->is_instanceRef(), "next field verify failed");
+ guarantee(next->is_oop(), "next field should be an oop");
+ guarantee(next->is_instance(), "next field should be an instance");
+ guarantee(InstanceKlass::cast(next->klass())->is_reference_instance_klass(), "next field verify failed");
}
}
--- a/hotspot/src/share/vm/oops/klass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/klass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -348,7 +348,7 @@
InstanceKlass* Klass::superklass() const {
- assert(super() == NULL || super()->oop_is_instance(), "must be instance klass");
+ assert(super() == NULL || super()->is_instance_klass(), "must be instance klass");
return _super == NULL ? NULL : InstanceKlass::cast(_super);
}
@@ -440,10 +440,9 @@
}
// Clean the implementors list and method data.
- if (clean_alive_klasses && current->oop_is_instance()) {
+ if (clean_alive_klasses && current->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(current);
- ik->clean_implementors_list(is_alive);
- ik->clean_method_data(is_alive);
+ ik->clean_weak_instanceklass_links(is_alive);
}
}
}
@@ -558,9 +557,11 @@
oop Klass::class_loader() const { return class_loader_data()->class_loader(); }
+// In product mode, this function doesn't have virtual function calls so
+// there might be some performance advantage to handling InstanceKlass here.
const char* Klass::external_name() const {
- if (oop_is_instance()) {
- InstanceKlass* ik = (InstanceKlass*) this;
+ if (is_instance_klass()) {
+ const InstanceKlass* ik = static_cast<const InstanceKlass*>(this);
if (ik->is_anonymous()) {
intptr_t hash = 0;
if (ik->java_mirror() != NULL) {
@@ -688,19 +689,13 @@
#ifndef PRODUCT
bool Klass::verify_vtable_index(int i) {
- if (oop_is_instance()) {
- int limit = ((InstanceKlass*)this)->vtable_length()/vtableEntry::size();
- assert(i >= 0 && i < limit, "index %d out of bounds %d", i, limit);
- } else {
- assert(oop_is_array(), "Must be");
- int limit = ((ArrayKlass*)this)->vtable_length()/vtableEntry::size();
- assert(i >= 0 && i < limit, "index %d out of bounds %d", i, limit);
- }
+ int limit = vtable_length()/vtableEntry::size();
+ assert(i >= 0 && i < limit, "index %d out of bounds %d", i, limit);
return true;
}
bool Klass::verify_itable_index(int i) {
- assert(oop_is_instance(), "");
+ assert(is_instance_klass(), "");
int method_count = klassItable::method_count_for_interface(this);
assert(i >= 0 && i < method_count, "index out of bounds");
return true;
@@ -716,11 +711,11 @@
public:
static void test_oop_is_instanceClassLoader() {
Klass* klass = SystemDictionary::ClassLoader_klass();
- guarantee(klass->oop_is_instance(), "assert");
+ guarantee(klass->is_instance_klass(), "assert");
guarantee(InstanceKlass::cast(klass)->is_class_loader_instance_klass(), "test failed");
klass = SystemDictionary::String_klass();
- guarantee(!klass->oop_is_instance() ||
+ guarantee(!klass->is_instance_klass() ||
!InstanceKlass::cast(klass)->is_class_loader_instance_klass(),
"test failed");
}
@@ -730,4 +725,4 @@
TestKlass::test_oop_is_instanceClassLoader();
}
-#endif
+#endif // PRODUCT
--- a/hotspot/src/share/vm/oops/klass.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/klass.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -373,8 +373,8 @@
#endif
// vtables
- virtual klassVtable* vtable() const { return NULL; }
- virtual int vtable_length() const { return 0; }
+ virtual klassVtable* vtable() const = 0;
+ virtual int vtable_length() const = 0;
// subclass check
bool is_subclass_of(const Klass* k) const;
@@ -474,11 +474,13 @@
virtual const char* signature_name() const;
// type testing operations
+#ifdef ASSERT
protected:
- virtual bool oop_is_instance_slow() const { return false; }
- virtual bool oop_is_array_slow() const { return false; }
- virtual bool oop_is_objArray_slow() const { return false; }
- virtual bool oop_is_typeArray_slow() const { return false; }
+ virtual bool is_instance_klass_slow() const { return false; }
+ virtual bool is_array_klass_slow() const { return false; }
+ virtual bool is_objArray_klass_slow() const { return false; }
+ virtual bool is_typeArray_klass_slow() const { return false; }
+#endif // ASSERT
public:
// Fast non-virtual versions
@@ -492,18 +494,18 @@
}
public:
#endif
- inline bool oop_is_instance() const { return assert_same_query(
- layout_helper_is_instance(layout_helper()),
- oop_is_instance_slow()); }
- inline bool oop_is_array() const { return assert_same_query(
+ inline bool is_instance_klass() const { return assert_same_query(
+ layout_helper_is_instance(layout_helper()),
+ is_instance_klass_slow()); }
+ inline bool is_array_klass() const { return assert_same_query(
layout_helper_is_array(layout_helper()),
- oop_is_array_slow()); }
- inline bool oop_is_objArray() const { return assert_same_query(
+ is_array_klass_slow()); }
+ inline bool is_objArray_klass() const { return assert_same_query(
layout_helper_is_objArray(layout_helper()),
- oop_is_objArray_slow()); }
- inline bool oop_is_typeArray() const { return assert_same_query(
+ is_objArray_klass_slow()); }
+ inline bool is_typeArray_klass() const { return assert_same_query(
layout_helper_is_typeArray(layout_helper()),
- oop_is_typeArray_slow()); }
+ is_typeArray_klass_slow()); }
#undef assert_same_query
// Access flags
--- a/hotspot/src/share/vm/oops/klass.inline.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/klass.inline.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
#include "oops/markOop.hpp"
inline void Klass::set_prototype_header(markOop header) {
- assert(!header->has_bias_pattern() || oop_is_instance(), "biased locking currently only supported for Java instances");
+ assert(!header->has_bias_pattern() || is_instance_klass(), "biased locking currently only supported for Java instances");
_prototype_header = header;
}
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -39,9 +39,7 @@
#include "utilities/copy.hpp"
inline InstanceKlass* klassVtable::ik() const {
- Klass* k = _klass();
- assert(k->oop_is_instance(), "not an InstanceKlass");
- return (InstanceKlass*)k;
+ return InstanceKlass::cast(_klass());
}
@@ -66,8 +64,7 @@
int vtable_length = 0;
// start off with super's vtable length
- InstanceKlass* sk = (InstanceKlass*)super;
- vtable_length = super == NULL ? 0 : sk->vtable_length();
+ vtable_length = super == NULL ? 0 : super->vtable_length();
// go thru each method in the methods table to see if it needs a new entry
int len = methods->length();
@@ -131,10 +128,7 @@
return 0;
} else {
// copy methods from superKlass
- // can't inherit from array class, so must be InstanceKlass
- assert(super->oop_is_instance(), "must be instance klass");
- InstanceKlass* sk = (InstanceKlass*)super();
- klassVtable* superVtable = sk->vtable();
+ klassVtable* superVtable = super->vtable();
assert(superVtable->length() <= _length, "vtable too short");
#ifdef ASSERT
superVtable->verify(tty, true);
@@ -143,7 +137,7 @@
#ifndef PRODUCT
if (PrintVtables && Verbose) {
ResourceMark rm;
- tty->print_cr("copy vtable from %s to %s size %d", sk->internal_name(), klass()->internal_name(), _length);
+ tty->print_cr("copy vtable from %s to %s size %d", super->internal_name(), klass()->internal_name(), _length);
}
#endif
return superVtable->length();
@@ -158,7 +152,7 @@
KlassHandle super (THREAD, klass()->java_super());
int nofNewEntries = 0;
- if (PrintVtables && !klass()->oop_is_array()) {
+ if (PrintVtables && !klass()->is_array_klass()) {
ResourceMark rm(THREAD);
tty->print_cr("Initializing: %s", _klass->name()->as_C_string());
}
@@ -176,10 +170,10 @@
}
int super_vtable_len = initialize_from_super(super);
- if (klass()->oop_is_array()) {
+ if (klass()->is_array_klass()) {
assert(super_vtable_len == _length, "arrays shouldn't introduce new methods");
} else {
- assert(_klass->oop_is_instance(), "must be InstanceKlass");
+ assert(_klass->is_instance_klass(), "must be InstanceKlass");
Array<Method*>* methods = ik()->methods();
int len = methods->length();
@@ -303,7 +297,7 @@
break;
}
// if no override found yet, continue to search up
- superk = InstanceKlass::cast(superk->super());
+ superk = superk->super() == NULL ? NULL : InstanceKlass::cast(superk->super());
}
return superk;
@@ -318,7 +312,7 @@
bool checkconstraints, TRAPS) {
ResourceMark rm;
bool allocate_new = true;
- assert(klass->oop_is_instance(), "must be InstanceKlass");
+ assert(klass->is_instance_klass(), "must be InstanceKlass");
Array<int>* def_vtable_indices = NULL;
bool is_default = false;
@@ -761,15 +755,14 @@
return false;
}
- InstanceKlass* cursuper;
- // Iterate on all superclasses, which should have instanceKlasses
+ // Iterate on all superclasses, which should be InstanceKlasses.
// Note that we explicitly look for overpasses at each level.
// Overpasses may or may not exist for supers for pass 1,
// they should have been created for pass 2 and later.
- for (cursuper = InstanceKlass::cast(super); cursuper != NULL; cursuper = (InstanceKlass*)cursuper->super())
+ for (Klass* cursuper = super; cursuper != NULL; cursuper = cursuper->super())
{
- if (cursuper->find_local_method(name, signature,
+ if (InstanceKlass::cast(cursuper)->find_local_method(name, signature,
Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) {
return false;
}
@@ -1117,7 +1110,7 @@
}
int klassItable::method_count_for_interface(Klass* interf) {
- assert(interf->oop_is_instance(), "must be");
+ assert(interf->is_instance_klass(), "must be");
assert(interf->is_interface(), "must be");
Array<Method*>* methods = InstanceKlass::cast(interf)->methods();
int nof_methods = methods->length();
@@ -1534,11 +1527,11 @@
klassVtable* vt = kl->vtable();
if (vt == NULL) return;
no_klasses++;
- if (kl->oop_is_instance()) {
+ if (kl->is_instance_klass()) {
no_instance_klasses++;
kl->array_klasses_do(do_class);
}
- if (kl->oop_is_array()) {
+ if (kl->is_array_klass()) {
no_array_klasses++;
sum_of_array_vtable_len += vt->length();
}
--- a/hotspot/src/share/vm/oops/method.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/method.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -299,10 +299,7 @@
Symbol* Method::klass_name() const {
- Klass* k = method_holder();
- assert(k->is_klass(), "must be klass");
- InstanceKlass* ik = (InstanceKlass*) k;
- return ik->name();
+ return method_holder()->name();
}
@@ -366,7 +363,7 @@
// Build a MethodData* object to hold information about this method
// collected in the interpreter.
-void Method::build_interpreter_method_data(methodHandle method, TRAPS) {
+void Method::build_interpreter_method_data(const methodHandle& method, TRAPS) {
// Do not profile the method if metaspace has hit an OOM previously
// allocating profiling data. Callers clear pending exception so don't
// add one here.
@@ -897,7 +894,7 @@
// Called when the method_holder is getting linked. Setup entrypoints so the method
// is ready to be called from interpreter, compiler, and vtables.
-void Method::link_method(methodHandle h_method, TRAPS) {
+void Method::link_method(const methodHandle& h_method, TRAPS) {
// If the code cache is full, we may reenter this function for the
// leftover methods that weren't linked.
if (_i2i_entry != NULL) return;
@@ -1178,7 +1175,7 @@
Klass* Method::check_non_bcp_klass(Klass* klass) {
if (klass != NULL && klass->class_loader() != NULL) {
- if (klass->oop_is_objArray())
+ if (klass->is_objArray_klass())
klass = ObjArrayKlass::cast(klass)->bottom_klass();
return klass;
}
@@ -1305,6 +1302,73 @@
return vmSymbols::find_sid(klass_name);
}
+static bool is_unsafe_alias(vmSymbols::SID name_id) {
+ // All 70 intrinsic candidate methods from sun.misc.Unsafe in 1.8.
+ // Some have the same method name but different signature, e.g.
+ // getByte(long), getByte(Object,long)
+ switch (name_id) {
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(allocateInstance_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(copyMemory_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(loadFence_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(storeFence_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(fullFence_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getObject_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getBoolean_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getByte_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getShort_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getChar_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getInt_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getLong_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getFloat_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getDouble_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putObject_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putBoolean_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putByte_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putShort_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putChar_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putInt_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putLong_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putFloat_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putDouble_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getObjectVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getBooleanVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getByteVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getShortVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getCharVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getIntVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getLongVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getFloatVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getDoubleVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putObjectVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putBooleanVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putByteVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putShortVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putCharVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putIntVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putLongVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putFloatVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putDoubleVolatile_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getAddress_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putAddress_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(compareAndSwapObject_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(compareAndSwapLong_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(compareAndSwapInt_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putOrderedObject_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putOrderedLong_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(putOrderedInt_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndAddInt_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndAddLong_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndSetInt_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndSetLong_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(getAndSetObject_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(park_name):
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(unpark_name):
+ return true;
+ }
+
+ return false;
+}
+
void Method::init_intrinsic_id() {
assert(_intrinsic_id == vmIntrinsics::_none, "do this just once");
const uintptr_t max_id_uint = right_n_bits((int)(sizeof(_intrinsic_id) * BitsPerByte));
@@ -1357,6 +1421,14 @@
if (is_static() != MethodHandles::is_signature_polymorphic_static(id))
id = vmIntrinsics::_none;
break;
+
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Unsafe):
+ // Map sun.misc.Unsafe to jdk.internal.misc.Unsafe
+ if (!is_unsafe_alias(name_id)) break;
+ // pretend it is the corresponding method in the internal Unsafe class:
+ klass_id = vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_misc_Unsafe);
+ id = vmIntrinsics::find_id(klass_id, name_id, sig_id, flags);
+ break;
}
if (id != vmIntrinsics::_none) {
--- a/hotspot/src/share/vm/oops/method.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/method.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -393,7 +393,7 @@
bool was_executed_more_than(int n);
bool was_never_executed() { return !was_executed_more_than(0); }
- static void build_interpreter_method_data(methodHandle method, TRAPS);
+ static void build_interpreter_method_data(const methodHandle& method, TRAPS);
static MethodCounters* build_method_counters(Method* m, TRAPS);
@@ -435,7 +435,7 @@
address get_c2i_unverified_entry();
AdapterHandlerEntry* adapter() { return _adapter; }
// setup entry points
- void link_method(methodHandle method, TRAPS);
+ void link_method(const methodHandle& method, TRAPS);
// clear entry points. Used by sharing code
void unlink_method();
--- a/hotspot/src/share/vm/oops/methodData.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/methodData.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -708,7 +708,7 @@
// A MethodData* holds information which has been collected about
// a method.
-MethodData* MethodData::allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS) {
+MethodData* MethodData::allocate(ClassLoaderData* loader_data, const methodHandle& method, TRAPS) {
int size = MethodData::compute_allocation_size_in_words(method);
return new (loader_data, size, false, MetaspaceObj::MethodDataType, THREAD)
@@ -898,7 +898,7 @@
// Compute the size of the MethodData* necessary to store
// profiling information about a given method. Size is in bytes.
-int MethodData::compute_allocation_size_in_bytes(methodHandle method) {
+int MethodData::compute_allocation_size_in_bytes(const methodHandle& method) {
int data_size = 0;
BytecodeStream stream(method);
Bytecodes::Code c;
@@ -931,7 +931,7 @@
// Compute the size of the MethodData* necessary to store
// profiling information about a given method. Size is in words
-int MethodData::compute_allocation_size_in_words(methodHandle method) {
+int MethodData::compute_allocation_size_in_words(const methodHandle& method) {
int byte_size = compute_allocation_size_in_bytes(method);
int word_size = align_size_up(byte_size, BytesPerWord) / BytesPerWord;
return align_object_size(word_size);
@@ -1102,7 +1102,9 @@
return new VirtualCallTypeData(this);
case DataLayout::parameters_type_data_tag:
return new ParametersTypeData(this);
- };
+ case DataLayout::speculative_trap_data_tag:
+ return new SpeculativeTrapData(this);
+ }
}
// Iteration over data.
@@ -1129,7 +1131,7 @@
}
// Initialize the MethodData* corresponding to a given method.
-MethodData::MethodData(methodHandle method, int size, TRAPS)
+MethodData::MethodData(const methodHandle& method, int size, TRAPS)
: _extra_data_lock(Monitor::leaf, "MDO extra data lock"),
_parameters_type_data_di(parameters_uninitialized) {
// Set the method back-pointer.
@@ -1513,7 +1515,7 @@
// not yet implemented.
}
-bool MethodData::profile_jsr292(methodHandle m, int bci) {
+bool MethodData::profile_jsr292(const methodHandle& m, int bci) {
if (m->is_compiled_lambda_form()) {
return true;
}
@@ -1538,7 +1540,7 @@
return profile_arguments_flag() == type_profile_all;
}
-bool MethodData::profile_arguments_for_invoke(methodHandle m, int bci) {
+bool MethodData::profile_arguments_for_invoke(const methodHandle& m, int bci) {
if (!profile_arguments()) {
return false;
}
@@ -1567,7 +1569,7 @@
return profile_return_flag() == type_profile_all;
}
-bool MethodData::profile_return_for_invoke(methodHandle m, int bci) {
+bool MethodData::profile_return_for_invoke(const methodHandle& m, int bci) {
if (!profile_return()) {
return false;
}
@@ -1596,7 +1598,7 @@
return profile_parameters_flag() == type_profile_all;
}
-bool MethodData::profile_parameters_for_method(methodHandle m) {
+bool MethodData::profile_parameters_for_method(const methodHandle& m) {
if (!profile_parameters()) {
return false;
}
--- a/hotspot/src/share/vm/oops/methodData.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/methodData.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -535,6 +535,7 @@
//
// A BitData holds a flag or two in its header.
class BitData : public ProfileData {
+ friend class VMStructs;
protected:
enum {
// null_seen:
@@ -603,6 +604,7 @@
//
// A CounterData corresponds to a simple counter.
class CounterData : public BitData {
+ friend class VMStructs;
protected:
enum {
count_off,
@@ -667,6 +669,7 @@
// plus a data displacement, used for realigning the data pointer to
// the corresponding target bci.
class JumpData : public ProfileData {
+ friend class VMStructs;
protected:
enum {
taken_off_set,
@@ -1173,6 +1176,7 @@
// that the check is reached, and a series of (Klass*, count) pairs
// which are used to store a type profile for the receiver of the check.
class ReceiverTypeData : public CounterData {
+ friend class VMStructs;
protected:
enum {
#if INCLUDE_JVMCI
@@ -1678,6 +1682,7 @@
// It consists of taken and not_taken counts as well as a data displacement
// for the taken case.
class BranchData : public JumpData {
+ friend class VMStructs;
protected:
enum {
not_taken_off_set = jump_cell_count,
@@ -1754,6 +1759,7 @@
// not have a statically known size. It consists of an array length
// and an array start.
class ArrayData : public ProfileData {
+ friend class VMStructs;
protected:
friend class DataLayout;
@@ -1831,6 +1837,7 @@
// of (count, displacement) pairs, which count the number of times each
// case was taken and specify the data displacment for each branch target.
class MultiBranchData : public ArrayData {
+ friend class VMStructs;
protected:
enum {
default_count_off_set,
@@ -2145,9 +2152,9 @@
Mutex _extra_data_lock;
- MethodData(methodHandle method, int size, TRAPS);
+ MethodData(const methodHandle& method, int size, TRAPS);
public:
- static MethodData* allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS);
+ static MethodData* allocate(ClassLoaderData* loader_data, const methodHandle& method, TRAPS);
MethodData() : _extra_data_lock(Monitor::leaf, "MDO extra data lock") {}; // For ciMethodData
bool is_methodData() const volatile { return true; }
@@ -2283,13 +2290,13 @@
type_profile_all = 2
};
- static bool profile_jsr292(methodHandle m, int bci);
+ static bool profile_jsr292(const methodHandle& m, int bci);
static int profile_arguments_flag();
static bool profile_all_arguments();
- static bool profile_arguments_for_invoke(methodHandle m, int bci);
+ static bool profile_arguments_for_invoke(const methodHandle& m, int bci);
static int profile_return_flag();
static bool profile_all_return();
- static bool profile_return_for_invoke(methodHandle m, int bci);
+ static bool profile_return_for_invoke(const methodHandle& m, int bci);
static int profile_parameters_flag();
static bool profile_parameters_jsr292_only();
static bool profile_all_parameters();
@@ -2304,8 +2311,8 @@
}
// Compute the size of a MethodData* before it is created.
- static int compute_allocation_size_in_bytes(methodHandle method);
- static int compute_allocation_size_in_words(methodHandle method);
+ static int compute_allocation_size_in_bytes(const methodHandle& method);
+ static int compute_allocation_size_in_words(const methodHandle& method);
static int compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps);
// Determine if a given bytecode can have profile information.
@@ -2589,7 +2596,7 @@
void verify_on(outputStream* st);
void verify_data_on(outputStream* st);
- static bool profile_parameters_for_method(methodHandle m);
+ static bool profile_parameters_for_method(const methodHandle& m);
static bool profile_arguments();
static bool profile_arguments_jsr292_only();
static bool profile_return();
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -102,7 +102,7 @@
// Create type name for klass.
Symbol* name = NULL;
- if (!element_klass->oop_is_instance() ||
+ if (!element_klass->is_instance_klass() ||
(name = InstanceKlass::cast(element_klass())->array_name()) == NULL) {
ResourceMark rm(THREAD);
@@ -111,17 +111,17 @@
char *new_str = NEW_RESOURCE_ARRAY(char, len + 4);
int idx = 0;
new_str[idx++] = '[';
- if (element_klass->oop_is_instance()) { // it could be an array or simple type
+ if (element_klass->is_instance_klass()) { // it could be an array or simple type
new_str[idx++] = 'L';
}
memcpy(&new_str[idx], name_str, len * sizeof(char));
idx += len;
- if (element_klass->oop_is_instance()) {
+ if (element_klass->is_instance_klass()) {
new_str[idx++] = ';';
}
new_str[idx++] = '\0';
name = SymbolTable::new_permanent_symbol(new_str, CHECK_0);
- if (element_klass->oop_is_instance()) {
+ if (element_klass->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(element_klass());
ik->set_array_name(name);
}
@@ -150,18 +150,18 @@
name->decrement_refcount();
Klass* bk;
- if (element_klass->oop_is_objArray()) {
+ if (element_klass->is_objArray_klass()) {
bk = ObjArrayKlass::cast(element_klass())->bottom_klass();
} else {
bk = element_klass();
}
- assert(bk != NULL && (bk->oop_is_instance() || bk->oop_is_typeArray()), "invalid bottom klass");
+ assert(bk != NULL && (bk->is_instance_klass() || bk->is_typeArray_klass()), "invalid bottom klass");
this->set_bottom_klass(bk);
this->set_class_loader_data(bk->class_loader_data());
this->set_layout_helper(array_layout_helper(T_OBJECT));
- assert(this->oop_is_array(), "sanity");
- assert(this->oop_is_objArray(), "sanity");
+ assert(this->is_array_klass(), "sanity");
+ assert(this->is_objArray_klass(), "sanity");
}
int ObjArrayKlass::oop_size(oop obj) const {
@@ -336,7 +336,7 @@
ak->set_lower_dimension(this);
OrderAccess::storestore();
set_higher_dimension(ak);
- assert(ak->oop_is_objArray(), "incorrect initialization of ObjArrayKlass");
+ assert(ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass");
}
}
} else {
@@ -386,7 +386,7 @@
}
bool ObjArrayKlass::compute_is_subtype_of(Klass* k) {
- if (!k->oop_is_objArray())
+ if (!k->is_objArray_klass())
return ArrayKlass::compute_is_subtype_of(k);
ObjArrayKlass* oak = ObjArrayKlass::cast(k);
@@ -484,7 +484,7 @@
guarantee(element_klass()->is_klass(), "should be klass");
guarantee(bottom_klass()->is_klass(), "should be klass");
Klass* bk = bottom_klass();
- guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(), "invalid bottom klass");
+ guarantee(bk->is_instance_klass() || bk->is_typeArray_klass(), "invalid bottom klass");
}
void ObjArrayKlass::oop_verify_on(oop obj, outputStream* st) {
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
bool can_be_primary_super_slow() const;
GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots);
bool compute_is_subtype_of(Klass* k);
- bool oop_is_objArray_slow() const { return true; }
+ DEBUG_ONLY(bool is_objArray_klass_slow() const { return true; })
int oop_size(oop obj) const;
// Allocation
@@ -91,8 +91,8 @@
public:
// Casting from Klass*
static ObjArrayKlass* cast(Klass* k) {
- assert(k->oop_is_objArray(), "cast to ObjArrayKlass");
- return (ObjArrayKlass*) k;
+ assert(k->is_objArray_klass(), "cast to ObjArrayKlass");
+ return static_cast<ObjArrayKlass*>(k);
}
// Sizing
--- a/hotspot/src/share/vm/oops/oop.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/oop.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -129,9 +129,6 @@
// type test operations that doesn't require inclusion of oop.inline.hpp.
bool oopDesc::is_instance_noinline() const { return is_instance(); }
-bool oopDesc::is_instanceMirror_noinline() const { return is_instanceMirror(); }
-bool oopDesc::is_instanceClassLoader_noline() const { return is_instanceClassLoader(); }
-bool oopDesc::is_instanceRef_noline() const { return is_instanceRef(); }
bool oopDesc::is_array_noinline() const { return is_array(); }
bool oopDesc::is_objArray_noinline() const { return is_objArray(); }
bool oopDesc::is_typeArray_noinline() const { return is_typeArray(); }
--- a/hotspot/src/share/vm/oops/oop.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/oop.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -110,18 +110,12 @@
// type test operations (inlined in oop.inline.hpp)
bool is_instance() const;
- bool is_instanceMirror() const;
- bool is_instanceClassLoader() const;
- bool is_instanceRef() const;
bool is_array() const;
bool is_objArray() const;
bool is_typeArray() const;
// type test operations that don't require inclusion of oop.inline.hpp.
bool is_instance_noinline() const;
- bool is_instanceMirror_noinline() const;
- bool is_instanceClassLoader_noline() const;
- bool is_instanceRef_noline() const;
bool is_array_noinline() const;
bool is_objArray_noinline() const;
bool is_typeArray_noinline() const;
--- a/hotspot/src/share/vm/oops/oop.inline.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -127,27 +127,12 @@
inline bool oopDesc::is_a(Klass* k) const { return klass()->is_subtype_of(k); }
inline bool oopDesc::is_instance() const {
- return klass()->oop_is_instance();
-}
-
-inline bool oopDesc::is_instanceClassLoader() const {
- Klass* k = klass();
- return k->oop_is_instance() && InstanceKlass::cast(k)->is_class_loader_instance_klass();
+ return klass()->is_instance_klass();
}
-inline bool oopDesc::is_instanceMirror() const {
- Klass* k = klass();
- return k->oop_is_instance() && InstanceKlass::cast(k)->is_mirror_instance_klass();
-}
-
-inline bool oopDesc::is_instanceRef() const {
- Klass* k = klass();
- return k->oop_is_instance() && InstanceKlass::cast(k)->is_reference_instance_klass();
-}
-
-inline bool oopDesc::is_array() const { return klass()->oop_is_array(); }
-inline bool oopDesc::is_objArray() const { return klass()->oop_is_objArray(); }
-inline bool oopDesc::is_typeArray() const { return klass()->oop_is_typeArray(); }
+inline bool oopDesc::is_array() const { return klass()->is_array_klass(); }
+inline bool oopDesc::is_objArray() const { return klass()->is_objArray_klass(); }
+inline bool oopDesc::is_typeArray() const { return klass()->is_typeArray_klass(); }
inline void* oopDesc::field_base(int offset) const { return (void*)&((char*)this)[offset]; }
@@ -724,7 +709,7 @@
inline void oopDesc::pc_update_contents() {
Klass* k = klass();
- if (!k->oop_is_typeArray()) {
+ if (!k->is_typeArray_klass()) {
// It might contain oops beyond the header, so take the virtual call.
k->oop_pc_update_pointers(this);
}
@@ -733,7 +718,7 @@
inline void oopDesc::ps_push_contents(PSPromotionManager* pm) {
Klass* k = klass();
- if (!k->oop_is_typeArray()) {
+ if (!k->is_typeArray_klass()) {
// It might contain oops beyond the header, so take the virtual call.
k->oop_ps_push_contents(this, pm);
}
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -43,7 +43,7 @@
#include "utilities/macros.hpp"
bool TypeArrayKlass::compute_is_subtype_of(Klass* k) {
- if (!k->oop_is_typeArray()) {
+ if (!k->is_typeArray_klass()) {
return ArrayKlass::compute_is_subtype_of(k);
}
@@ -86,8 +86,8 @@
TypeArrayKlass::TypeArrayKlass(BasicType type, Symbol* name) : ArrayKlass(name) {
set_layout_helper(array_layout_helper(type));
- assert(oop_is_array(), "sanity");
- assert(oop_is_typeArray(), "sanity");
+ assert(is_array_klass(), "sanity");
+ assert(is_typeArray_klass(), "sanity");
set_max_length(arrayOopDesc::max_array_length(type));
assert(size() >= TypeArrayKlass::header_size(), "bad size");
@@ -181,7 +181,7 @@
h_ak->set_lower_dimension(this);
OrderAccess::storestore();
set_higher_dimension(h_ak);
- assert(h_ak->oop_is_objArray(), "incorrect initialization of ObjArrayKlass");
+ assert(h_ak->is_objArray_klass(), "incorrect initialization of ObjArrayKlass");
}
}
} else {
--- a/hotspot/src/share/vm/oops/typeArrayKlass.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@
void set_max_length(jint m) { _max_length = m; }
// testers
- bool oop_is_typeArray_slow() const { return true; }
+ DEBUG_ONLY(bool is_typeArray_klass_slow() const { return true; })
// klass allocation
static TypeArrayKlass* create_klass(BasicType type, const char* name_str,
@@ -122,8 +122,8 @@
public:
// Casting from Klass*
static TypeArrayKlass* cast(Klass* k) {
- assert(k->oop_is_typeArray(), "cast to TypeArrayKlass");
- return (TypeArrayKlass*) k;
+ assert(k->is_typeArray_klass(), "cast to TypeArrayKlass");
+ return static_cast<TypeArrayKlass*>(k);
}
// Naming
--- a/hotspot/src/share/vm/oops/typeArrayOop.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/oops/typeArrayOop.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -48,47 +48,47 @@
public:
jbyte* byte_at_addr(int which) const {
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return &byte_base()[which];
}
jboolean* bool_at_addr(int which) const {
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return &bool_base()[which];
}
jchar* char_at_addr(int which) const {
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return &char_base()[which];
}
jint* int_at_addr(int which) const {
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return &int_base()[which];
}
jshort* short_at_addr(int which) const {
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return &short_base()[which];
}
jushort* ushort_at_addr(int which) const { // for field descriptor arrays
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return (jushort*) &short_base()[which];
}
jlong* long_at_addr(int which) const {
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return &long_base()[which];
}
jfloat* float_at_addr(int which) const {
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return &float_base()[which];
}
jdouble* double_at_addr(int which) const {
- assert(is_within_bounds(which), "index out of bounds");
+ assert(is_within_bounds(which), "index %d out of bounds %d", which, length());
return &double_base()[which];
}
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -158,7 +158,7 @@
Compile::print_timers();
}
-bool C2Compiler::is_intrinsic_supported(methodHandle method, bool is_virtual) {
+bool C2Compiler::is_intrinsic_supported(const methodHandle& method, bool is_virtual) {
vmIntrinsics::ID id = method->intrinsic_id();
assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
@@ -181,12 +181,25 @@
}
switch (id) {
- case vmIntrinsics::_compareTo:
+ case vmIntrinsics::_compressStringC:
+ case vmIntrinsics::_compressStringB:
+ if (!Matcher::has_match_rule(Op_StrCompressedCopy)) return false;
+ break;
+ case vmIntrinsics::_inflateStringC:
+ case vmIntrinsics::_inflateStringB:
+ if (!Matcher::has_match_rule(Op_StrInflatedCopy)) return false;
+ break;
+ case vmIntrinsics::_compareToL:
+ case vmIntrinsics::_compareToU:
+ case vmIntrinsics::_compareToLU:
+ case vmIntrinsics::_compareToUL:
if (!Matcher::match_rule_supported(Op_StrComp)) return false;
break;
- case vmIntrinsics::_equals:
+ case vmIntrinsics::_equalsL:
+ case vmIntrinsics::_equalsU:
if (!Matcher::match_rule_supported(Op_StrEquals)) return false;
break;
+ case vmIntrinsics::_equalsB:
case vmIntrinsics::_equalsC:
if (!Matcher::match_rule_supported(Op_AryEq)) return false;
break;
@@ -194,8 +207,12 @@
if (StubRoutines::unsafe_arraycopy() == NULL) return false;
break;
case vmIntrinsics::_encodeISOArray:
+ case vmIntrinsics::_encodeByteISOArray:
if (!Matcher::match_rule_supported(Op_EncodeISOArray)) return false;
break;
+ case vmIntrinsics::_hasNegatives:
+ if (!Matcher::match_rule_supported(Op_HasNegatives)) return false;
+ break;
case vmIntrinsics::_bitCount_i:
if (!Matcher::match_rule_supported(Op_PopCountI)) return false;
break;
@@ -302,7 +319,17 @@
case vmIntrinsics::_min:
case vmIntrinsics::_max:
case vmIntrinsics::_arraycopy:
- case vmIntrinsics::_indexOf:
+ case vmIntrinsics::_indexOfL:
+ case vmIntrinsics::_indexOfU:
+ case vmIntrinsics::_indexOfUL:
+ case vmIntrinsics::_indexOfIL:
+ case vmIntrinsics::_indexOfIU:
+ case vmIntrinsics::_indexOfIUL:
+ case vmIntrinsics::_indexOfU_char:
+ case vmIntrinsics::_toBytesStringU:
+ case vmIntrinsics::_getCharsStringU:
+ case vmIntrinsics::_getCharStringU:
+ case vmIntrinsics::_putCharStringU:
case vmIntrinsics::_getObject:
case vmIntrinsics::_getBoolean:
case vmIntrinsics::_getByte:
--- a/hotspot/src/share/vm/opto/c2compiler.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/c2compiler.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,13 +57,13 @@
// possible for only a limited set of available intrinsics whereas
// a non-virtual dispatch is possible for all available intrinsics.)
// Return false otherwise.
- virtual bool is_intrinsic_supported(methodHandle method) {
+ virtual bool is_intrinsic_supported(const methodHandle& method) {
return is_intrinsic_supported(method, false);
}
// Check if the compiler supports an intrinsic for 'method' given the
// the dispatch mode specified by the 'is_virtual' parameter.
- virtual bool is_intrinsic_supported(methodHandle method, bool is_virtual);
+ virtual bool is_intrinsic_supported(const methodHandle& method, bool is_virtual);
// Initial size of the code buffer (may be increased at runtime)
static int initial_code_buffer_size();
--- a/hotspot/src/share/vm/opto/callGenerator.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -671,7 +671,7 @@
&exact_receiver);
SafePointNode* slow_map = NULL;
- JVMState* slow_jvms;
+ JVMState* slow_jvms = NULL;
{ PreserveJVMState pjvms(&kit);
kit.set_control(slow_ctl);
if (!kit.stopped()) {
--- a/hotspot/src/share/vm/opto/classes.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/classes.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -136,6 +136,7 @@
macro(FastUnlock)
macro(Goto)
macro(Halt)
+macro(HasNegatives)
macro(If)
macro(IfFalse)
macro(IfTrue)
@@ -246,8 +247,11 @@
macro(StoreN)
macro(StoreNKlass)
macro(StrComp)
+macro(StrCompressedCopy)
macro(StrEquals)
macro(StrIndexOf)
+macro(StrIndexOfChar)
+macro(StrInflatedCopy)
macro(SubD)
macro(SubF)
macro(SubI)
--- a/hotspot/src/share/vm/opto/compile.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -3762,7 +3762,7 @@
MacroAssembler _masm(&cb);
for (int i = 0; i < _constants.length(); i++) {
Constant con = _constants.at(i);
- address constant_addr;
+ address constant_addr = NULL;
switch (con.type()) {
case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break;
case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break;
--- a/hotspot/src/share/vm/opto/compile.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/compile.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -89,7 +89,7 @@
typedef unsigned int node_idx_t;
class NodeCloneInfo {
private:
- uint64_t _idx_clone_orig;
+ uint64_t _idx_clone_orig;
public:
void set_idx(node_idx_t idx) {
@@ -98,17 +98,17 @@
node_idx_t idx() const { return (node_idx_t)(_idx_clone_orig & 0xFFFFFFFF); }
void set_gen(int generation) {
- uint64_t g = (uint64_t)generation << 32;
+ uint64_t g = (uint64_t)generation << 32;
_idx_clone_orig = _idx_clone_orig & 0xFFFFFFFF | g;
}
int gen() const { return (int)(_idx_clone_orig >> 32); }
- void set(uint64_t x) { _idx_clone_orig = x; }
- void set(node_idx_t x, int g) { set_idx(x); set_gen(g); }
+ void set(uint64_t x) { _idx_clone_orig = x; }
+ void set(node_idx_t x, int g) { set_idx(x); set_gen(g); }
uint64_t get() const { return _idx_clone_orig; }
NodeCloneInfo(uint64_t idx_clone_orig) : _idx_clone_orig(idx_clone_orig) {}
- NodeCloneInfo(node_idx_t x, int g) {set(x, g);}
+ NodeCloneInfo(node_idx_t x, int g) : _idx_clone_orig(0) { set(x, g); }
void dump() const;
};
--- a/hotspot/src/share/vm/opto/escape.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -560,9 +560,13 @@
break;
}
case Op_AryEq:
+ case Op_HasNegatives:
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
+ case Op_StrInflatedCopy:
+ case Op_StrCompressedCopy:
case Op_EncodeISOArray: {
add_local_var(n, PointsToNode::ArgEscape);
delayed_worklist->push(n); // Process it later.
@@ -743,11 +747,15 @@
ELSE_FAIL("Op_StoreP");
}
case Op_AryEq:
+ case Op_HasNegatives:
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
+ case Op_StrInflatedCopy:
+ case Op_StrCompressedCopy:
case Op_EncodeISOArray: {
- // char[] arrays passed to string intrinsic do not escape but
+ // char[]/byte[] arrays passed to string intrinsic do not escape but
// they are not scalar replaceable. Adjust escape state for them.
// Start from in(2) edge since in(1) is memory edge.
for (uint i = 2; i < n->req(); i++) {
@@ -2722,17 +2730,34 @@
if (mem->is_LoadStore()) {
adr = mem->in(MemNode::Address);
} else {
- assert(mem->Opcode() == Op_EncodeISOArray, "sanity");
+ assert(mem->Opcode() == Op_EncodeISOArray ||
+ mem->Opcode() == Op_StrCompressedCopy, "sanity");
adr = mem->in(3); // Memory edge corresponds to destination array
}
const Type *at = igvn->type(adr);
if (at != Type::TOP) {
- assert (at->isa_ptr() != NULL, "pointer type required.");
+ assert(at->isa_ptr() != NULL, "pointer type required.");
int idx = C->get_alias_index(at->is_ptr());
- assert(idx != alias_idx, "Object is not scalar replaceable if a LoadStore node access its field");
- break;
+ if (idx == alias_idx) {
+ // Assert in debug mode
+ assert(false, "Object is not scalar replaceable if a LoadStore node accesses its field");
+ break; // In product mode return SCMemProj node
+ }
}
result = mem->in(MemNode::Memory);
+ } else if (result->Opcode() == Op_StrInflatedCopy) {
+ Node* adr = result->in(3); // Memory edge corresponds to destination array
+ const Type *at = igvn->type(adr);
+ if (at != Type::TOP) {
+ assert(at->isa_ptr() != NULL, "pointer type required.");
+ int idx = C->get_alias_index(at->is_ptr());
+ if (idx == alias_idx) {
+ // Assert in debug mode
+ assert(false, "Object is not scalar replaceable if a StrInflatedCopy node accesses its field");
+ break; // In product mode return SCMemProj node
+ }
+ }
+ result = result->in(MemNode::Memory);
}
}
if (result->is_Phi()) {
@@ -3096,10 +3121,15 @@
}
} else {
uint op = use->Opcode();
- if (!(op == Op_CmpP || op == Op_Conv2B ||
+ if ((use->in(MemNode::Memory) == n) &&
+ (op == Op_StrCompressedCopy || op == Op_StrInflatedCopy)) {
+ // They overwrite memory edge corresponding to destination array,
+ memnode_worklist.append_if_missing(use);
+ } else if (!(op == Op_CmpP || op == Op_Conv2B ||
op == Op_CastP2X || op == Op_StoreCM ||
- op == Op_FastLock || op == Op_AryEq || op == Op_StrComp ||
- op == Op_StrEquals || op == Op_StrIndexOf)) {
+ op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || op == Op_HasNegatives ||
+ op == Op_StrCompressedCopy || op == Op_StrInflatedCopy ||
+ op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar)) {
n->dump();
use->dump();
assert(false, "EA: missing allocation reference path");
@@ -3161,7 +3191,8 @@
n = n->as_MemBar()->proj_out(TypeFunc::Memory);
if (n == NULL)
continue;
- } else if (n->Opcode() == Op_EncodeISOArray) {
+ } else if (n->Opcode() == Op_StrCompressedCopy ||
+ n->Opcode() == Op_EncodeISOArray) {
// get the memory projection
n = n->find_out_with(Op_SCMemProj);
assert(n->Opcode() == Op_SCMemProj, "memory projection required");
@@ -3216,11 +3247,16 @@
}
} else {
uint op = use->Opcode();
- if (!(op == Op_StoreCM ||
+ if ((use->in(MemNode::Memory) == n) &&
+ (op == Op_StrCompressedCopy || op == Op_StrInflatedCopy)) {
+ // They overwrite memory edge corresponding to destination array,
+ memnode_worklist.append_if_missing(use);
+ } else if (!(op == Op_StoreCM ||
(op == Op_CallLeaf && use->as_CallLeaf()->_name != NULL &&
strcmp(use->as_CallLeaf()->_name, "g1_wb_pre") == 0) ||
- op == Op_AryEq || op == Op_StrComp ||
- op == Op_StrEquals || op == Op_StrIndexOf)) {
+ op == Op_AryEq || op == Op_StrComp || op == Op_HasNegatives ||
+ op == Op_StrCompressedCopy || op == Op_StrInflatedCopy ||
+ op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar)) {
n->dump();
use->dump();
assert(false, "EA: missing memory path");
--- a/hotspot/src/share/vm/opto/gcm.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/gcm.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -504,8 +504,12 @@
"String equals is a 'load' that does not conflict with any stores");
assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrIndexOf),
"String indexOf is a 'load' that does not conflict with any stores");
+ assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_StrIndexOfChar),
+ "String indexOfChar is a 'load' that does not conflict with any stores");
assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_AryEq),
- "Arrays equals is a 'load' that do not conflict with any stores");
+ "Arrays equals is a 'load' that does not conflict with any stores");
+ assert(load_alias_idx || (load->is_Mach() && load->as_Mach()->ideal_Opcode() == Op_HasNegatives),
+ "HasNegatives is a 'load' that does not conflict with any stores");
if (!C->alias_type(load_alias_idx)->is_rewritable()) {
// It is impossible to spoil this load by putting stores before it,
--- a/hotspot/src/share/vm/opto/generateOptoStub.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/generateOptoStub.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -261,7 +261,7 @@
//-----------------------------
// If this is a normal subroutine return, issue the return and be done.
- Node *ret;
+ Node *ret = NULL;
switch( is_fancy_jump ) {
case 0: // Make a return instruction
// Return to caller, free any space for return address
--- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -4266,35 +4266,11 @@
#undef __
-
-Node* GraphKit::load_String_offset(Node* ctrl, Node* str) {
- if (java_lang_String::has_offset_field()) {
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
- false, NULL, 0);
- const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
- int offset_field_idx = C->get_alias_index(offset_field_type);
- return make_load(ctrl,
- basic_plus_adr(str, str, offset_offset),
- TypeInt::INT, T_INT, offset_field_idx, MemNode::unordered);
- } else {
- return intcon(0);
- }
-}
-
Node* GraphKit::load_String_length(Node* ctrl, Node* str) {
- if (java_lang_String::has_count_field()) {
- int count_offset = java_lang_String::count_offset_in_bytes();
- const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
- false, NULL, 0);
- const TypePtr* count_field_type = string_type->add_offset(count_offset);
- int count_field_idx = C->get_alias_index(count_field_type);
- return make_load(ctrl,
- basic_plus_adr(str, str, count_offset),
- TypeInt::INT, T_INT, count_field_idx, MemNode::unordered);
- } else {
- return load_array_length(load_String_value(ctrl, str));
- }
+ Node* len = load_array_length(load_String_value(ctrl, str));
+ Node* coder = load_String_coder(ctrl, str);
+ // Divide length by 2 if coder is UTF16
+ return _gvn.transform(new RShiftINode(len, coder));
}
Node* GraphKit::load_String_value(Node* ctrl, Node* str) {
@@ -4302,9 +4278,9 @@
const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
false, NULL, 0);
const TypePtr* value_field_type = string_type->add_offset(value_offset);
- const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
- TypeAry::make(TypeInt::CHAR,TypeInt::POS),
- ciTypeArrayKlass::make(T_CHAR), true, 0);
+ const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull,
+ TypeAry::make(TypeInt::BYTE, TypeInt::POS),
+ ciTypeArrayKlass::make(T_BYTE), true, 0);
int value_field_idx = C->get_alias_index(value_field_type);
Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset),
value_type, T_OBJECT, value_field_idx, MemNode::unordered);
@@ -4315,14 +4291,21 @@
return load;
}
-void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) {
- int offset_offset = java_lang_String::offset_offset_in_bytes();
- const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
- false, NULL, 0);
- const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
- int offset_field_idx = C->get_alias_index(offset_field_type);
- store_to_memory(ctrl, basic_plus_adr(str, offset_offset),
- value, T_INT, offset_field_idx, MemNode::unordered);
+Node* GraphKit::load_String_coder(Node* ctrl, Node* str) {
+ if (java_lang_String::has_coder_field()) {
+ if (!CompactStrings) {
+ return intcon(java_lang_String::CODER_UTF16);
+ }
+ int coder_offset = java_lang_String::coder_offset_in_bytes();
+ const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
+ false, NULL, 0);
+ const TypePtr* coder_field_type = string_type->add_offset(coder_offset);
+ int coder_field_idx = C->get_alias_index(coder_field_type);
+ return make_load(ctrl, basic_plus_adr(str, str, coder_offset),
+ TypeInt::BYTE, T_BYTE, coder_field_idx, MemNode::unordered);
+ } else {
+ return intcon(0); // false
+ }
}
void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
@@ -4330,19 +4313,76 @@
const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
false, NULL, 0);
const TypePtr* value_field_type = string_type->add_offset(value_offset);
-
store_oop_to_object(ctrl, str, basic_plus_adr(str, value_offset), value_field_type,
- value, TypeAryPtr::CHARS, T_OBJECT, MemNode::unordered);
+ value, TypeAryPtr::BYTES, T_OBJECT, MemNode::unordered);
}
-void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
- int count_offset = java_lang_String::count_offset_in_bytes();
+void GraphKit::store_String_coder(Node* ctrl, Node* str, Node* value) {
+ int coder_offset = java_lang_String::coder_offset_in_bytes();
const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(),
false, NULL, 0);
- const TypePtr* count_field_type = string_type->add_offset(count_offset);
- int count_field_idx = C->get_alias_index(count_field_type);
- store_to_memory(ctrl, basic_plus_adr(str, count_offset),
- value, T_INT, count_field_idx, MemNode::unordered);
+ const TypePtr* coder_field_type = string_type->add_offset(coder_offset);
+ int coder_field_idx = C->get_alias_index(coder_field_type);
+ store_to_memory(ctrl, basic_plus_adr(str, coder_offset),
+ value, T_BYTE, coder_field_idx, MemNode::unordered);
+}
+
+Node* GraphKit::compress_string(Node* src, Node* dst, Node* count) {
+ assert(Matcher::match_rule_supported(Op_StrCompressedCopy), "Intrinsic not supported");
+ uint idx = C->get_alias_index(TypeAryPtr::BYTES);
+ StrCompressedCopyNode* str = new StrCompressedCopyNode(control(), memory(idx), src, dst, count);
+ Node* res_mem = _gvn.transform(new SCMemProjNode(str));
+ set_memory(res_mem, idx);
+ return str;
+}
+
+void GraphKit::inflate_string(Node* src, Node* dst, Node* count) {
+ assert(Matcher::match_rule_supported(Op_StrInflatedCopy), "Intrinsic not supported");
+ uint idx = C->get_alias_index(TypeAryPtr::BYTES);
+ StrInflatedCopyNode* str = new StrInflatedCopyNode(control(), memory(idx), src, dst, count);
+ set_memory(_gvn.transform(str), idx);
+}
+
+void GraphKit::inflate_string_slow(Node* src, Node* dst, Node* start, Node* count) {
+ /**
+ * int i_char = start;
+ * for (int i_byte = 0; i_byte < count; i_byte++) {
+ * dst[i_char++] = (char)(src[i_byte] & 0xff);
+ * }
+ */
+ add_predicate();
+ RegionNode* head = new RegionNode(3);
+ head->init_req(1, control());
+ gvn().set_type(head, Type::CONTROL);
+ record_for_igvn(head);
+
+ Node* i_byte = new PhiNode(head, TypeInt::INT);
+ i_byte->init_req(1, intcon(0));
+ gvn().set_type(i_byte, TypeInt::INT);
+ record_for_igvn(i_byte);
+
+ Node* i_char = new PhiNode(head, TypeInt::INT);
+ i_char->init_req(1, start);
+ gvn().set_type(i_char, TypeInt::INT);
+ record_for_igvn(i_char);
+
+ Node* mem = PhiNode::make(head, memory(TypeAryPtr::BYTES), Type::MEMORY, TypeAryPtr::BYTES);
+ gvn().set_type(mem, Type::MEMORY);
+ record_for_igvn(mem);
+ set_control(head);
+ set_memory(mem, TypeAryPtr::BYTES);
+ Node* ch = load_array_element(control(), src, i_byte, TypeAryPtr::BYTES);
+ Node* st = store_to_memory(control(), array_element_address(dst, i_char, T_BYTE),
+ AndI(ch, intcon(0xff)), T_CHAR, TypeAryPtr::BYTES, MemNode::unordered);
+
+ IfNode* iff = create_and_map_if(head, Bool(CmpI(i_byte, count), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN);
+ head->init_req(2, IfTrue(iff));
+ mem->init_req(2, st);
+ i_byte->init_req(2, AddI(i_byte, intcon(1)));
+ i_char->init_req(2, AddI(i_char, intcon(2)));
+
+ set_control(IfFalse(iff));
+ set_memory(st, TypeAryPtr::BYTES);
}
Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) {
--- a/hotspot/src/share/vm/opto/graphKit.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -864,12 +864,14 @@
bool deoptimize_on_exception = false);
// java.lang.String helpers
- Node* load_String_offset(Node* ctrl, Node* str);
Node* load_String_length(Node* ctrl, Node* str);
Node* load_String_value(Node* ctrl, Node* str);
- void store_String_offset(Node* ctrl, Node* str, Node* value);
- void store_String_length(Node* ctrl, Node* str, Node* value);
+ Node* load_String_coder(Node* ctrl, Node* str);
void store_String_value(Node* ctrl, Node* str, Node* value);
+ void store_String_coder(Node* ctrl, Node* str, Node* value);
+ Node* compress_string(Node* src, Node* dst, Node* count);
+ void inflate_string(Node* src, Node* dst, Node* count);
+ void inflate_string_slow(Node* src, Node* dst, Node* start, Node* count);
// Handy for making control flow
IfNode* create_and_map_if(Node* ctrl, Node* tst, float prob, float cnt) {
--- a/hotspot/src/share/vm/opto/idealKit.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/idealKit.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -530,7 +530,6 @@
"call node must be constructed correctly");
}
-
void IdealKit::make_leaf_call_no_fp(const TypeFunc *slow_call_type,
address slow_call,
const char *leaf_name,
--- a/hotspot/src/share/vm/opto/idealKit.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/idealKit.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -183,6 +183,7 @@
Node* AddI(Node* l, Node* r) { return transform(new AddINode(l, r)); }
Node* SubI(Node* l, Node* r) { return transform(new SubINode(l, r)); }
Node* AndI(Node* l, Node* r) { return transform(new AndINode(l, r)); }
+ Node* OrI(Node* l, Node* r) { return transform(new OrINode(l, r)); }
Node* MaxI(Node* l, Node* r) { return transform(new MaxINode(l, r)); }
Node* LShiftI(Node* l, Node* r) { return transform(new LShiftINode(l, r)); }
Node* CmpI(Node* l, Node* r) { return transform(new CmpINode(l, r)); }
@@ -256,7 +257,6 @@
Node* parm1,
Node* parm2,
Node* parm3);
-
};
#endif // SHARE_VM_OPTO_IDEALKIT_HPP
--- a/hotspot/src/share/vm/opto/intrinsicnode.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/intrinsicnode.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node. Strip out
// control copies
-Node *StrIntrinsicNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+Node* StrIntrinsicNode::Ideal(PhaseGVN* phase, bool can_reshape) {
if (remove_dead_region(phase, can_reshape)) return this;
// Don't bother trying to transform a dead node
if (in(0) && in(0)->is_top()) return NULL;
@@ -55,11 +55,29 @@
}
//------------------------------Value------------------------------------------
-const Type *StrIntrinsicNode::Value( PhaseTransform *phase ) const {
+const Type* StrIntrinsicNode::Value(PhaseTransform* phase) const {
if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP;
return bottom_type();
}
+uint StrIntrinsicNode::size_of() const { return sizeof(*this); }
+
+//=============================================================================
+//------------------------------Ideal------------------------------------------
+// Return a node which is more "ideal" than the current node. Strip out
+// control copies
+Node* StrCompressedCopyNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ return remove_dead_region(phase, can_reshape) ? this : NULL;
+}
+
+//=============================================================================
+//------------------------------Ideal------------------------------------------
+// Return a node which is more "ideal" than the current node. Strip out
+// control copies
+Node* StrInflatedCopyNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ return remove_dead_region(phase, can_reshape) ? this : NULL;
+}
+
//=============================================================================
//------------------------------match_edge-------------------------------------
// Do not match memory edge
@@ -70,12 +88,12 @@
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node. Strip out
// control copies
-Node *EncodeISOArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+Node* EncodeISOArrayNode::Ideal(PhaseGVN* phase, bool can_reshape) {
return remove_dead_region(phase, can_reshape) ? this : NULL;
}
//------------------------------Value------------------------------------------
-const Type *EncodeISOArrayNode::Value(PhaseTransform *phase) const {
+const Type* EncodeISOArrayNode::Value(PhaseTransform* phase) const {
if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP;
return bottom_type();
}
--- a/hotspot/src/share/vm/opto/intrinsicnode.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/intrinsicnode.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,75 +35,131 @@
// hit (cache is checked with exposed code in gen_subtype_check()). Return
// not zero for a miss or zero for a hit.
class PartialSubtypeCheckNode : public Node {
- public:
+ public:
PartialSubtypeCheckNode(Node* c, Node* sub, Node* super) : Node(c,sub,super) {}
virtual int Opcode() const;
- virtual const Type *bottom_type() const { return TypeRawPtr::BOTTOM; }
+ virtual const Type* bottom_type() const { return TypeRawPtr::BOTTOM; }
virtual uint ideal_reg() const { return Op_RegP; }
};
//------------------------------StrIntrinsic-------------------------------
-// Base class for Ideal nodes used in String instrinsic code.
+// Base class for Ideal nodes used in String intrinsic code.
class StrIntrinsicNode: public Node {
- public:
+ public:
+ // Possible encodings of the two parameters passed to the string intrinsic.
+ // 'L' stands for Latin1 and 'U' stands for UTF16. For example, 'LU' means that
+ // the first string is Latin1 encoded and the second string is UTF16 encoded.
+ typedef enum ArgEncoding { LL, LU, UL, UU, none } ArgEnc;
+
+ protected:
+ // Encoding of strings. Used to select the right version of the intrinsic.
+ const ArgEncoding _encoding;
+ virtual uint size_of() const;
+
+ public:
StrIntrinsicNode(Node* control, Node* char_array_mem,
- Node* s1, Node* c1, Node* s2, Node* c2):
- Node(control, char_array_mem, s1, c1, s2, c2) {
+ Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
+ Node(control, char_array_mem, s1, c1, s2, c2), _encoding(encoding) {
}
StrIntrinsicNode(Node* control, Node* char_array_mem,
- Node* s1, Node* s2, Node* c):
- Node(control, char_array_mem, s1, s2, c) {
+ Node* s1, Node* s2, Node* c, ArgEncoding encoding):
+ Node(control, char_array_mem, s1, s2, c), _encoding(encoding) {
}
StrIntrinsicNode(Node* control, Node* char_array_mem,
- Node* s1, Node* s2):
- Node(control, char_array_mem, s1, s2) {
+ Node* s1, Node* s2, ArgEncoding encoding):
+ Node(control, char_array_mem, s1, s2), _encoding(encoding) {
}
virtual bool depends_only_on_test() const { return false; }
- virtual const TypePtr* adr_type() const { return TypeAryPtr::CHARS; }
+ virtual const TypePtr* adr_type() const { return TypeAryPtr::BYTES; }
virtual uint match_edge(uint idx) const;
virtual uint ideal_reg() const { return Op_RegI; }
- virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
- virtual const Type *Value(PhaseTransform *phase) const;
+ virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+ virtual const Type* Value(PhaseTransform* phase) const;
+ ArgEncoding encoding() const { return _encoding; }
};
//------------------------------StrComp-------------------------------------
class StrCompNode: public StrIntrinsicNode {
- public:
+ public:
StrCompNode(Node* control, Node* char_array_mem,
- Node* s1, Node* c1, Node* s2, Node* c2):
- StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {};
+ Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
+ StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {};
virtual int Opcode() const;
virtual const Type* bottom_type() const { return TypeInt::INT; }
};
//------------------------------StrEquals-------------------------------------
class StrEqualsNode: public StrIntrinsicNode {
- public:
+ public:
StrEqualsNode(Node* control, Node* char_array_mem,
- Node* s1, Node* s2, Node* c):
- StrIntrinsicNode(control, char_array_mem, s1, s2, c) {};
+ Node* s1, Node* s2, Node* c, ArgEncoding encoding):
+ StrIntrinsicNode(control, char_array_mem, s1, s2, c, encoding) {};
virtual int Opcode() const;
virtual const Type* bottom_type() const { return TypeInt::BOOL; }
};
//------------------------------StrIndexOf-------------------------------------
class StrIndexOfNode: public StrIntrinsicNode {
- public:
+ public:
StrIndexOfNode(Node* control, Node* char_array_mem,
- Node* s1, Node* c1, Node* s2, Node* c2):
- StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2) {};
+ Node* s1, Node* c1, Node* s2, Node* c2, ArgEncoding encoding):
+ StrIntrinsicNode(control, char_array_mem, s1, c1, s2, c2, encoding) {};
+ virtual int Opcode() const;
+ virtual const Type* bottom_type() const { return TypeInt::INT; }
+};
+
+//------------------------------StrIndexOfChar-------------------------------------
+class StrIndexOfCharNode: public StrIntrinsicNode {
+ public:
+ StrIndexOfCharNode(Node* control, Node* char_array_mem,
+ Node* s1, Node* c1, Node* c, ArgEncoding encoding):
+ StrIntrinsicNode(control, char_array_mem, s1, c1, c, encoding) {};
virtual int Opcode() const;
virtual const Type* bottom_type() const { return TypeInt::INT; }
};
+//--------------------------StrCompressedCopy-------------------------------
+class StrCompressedCopyNode: public StrIntrinsicNode {
+ public:
+ StrCompressedCopyNode(Node* control, Node* arymem,
+ Node* s1, Node* s2, Node* c):
+ StrIntrinsicNode(control, arymem, s1, s2, c, none) {};
+ virtual int Opcode() const;
+ virtual const Type* bottom_type() const { return TypeInt::INT; }
+ virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
+ virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+};
+
+//--------------------------StrInflatedCopy---------------------------------
+class StrInflatedCopyNode: public StrIntrinsicNode {
+ public:
+ StrInflatedCopyNode(Node* control, Node* arymem,
+ Node* s1, Node* s2, Node* c):
+ StrIntrinsicNode(control, arymem, s1, s2, c, none) {};
+ virtual int Opcode() const;
+ virtual const Type* bottom_type() const { return Type::MEMORY; }
+ virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
+ virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+};
+
//------------------------------AryEq---------------------------------------
class AryEqNode: public StrIntrinsicNode {
- public:
- AryEqNode(Node* control, Node* char_array_mem, Node* s1, Node* s2):
- StrIntrinsicNode(control, char_array_mem, s1, s2) {};
+ public:
+ AryEqNode(Node* control, Node* char_array_mem,
+ Node* s1, Node* s2, ArgEncoding encoding):
+ StrIntrinsicNode(control, char_array_mem, s1, s2, encoding) {};
+ virtual int Opcode() const;
+ virtual const Type* bottom_type() const { return TypeInt::BOOL; }
+};
+
+//------------------------------HasNegatives---------------------------------
+class HasNegativesNode: public StrIntrinsicNode {
+ public:
+ HasNegativesNode(Node* control, Node* char_array_mem, Node* s1, Node* c1):
+ StrIntrinsicNode(control, char_array_mem, s1, c1, none) {};
virtual int Opcode() const;
virtual const Type* bottom_type() const { return TypeInt::BOOL; }
};
@@ -112,16 +168,16 @@
//------------------------------EncodeISOArray--------------------------------
// encode char[] to byte[] in ISO_8859_1
class EncodeISOArrayNode: public Node {
- public:
- EncodeISOArrayNode(Node *control, Node* arymem, Node* s1, Node* s2, Node* c): Node(control, arymem, s1, s2, c) {};
+ public:
+ EncodeISOArrayNode(Node* control, Node* arymem, Node* s1, Node* s2, Node* c): Node(control, arymem, s1, s2, c) {};
virtual int Opcode() const;
virtual bool depends_only_on_test() const { return false; }
virtual const Type* bottom_type() const { return TypeInt::INT; }
virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
virtual uint match_edge(uint idx) const;
virtual uint ideal_reg() const { return Op_RegI; }
- virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
- virtual const Type *Value(PhaseTransform *phase) const;
+ virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+ virtual const Type* Value(PhaseTransform* phase) const;
};
#endif // SHARE_VM_OPTO_INTRINSICNODE_HPP
--- a/hotspot/src/share/vm/opto/lcm.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -196,8 +196,12 @@
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
case Op_AryEq:
+ case Op_StrInflatedCopy:
+ case Op_StrCompressedCopy:
case Op_EncodeISOArray:
+ case Op_HasNegatives:
// Not a legit memory op for implicit null check regardless of
// embedded loads
continue;
@@ -806,7 +810,7 @@
block->insert_node(proj, node_cnt++);
// Select the right register save policy.
- const char * save_policy;
+ const char *save_policy = NULL;
switch (op) {
case Op_CallRuntime:
case Op_CallLeaf:
--- a/hotspot/src/share/vm/opto/library_call.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -200,12 +200,16 @@
}
Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static, ciInstanceKlass * fromKls);
- Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
- Node* make_string_method_node(int opcode, Node* str1, Node* str2);
- bool inline_string_compareTo();
- bool inline_string_indexOf();
- Node* string_indexOf(Node* string_object, ciTypeArray* target_array, jint offset, jint cache_i, jint md2_i);
- bool inline_string_equals();
+ Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae);
+ bool inline_string_compareTo(StrIntrinsicNode::ArgEnc ae);
+ bool inline_string_indexOf(StrIntrinsicNode::ArgEnc ae);
+ bool inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae);
+ bool inline_string_indexOfChar();
+ bool inline_string_equals(StrIntrinsicNode::ArgEnc ae);
+ bool inline_string_toBytesU();
+ bool inline_string_getCharsU();
+ bool inline_string_copy(bool compress);
+ bool inline_string_char_access(bool is_store);
Node* round_double_node(Node* n);
bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
bool inline_math_native(vmIntrinsics::ID id);
@@ -251,7 +255,7 @@
bool inline_native_newArray();
bool inline_native_getLength();
bool inline_array_copyOf(bool is_copyOfRange);
- bool inline_array_equals();
+ bool inline_array_equals(StrIntrinsicNode::ArgEnc ae);
void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark);
bool inline_native_clone(bool is_virtual);
bool inline_native_Reflection_getCallerClass();
@@ -298,6 +302,7 @@
bool inline_updateBytesAdler32();
bool inline_updateByteBufferAdler32();
bool inline_multiplyToLen();
+ bool inline_hasNegatives();
bool inline_squareToLen();
bool inline_mulAdd();
bool inline_montgomeryMultiply();
@@ -458,6 +463,7 @@
bool LibraryCallKit::try_to_inline(int predicate) {
// Handle symbolic names for otherwise undistinguished boolean switches:
const bool is_store = true;
+ const bool is_compress = true;
const bool is_native_ptr = true;
const bool is_static = true;
const bool is_volatile = true;
@@ -512,9 +518,31 @@
case vmIntrinsics::_arraycopy: return inline_arraycopy();
- case vmIntrinsics::_compareTo: return inline_string_compareTo();
- case vmIntrinsics::_indexOf: return inline_string_indexOf();
- case vmIntrinsics::_equals: return inline_string_equals();
+ case vmIntrinsics::_compareToL: return inline_string_compareTo(StrIntrinsicNode::LL);
+ case vmIntrinsics::_compareToU: return inline_string_compareTo(StrIntrinsicNode::UU);
+ case vmIntrinsics::_compareToLU: return inline_string_compareTo(StrIntrinsicNode::LU);
+ case vmIntrinsics::_compareToUL: return inline_string_compareTo(StrIntrinsicNode::UL);
+
+ case vmIntrinsics::_indexOfL: return inline_string_indexOf(StrIntrinsicNode::LL);
+ case vmIntrinsics::_indexOfU: return inline_string_indexOf(StrIntrinsicNode::UU);
+ case vmIntrinsics::_indexOfUL: return inline_string_indexOf(StrIntrinsicNode::UL);
+ case vmIntrinsics::_indexOfIL: return inline_string_indexOfI(StrIntrinsicNode::LL);
+ case vmIntrinsics::_indexOfIU: return inline_string_indexOfI(StrIntrinsicNode::UU);
+ case vmIntrinsics::_indexOfIUL: return inline_string_indexOfI(StrIntrinsicNode::UL);
+ case vmIntrinsics::_indexOfU_char: return inline_string_indexOfChar();
+
+ case vmIntrinsics::_equalsL: return inline_string_equals(StrIntrinsicNode::LL);
+ case vmIntrinsics::_equalsU: return inline_string_equals(StrIntrinsicNode::UU);
+
+ case vmIntrinsics::_toBytesStringU: return inline_string_toBytesU();
+ case vmIntrinsics::_getCharsStringU: return inline_string_getCharsU();
+ case vmIntrinsics::_getCharStringU: return inline_string_char_access(!is_store);
+ case vmIntrinsics::_putCharStringU: return inline_string_char_access( is_store);
+
+ case vmIntrinsics::_compressStringC:
+ case vmIntrinsics::_compressStringB: return inline_string_copy( is_compress);
+ case vmIntrinsics::_inflateStringC:
+ case vmIntrinsics::_inflateStringB: return inline_string_copy(!is_compress);
case vmIntrinsics::_getObject: return inline_unsafe_access(!is_native_ptr, !is_store, T_OBJECT, !is_volatile);
case vmIntrinsics::_getBoolean: return inline_unsafe_access(!is_native_ptr, !is_store, T_BOOLEAN, !is_volatile);
@@ -617,7 +645,8 @@
case vmIntrinsics::_getLength: return inline_native_getLength();
case vmIntrinsics::_copyOf: return inline_array_copyOf(false);
case vmIntrinsics::_copyOfRange: return inline_array_copyOf(true);
- case vmIntrinsics::_equalsC: return inline_array_equals();
+ case vmIntrinsics::_equalsB: return inline_array_equals(StrIntrinsicNode::LL);
+ case vmIntrinsics::_equalsC: return inline_array_equals(StrIntrinsicNode::UU);
case vmIntrinsics::_clone: return inline_native_clone(intrinsic()->is_virtual());
case vmIntrinsics::_isAssignableFrom: return inline_native_subtype_check();
@@ -687,6 +716,7 @@
return inline_ghash_processBlocks();
case vmIntrinsics::_encodeISOArray:
+ case vmIntrinsics::_encodeByteISOArray:
return inline_encodeISOArray();
case vmIntrinsics::_updateCRC32:
@@ -711,6 +741,9 @@
case vmIntrinsics::_isCompileConstant:
return inline_isCompileConstant();
+ case vmIntrinsics::_hasNegatives:
+ return inline_hasNegatives();
+
default:
// If you get here, it may be that someone has added a new intrinsic
// to the list in vmSymbols.hpp without implementing it here.
@@ -876,75 +909,24 @@
//------------------------------make_string_method_node------------------------
-// Helper method for String intrinsic functions. This version is called
-// with str1 and str2 pointing to String object nodes.
-//
-Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1, Node* str2) {
- Node* no_ctrl = NULL;
-
- // Get start addr of string
- Node* str1_value = load_String_value(no_ctrl, str1);
- Node* str1_offset = load_String_offset(no_ctrl, str1);
- Node* str1_start = array_element_address(str1_value, str1_offset, T_CHAR);
-
- // Get length of string 1
- Node* str1_len = load_String_length(no_ctrl, str1);
-
- Node* str2_value = load_String_value(no_ctrl, str2);
- Node* str2_offset = load_String_offset(no_ctrl, str2);
- Node* str2_start = array_element_address(str2_value, str2_offset, T_CHAR);
-
- Node* str2_len = NULL;
- Node* result = NULL;
-
- switch (opcode) {
- case Op_StrIndexOf:
- // Get length of string 2
- str2_len = load_String_length(no_ctrl, str2);
-
- result = new StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
- str1_start, str1_len, str2_start, str2_len);
- break;
- case Op_StrComp:
- // Get length of string 2
- str2_len = load_String_length(no_ctrl, str2);
-
- result = new StrCompNode(control(), memory(TypeAryPtr::CHARS),
- str1_start, str1_len, str2_start, str2_len);
- break;
- case Op_StrEquals:
- result = new StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
- str1_start, str2_start, str1_len);
- break;
- default:
- ShouldNotReachHere();
- return NULL;
- }
-
- // All these intrinsics have checks.
- C->set_has_split_ifs(true); // Has chance for split-if optimization
-
- return _gvn.transform(result);
-}
-
-// Helper method for String intrinsic functions. This version is called
-// with str1 and str2 pointing to char[] nodes, with cnt1 and cnt2 pointing
-// to Int nodes containing the lenghts of str1 and str2.
-//
-Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2) {
+// Helper method for String intrinsic functions. This version is called with
+// str1 and str2 pointing to byte[] nodes containing Latin1 or UTF16 encoded
+// characters (depending on 'is_byte'). cnt1 and cnt2 are pointing to Int nodes
+// containing the lengths of str1 and str2.
+Node* LibraryCallKit::make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae) {
Node* result = NULL;
switch (opcode) {
case Op_StrIndexOf:
- result = new StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
- str1_start, cnt1, str2_start, cnt2);
+ result = new StrIndexOfNode(control(), memory(TypeAryPtr::BYTES),
+ str1_start, cnt1, str2_start, cnt2, ae);
break;
case Op_StrComp:
- result = new StrCompNode(control(), memory(TypeAryPtr::CHARS),
- str1_start, cnt1, str2_start, cnt2);
+ result = new StrCompNode(control(), memory(TypeAryPtr::BYTES),
+ str1_start, cnt1, str2_start, cnt2, ae);
break;
case Op_StrEquals:
- result = new StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
- str1_start, str2_start, cnt1);
+ result = new StrEqualsNode(control(), memory(TypeAryPtr::BYTES),
+ str1_start, str2_start, cnt1, ae);
break;
default:
ShouldNotReachHere();
@@ -958,98 +940,54 @@
}
//------------------------------inline_string_compareTo------------------------
-// public int java.lang.String.compareTo(String anotherString);
-bool LibraryCallKit::inline_string_compareTo() {
- Node* receiver = null_check(argument(0));
- Node* arg = null_check(argument(1));
- if (stopped()) {
- return true;
- }
- set_result(make_string_method_node(Op_StrComp, receiver, arg));
+bool LibraryCallKit::inline_string_compareTo(StrIntrinsicNode::ArgEnc ae) {
+ Node* arg1 = argument(0);
+ Node* arg2 = argument(1);
+
+ // Get start addr and length of first argument
+ Node* arg1_start = array_element_address(arg1, intcon(0), T_BYTE);
+ Node* arg1_cnt = load_array_length(arg1);
+
+ // Get start addr and length of second argument
+ Node* arg2_start = array_element_address(arg2, intcon(0), T_BYTE);
+ Node* arg2_cnt = load_array_length(arg2);
+
+ Node* result = make_string_method_node(Op_StrComp, arg1_start, arg1_cnt, arg2_start, arg2_cnt, ae);
+ set_result(result);
return true;
}
//------------------------------inline_string_equals------------------------
-bool LibraryCallKit::inline_string_equals() {
- Node* receiver = null_check_receiver();
- // NOTE: Do not null check argument for String.equals() because spec
- // allows to specify NULL as argument.
- Node* argument = this->argument(1);
- if (stopped()) {
- return true;
- }
+bool LibraryCallKit::inline_string_equals(StrIntrinsicNode::ArgEnc ae) {
+ Node* arg1 = argument(0);
+ Node* arg2 = argument(1);
// paths (plus control) merge
- RegionNode* region = new RegionNode(5);
+ RegionNode* region = new RegionNode(3);
Node* phi = new PhiNode(region, TypeInt::BOOL);
- // does source == target string?
- Node* cmp = _gvn.transform(new CmpPNode(receiver, argument));
- Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
-
- Node* if_eq = generate_slow_guard(bol, NULL);
- if (if_eq != NULL) {
- // receiver == argument
- phi->init_req(2, intcon(1));
- region->init_req(2, if_eq);
- }
-
- // get String klass for instanceOf
- ciInstanceKlass* klass = env()->String_klass();
-
if (!stopped()) {
- Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
- Node* cmp = _gvn.transform(new CmpINode(inst, intcon(1)));
- Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne));
-
- Node* inst_false = generate_guard(bol, NULL, PROB_MIN);
- //instanceOf == true, fallthrough
-
- if (inst_false != NULL) {
- phi->init_req(3, intcon(0));
- region->init_req(3, inst_false);
- }
- }
-
- if (!stopped()) {
- const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
-
- // Properly cast the argument to String
- argument = _gvn.transform(new CheckCastPPNode(control(), argument, string_type));
- // This path is taken only when argument's type is String:NotNull.
- argument = cast_not_null(argument, false);
-
- Node* no_ctrl = NULL;
-
- // Get start addr of receiver
- Node* receiver_val = load_String_value(no_ctrl, receiver);
- Node* receiver_offset = load_String_offset(no_ctrl, receiver);
- Node* receiver_start = array_element_address(receiver_val, receiver_offset, T_CHAR);
-
- // Get length of receiver
- Node* receiver_cnt = load_String_length(no_ctrl, receiver);
-
- // Get start addr of argument
- Node* argument_val = load_String_value(no_ctrl, argument);
- Node* argument_offset = load_String_offset(no_ctrl, argument);
- Node* argument_start = array_element_address(argument_val, argument_offset, T_CHAR);
-
- // Get length of argument
- Node* argument_cnt = load_String_length(no_ctrl, argument);
-
- // Check for receiver count != argument count
- Node* cmp = _gvn.transform(new CmpINode(receiver_cnt, argument_cnt));
+ // Get start addr and length of first argument
+ Node* arg1_start = array_element_address(arg1, intcon(0), T_BYTE);
+ Node* arg1_cnt = load_array_length(arg1);
+
+ // Get start addr and length of second argument
+ Node* arg2_start = array_element_address(arg2, intcon(0), T_BYTE);
+ Node* arg2_cnt = load_array_length(arg2);
+
+ // Check for arg1_cnt != arg2_cnt
+ Node* cmp = _gvn.transform(new CmpINode(arg1_cnt, arg2_cnt));
Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne));
Node* if_ne = generate_slow_guard(bol, NULL);
if (if_ne != NULL) {
- phi->init_req(4, intcon(0));
- region->init_req(4, if_ne);
+ phi->init_req(2, intcon(0));
+ region->init_req(2, if_ne);
}
// Check for count == 0 is done by assembler code for StrEquals.
if (!stopped()) {
- Node* equals = make_string_method_node(Op_StrEquals, receiver_start, receiver_cnt, argument_start, argument_cnt);
+ Node* equals = make_string_method_node(Op_StrEquals, arg1_start, arg1_cnt, arg2_start, arg2_cnt, ae);
phi->init_req(1, equals);
region->init_req(1, control());
}
@@ -1064,289 +1002,462 @@
}
//------------------------------inline_array_equals----------------------------
-bool LibraryCallKit::inline_array_equals() {
+bool LibraryCallKit::inline_array_equals(StrIntrinsicNode::ArgEnc ae) {
+ assert(ae == StrIntrinsicNode::UU || ae == StrIntrinsicNode::LL, "unsupported array types");
Node* arg1 = argument(0);
Node* arg2 = argument(1);
- set_result(_gvn.transform(new AryEqNode(control(), memory(TypeAryPtr::CHARS), arg1, arg2)));
+
+ const TypeAryPtr* mtype = (ae == StrIntrinsicNode::UU) ? TypeAryPtr::CHARS : TypeAryPtr::BYTES;
+ set_result(_gvn.transform(new AryEqNode(control(), memory(mtype), arg1, arg2, ae)));
return true;
}
-// Java version of String.indexOf(constant string)
-// class StringDecl {
-// StringDecl(char[] ca) {
-// offset = 0;
-// count = ca.length;
-// value = ca;
-// }
-// int offset;
-// int count;
-// char[] value;
-// }
-//
-// static int string_indexOf_J(StringDecl string_object, char[] target_object,
-// int targetOffset, int cache_i, int md2) {
-// int cache = cache_i;
-// int sourceOffset = string_object.offset;
-// int sourceCount = string_object.count;
-// int targetCount = target_object.length;
-//
-// int targetCountLess1 = targetCount - 1;
-// int sourceEnd = sourceOffset + sourceCount - targetCountLess1;
-//
-// char[] source = string_object.value;
-// char[] target = target_object;
-// int lastChar = target[targetCountLess1];
-//
-// outer_loop:
-// for (int i = sourceOffset; i < sourceEnd; ) {
-// int src = source[i + targetCountLess1];
-// if (src == lastChar) {
-// // With random strings and a 4-character alphabet,
-// // reverse matching at this point sets up 0.8% fewer
-// // frames, but (paradoxically) makes 0.3% more probes.
-// // Since those probes are nearer the lastChar probe,
-// // there is may be a net D$ win with reverse matching.
-// // But, reversing loop inhibits unroll of inner loop
-// // for unknown reason. So, does running outer loop from
-// // (sourceOffset - targetCountLess1) to (sourceOffset + sourceCount)
-// for (int j = 0; j < targetCountLess1; j++) {
-// if (target[targetOffset + j] != source[i+j]) {
-// if ((cache & (1 << source[i+j])) == 0) {
-// if (md2 < j+1) {
-// i += j+1;
-// continue outer_loop;
-// }
-// }
-// i += md2;
-// continue outer_loop;
-// }
-// }
-// return i - sourceOffset;
-// }
-// if ((cache & (1 << src)) == 0) {
-// i += targetCountLess1;
-// } // using "i += targetCount;" and an "else i++;" causes a jump to jump.
-// i++;
-// }
-// return -1;
-// }
-
-//------------------------------string_indexOf------------------------
-Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_array, jint targetOffset_i,
- jint cache_i, jint md2_i) {
-
- Node* no_ctrl = NULL;
- float likely = PROB_LIKELY(0.9);
- float unlikely = PROB_UNLIKELY(0.9);
-
- const int nargs = 0; // no arguments to push back for uncommon trap in predicate
-
- Node* source = load_String_value(no_ctrl, string_object);
- Node* sourceOffset = load_String_offset(no_ctrl, string_object);
- Node* sourceCount = load_String_length(no_ctrl, string_object);
-
- Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true)));
- jint target_length = target_array->length();
- const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin));
- const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot);
-
- // String.value field is known to be @Stable.
- if (UseImplicitStableValues) {
- target = cast_array_to_stable(target, target_type);
- }
-
- IdealKit kit(this, false, true);
-#define __ kit.
- Node* zero = __ ConI(0);
- Node* one = __ ConI(1);
- Node* cache = __ ConI(cache_i);
- Node* md2 = __ ConI(md2_i);
- Node* lastChar = __ ConI(target_array->char_at(target_length - 1));
- Node* targetCountLess1 = __ ConI(target_length - 1);
- Node* targetOffset = __ ConI(targetOffset_i);
- Node* sourceEnd = __ SubI(__ AddI(sourceOffset, sourceCount), targetCountLess1);
-
- IdealVariable rtn(kit), i(kit), j(kit); __ declarations_done();
- Node* outer_loop = __ make_label(2 /* goto */);
- Node* return_ = __ make_label(1);
-
- __ set(rtn,__ ConI(-1));
- __ loop(this, nargs, i, sourceOffset, BoolTest::lt, sourceEnd); {
- Node* i2 = __ AddI(__ value(i), targetCountLess1);
- // pin to prohibit loading of "next iteration" value which may SEGV (rare)
- Node* src = load_array_element(__ ctrl(), source, i2, TypeAryPtr::CHARS);
- __ if_then(src, BoolTest::eq, lastChar, unlikely); {
- __ loop(this, nargs, j, zero, BoolTest::lt, targetCountLess1); {
- Node* tpj = __ AddI(targetOffset, __ value(j));
- Node* targ = load_array_element(no_ctrl, target, tpj, target_type);
- Node* ipj = __ AddI(__ value(i), __ value(j));
- Node* src2 = load_array_element(no_ctrl, source, ipj, TypeAryPtr::CHARS);
- __ if_then(targ, BoolTest::ne, src2); {
- __ if_then(__ AndI(cache, __ LShiftI(one, src2)), BoolTest::eq, zero); {
- __ if_then(md2, BoolTest::lt, __ AddI(__ value(j), one)); {
- __ increment(i, __ AddI(__ value(j), one));
- __ goto_(outer_loop);
- } __ end_if(); __ dead(j);
- }__ end_if(); __ dead(j);
- __ increment(i, md2);
- __ goto_(outer_loop);
- }__ end_if();
- __ increment(j, one);
- }__ end_loop(); __ dead(j);
- __ set(rtn, __ SubI(__ value(i), sourceOffset)); __ dead(i);
- __ goto_(return_);
- }__ end_if();
- __ if_then(__ AndI(cache, __ LShiftI(one, src)), BoolTest::eq, zero, likely); {
- __ increment(i, targetCountLess1);
- }__ end_if();
- __ increment(i, one);
- __ bind(outer_loop);
- }__ end_loop(); __ dead(i);
- __ bind(return_);
-
- // Final sync IdealKit and GraphKit.
- final_sync(kit);
- Node* result = __ value(rtn);
-#undef __
- C->set_has_loops(true);
- return result;
+//------------------------------inline_hasNegatives------------------------------
+bool LibraryCallKit::inline_hasNegatives() {
+ if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
+
+ assert(callee()->signature()->size() == 3, "hasNegatives has 3 parameters");
+ // no receiver since it is static method
+ Node* ba = argument(0);
+ Node* offset = argument(1);
+ Node* len = argument(2);
+
+ RegionNode* bailout = new RegionNode(1);
+ record_for_igvn(bailout);
+
+ // offset must not be negative.
+ generate_negative_guard(offset, bailout);
+
+ // offset + length must not exceed length of ba.
+ generate_limit_guard(offset, len, load_array_length(ba), bailout);
+
+ if (bailout->req() > 1) {
+ PreserveJVMState pjvms(this);
+ set_control(_gvn.transform(bailout));
+ uncommon_trap(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_maybe_recompile);
+ }
+ if (!stopped()) {
+ Node* ba_start = array_element_address(ba, offset, T_BYTE);
+ Node* result = new HasNegativesNode(control(), memory(TypeAryPtr::BYTES), ba_start, len);
+ set_result(_gvn.transform(result));
+ }
+ return true;
}
//------------------------------inline_string_indexOf------------------------
-bool LibraryCallKit::inline_string_indexOf() {
- Node* receiver = argument(0);
- Node* arg = argument(1);
-
- Node* result;
- if (Matcher::has_match_rule(Op_StrIndexOf) &&
- UseSSE42Intrinsics) {
- // Generate SSE4.2 version of indexOf
- // We currently only have match rules that use SSE4.2
-
- receiver = null_check(receiver);
- arg = null_check(arg);
- if (stopped()) {
- return true;
- }
-
- // Make the merge point
- RegionNode* result_rgn = new RegionNode(4);
- Node* result_phi = new PhiNode(result_rgn, TypeInt::INT);
- Node* no_ctrl = NULL;
-
- // Get start addr of source string
- Node* source = load_String_value(no_ctrl, receiver);
- Node* source_offset = load_String_offset(no_ctrl, receiver);
- Node* source_start = array_element_address(source, source_offset, T_CHAR);
-
- // Get length of source string
- Node* source_cnt = load_String_length(no_ctrl, receiver);
-
- // Get start addr of substring
- Node* substr = load_String_value(no_ctrl, arg);
- Node* substr_offset = load_String_offset(no_ctrl, arg);
- Node* substr_start = array_element_address(substr, substr_offset, T_CHAR);
-
- // Get length of source string
- Node* substr_cnt = load_String_length(no_ctrl, arg);
-
- // Check for substr count > string count
- Node* cmp = _gvn.transform(new CmpINode(substr_cnt, source_cnt));
- Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::gt));
- Node* if_gt = generate_slow_guard(bol, NULL);
- if (if_gt != NULL) {
- result_phi->init_req(2, intcon(-1));
- result_rgn->init_req(2, if_gt);
- }
-
- if (!stopped()) {
- // Check for substr count == 0
- cmp = _gvn.transform(new CmpINode(substr_cnt, intcon(0)));
- bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
- Node* if_zero = generate_slow_guard(bol, NULL);
- if (if_zero != NULL) {
- result_phi->init_req(3, intcon(0));
- result_rgn->init_req(3, if_zero);
- }
- }
-
- if (!stopped()) {
- result = make_string_method_node(Op_StrIndexOf, source_start, source_cnt, substr_start, substr_cnt);
- result_phi->init_req(1, result);
- result_rgn->init_req(1, control());
+bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
+ if (!Matcher::has_match_rule(Op_StrIndexOf) || !UseSSE42Intrinsics) {
+ return false;
+ }
+ Node* src = argument(0);
+ Node* tgt = argument(1);
+
+ // Make the merge point
+ RegionNode* result_rgn = new RegionNode(4);
+ Node* result_phi = new PhiNode(result_rgn, TypeInt::INT);
+
+ // Get start addr and length of source string
+ Node* src_start = array_element_address(src, intcon(0), T_BYTE);
+ Node* src_count = load_array_length(src);
+
+ // Get start addr and length of substring
+ Node* tgt_start = array_element_address(tgt, intcon(0), T_BYTE);
+ Node* tgt_count = load_array_length(tgt);
+
+ if (ae == StrIntrinsicNode::UU || ae == StrIntrinsicNode::UL) {
+ // Divide src size by 2 if String is UTF16 encoded
+ src_count = _gvn.transform(new RShiftINode(src_count, intcon(1)));
+ }
+ if (ae == StrIntrinsicNode::UU) {
+ // Divide substring size by 2 if String is UTF16 encoded
+ tgt_count = _gvn.transform(new RShiftINode(tgt_count, intcon(1)));
+ }
+
+ // Check for substr count > string count
+ Node* cmp = _gvn.transform(new CmpINode(tgt_count, src_count));
+ Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::gt));
+ Node* if_gt = generate_slow_guard(bol, NULL);
+ if (if_gt != NULL) {
+ result_phi->init_req(2, intcon(-1));
+ result_rgn->init_req(2, if_gt);
+ }
+
+ if (!stopped()) {
+ // Check for substr count == 0
+ cmp = _gvn.transform(new CmpINode(tgt_count, intcon(0)));
+ bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
+ Node* if_zero = generate_slow_guard(bol, NULL);
+ if (if_zero != NULL) {
+ result_phi->init_req(3, intcon(0));
+ result_rgn->init_req(3, if_zero);
}
- set_control(_gvn.transform(result_rgn));
- record_for_igvn(result_rgn);
- result = _gvn.transform(result_phi);
-
- } else { // Use LibraryCallKit::string_indexOf
- // don't intrinsify if argument isn't a constant string.
- if (!arg->is_Con()) {
- return false;
- }
- const TypeOopPtr* str_type = _gvn.type(arg)->isa_oopptr();
- if (str_type == NULL) {
- return false;
- }
- ciInstanceKlass* klass = env()->String_klass();
- ciObject* str_const = str_type->const_oop();
- if (str_const == NULL || str_const->klass() != klass) {
- return false;
- }
- ciInstance* str = str_const->as_instance();
- assert(str != NULL, "must be instance");
-
- ciObject* v = str->field_value_by_offset(java_lang_String::value_offset_in_bytes()).as_object();
- ciTypeArray* pat = v->as_type_array(); // pattern (argument) character array
-
- int o;
- int c;
- if (java_lang_String::has_offset_field()) {
- o = str->field_value_by_offset(java_lang_String::offset_offset_in_bytes()).as_int();
- c = str->field_value_by_offset(java_lang_String::count_offset_in_bytes()).as_int();
- } else {
- o = 0;
- c = pat->length();
+ }
+
+ if (!stopped()) {
+ Node* result = make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
+ result_phi->init_req(1, result);
+ result_rgn->init_req(1, control());
+ }
+ set_control(_gvn.transform(result_rgn));
+ record_for_igvn(result_rgn);
+ set_result(_gvn.transform(result_phi));
+
+ return true;
+}
+
+//-----------------------------inline_string_indexOf-----------------------
+bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
+ if (!Matcher::has_match_rule(Op_StrIndexOf) || !UseSSE42Intrinsics) {
+ return false;
+ }
+ assert(callee()->signature()->size() == 5, "String.indexOf() has 5 arguments");
+ Node* src = argument(0); // byte[]
+ Node* src_count = argument(1);
+ Node* tgt = argument(2); // byte[]
+ Node* tgt_count = argument(3);
+ Node* from_index = argument(4);
+
+ // Java code which calls this method has range checks for from_index value.
+ src_count = _gvn.transform(new SubINode(src_count, from_index));
+
+ // Multiply byte array index by 2 if String is UTF16 encoded
+ Node* src_offset = (ae == StrIntrinsicNode::LL) ? from_index : _gvn.transform(new LShiftINode(from_index, intcon(1)));
+ Node* src_start = array_element_address(src, src_offset, T_BYTE);
+ Node* tgt_start = array_element_address(tgt, intcon(0), T_BYTE);
+
+ Node* result = make_string_method_node(Op_StrIndexOf, src_start, src_count, tgt_start, tgt_count, ae);
+
+ // The result is index relative to from_index if substring was found, -1 otherwise.
+ // Generate code which will fold into cmove.
+ RegionNode* region = new RegionNode(3);
+ Node* phi = new PhiNode(region, TypeInt::INT);
+
+ Node* cmp = _gvn.transform(new CmpINode(result, intcon(0)));
+ Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::lt));
+
+ Node* if_lt = generate_slow_guard(bol, NULL);
+ if (if_lt != NULL) {
+ // result == -1
+ phi->init_req(2, result);
+ region->init_req(2, if_lt);
+ }
+ if (!stopped()) {
+ result = _gvn.transform(new AddINode(result, from_index));
+ phi->init_req(1, result);
+ region->init_req(1, control());
+ }
+
+ set_control(_gvn.transform(region));
+ record_for_igvn(region);
+ set_result(_gvn.transform(phi));
+
+ return true;
+}
+
+//-----------------------------inline_string_indexOfChar-----------------------
+bool LibraryCallKit::inline_string_indexOfChar() {
+ if (!Matcher::has_match_rule(Op_StrIndexOfChar) || !(UseSSE > 4)) {
+ return false;
+ }
+ assert(callee()->signature()->size() == 4, "String.indexOfChar() has 4 arguments");
+ Node* src = argument(0); // byte[]
+ Node* tgt = argument(1); // tgt is int ch
+ Node* from_index = argument(2);
+ Node* max = argument(3);
+
+ Node* src_offset = _gvn.transform(new LShiftINode(from_index, intcon(1)));
+ Node* src_start = array_element_address(src, src_offset, T_BYTE);
+
+ Node* src_count = _gvn.transform(new SubINode(max, from_index));
+
+ RegionNode* region = new RegionNode(3);
+ Node* phi = new PhiNode(region, TypeInt::INT);
+
+ Node* result = new StrIndexOfCharNode(control(), memory(TypeAryPtr::BYTES), src_start, src_count, tgt, StrIntrinsicNode::none);
+ C->set_has_split_ifs(true); // Has chance for split-if optimization
+ _gvn.transform(result);
+
+ Node* cmp = _gvn.transform(new CmpINode(result, intcon(0)));
+ Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::lt));
+
+ Node* if_lt = generate_slow_guard(bol, NULL);
+ if (if_lt != NULL) {
+ // result == -1
+ phi->init_req(2, result);
+ region->init_req(2, if_lt);
+ }
+ if (!stopped()) {
+ result = _gvn.transform(new AddINode(result, from_index));
+ phi->init_req(1, result);
+ region->init_req(1, control());
+ }
+ set_control(_gvn.transform(region));
+ record_for_igvn(region);
+ set_result(_gvn.transform(phi));
+
+ return true;
+}
+//---------------------------inline_string_copy---------------------
+// compressIt == true --> generate a compressed copy operation (compress char[]/byte[] to byte[])
+// int StringUTF16.compress(char[] src, int srcOff, byte[] dst, int dstOff, int len)
+// int StringUTF16.compress(byte[] src, int srcOff, byte[] dst, int dstOff, int len)
+// compressIt == false --> generate an inflated copy operation (inflate byte[] to char[]/byte[])
+// void StringLatin1.inflate(byte[] src, int srcOff, char[] dst, int dstOff, int len)
+// void StringLatin1.inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len)
+bool LibraryCallKit::inline_string_copy(bool compress) {
+ int nargs = 5; // 2 oops, 3 ints
+ assert(callee()->signature()->size() == nargs, "string copy has 5 arguments");
+
+ Node* src = argument(0);
+ Node* src_offset = argument(1);
+ Node* dst = argument(2);
+ Node* dst_offset = argument(3);
+ Node* length = argument(4);
+
+ // Check for allocation before we add nodes that would confuse
+ // tightly_coupled_allocation()
+ AllocateArrayNode* alloc = tightly_coupled_allocation(dst, NULL);
+
+ // Figure out the size and type of the elements we will be copying.
+ const Type* src_type = src->Value(&_gvn);
+ const Type* dst_type = dst->Value(&_gvn);
+ BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ assert((compress && dst_elem == T_BYTE && (src_elem == T_BYTE || src_elem == T_CHAR)) ||
+ (!compress && src_elem == T_BYTE && (dst_elem == T_BYTE || dst_elem == T_CHAR)),
+ "Unsupported array types for inline_string_copy");
+
+ // Convert char[] offsets to byte[] offsets
+ if (compress && src_elem == T_BYTE) {
+ src_offset = _gvn.transform(new LShiftINode(src_offset, intcon(1)));
+ } else if (!compress && dst_elem == T_BYTE) {
+ dst_offset = _gvn.transform(new LShiftINode(dst_offset, intcon(1)));
+ }
+
+ Node* src_start = array_element_address(src, src_offset, src_elem);
+ Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
+ // 'src_start' points to src array + scaled offset
+ // 'dst_start' points to dst array + scaled offset
+ Node* count = NULL;
+ if (compress) {
+ count = compress_string(src_start, dst_start, length);
+ } else {
+ inflate_string(src_start, dst_start, length);
+ }
+
+ if (alloc != NULL) {
+ if (alloc->maybe_set_complete(&_gvn)) {
+ // "You break it, you buy it."
+ InitializeNode* init = alloc->initialization();
+ assert(init->is_complete(), "we just did this");
+ init->set_complete_with_arraycopy();
+ assert(dst->is_CheckCastPP(), "sanity");
+ assert(dst->in(0)->in(0) == init, "dest pinned");
}
-
- // constant strings have no offset and count == length which
- // simplifies the resulting code somewhat so lets optimize for that.
- if (o != 0 || c != pat->length()) {
- return false;
+ // Do not let stores that initialize this object be reordered with
+ // a subsequent store that would make this object accessible by
+ // other threads.
+ // Record what AllocateNode this StoreStore protects so that
+ // escape analysis can go from the MemBarStoreStoreNode to the
+ // AllocateNode and eliminate the MemBarStoreStoreNode if possible
+ // based on the escape status of the AllocateNode.
+ insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
+ }
+ if (compress) {
+ set_result(_gvn.transform(count));
+ }
+ return true;
+}
+
+#ifdef _LP64
+#define XTOP ,top() /*additional argument*/
+#else //_LP64
+#define XTOP /*no additional argument*/
+#endif //_LP64
+
+//------------------------inline_string_toBytesU--------------------------
+// public static byte[] StringUTF16.toBytes(char[] value, int off, int len)
+bool LibraryCallKit::inline_string_toBytesU() {
+ // Get the arguments.
+ Node* value = argument(0);
+ Node* offset = argument(1);
+ Node* length = argument(2);
+
+ Node* newcopy = NULL;
+
+ // Set the original stack and the reexecute bit for the interpreter to reexecute
+ // the bytecode that invokes StringUTF16.toBytes() if deoptimization happens.
+ { PreserveReexecuteState preexecs(this);
+ jvms()->set_should_reexecute(true);
+
+ // Check if a null path was taken unconditionally.
+ value = null_check(value);
+
+ RegionNode* bailout = new RegionNode(1);
+ record_for_igvn(bailout);
+
+ // Make sure that resulting byte[] length does not overflow Integer.MAX_VALUE
+ generate_negative_guard(length, bailout);
+ generate_limit_guard(length, intcon(0), intcon(max_jint/2), bailout);
+
+ if (bailout->req() > 1) {
+ PreserveJVMState pjvms(this);
+ set_control(_gvn.transform(bailout));
+ uncommon_trap(Deoptimization::Reason_intrinsic,
+ Deoptimization::Action_maybe_recompile);
}
-
- receiver = null_check(receiver, T_OBJECT);
- // NOTE: No null check on the argument is needed since it's a constant String oop.
- if (stopped()) {
- return true;
- }
-
- // The null string as a pattern always returns 0 (match at beginning of string)
- if (c == 0) {
- set_result(intcon(0));
- return true;
+ if (stopped()) return true;
+
+ // Range checks are done by caller.
+
+ Node* size = _gvn.transform(new LShiftINode(length, intcon(1)));
+ Node* klass_node = makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_BYTE)));
+ newcopy = new_array(klass_node, size, 0); // no arguments to push
+ AllocateArrayNode* alloc = tightly_coupled_allocation(newcopy, NULL);
+
+ // Calculate starting addresses.
+ Node* src_start = array_element_address(value, offset, T_CHAR);
+ Node* dst_start = basic_plus_adr(newcopy, arrayOopDesc::base_offset_in_bytes(T_BYTE));
+
+ // Check if src array address is aligned to HeapWordSize (dst is always aligned)
+ const TypeInt* toffset = gvn().type(offset)->is_int();
+ bool aligned = toffset->is_con() && ((toffset->get_con() * type2aelembytes(T_CHAR)) % HeapWordSize == 0);
+
+ // Figure out which arraycopy runtime method to call (disjoint, uninitialized).
+ const char* copyfunc_name = "arraycopy";
+ address copyfunc_addr = StubRoutines::select_arraycopy_function(T_CHAR, aligned, true, copyfunc_name, true);
+ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
+ OptoRuntime::fast_arraycopy_Type(),
+ copyfunc_addr, copyfunc_name, TypeRawPtr::BOTTOM,
+ src_start, dst_start, ConvI2X(length) XTOP);
+ // Do not let reads from the cloned object float above the arraycopy.
+ if (alloc != NULL) {
+ if (alloc->maybe_set_complete(&_gvn)) {
+ // "You break it, you buy it."
+ InitializeNode* init = alloc->initialization();
+ assert(init->is_complete(), "we just did this");
+ init->set_complete_with_arraycopy();
+ assert(newcopy->is_CheckCastPP(), "sanity");
+ assert(newcopy->in(0)->in(0) == init, "dest pinned");
+ }
+ // Do not let stores that initialize this object be reordered with
+ // a subsequent store that would make this object accessible by
+ // other threads.
+ // Record what AllocateNode this StoreStore protects so that
+ // escape analysis can go from the MemBarStoreStoreNode to the
+ // AllocateNode and eliminate the MemBarStoreStoreNode if possible
+ // based on the escape status of the AllocateNode.
+ insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
+ } else {
+ insert_mem_bar(Op_MemBarCPUOrder);
}
-
- // Generate default indexOf
- jchar lastChar = pat->char_at(o + (c - 1));
- int cache = 0;
- int i;
- for (i = 0; i < c - 1; i++) {
- assert(i < pat->length(), "out of range");
- cache |= (1 << (pat->char_at(o + i) & (sizeof(cache) * BitsPerByte - 1)));
+ } // original reexecute is set back here
+
+ C->set_has_split_ifs(true); // Has chance for split-if optimization
+ if (!stopped()) {
+ set_result(newcopy);
+ }
+ return true;
+}
+
+//------------------------inline_string_getCharsU--------------------------
+// public void StringUTF16.getChars(byte[] value, int srcBegin, int srcEnd, char dst[], int dstBegin)
+bool LibraryCallKit::inline_string_getCharsU() {
+ if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
+
+ // Get the arguments.
+ Node* value = argument(0);
+ Node* src_begin = argument(1);
+ Node* src_end = argument(2); // exclusive offset (i < src_end)
+ Node* dst = argument(3);
+ Node* dst_begin = argument(4);
+
+ // Check for allocation before we add nodes that would confuse
+ // tightly_coupled_allocation()
+ AllocateArrayNode* alloc = tightly_coupled_allocation(dst, NULL);
+
+ // Check if a null path was taken unconditionally.
+ value = null_check(value);
+ dst = null_check(dst);
+ if (stopped()) {
+ return true;
+ }
+
+ // Range checks are done by caller.
+
+ // Get length and convert char[] offset to byte[] offset
+ Node* length = _gvn.transform(new SubINode(src_end, src_begin));
+ src_begin = _gvn.transform(new LShiftINode(src_begin, intcon(1)));
+
+ if (!stopped()) {
+ // Calculate starting addresses.
+ Node* src_start = array_element_address(value, src_begin, T_BYTE);
+ Node* dst_start = array_element_address(dst, dst_begin, T_CHAR);
+
+ // Check if array addresses are aligned to HeapWordSize
+ const TypeInt* tsrc = gvn().type(src_begin)->is_int();
+ const TypeInt* tdst = gvn().type(dst_begin)->is_int();
+ bool aligned = tsrc->is_con() && ((tsrc->get_con() * type2aelembytes(T_BYTE)) % HeapWordSize == 0) &&
+ tdst->is_con() && ((tdst->get_con() * type2aelembytes(T_CHAR)) % HeapWordSize == 0);
+
+ // Figure out which arraycopy runtime method to call (disjoint, uninitialized).
+ const char* copyfunc_name = "arraycopy";
+ address copyfunc_addr = StubRoutines::select_arraycopy_function(T_CHAR, aligned, true, copyfunc_name, true);
+ Node* call = make_runtime_call(RC_LEAF|RC_NO_FP,
+ OptoRuntime::fast_arraycopy_Type(),
+ copyfunc_addr, copyfunc_name, TypeRawPtr::BOTTOM,
+ src_start, dst_start, ConvI2X(length) XTOP);
+ // Do not let reads from the cloned object float above the arraycopy.
+ if (alloc != NULL) {
+ if (alloc->maybe_set_complete(&_gvn)) {
+ // "You break it, you buy it."
+ InitializeNode* init = alloc->initialization();
+ assert(init->is_complete(), "we just did this");
+ init->set_complete_with_arraycopy();
+ assert(dst->is_CheckCastPP(), "sanity");
+ assert(dst->in(0)->in(0) == init, "dest pinned");
+ }
+ // Do not let stores that initialize this object be reordered with
+ // a subsequent store that would make this object accessible by
+ // other threads.
+ // Record what AllocateNode this StoreStore protects so that
+ // escape analysis can go from the MemBarStoreStoreNode to the
+ // AllocateNode and eliminate the MemBarStoreStoreNode if possible
+ // based on the escape status of the AllocateNode.
+ insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out(AllocateNode::RawAddress));
+ } else {
+ insert_mem_bar(Op_MemBarCPUOrder);
}
-
- int md2 = c;
- for (i = 0; i < c - 1; i++) {
- assert(i < pat->length(), "out of range");
- if (pat->char_at(o + i) == lastChar) {
- md2 = (c - 1) - i;
- }
- }
-
- result = string_indexOf(receiver, pat, o, cache, md2);
- }
- set_result(result);
+ }
+
+ C->set_has_split_ifs(true); // Has chance for split-if optimization
+ return true;
+}
+
+//----------------------inline_string_char_access----------------------------
+// Store/Load char to/from byte[] array.
+// static void StringUTF16.putChar(byte[] val, int index, int c)
+// static char StringUTF16.getChar(byte[] val, int index)
+bool LibraryCallKit::inline_string_char_access(bool is_store) {
+ Node* value = argument(0);
+ Node* index = argument(1);
+ Node* ch = is_store ? argument(2) : NULL;
+
+ // This intrinsic accesses byte[] array as char[] array. Computing the offsets
+ // correctly requires matched array shapes.
+ assert (arrayOopDesc::base_offset_in_bytes(T_CHAR) == arrayOopDesc::base_offset_in_bytes(T_BYTE),
+ "sanity: byte[] and char[] bases agree");
+ assert (type2aelembytes(T_CHAR) == type2aelembytes(T_BYTE)*2,
+ "sanity: byte[] and char[] scales agree");
+
+ Node* adr = array_element_address(value, index, T_CHAR);
+ if (is_store) {
+ (void) store_to_memory(control(), adr, ch, T_CHAR, TypeAryPtr::BYTES, MemNode::unordered);
+ } else {
+ ch = make_load(control(), adr, TypeInt::CHAR, T_CHAR, MemNode::unordered);
+ set_result(ch);
+ }
return true;
}
@@ -1365,7 +1476,7 @@
// public static double Math.log10(double)
bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
Node* arg = round_double_node(argument(0));
- Node* n;
+ Node* n = NULL;
switch (id) {
case vmIntrinsics::_dabs: n = new AbsDNode( arg); break;
case vmIntrinsics::_dsqrt: n = new SqrtDNode(C, control(), arg); break;
@@ -2110,7 +2221,7 @@
// inline long Long.reverseBytes(long)
bool LibraryCallKit::inline_number_methods(vmIntrinsics::ID id) {
Node* arg = argument(0);
- Node* n;
+ Node* n = NULL;
switch (id) {
case vmIntrinsics::_numberOfLeadingZeros_i: n = new CountLeadingZerosINode( arg); break;
case vmIntrinsics::_numberOfLeadingZeros_l: n = new CountLeadingZerosLNode( arg); break;
@@ -2650,7 +2761,7 @@
// For now, we handle only those cases that actually exist: ints,
// longs, and Object. Adding others should be straightforward.
- Node* load_store;
+ Node* load_store = NULL;
switch(type) {
case T_INT:
if (kind == LS_xadd) {
@@ -2781,9 +2892,9 @@
}
//----------------------------inline_unsafe_ordered_store----------------------
-// public native void sun.misc.Unsafe.putOrderedObject(Object o, long offset, Object x);
-// public native void sun.misc.Unsafe.putOrderedInt(Object o, long offset, int x);
-// public native void sun.misc.Unsafe.putOrderedLong(Object o, long offset, long x);
+// public native void Unsafe.putOrderedObject(Object o, long offset, Object x);
+// public native void Unsafe.putOrderedInt(Object o, long offset, int x);
+// public native void Unsafe.putOrderedLong(Object o, long offset, long x);
bool LibraryCallKit::inline_unsafe_ordered_store(BasicType type) {
// This is another variant of inline_unsafe_access, differing in
// that it always issues store-store ("release") barrier and ensures
@@ -2877,7 +2988,7 @@
}
//----------------------------inline_unsafe_allocate---------------------------
-// public native Object sun.misc.Unsafe.allocateInstance(Class<?> cls);
+// public native Object Unsafe.allocateInstance(Class<?> cls);
bool LibraryCallKit::inline_unsafe_allocate() {
if (callee()->is_static()) return false; // caller must have the capability!
@@ -3656,7 +3767,7 @@
Node* end = is_copyOfRange? argument(2): argument(1);
Node* array_type_mirror = is_copyOfRange? argument(3): argument(2);
- Node* newcopy;
+ Node* newcopy = NULL;
// Set the original stack and the reexecute bit for the interpreter to reexecute
// the bytecode that invokes Arrays.copyOf if deoptimization happens.
@@ -4091,7 +4202,7 @@
bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) {
Node* arg = argument(0);
- Node* result;
+ Node* result = NULL;
switch (id) {
case vmIntrinsics::_floatToRawIntBits: result = new MoveF2INode(arg); break;
@@ -4189,14 +4300,8 @@
return true;
}
-#ifdef _LP64
-#define XTOP ,top() /*additional argument*/
-#else //_LP64
-#define XTOP /*no additional argument*/
-#endif //_LP64
-
//----------------------inline_unsafe_copyMemory-------------------------
-// public native void sun.misc.Unsafe.copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
+// public native void Unsafe.copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
bool LibraryCallKit::inline_unsafe_copyMemory() {
if (callee()->is_static()) return false; // caller must have the capability!
null_check_receiver(); // null-check receiver
@@ -5003,10 +5108,11 @@
// Figure out the size and type of the elements we will be copying.
BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
- if (src_elem != T_CHAR || dst_elem != T_BYTE) {
+ if (!((src_elem == T_CHAR) || (src_elem== T_BYTE)) || dst_elem != T_BYTE) {
return false;
}
- Node* src_start = array_element_address(src, src_offset, src_elem);
+
+ Node* src_start = array_element_address(src, src_offset, T_CHAR);
Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
// 'src_start' points to src array + scaled offset
// 'dst_start' points to dst array + scaled offset
@@ -5124,7 +5230,7 @@
//-------------inline_squareToLen------------------------------------
bool LibraryCallKit::inline_squareToLen() {
- assert(UseSquareToLenIntrinsic, "not implementated on this platform");
+ assert(UseSquareToLenIntrinsic, "not implemented on this platform");
address stubAddr = StubRoutines::squareToLen();
if (stubAddr == NULL) {
@@ -5170,7 +5276,7 @@
//-------------inline_mulAdd------------------------------------------
bool LibraryCallKit::inline_mulAdd() {
- assert(UseMulAddIntrinsic, "not implementated on this platform");
+ assert(UseMulAddIntrinsic, "not implemented on this platform");
address stubAddr = StubRoutines::mulAdd();
if (stubAddr == NULL) {
@@ -5720,7 +5826,7 @@
//------------------------------inline_aescrypt_Block-----------------------
bool LibraryCallKit::inline_aescrypt_Block(vmIntrinsics::ID id) {
- address stubAddr;
+ address stubAddr = NULL;
const char *stubName;
assert(UseAES, "need AES instruction support");
@@ -5786,8 +5892,8 @@
//------------------------------inline_cipherBlockChaining_AESCrypt-----------------------
bool LibraryCallKit::inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id) {
- address stubAddr;
- const char *stubName;
+ address stubAddr = NULL;
+ const char *stubName = NULL;
assert(UseAES, "need AES instruction support");
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -622,8 +622,10 @@
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
case Op_EncodeISOArray:
- case Op_AryEq: {
+ case Op_AryEq:
+ case Op_HasNegatives: {
return false;
}
#if INCLUDE_RTM_OPT
@@ -741,8 +743,10 @@
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
case Op_EncodeISOArray:
- case Op_AryEq: {
+ case Op_AryEq:
+ case Op_HasNegatives: {
// Do not unroll a loop with String intrinsics code.
// String intrinsics are large and have loops.
return false;
--- a/hotspot/src/share/vm/opto/loopnode.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/loopnode.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -3494,7 +3494,9 @@
case Op_StrComp: // Does a bunch of load-like effects
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
case Op_AryEq:
+ case Op_HasNegatives:
pinned = false;
}
if( pinned ) {
--- a/hotspot/src/share/vm/opto/macro.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -379,13 +379,25 @@
if (mem->is_LoadStore()) {
adr = mem->in(MemNode::Address);
} else {
- assert(mem->Opcode() == Op_EncodeISOArray, "sanity");
+ assert(mem->Opcode() == Op_EncodeISOArray ||
+ mem->Opcode() == Op_StrCompressedCopy, "sanity");
adr = mem->in(3); // Destination array
}
const TypePtr* atype = adr->bottom_type()->is_ptr();
int adr_idx = phase->C->get_alias_index(atype);
if (adr_idx == alias_idx) {
- assert(false, "Object is not scalar replaceable if a LoadStore node access its field");
+ DEBUG_ONLY(mem->dump();)
+ assert(false, "Object is not scalar replaceable if a LoadStore node accesses its field");
+ return NULL;
+ }
+ mem = mem->in(MemNode::Memory);
+ } else if (mem->Opcode() == Op_StrInflatedCopy) {
+ Node* adr = mem->in(3); // Destination array
+ const TypePtr* atype = adr->bottom_type()->is_ptr();
+ int adr_idx = phase->C->get_alias_index(atype);
+ if (adr_idx == alias_idx) {
+ DEBUG_ONLY(mem->dump();)
+ assert(false, "Object is not scalar replaceable if a StrInflatedCopy node accesses its field");
return NULL;
}
mem = mem->in(MemNode::Memory);
@@ -516,8 +528,10 @@
}
values.at_put(j, val);
} else if (val->Opcode() == Op_SCMemProj) {
- assert(val->in(0)->is_LoadStore() || val->in(0)->Opcode() == Op_EncodeISOArray, "sanity");
- assert(false, "Object is not scalar replaceable if a LoadStore node access its field");
+ assert(val->in(0)->is_LoadStore() ||
+ val->in(0)->Opcode() == Op_EncodeISOArray ||
+ val->in(0)->Opcode() == Op_StrCompressedCopy, "sanity");
+ assert(false, "Object is not scalar replaceable if a LoadStore node accesses its field");
return NULL;
} else if (val->is_ArrayCopy()) {
Node* res = make_arraycopy_load(val->as_ArrayCopy(), offset, val->in(0), ft, phi_type, alloc);
@@ -779,10 +793,10 @@
ciKlass* klass = NULL;
ciInstanceKlass* iklass = NULL;
int nfields = 0;
- int array_base;
- int element_size;
- BasicType basic_elem_type;
- ciType* elem_type;
+ int array_base = 0;
+ int element_size = 0;
+ BasicType basic_elem_type = T_ILLEGAL;
+ ciType* elem_type = NULL;
Node* res = alloc->result_cast();
assert(res == NULL || res->is_CheckCastPP(), "unexpected AllocateNode result");
@@ -1305,10 +1319,10 @@
// We need a Region and corresponding Phi's to merge the slow-path and fast-path results.
// they will not be used if "always_slow" is set
enum { slow_result_path = 1, fast_result_path = 2 };
- Node *result_region;
- Node *result_phi_rawmem;
- Node *result_phi_rawoop;
- Node *result_phi_i_o;
+ Node *result_region = NULL;
+ Node *result_phi_rawmem = NULL;
+ Node *result_phi_rawoop = NULL;
+ Node *result_phi_i_o = NULL;
// The initial slow comparison is a size check, the comparison
// we want to do is a BoolTest::gt
--- a/hotspot/src/share/vm/opto/matcher.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/matcher.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -936,9 +936,13 @@
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
case Op_AryEq:
+ case Op_HasNegatives:
case Op_MemBarVolatile:
case Op_MemBarCPUOrder: // %%% these ideals should have narrower adr_type?
+ case Op_StrInflatedCopy:
+ case Op_StrCompressedCopy:
case Op_EncodeISOArray:
nidx = Compile::AliasIdxTop;
nat = NULL;
@@ -2156,7 +2160,11 @@
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_StrIndexOfChar:
case Op_AryEq:
+ case Op_HasNegatives:
+ case Op_StrInflatedCopy:
+ case Op_StrCompressedCopy:
case Op_EncodeISOArray:
set_shared(n); // Force result into register (it will be anyways)
break;
@@ -2336,7 +2344,8 @@
n->del_req(3);
break;
}
- case Op_StrEquals: {
+ case Op_StrEquals:
+ case Op_StrIndexOfChar: {
Node *pair1 = new BinaryNode(n->in(2),n->in(3));
n->set_req(2,pair1);
n->set_req(3,n->in(4));
@@ -2353,6 +2362,8 @@
n->del_req(4);
break;
}
+ case Op_StrCompressedCopy:
+ case Op_StrInflatedCopy:
case Op_EncodeISOArray: {
// Restructure into a binary tree for Matching.
Node* pair = new BinaryNode(n->in(3), n->in(4));
--- a/hotspot/src/share/vm/opto/memnode.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/memnode.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -997,7 +997,7 @@
// "Acquire" - no following ref can move before (but earlier refs can
// follow, like an early Load stalled in cache). Requires multi-cpu
// visibility. Inserted independ of any load, as required
-// for intrinsic sun.misc.Unsafe.loadFence().
+// for intrinsic Unsafe.loadFence().
class LoadFenceNode: public MemBarNode {
public:
LoadFenceNode(Compile* C, int alias_idx, Node* precedent)
@@ -1018,7 +1018,7 @@
// "Release" - no earlier ref can move after (but later refs can move
// up, like a speculative pipelined cache-hitting Load). Requires
// multi-cpu visibility. Inserted independent of any store, as required
-// for intrinsic sun.misc.Unsafe.storeFence().
+// for intrinsic Unsafe.storeFence().
class StoreFenceNode: public MemBarNode {
public:
StoreFenceNode(Compile* C, int alias_idx, Node* precedent)
--- a/hotspot/src/share/vm/opto/parse1.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/parse1.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -108,7 +108,7 @@
// Very similar to LoadNode::make, except we handle un-aligned longs and
// doubles on Sparc. Intel can handle them just fine directly.
- Node *l;
+ Node *l = NULL;
switch (bt) { // Signature is flattened
case T_INT: l = new LoadINode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInt::INT, MemNode::unordered); break;
case T_FLOAT: l = new LoadFNode(ctl, mem, adr, TypeRawPtr::BOTTOM, Type::FLOAT, MemNode::unordered); break;
@@ -1903,7 +1903,7 @@
// Now use a Phi here for merging
assert(!nocreate, "Cannot build a phi for a block already parsed.");
const JVMState* jvms = map->jvms();
- const Type* t;
+ const Type* t = NULL;
if (jvms->is_loc(idx)) {
t = block()->local_type_at(idx - jvms->locoff());
} else if (jvms->is_stk(idx)) {
--- a/hotspot/src/share/vm/opto/runtime.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/runtime.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -264,7 +264,7 @@
// Scavenge and allocate an instance.
oop result;
- if (array_type->oop_is_typeArray()) {
+ if (array_type->is_typeArray_klass()) {
// The oopFactory likes to work with the element type.
// (We could bypass the oopFactory, since it doesn't add much value.)
BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
@@ -302,7 +302,7 @@
// Scavenge and allocate an instance.
oop result;
- assert(array_type->oop_is_typeArray(), "should be called only for type array");
+ assert(array_type->is_typeArray_klass(), "should be called only for type array");
// The oopFactory likes to work with the element type.
BasicType elem_type = TypeArrayKlass::cast(array_type)->element_type();
result = oopFactory::new_typeArray_nozero(elem_type, len, THREAD);
--- a/hotspot/src/share/vm/opto/split_if.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/split_if.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -451,8 +451,8 @@
// Replace both uses of 'new_iff' with Regions merging True/False
// paths. This makes 'new_iff' go dead.
- Node *old_false, *old_true;
- Node *new_false, *new_true;
+ Node *old_false = NULL, *old_true = NULL;
+ Node *new_false = NULL, *new_true = NULL;
for (DUIterator_Last j2min, j2 = iff->last_outs(j2min); j2 >= j2min; --j2) {
Node *ifp = iff->last_out(j2);
assert( ifp->Opcode() == Op_IfFalse || ifp->Opcode() == Op_IfTrue, "" );
--- a/hotspot/src/share/vm/opto/stringopts.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/stringopts.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -598,7 +598,7 @@
}
// Collect the types needed to talk about the various slices of memory
- char_adr_idx = C->get_alias_index(TypeAryPtr::CHARS);
+ byte_adr_idx = C->get_alias_index(TypeAryPtr::BYTES);
// For each locally allocated StringBuffer see if the usages can be
// collapsed into a single String construction.
@@ -1128,6 +1128,25 @@
}
Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
+ if (arg->is_Con()) {
+ // Constant integer. Compute constant length using Integer.sizeTable
+ int arg_val = arg->get_int();
+ int count = 1;
+ if (arg_val < 0) {
+ arg_val = -arg_val;
+ count++;
+ }
+
+ ciArray* size_table = (ciArray*)size_table_field->constant_value().as_object();
+ for (int i = 0; i < size_table->length(); i++) {
+ if (arg_val <= size_table->element_value(i).as_int()) {
+ count += i;
+ break;
+ }
+ }
+ return __ intcon(count);
+ }
+
RegionNode *final_merge = new RegionNode(3);
kit.gvn().set_type(final_merge, Type::CONTROL);
Node* final_size = new PhiNode(final_merge, TypeInt::INT);
@@ -1212,77 +1231,34 @@
return final_size;
}
-void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, Node* start, Node* end) {
- RegionNode *final_merge = new RegionNode(4);
- kit.gvn().set_type(final_merge, Type::CONTROL);
- Node *final_mem = PhiNode::make(final_merge, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
- kit.gvn().set_type(final_mem, Type::MEMORY);
-
- // need to handle Integer.MIN_VALUE specially because negating doesn't make it positive
- {
- // i == MIN_VALUE
- IfNode* iff = kit.create_and_map_if(kit.control(),
- __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
- PROB_FAIR, COUNT_UNKNOWN);
-
- Node* old_mem = kit.memory(char_adr_idx);
-
- kit.set_control(__ IfFalse(iff));
- if (kit.stopped()) {
- // Statically not equal to MIN_VALUE so this path is dead
- final_merge->init_req(3, kit.control());
- } else {
- copy_string(kit, __ makecon(TypeInstPtr::make(C->env()->the_min_jint_string())),
- char_array, start);
- final_merge->init_req(3, kit.control());
- final_mem->init_req(3, kit.memory(char_adr_idx));
- }
-
- kit.set_control(__ IfTrue(iff));
- kit.set_memory(old_mem, char_adr_idx);
- }
-
-
- // Simplified version of Integer.getChars
-
- // int q, r;
- // int charPos = index;
- Node* charPos = end;
-
- // char sign = 0;
-
- Node* i = arg;
- Node* sign = __ intcon(0);
-
+// Simplified version of Integer.getChars
+void PhaseStringOpts::getChars(GraphKit& kit, Node* arg, Node* dst_array, BasicType bt, Node* end, Node* final_merge, Node* final_mem, int merge_index) {
// if (i < 0) {
// sign = '-';
// i = -i;
// }
- {
- IfNode* iff = kit.create_and_map_if(kit.control(),
- __ Bool(__ CmpI(arg, __ intcon(0)), BoolTest::lt),
- PROB_FAIR, COUNT_UNKNOWN);
+ IfNode* iff = kit.create_and_map_if(kit.control(), __ Bool(__ CmpI(arg, __ intcon(0)), BoolTest::lt),
+ PROB_FAIR, COUNT_UNKNOWN);
- RegionNode *merge = new RegionNode(3);
- kit.gvn().set_type(merge, Type::CONTROL);
- i = new PhiNode(merge, TypeInt::INT);
- kit.gvn().set_type(i, TypeInt::INT);
- sign = new PhiNode(merge, TypeInt::INT);
- kit.gvn().set_type(sign, TypeInt::INT);
+ RegionNode* merge = new RegionNode(3);
+ kit.gvn().set_type(merge, Type::CONTROL);
+ Node* i = new PhiNode(merge, TypeInt::INT);
+ kit.gvn().set_type(i, TypeInt::INT);
+ Node* sign = new PhiNode(merge, TypeInt::INT);
+ kit.gvn().set_type(sign, TypeInt::INT);
- merge->init_req(1, __ IfTrue(iff));
- i->init_req(1, __ SubI(__ intcon(0), arg));
- sign->init_req(1, __ intcon('-'));
- merge->init_req(2, __ IfFalse(iff));
- i->init_req(2, arg);
- sign->init_req(2, __ intcon(0));
+ merge->init_req(1, __ IfTrue(iff));
+ i->init_req(1, __ SubI(__ intcon(0), arg));
+ sign->init_req(1, __ intcon('-'));
+ merge->init_req(2, __ IfFalse(iff));
+ i->init_req(2, arg);
+ sign->init_req(2, __ intcon(0));
- kit.set_control(merge);
+ kit.set_control(merge);
- C->record_for_igvn(merge);
- C->record_for_igvn(i);
- C->record_for_igvn(sign);
- }
+ C->record_for_igvn(merge);
+ C->record_for_igvn(i);
+ C->record_for_igvn(sign);
// for (;;) {
// q = i / 10;
@@ -1292,126 +1268,409 @@
// if (i == 0) break;
// }
- {
- // Add loop predicate first.
- kit.add_predicate();
+ // Add loop predicate first.
+ kit.add_predicate();
+
+ RegionNode* head = new RegionNode(3);
+ head->init_req(1, kit.control());
- RegionNode *head = new RegionNode(3);
- head->init_req(1, kit.control());
- kit.gvn().set_type(head, Type::CONTROL);
- Node *i_phi = new PhiNode(head, TypeInt::INT);
- i_phi->init_req(1, i);
- kit.gvn().set_type(i_phi, TypeInt::INT);
- charPos = PhiNode::make(head, charPos);
- kit.gvn().set_type(charPos, TypeInt::INT);
- Node *mem = PhiNode::make(head, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
- kit.gvn().set_type(mem, Type::MEMORY);
- kit.set_control(head);
- kit.set_memory(mem, char_adr_idx);
+ kit.gvn().set_type(head, Type::CONTROL);
+ Node* i_phi = new PhiNode(head, TypeInt::INT);
+ i_phi->init_req(1, i);
+ kit.gvn().set_type(i_phi, TypeInt::INT);
+ Node* charPos = new PhiNode(head, TypeInt::INT);
+ charPos->init_req(1, end);
+ kit.gvn().set_type(charPos, TypeInt::INT);
+ Node* mem = PhiNode::make(head, kit.memory(byte_adr_idx), Type::MEMORY, TypeAryPtr::BYTES);
+ kit.gvn().set_type(mem, Type::MEMORY);
- Node* q = __ DivI(NULL, i_phi, __ intcon(10));
- Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)),
- __ LShiftI(q, __ intcon(1))));
- Node* m1 = __ SubI(charPos, __ intcon(1));
- Node* ch = __ AddI(r, __ intcon('0'));
-
- Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
- ch, T_CHAR, char_adr_idx, MemNode::unordered);
-
+ kit.set_control(head);
+ kit.set_memory(mem, byte_adr_idx);
- IfNode* iff = kit.create_and_map_if(head, __ Bool(__ CmpI(q, __ intcon(0)), BoolTest::ne),
- PROB_FAIR, COUNT_UNKNOWN);
- Node* ne = __ IfTrue(iff);
- Node* eq = __ IfFalse(iff);
+ Node* q = __ DivI(kit.null(), i_phi, __ intcon(10));
+ Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)),
+ __ LShiftI(q, __ intcon(1))));
+ Node* index = __ SubI(charPos, __ intcon((bt == T_BYTE) ? 1 : 2));
+ Node* ch = __ AddI(r, __ intcon('0'));
+ Node* st = __ store_to_memory(kit.control(), kit.array_element_address(dst_array, index, T_BYTE),
+ ch, bt, byte_adr_idx, MemNode::unordered);
- head->init_req(2, ne);
- mem->init_req(2, st);
- i_phi->init_req(2, q);
- charPos->init_req(2, m1);
-
- charPos = m1;
+ iff = kit.create_and_map_if(head, __ Bool(__ CmpI(q, __ intcon(0)), BoolTest::ne),
+ PROB_FAIR, COUNT_UNKNOWN);
+ Node* ne = __ IfTrue(iff);
+ Node* eq = __ IfFalse(iff);
- kit.set_control(eq);
- kit.set_memory(st, char_adr_idx);
+ head->init_req(2, ne);
+ mem->init_req(2, st);
+
+ i_phi->init_req(2, q);
+ charPos->init_req(2, index);
+ charPos = index;
- C->record_for_igvn(head);
- C->record_for_igvn(mem);
- C->record_for_igvn(i_phi);
- C->record_for_igvn(charPos);
- }
+ kit.set_control(eq);
+ kit.set_memory(st, byte_adr_idx);
- {
- // if (sign != 0) {
- // buf [--charPos] = sign;
- // }
- IfNode* iff = kit.create_and_map_if(kit.control(),
- __ Bool(__ CmpI(sign, __ intcon(0)), BoolTest::ne),
- PROB_FAIR, COUNT_UNKNOWN);
+ C->record_for_igvn(head);
+ C->record_for_igvn(mem);
+ C->record_for_igvn(i_phi);
+ C->record_for_igvn(charPos);
- final_merge->init_req(2, __ IfFalse(iff));
- final_mem->init_req(2, kit.memory(char_adr_idx));
+ // if (sign != 0) {
+ // buf [--charPos] = sign;
+ // }
+ iff = kit.create_and_map_if(kit.control(), __ Bool(__ CmpI(sign, __ intcon(0)), BoolTest::ne),
+ PROB_FAIR, COUNT_UNKNOWN);
+
+ final_merge->init_req(merge_index + 2, __ IfFalse(iff));
+ final_mem->init_req(merge_index + 2, kit.memory(byte_adr_idx));
- kit.set_control(__ IfTrue(iff));
- if (kit.stopped()) {
- final_merge->init_req(1, C->top());
- final_mem->init_req(1, C->top());
- } else {
- Node* m1 = __ SubI(charPos, __ intcon(1));
- Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
- sign, T_CHAR, char_adr_idx, MemNode::unordered);
+ kit.set_control(__ IfTrue(iff));
+ if (kit.stopped()) {
+ final_merge->init_req(merge_index + 1, C->top());
+ final_mem->init_req(merge_index + 1, C->top());
+ } else {
+ Node* index = __ SubI(charPos, __ intcon((bt == T_BYTE) ? 1 : 2));
+ st = __ store_to_memory(kit.control(), kit.array_element_address(dst_array, index, T_BYTE),
+ sign, bt, byte_adr_idx, MemNode::unordered);
- final_merge->init_req(1, kit.control());
- final_mem->init_req(1, st);
- }
-
- kit.set_control(final_merge);
- kit.set_memory(final_mem, char_adr_idx);
-
- C->record_for_igvn(final_merge);
- C->record_for_igvn(final_mem);
+ final_merge->init_req(merge_index + 1, kit.control());
+ final_mem->init_req(merge_index + 1, st);
}
}
+// Copy the characters representing arg into dst_array starting at start
+Node* PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* dst_array, Node* dst_coder, Node* start, Node* size) {
+ bool dcon = dst_coder->is_Con();
+ bool dbyte = dcon ? (dst_coder->get_int() == java_lang_String::CODER_LATIN1) : false;
+ Node* end = __ AddI(start, __ LShiftI(size, dst_coder));
-Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
- Node* string = str;
- Node* offset = kit.load_String_offset(kit.control(), string);
- Node* count = kit.load_String_length(kit.control(), string);
- Node* value = kit.load_String_value (kit.control(), string);
+ // The final_merge node has 4 entries in case the encoding is known:
+ // (0) Control, (1) result w/ sign, (2) result w/o sign, (3) result for Integer.min_value
+ // or 6 entries in case the encoding is not known:
+ // (0) Control, (1) Latin1 w/ sign, (2) Latin1 w/o sign, (3) min_value, (4) UTF16 w/ sign, (5) UTF16 w/o sign
+ RegionNode* final_merge = new RegionNode(dcon ? 4 : 6);
+ kit.gvn().set_type(final_merge, Type::CONTROL);
+
+ Node* final_mem = PhiNode::make(final_merge, kit.memory(byte_adr_idx), Type::MEMORY, TypeAryPtr::BYTES);
+ kit.gvn().set_type(final_mem, Type::MEMORY);
+
+ // need to handle arg == Integer.MIN_VALUE specially because negating doesn't make it positive
+ IfNode* iff = kit.create_and_map_if(kit.control(), __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
+ PROB_FAIR, COUNT_UNKNOWN);
+
+ Node* old_mem = kit.memory(byte_adr_idx);
+
+ kit.set_control(__ IfFalse(iff));
+ if (kit.stopped()) {
+ // Statically not equal to MIN_VALUE so this path is dead
+ final_merge->init_req(3, kit.control());
+ } else {
+ copy_string(kit, __ makecon(TypeInstPtr::make(C->env()->the_min_jint_string())),
+ dst_array, dst_coder, start);
+ final_merge->init_req(3, kit.control());
+ final_mem->init_req(3, kit.memory(byte_adr_idx));
+ }
+
+ kit.set_control(__ IfTrue(iff));
+ kit.set_memory(old_mem, byte_adr_idx);
+
+ if (!dcon) {
+ // Check encoding of destination
+ iff = kit.create_and_map_if(kit.control(), __ Bool(__ CmpI(dst_coder, __ intcon(0)), BoolTest::eq),
+ PROB_FAIR, COUNT_UNKNOWN);
+ old_mem = kit.memory(byte_adr_idx);
+ }
+ if (!dcon || dbyte) {
+ // Destination is Latin1,
+ if (!dcon) {
+ kit.set_control(__ IfTrue(iff));
+ }
+ getChars(kit, arg, dst_array, T_BYTE, end, final_merge, final_mem);
+ }
+ if (!dcon || !dbyte) {
+ // Destination is UTF16
+ int merge_index = 0;
+ if (!dcon) {
+ kit.set_control(__ IfFalse(iff));
+ kit.set_memory(old_mem, byte_adr_idx);
+ merge_index = 3; // Account for Latin1 case
+ }
+ getChars(kit, arg, dst_array, T_CHAR, end, final_merge, final_mem, merge_index);
+ }
+
+ // Final merge point for Latin1 and UTF16 case
+ kit.set_control(final_merge);
+ kit.set_memory(final_mem, byte_adr_idx);
+
+ C->record_for_igvn(final_merge);
+ C->record_for_igvn(final_mem);
+ return end;
+}
+
+// Copy 'count' bytes/chars from src_array to dst_array starting at index start
+void PhaseStringOpts::arraycopy(GraphKit& kit, IdealKit& ideal, Node* src_array, Node* dst_array, BasicType elembt, Node* start, Node* count) {
+ assert(elembt == T_BYTE || elembt == T_CHAR, "Invalid type for arraycopy");
+
+ if (elembt == T_CHAR) {
+ // Get number of chars
+ count = __ RShiftI(count, __ intcon(1));
+ }
+
+ Node* extra = NULL;
+#ifdef _LP64
+ count = __ ConvI2L(count);
+ extra = C->top();
+#endif
+
+ Node* src_ptr = __ array_element_address(src_array, __ intcon(0), T_BYTE);
+ Node* dst_ptr = __ array_element_address(dst_array, start, T_BYTE);
+ // Check if destination address is aligned to HeapWordSize
+ const TypeInt* tdst = __ gvn().type(start)->is_int();
+ bool aligned = tdst->is_con() && ((tdst->get_con() * type2aelembytes(T_BYTE)) % HeapWordSize == 0);
+ // Figure out which arraycopy runtime method to call (disjoint, uninitialized).
+ const char* copyfunc_name = "arraycopy";
+ address copyfunc_addr = StubRoutines::select_arraycopy_function(elembt, aligned, true, copyfunc_name, true);
+ ideal.make_leaf_call_no_fp(OptoRuntime::fast_arraycopy_Type(), copyfunc_addr, copyfunc_name,
+ TypeAryPtr::BYTES, src_ptr, dst_ptr, count, extra);
+}
+
+#undef __
+#define __ ideal.
+
+// Copy contents of a Latin1 encoded string from src_array to dst_array
+void PhaseStringOpts::copy_latin1_string(GraphKit& kit, IdealKit& ideal, Node* src_array, IdealVariable& count,
+ Node* dst_array, Node* dst_coder, Node* start) {
+ bool dcon = dst_coder->is_Con();
+ bool dbyte = dcon ? (dst_coder->get_int() == java_lang_String::CODER_LATIN1) : false;
- // copy the contents
- if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
+ if (!dcon) {
+ __ if_then(dst_coder, BoolTest::eq, __ ConI(java_lang_String::CODER_LATIN1));
+ }
+ if (!dcon || dbyte) {
+ // Destination is Latin1. Simply emit a byte arraycopy.
+ arraycopy(kit, ideal, src_array, dst_array, T_BYTE, start, __ value(count));
+ }
+ if (!dcon) {
+ __ else_();
+ }
+ if (!dcon || !dbyte) {
+ // Destination is UTF16. Inflate src_array into dst_array.
+ kit.sync_kit(ideal);
+ if (Matcher::match_rule_supported(Op_StrInflatedCopy)) {
+ // Use fast intrinsic
+ Node* src = kit.array_element_address(src_array, kit.intcon(0), T_BYTE);
+ Node* dst = kit.array_element_address(dst_array, start, T_BYTE);
+ kit.inflate_string(src, dst, __ value(count));
+ } else {
+ // No intrinsic available, use slow method
+ kit.inflate_string_slow(src_array, dst_array, start, __ value(count));
+ }
+ ideal.sync_kit(&kit);
+ // Multiply count by two since we now need two bytes per char
+ __ set(count, __ LShiftI(__ value(count), __ ConI(1)));
+ }
+ if (!dcon) {
+ __ end_if();
+ }
+}
+
+// Read two bytes from index and index+1 and convert them to a char
+static jchar readChar(ciTypeArray* array, int index) {
+ int shift_high, shift_low;
+#ifdef VM_LITTLE_ENDIAN
+ shift_high = 0;
+ shift_low = 8;
+#else
+ shift_high = 8;
+ shift_low = 0;
+#endif
+
+ jchar b1 = ((jchar) array->byte_at(index)) & 0xff;
+ jchar b2 = ((jchar) array->byte_at(index+1)) & 0xff;
+ return (b1 << shift_high) | (b2 << shift_low);
+}
+
+// Copy contents of constant src_array to dst_array by emitting individual stores
+void PhaseStringOpts::copy_constant_string(GraphKit& kit, IdealKit& ideal, ciTypeArray* src_array, IdealVariable& count,
+ bool src_is_byte, Node* dst_array, Node* dst_coder, Node* start) {
+ bool dcon = dst_coder->is_Con();
+ bool dbyte = dcon ? (dst_coder->get_int() == java_lang_String::CODER_LATIN1) : false;
+ int length = src_array->length();
+
+ if (!dcon) {
+ __ if_then(dst_coder, BoolTest::eq, __ ConI(java_lang_String::CODER_LATIN1));
+ }
+ if (!dcon || dbyte) {
+ // Destination is Latin1. Copy each byte of src_array into dst_array.
+ Node* index = start;
+ for (int i = 0; i < length; i++) {
+ Node* adr = kit.array_element_address(dst_array, index, T_BYTE);
+ Node* val = __ ConI(src_array->byte_at(i));
+ __ store(__ ctrl(), adr, val, T_BYTE, byte_adr_idx, MemNode::unordered);
+ index = __ AddI(index, __ ConI(1));
+ }
+ }
+ if (!dcon) {
+ __ else_();
+ }
+ if (!dcon || !dbyte) {
+ // Destination is UTF16. Copy each char of src_array into dst_array.
+ Node* index = start;
+ for (int i = 0; i < length; i++) {
+ Node* adr = kit.array_element_address(dst_array, index, T_BYTE);
+ jchar val;
+ if (src_is_byte) {
+ val = src_array->byte_at(i) & 0xff;
+ } else {
+ val = readChar(src_array, i++);
+ }
+ __ store(__ ctrl(), adr, __ ConI(val), T_CHAR, byte_adr_idx, MemNode::unordered);
+ index = __ AddI(index, __ ConI(2));
+ }
+ if (src_is_byte) {
+ // Multiply count by two since we now need two bytes per char
+ __ set(count, __ ConI(2 * length));
+ }
+ }
+ if (!dcon) {
+ __ end_if();
+ }
+}
+
+// Compress copy contents of the byte/char String str into dst_array starting at index start.
+Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* dst_array, Node* dst_coder, Node* start) {
+ Node* src_array = kit.load_String_value(kit.control(), str);
+
+ IdealKit ideal(&kit, true, true);
+ IdealVariable count(ideal); __ declarations_done();
+
+ if (str->is_Con()) {
+ // Constant source string
+ const TypeOopPtr* t = kit.gvn().type(src_array)->isa_oopptr();
+ ciTypeArray* src_array_type = t->const_oop()->as_type_array();
+
+ // Check encoding of constant string
+ bool src_is_byte = (get_constant_coder(kit, str) == java_lang_String::CODER_LATIN1);
+
// For small constant strings just emit individual stores.
// A length of 6 seems like a good space/speed tradeof.
- int c = count->get_int();
- int o = offset->get_int();
- const TypeOopPtr* t = kit.gvn().type(value)->isa_oopptr();
- ciTypeArray* value_array = t->const_oop()->as_type_array();
- for (int e = 0; e < c; e++) {
- __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
- __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx,
- MemNode::unordered);
- start = __ AddI(start, __ intcon(1));
+ __ set(count, __ ConI(src_array_type->length()));
+ int src_len = src_array_type->length() / (src_is_byte ? 1 : 2);
+ if (src_len < unroll_string_copy_length) {
+ // Small constant string
+ copy_constant_string(kit, ideal, src_array_type, count, src_is_byte, dst_array, dst_coder, start);
+ } else if (src_is_byte) {
+ // Source is Latin1
+ copy_latin1_string(kit, ideal, src_array, count, dst_array, dst_coder, start);
+ } else {
+ // Source is UTF16 (destination too). Simply emit a char arraycopy.
+ arraycopy(kit, ideal, src_array, dst_array, T_CHAR, start, __ value(count));
}
} else {
- Node* src_ptr = kit.array_element_address(value, offset, T_CHAR);
- Node* dst_ptr = kit.array_element_address(char_array, start, T_CHAR);
- Node* c = count;
- Node* extra = NULL;
-#ifdef _LP64
- c = __ ConvI2L(c);
- extra = C->top();
-#endif
- Node* call = kit.make_runtime_call(GraphKit::RC_LEAF|GraphKit::RC_NO_FP,
- OptoRuntime::fast_arraycopy_Type(),
- CAST_FROM_FN_PTR(address, StubRoutines::jshort_disjoint_arraycopy()),
- "jshort_disjoint_arraycopy", TypeAryPtr::CHARS,
- src_ptr, dst_ptr, c, extra);
- start = __ AddI(start, count);
+ Node* size = kit.load_array_length(src_array);
+ __ set(count, size);
+ // Non-constant source string
+ if (CompactStrings) {
+ // Emit runtime check for coder
+ Node* coder = kit.load_String_coder(__ ctrl(), str);
+ __ if_then(coder, BoolTest::eq, __ ConI(java_lang_String::CODER_LATIN1)); {
+ // Source is Latin1
+ copy_latin1_string(kit, ideal, src_array, count, dst_array, dst_coder, start);
+ } __ else_();
+ }
+ // Source is UTF16 (destination too). Simply emit a char arraycopy.
+ arraycopy(kit, ideal, src_array, dst_array, T_CHAR, start, __ value(count));
+
+ if (CompactStrings) {
+ __ end_if();
+ }
}
- return start;
+
+ // Finally sync IdealKit and GraphKit.
+ kit.sync_kit(ideal);
+ return __ AddI(start, __ value(count));
}
+// Compress copy the char into dst_array at index start.
+Node* PhaseStringOpts::copy_char(GraphKit& kit, Node* val, Node* dst_array, Node* dst_coder, Node* start) {
+ bool dcon = (dst_coder != NULL) && dst_coder->is_Con();
+ bool dbyte = dcon ? (dst_coder->get_int() == java_lang_String::CODER_LATIN1) : false;
+
+ IdealKit ideal(&kit, true, true);
+ IdealVariable end(ideal); __ declarations_done();
+ Node* adr = kit.array_element_address(dst_array, start, T_BYTE);
+ if (!dcon){
+ __ if_then(dst_coder, BoolTest::eq, __ ConI(java_lang_String::CODER_LATIN1));
+ }
+ if (!dcon || dbyte) {
+ // Destination is Latin1. Store a byte.
+ __ store(__ ctrl(), adr, val, T_BYTE, byte_adr_idx, MemNode::unordered);
+ __ set(end, __ AddI(start, __ ConI(1)));
+ }
+ if (!dcon) {
+ __ else_();
+ }
+ if (!dcon || !dbyte) {
+ // Destination is UTF16. Store a char.
+ __ store(__ ctrl(), adr, val, T_CHAR, byte_adr_idx, MemNode::unordered);
+ __ set(end, __ AddI(start, __ ConI(2)));
+ }
+ if (!dcon) {
+ __ end_if();
+ }
+ // Finally sync IdealKit and GraphKit.
+ kit.sync_kit(ideal);
+ return __ value(end);
+}
+
+#undef __
+#define __ kit.
+
+// Allocate a byte array of specified length.
+Node* PhaseStringOpts::allocate_byte_array(GraphKit& kit, IdealKit* ideal, Node* length) {
+ if (ideal != NULL) {
+ // Sync IdealKit and graphKit.
+ kit.sync_kit(*ideal);
+ }
+ Node* byte_array = NULL;
+ {
+ PreserveReexecuteState preexecs(&kit);
+ // The original jvms is for an allocation of either a String or
+ // StringBuffer so no stack adjustment is necessary for proper
+ // reexecution. If we deoptimize in the slow path the bytecode
+ // will be reexecuted and the char[] allocation will be thrown away.
+ kit.jvms()->set_should_reexecute(true);
+ byte_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_BYTE))),
+ length, 1);
+ }
+
+ // Mark the allocation so that zeroing is skipped since the code
+ // below will overwrite the entire array
+ AllocateArrayNode* byte_alloc = AllocateArrayNode::Ideal_array_allocation(byte_array, _gvn);
+ byte_alloc->maybe_set_complete(_gvn);
+
+ if (ideal != NULL) {
+ // Sync IdealKit and graphKit.
+ ideal->sync_kit(&kit);
+ }
+ return byte_array;
+}
+
+jbyte PhaseStringOpts::get_constant_coder(GraphKit& kit, Node* str) {
+ assert(str->is_Con(), "String must be constant");
+ const TypeOopPtr* str_type = kit.gvn().type(str)->isa_oopptr();
+ ciInstance* str_instance = str_type->const_oop()->as_instance();
+ jbyte coder = str_instance->field_value_by_offset(java_lang_String::coder_offset_in_bytes()).as_byte();
+ assert(CompactStrings || (coder == java_lang_String::CODER_UTF16), "Strings must be UTF16 encoded");
+ return coder;
+}
+
+int PhaseStringOpts::get_constant_length(GraphKit& kit, Node* str) {
+ assert(str->is_Con(), "String must be constant");
+ Node* src_array = kit.load_String_value(kit.control(), str);
+ const TypeOopPtr* t = kit.gvn().type(src_array)->isa_oopptr();
+ return t->const_oop()->as_type_array()->length();
+}
void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
// Log a little info about the transformation
@@ -1445,7 +1704,6 @@
jvms->set_map(map);
map->ensure_stack(jvms, jvms->method()->max_stack());
-
// disconnect all the old StringBuilder calls from the graph
sc->eliminate_unneeded_control();
@@ -1473,7 +1731,17 @@
// are need for the copying phase.
Node* string_sizes = new Node(args);
+ Node* coder = __ intcon(0);
Node* length = __ intcon(0);
+ // If at least one argument is UTF16 encoded, we can fix the encoding.
+ bool coder_fixed = false;
+
+ if (!CompactStrings) {
+ // Fix encoding of result string to UTF16
+ coder_fixed = true;
+ coder = __ intcon(java_lang_String::CODER_UTF16);
+ }
+
for (int argi = 0; argi < sc->num_arguments(); argi++) {
Node* arg = sc->argument(argi);
switch (sc->mode(argi)) {
@@ -1491,7 +1759,7 @@
const Type* type = kit.gvn().type(arg);
assert(type != TypePtr::NULL_PTR, "missing check");
if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
- // Null check with uncommont trap since
+ // Null check with uncommon trap since
// StringBuilder(null) throws exception.
// Use special uncommon trap instead of
// calling normal do_null_check().
@@ -1509,11 +1777,13 @@
case StringConcat::StringMode: {
const Type* type = kit.gvn().type(arg);
Node* count = NULL;
+ Node* arg_coder = NULL;
if (type == TypePtr::NULL_PTR) {
// replace the argument with the null checked version
arg = null_string;
sc->set_argument(argi, arg);
count = kit.load_String_length(kit.control(), arg);
+ arg_coder = kit.load_String_coder(kit.control(), arg);
} else if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
// s = s != null ? s : "null";
// length = length + (s.count - s.offset);
@@ -1537,11 +1807,32 @@
arg = phi;
sc->set_argument(argi, arg);
count = kit.load_String_length(kit.control(), arg);
+ arg_coder = kit.load_String_coder(kit.control(), arg);
} else {
// A corresponding nullcheck will be connected during IGVN MemNode::Ideal_common_DU_postCCP
// kit.control might be a different test, that can be hoisted above the actual nullcheck
// in case, that the control input is not null, Ideal_common_DU_postCCP will not look for a nullcheck.
count = kit.load_String_length(NULL, arg);
+ arg_coder = kit.load_String_coder(NULL, arg);
+ }
+ if (arg->is_Con()) {
+ // Constant string. Get constant coder and length.
+ jbyte const_coder = get_constant_coder(kit, arg);
+ int const_length = get_constant_length(kit, arg);
+ if (const_coder == java_lang_String::CODER_LATIN1) {
+ // Can be latin1 encoded
+ arg_coder = __ intcon(const_coder);
+ count = __ intcon(const_length);
+ } else {
+ // Found UTF16 encoded string. Fix result array encoding to UTF16.
+ coder_fixed = true;
+ coder = __ intcon(const_coder);
+ count = __ intcon(const_length / 2);
+ }
+ }
+
+ if (!coder_fixed) {
+ coder = __ OrI(coder, arg_coder);
}
length = __ AddI(length, count);
string_sizes->init_req(argi, NULL);
@@ -1549,6 +1840,34 @@
}
case StringConcat::CharMode: {
// one character only
+ const TypeInt* t = kit.gvn().type(arg)->is_int();
+ if (!coder_fixed && t->is_con()) {
+ // Constant char
+ if (t->get_con() <= 255) {
+ // Can be latin1 encoded
+ coder = __ OrI(coder, __ intcon(java_lang_String::CODER_LATIN1));
+ } else {
+ // Must be UTF16 encoded. Fix result array encoding to UTF16.
+ coder_fixed = true;
+ coder = __ intcon(java_lang_String::CODER_UTF16);
+ }
+ } else if (!coder_fixed) {
+ // Not constant
+#undef __
+#define __ ideal.
+ IdealKit ideal(&kit, true, true);
+ IdealVariable char_coder(ideal); __ declarations_done();
+ // Check if character can be latin1 encoded
+ __ if_then(arg, BoolTest::le, __ ConI(0xFF));
+ __ set(char_coder, __ ConI(java_lang_String::CODER_LATIN1));
+ __ else_();
+ __ set(char_coder, __ ConI(java_lang_String::CODER_UTF16));
+ __ end_if();
+ kit.sync_kit(ideal);
+ coder = __ OrI(coder, __ value(char_coder));
+#undef __
+#define __ kit.
+ }
length = __ AddI(length, __ intcon(1));
break;
}
@@ -1576,54 +1895,37 @@
Node* result;
if (!kit.stopped()) {
- Node* char_array = NULL;
+ assert(CompactStrings || (coder->is_Con() && coder->get_int() == java_lang_String::CODER_UTF16),
+ "Result string must be UTF16 encoded if CompactStrings is disabled");
+
+ Node* dst_array = NULL;
if (sc->num_arguments() == 1 &&
- (sc->mode(0) == StringConcat::StringMode ||
- sc->mode(0) == StringConcat::StringNullCheckMode)) {
+ (sc->mode(0) == StringConcat::StringMode ||
+ sc->mode(0) == StringConcat::StringNullCheckMode)) {
// Handle the case when there is only a single String argument.
// In this case, we can just pull the value from the String itself.
- char_array = kit.load_String_value(kit.control(), sc->argument(0));
+ dst_array = kit.load_String_value(kit.control(), sc->argument(0));
} else {
- // length now contains the number of characters needed for the
- // char[] so create a new AllocateArray for the char[]
- {
- PreserveReexecuteState preexecs(&kit);
- // The original jvms is for an allocation of either a String or
- // StringBuffer so no stack adjustment is necessary for proper
- // reexecution. If we deoptimize in the slow path the bytecode
- // will be reexecuted and the char[] allocation will be thrown away.
- kit.jvms()->set_should_reexecute(true);
- char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
- length, 1);
- }
+ // Allocate destination byte array according to coder
+ dst_array = allocate_byte_array(kit, NULL, __ LShiftI(length, coder));
- // Mark the allocation so that zeroing is skipped since the code
- // below will overwrite the entire array
- AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
- char_alloc->maybe_set_complete(_gvn);
-
- // Now copy the string representations into the final char[]
+ // Now copy the string representations into the final byte[]
Node* start = __ intcon(0);
for (int argi = 0; argi < sc->num_arguments(); argi++) {
Node* arg = sc->argument(argi);
switch (sc->mode(argi)) {
case StringConcat::IntMode: {
- Node* end = __ AddI(start, string_sizes->in(argi));
- // getChars words backwards so pass the ending point as well as the start
- int_getChars(kit, arg, char_array, start, end);
- start = end;
+ start = int_getChars(kit, arg, dst_array, coder, start, string_sizes->in(argi));
break;
}
case StringConcat::StringNullCheckMode:
case StringConcat::StringMode: {
- start = copy_string(kit, arg, char_array, start);
+ start = copy_string(kit, arg, dst_array, coder, start);
break;
}
case StringConcat::CharMode: {
- __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
- arg, T_CHAR, char_adr_idx, MemNode::unordered);
- start = __ AddI(start, __ intcon(1));
- break;
+ start = copy_char(kit, arg, dst_array, coder, start);
+ break;
}
default:
ShouldNotReachHere();
@@ -1642,12 +1944,9 @@
result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
}
- // Intialize the string
- if (java_lang_String::has_offset_field()) {
- kit.store_String_offset(kit.control(), result, __ intcon(0));
- kit.store_String_length(kit.control(), result, length);
- }
- kit.store_String_value(kit.control(), result, char_array);
+ // Initialize the string
+ kit.store_String_value(kit.control(), result, dst_array);
+ kit.store_String_coder(kit.control(), result, coder);
} else {
result = C->top();
}
--- a/hotspot/src/share/vm/opto/stringopts.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/stringopts.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
#include "opto/phaseX.hpp"
class StringConcat;
+class IdealVariable;
class PhaseStringOpts : public Phase {
friend class StringConcat;
@@ -40,7 +41,7 @@
Unique_Node_List dead_worklist;
// Memory slices needed for code gen
- int char_adr_idx;
+ int byte_adr_idx;
// Integer.sizeTable - used for int to String conversion
ciField* size_table_field;
@@ -64,11 +65,37 @@
// Compute the number of characters required to represent the int value
Node* int_stringSize(GraphKit& kit, Node* value);
- // Copy the characters representing value into char_array starting at start
- void int_getChars(GraphKit& kit, Node* value, Node* char_array, Node* start, Node* end);
+ // Simplified version of Integer.getChars
+ void getChars(GraphKit& kit, Node* arg, Node* dst_array, BasicType bt, Node* end, Node* final_merge, Node* final_mem, int merge_index = 0);
+
+ // Copy the characters representing arg into dst_array starting at start
+ Node* int_getChars(GraphKit& kit, Node* arg, Node* dst_array, Node* dst_coder, Node* start, Node* size);
+
+ // Copy contents of the String str into dst_array starting at index start.
+ Node* copy_string(GraphKit& kit, Node* str, Node* dst_array, Node* dst_coder, Node* start);
+
+ // Copy 'count' bytes/chars from src_array to dst_array starting at index start
+ void arraycopy(GraphKit& kit, IdealKit& ideal, Node* src_array, Node* dst_array, BasicType elembt, Node* start, Node* count);
+
+ // Copy contents of constant src_array to dst_array by emitting individual stores
+ void copy_constant_string(GraphKit& kit, IdealKit& ideal, ciTypeArray* src_array, IdealVariable& count,
+ bool src_is_byte, Node* dst_array, Node* dst_coder, Node* start);
- // Copy of the contents of the String str into char_array starting at index start.
- Node* copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start);
+ // Copy contents of a Latin1 encoded string from src_array to dst_array
+ void copy_latin1_string(GraphKit& kit, IdealKit& ideal, Node* src_array, IdealVariable& count,
+ Node* dst_array, Node* dst_coder, Node* start);
+
+ // Copy the char into dst_array at index start.
+ Node* copy_char(GraphKit& kit, Node* val, Node* dst_array, Node* dst_coder, Node* start);
+
+ // Allocate a byte array of specified length.
+ Node* allocate_byte_array(GraphKit& kit, IdealKit* ideal, Node* length);
+
+ // Returns the coder of a constant string
+ jbyte get_constant_coder(GraphKit& kit, Node* str);
+
+ // Returns the length of a constant string
+ int get_constant_length(GraphKit& kit, Node* str);
// Clean up any leftover nodes
void record_dead_node(Node* node);
--- a/hotspot/src/share/vm/opto/superword.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/opto/superword.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -4001,7 +4001,7 @@
}
int SuperWord::mark_generations() {
- Node *ii_err = 0, *tail_err;
+ Node *ii_err = NULL, *tail_err = NULL;
for (int i = 0; i < _mem_slice_head.length(); i++) {
Node* phi = _mem_slice_head.at(i);
assert(phi->is_Phi(), "must be phi");
--- a/hotspot/src/share/vm/prims/jni.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jni.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -563,7 +563,7 @@
// return mirror for superclass
Klass* super = k->java_super();
// super2 is the value computed by the compiler's getSuperClass intrinsic:
- debug_only(Klass* super2 = ( k->oop_is_array()
+ debug_only(Klass* super2 = ( k->is_array_klass()
? SystemDictionary::Object_klass()
: k->super() ) );
assert(super == super2,
@@ -1344,14 +1344,14 @@
if (name == vmSymbols::object_initializer_name() ||
name == vmSymbols::class_initializer_name()) {
// Never search superclasses for constructors
- if (klass->oop_is_instance()) {
+ if (klass->is_instance_klass()) {
m = InstanceKlass::cast(klass())->find_method(name, signature);
} else {
m = NULL;
}
} else {
m = klass->lookup_method(name, signature);
- if (m == NULL && klass->oop_is_instance()) {
+ if (m == NULL && klass->is_instance_klass()) {
m = InstanceKlass::cast(klass())->lookup_method_in_ordered_interfaces(name, signature);
}
}
@@ -2038,7 +2038,7 @@
k()->initialize(CHECK_NULL);
fieldDescriptor fd;
- if (!k()->oop_is_instance() ||
+ if (!k()->is_instance_klass() ||
!InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
@@ -2292,7 +2292,7 @@
k()->initialize(CHECK_NULL);
fieldDescriptor fd;
- if (!k()->oop_is_instance() ||
+ if (!k()->is_instance_klass() ||
!InstanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
}
@@ -2474,12 +2474,18 @@
typeArrayOop s_value = java_lang_String::value(s);
if (s_value != NULL) {
int s_len = java_lang_String::length(s);
- int s_offset = java_lang_String::offset(s);
+ bool is_latin1 = java_lang_String::is_latin1(s);
buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination
/* JNI Specification states return NULL on OOM */
if (buf != NULL) {
if (s_len > 0) {
- memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
+ if (!is_latin1) {
+ memcpy(buf, s_value->char_at_addr(0), sizeof(jchar)*s_len);
+ } else {
+ for (int i = 0; i < s_len; i++) {
+ buf[i] = ((jchar) s_value->byte_at(i)) & 0xff;
+ }
+ }
}
buf[s_len] = 0;
//%note jni_5
@@ -3045,7 +3051,7 @@
HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(env, clazz);
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
//%note jni_2
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) {
Method* m = InstanceKlass::cast(k)->methods()->at(index);
if (m->is_native()) {
@@ -3118,9 +3124,15 @@
THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
} else {
if (len > 0) {
- int s_offset = java_lang_String::offset(s);
typeArrayOop s_value = java_lang_String::value(s);
- memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);
+ bool is_latin1 = java_lang_String::is_latin1(s);
+ if (!is_latin1) {
+ memcpy(buf, s_value->char_at_addr(start), sizeof(jchar)*len);
+ } else {
+ for (int i = 0; i < len; i++) {
+ buf[i] = ((jchar) s_value->byte_at(i + start)) & 0xff;
+ }
+ }
}
}
JNI_END
@@ -3186,18 +3198,23 @@
JNIWrapper("GetStringCritical");
HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(env, string, (uintptr_t *) isCopy);
GC_locker::lock_critical(thread);
- if (isCopy != NULL) {
- *isCopy = JNI_FALSE;
- }
oop s = JNIHandles::resolve_non_null(string);
- int s_len = java_lang_String::length(s);
typeArrayOop s_value = java_lang_String::value(s);
- int s_offset = java_lang_String::offset(s);
+ bool is_latin1 = java_lang_String::is_latin1(s);
+ if (isCopy != NULL) {
+ *isCopy = is_latin1 ? JNI_TRUE : JNI_FALSE;
+ }
const jchar* ret;
- if (s_len > 0) {
- ret = s_value->char_at_addr(s_offset);
+ if (!is_latin1) {
+ ret = s_value->char_at_addr(0);
} else {
- ret = (jchar*) s_value->base(T_CHAR);
+ // Inflate latin1 encoded string to UTF16
+ int s_len = java_lang_String::length(s);
+ jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len, mtInternal);
+ for (int i = 0; i < s_len; i++) {
+ buf[i] = ((jchar) s_value->byte_at(i)) & 0xff;
+ }
+ ret = &buf[0];
}
HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN((uint16_t *) ret);
return ret;
@@ -3207,7 +3224,14 @@
JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
JNIWrapper("ReleaseStringCritical");
HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(env, str, (uint16_t *) chars);
- // The str and chars arguments are ignored
+ // The str and chars arguments are ignored for UTF16 strings
+ oop s = JNIHandles::resolve_non_null(str);
+ bool is_latin1 = java_lang_String::is_latin1(s);
+ if (is_latin1) {
+ // For latin1 string, free jchar array allocated by earlier call to GetStringCritical.
+ // This assumes that ReleaseStringCritical bookends GetStringCritical.
+ FREE_C_HEAP_ARRAY(jchar, chars);
+ }
GC_locker::unlock_critical(thread);
HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN();
JNI_END
@@ -3854,6 +3878,7 @@
unit_test_function_call
// Forward declaration
+void TestNmethodBucket_test();
void test_semaphore();
void TestOS_test();
void TestReservedSpace_test();
@@ -3877,11 +3902,13 @@
void FreeRegionList_test();
void test_memset_with_concurrent_readers();
void TestPredictions_test();
+void WorkerDataArray_test();
#endif
void execute_internal_vm_tests() {
if (ExecuteInternalVMTests) {
tty->print_cr("Running internal VM tests");
+ run_unit_test(TestNmethodBucket_test());
run_unit_test(test_semaphore());
run_unit_test(TestOS_test());
run_unit_test(TestReservedSpace_test());
@@ -3922,6 +3949,7 @@
}
run_unit_test(test_memset_with_concurrent_readers());
run_unit_test(TestPredictions_test());
+ run_unit_test(WorkerDataArray_test());
#endif
tty->print_cr("All internal VM tests passed");
}
@@ -4063,6 +4091,10 @@
OrderAccess::release_store(&vm_created, 0);
}
+ // Flush stdout and stderr before exit.
+ fflush(stdout);
+ fflush(stderr);
+
return result;
}
--- a/hotspot/src/share/vm/prims/jniCheck.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -514,7 +514,7 @@
ASSERT_OOPS_ALLOWED;
assert(klass != NULL, "klass argument must have a value");
- if (!klass->oop_is_instance() ||
+ if (!klass->is_instance_klass() ||
!InstanceKlass::cast(klass)->is_subclass_of(SystemDictionary::Throwable_klass())) {
ReportJNIFatalError(thr, fatal_class_not_a_throwable_class);
}
--- a/hotspot/src/share/vm/prims/jvm.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1022,10 +1022,10 @@
KlassHandle klass(thread, java_lang_Class::as_Klass(mirror));
// Figure size of result array
int size;
- if (klass->oop_is_instance()) {
+ if (klass->is_instance_klass()) {
size = InstanceKlass::cast(klass())->local_interfaces()->length();
} else {
- assert(klass->oop_is_objArray() || klass->oop_is_typeArray(), "Illegal mirror klass");
+ assert(klass->is_objArray_klass() || klass->is_typeArray_klass(), "Illegal mirror klass");
size = 2;
}
@@ -1033,7 +1033,7 @@
objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), size, CHECK_NULL);
objArrayHandle result (THREAD, r);
// Fill in result
- if (klass->oop_is_instance()) {
+ if (klass->is_instance_klass()) {
// Regular instance klass, fill in all local interfaces
for (int index = 0; index < size; index++) {
Klass* k = InstanceKlass::cast(klass())->local_interfaces()->at(index);
@@ -1056,7 +1056,7 @@
}
Klass* k = java_lang_Class::as_Klass(mirror);
jboolean result = k->is_interface();
- assert(!result || k->oop_is_instance(),
+ assert(!result || k->is_instance_klass(),
"all interfaces are instance types");
// The compiler intrinsic for isInterface tests the
// Klass::_access_flags bits in the same way.
@@ -1097,7 +1097,7 @@
// Signers are only set once, ClassLoader.java, and thus shouldn't
// be called with an array. Only the bootstrap loader creates arrays.
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers)));
}
}
@@ -1156,7 +1156,7 @@
// Create an AccessControlContext with a protection domain with null codesource
// and null permissions - which gives no permissions.
oop create_dummy_access_control_context(TRAPS) {
- InstanceKlass* pd_klass = InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass());
+ InstanceKlass* pd_klass = SystemDictionary::ProtectionDomain_klass();
Handle obj = pd_klass->allocate_instance_handle(CHECK_NULL);
// Call constructor ProtectionDomain(null, null);
JavaValue result(T_VOID);
@@ -1356,7 +1356,7 @@
JVM_QUICK_ENTRY(jboolean, JVM_IsArrayClass(JNIEnv *env, jclass cls))
JVMWrapper("JVM_IsArrayClass");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- return (k != NULL) && k->oop_is_array() ? true : false;
+ return (k != NULL) && k->is_array_klass() ? true : false;
JVM_END
@@ -1389,7 +1389,7 @@
// of an InstanceKlass
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
- ! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_instance()) {
+ ! 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);
}
@@ -1453,7 +1453,7 @@
{
// ofClass is a reference to a java_lang_Class object.
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
- ! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_instance()) {
+ ! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_instance_klass()) {
return NULL;
}
@@ -1471,7 +1471,7 @@
{
oop mirror = JNIHandles::resolve_non_null(cls);
if (java_lang_Class::is_primitive(mirror) ||
- !java_lang_Class::as_Klass(mirror)->oop_is_instance()) {
+ !java_lang_Class::as_Klass(mirror)->is_instance_klass()) {
return NULL;
}
instanceKlassHandle k(THREAD, InstanceKlass::cast(java_lang_Class::as_Klass(mirror)));
@@ -1496,7 +1496,7 @@
// Return null for arrays and primatives
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
Symbol* sym = InstanceKlass::cast(k)->generic_signature();
if (sym == NULL) return NULL;
Handle str = java_lang_String::create_from_symbol(sym, CHECK_NULL);
@@ -1514,7 +1514,7 @@
// Return null for arrays and primitives
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
- if (k->oop_is_instance()) {
+ 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);
}
@@ -1584,7 +1584,7 @@
// Return null for arrays and primitives
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
AnnotationArray* type_annotations = InstanceKlass::cast(k)->class_type_annotations();
if (type_annotations != NULL) {
typeArrayOop a = Annotations::make_java_array(type_annotations, CHECK_NULL);
@@ -1693,7 +1693,7 @@
// Exclude primitive types and array types
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
- java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {
+ 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);
@@ -1767,7 +1767,7 @@
// Exclude primitive types and array types
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass))
- || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) {
+ || 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);
@@ -1868,7 +1868,7 @@
// Return null for primitives and arrays
if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
instanceKlassHandle k_h(THREAD, k);
Handle jcp = sun_reflect_ConstantPool::create(CHECK_NULL);
sun_reflect_ConstantPool::set_cp(jcp(), k_h->constants());
@@ -2136,8 +2136,8 @@
if (java_lang_Class::is_primitive(r)) return false;
Klass* k = java_lang_Class::as_Klass(r);
- assert(k->oop_is_instance(), "must be an instance klass");
- if (! k->oop_is_instance()) return false;
+ assert(k->is_instance_klass(), "must be an instance klass");
+ if (!k->is_instance_klass()) return false;
ResourceMark rm(THREAD);
const char* name = k->name()->as_C_string();
@@ -2182,12 +2182,12 @@
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
// types will have length zero if this is not an InstanceKlass
// (length is determined by call to JVM_GetClassCPEntriesCount)
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
ConstantPool* cp = InstanceKlass::cast(k)->constants();
for (int index = cp->length() - 1; index >= 0; index--) {
constantTag tag = cp->tag_at(index);
types[index] = (tag.is_unresolved_klass()) ? JVM_CONSTANT_Class : tag.value();
- }
+ }
}
JVM_END
@@ -2196,9 +2196,7 @@
JVMWrapper("JVM_GetClassCPEntriesCount");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
- if (!k->oop_is_instance())
- return 0;
- return InstanceKlass::cast(k)->constants()->length();
+ return (!k->is_instance_klass()) ? 0 : InstanceKlass::cast(k)->constants()->length();
JVM_END
@@ -2206,9 +2204,7 @@
JVMWrapper("JVM_GetClassFieldsCount");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
- if (!k->oop_is_instance())
- return 0;
- return InstanceKlass::cast(k)->java_fields_count();
+ return (!k->is_instance_klass()) ? 0 : InstanceKlass::cast(k)->java_fields_count();
JVM_END
@@ -2216,9 +2212,7 @@
JVMWrapper("JVM_GetClassMethodsCount");
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
- if (!k->oop_is_instance())
- return 0;
- return InstanceKlass::cast(k)->methods()->length();
+ return (!k->is_instance_klass()) ? 0 : InstanceKlass::cast(k)->methods()->length();
JVM_END
@@ -3476,7 +3470,7 @@
KlassHandle klass_handle(THREAD, klass);
// Check if we should initialize the class
- if (init && klass_handle->oop_is_instance()) {
+ if (init && klass_handle->is_instance_klass()) {
klass_handle->initialize(CHECK_NULL);
}
return (jclass) JNIHandles::make_local(env, klass_handle->java_mirror());
@@ -3624,7 +3618,7 @@
return NULL;
}
Klass* k = java_lang_Class::as_Klass(mirror());
- if (!k->oop_is_instance()) {
+ if (!k->is_instance_klass()) {
return NULL;
}
instanceKlassHandle ik_h(THREAD, k);
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,7 +125,7 @@
// JVMSpec| u2 attributes_count;
// JVMSpec| attribute_info attributes[attributes_count];
// JVMSpec| }
-void JvmtiClassFileReconstituter::write_code_attribute(methodHandle method) {
+void JvmtiClassFileReconstituter::write_code_attribute(const methodHandle& method) {
ConstMethod* const_method = method->constMethod();
u2 line_num_cnt = 0;
int stackmap_len = 0;
@@ -415,7 +415,7 @@
}
// Compute size of LineNumberTable
-u2 JvmtiClassFileReconstituter::line_number_table_entries(methodHandle method) {
+u2 JvmtiClassFileReconstituter::line_number_table_entries(const methodHandle& method) {
// The line number table is compressed so we don't know how big it is until decompressed.
// Decompression is really fast so we just do it twice.
u2 num_entries = 0;
@@ -435,7 +435,7 @@
// JVMSpec| u2 line_number;
// JVMSpec| } line_number_table[line_number_table_length];
// JVMSpec| }
-void JvmtiClassFileReconstituter::write_line_number_table_attribute(methodHandle method,
+void JvmtiClassFileReconstituter::write_line_number_table_attribute(const methodHandle& method,
u2 num_entries) {
write_attribute_name_index("LineNumberTable");
@@ -461,7 +461,7 @@
// JVMSpec| u2 index;
// JVMSpec| } local_variable_table[local_variable_table_length];
// JVMSpec| }
-void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {
+void JvmtiClassFileReconstituter::write_local_variable_table_attribute(const methodHandle& method, u2 num_entries) {
write_attribute_name_index("LocalVariableTable");
write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
write_u2(num_entries);
@@ -491,7 +491,7 @@
// JVMSpec| u2 index;
// JVMSpec| } local_variable_type_table[local_variable_type_table_length];
// JVMSpec| }
-void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(methodHandle method, u2 num_entries) {
+void JvmtiClassFileReconstituter::write_local_variable_type_table_attribute(const methodHandle& method, u2 num_entries) {
write_attribute_name_index("LocalVariableTypeTable");
write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
write_u2(num_entries);
@@ -519,7 +519,7 @@
// JSR-202| u2 number_of_entries;
// JSR-202| stack_map_frame_entries[number_of_entries];
// JSR-202| }
-void JvmtiClassFileReconstituter::write_stackmap_table_attribute(methodHandle method,
+void JvmtiClassFileReconstituter::write_stackmap_table_attribute(const methodHandle& method,
int stackmap_len) {
write_attribute_name_index("StackMapTable");
@@ -538,7 +538,7 @@
// JVMSpec| u2 attributes_count;
// JVMSpec| attribute_info attributes[attributes_count];
// JVMSpec| }
-void JvmtiClassFileReconstituter::write_method_info(methodHandle method) {
+void JvmtiClassFileReconstituter::write_method_info(const methodHandle& method) {
AccessFlags access_flags = method->access_flags();
ConstMethod* const_method = method->constMethod();
u2 generic_signature_index = const_method->generic_signature_index();
@@ -813,7 +813,7 @@
Bytes::put_Java_u8(writeable_address(8), x);
}
-void JvmtiClassFileReconstituter::copy_bytecodes(methodHandle mh,
+void JvmtiClassFileReconstituter::copy_bytecodes(const methodHandle& mh,
unsigned char* bytecodes) {
// use a BytecodeStream to iterate over the bytecodes. JVM/fast bytecodes
// and the breakpoint bytecode are converted to their original bytecodes.
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -110,18 +110,18 @@
void write_class_file_format();
void write_field_infos();
void write_method_infos();
- void write_method_info(methodHandle method);
- void write_code_attribute(methodHandle method);
+ void write_method_info(const methodHandle& method);
+ void write_code_attribute(const methodHandle& method);
void write_exceptions_attribute(ConstMethod* const_method);
void write_synthetic_attribute();
void write_class_attributes();
void write_source_file_attribute();
void write_source_debug_extension_attribute();
- u2 line_number_table_entries(methodHandle method);
- void write_line_number_table_attribute(methodHandle method, u2 num_entries);
- void write_local_variable_table_attribute(methodHandle method, u2 num_entries);
- void write_local_variable_type_table_attribute(methodHandle method, u2 num_entries);
- void write_stackmap_table_attribute(methodHandle method, int stackmap_table_len);
+ u2 line_number_table_entries(const methodHandle& method);
+ void write_line_number_table_attribute(const methodHandle& method, u2 num_entries);
+ void write_local_variable_table_attribute(const methodHandle& method, u2 num_entries);
+ void write_local_variable_type_table_attribute(const methodHandle& method, u2 num_entries);
+ void write_stackmap_table_attribute(const methodHandle& method, int stackmap_table_len);
u2 inner_classes_attribute_length();
void write_inner_classes_attribute(int length);
void write_signature_attribute(u2 generic_signaure_index);
@@ -150,7 +150,7 @@
u1* class_file_bytes() { return _buffer; }
- static void copy_bytecodes(methodHandle method, unsigned char* bytecodes);
+ static void copy_bytecodes(const methodHandle& method, unsigned char* bytecodes);
};
#endif // SHARE_VM_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP
--- a/hotspot/src/share/vm/prims/jvmtiEnter.xsl Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnter.xsl Wed Jul 05 21:00:20 2017 +0200
@@ -629,8 +629,8 @@
jint trace_flags = JvmtiTrace::trace_flags(</xsl:text>
<xsl:value-of select="@num"/>
<xsl:text>);
- const char *func_name;
- const char *curr_thread_name;
+ const char *func_name = NULL;
+ const char *curr_thread_name = NULL;
if (trace_flags) {
func_name = JvmtiTrace::function_name(</xsl:text>
<xsl:value-of select="@num"/>
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -966,7 +966,7 @@
if (name() != NULL) {
n = java_lang_String::as_utf8_string(name());
} else {
- n = UNICODE::as_utf8(NULL, 0);
+ n = UNICODE::as_utf8((jchar*) NULL, 0);
}
info_ptr->name = (char *) jvmtiMalloc(strlen(n)+1);
@@ -1187,15 +1187,14 @@
Handle group_obj (current_thread, JNIHandles::resolve_external_guard(group));
NULL_CHECK(group_obj(), JVMTI_ERROR_INVALID_THREAD_GROUP);
- typeArrayHandle name;
+ const char* name;
Handle parent_group;
bool is_daemon;
ThreadPriority max_priority;
{ MutexLocker mu(Threads_lock);
- name = typeArrayHandle(current_thread,
- java_lang_ThreadGroup::name(group_obj()));
+ name = java_lang_ThreadGroup::name(group_obj());
parent_group = Handle(current_thread, java_lang_ThreadGroup::parent(group_obj()));
is_daemon = java_lang_ThreadGroup::is_daemon(group_obj());
max_priority = java_lang_ThreadGroup::maxPriority(group_obj());
@@ -1205,11 +1204,10 @@
info_ptr->max_priority = max_priority;
info_ptr->parent = jni_reference(parent_group);
- if (name() != NULL) {
- const char* n = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
- info_ptr->name = (char *)jvmtiMalloc(strlen(n)+1);
+ if (name != NULL) {
+ info_ptr->name = (char*)jvmtiMalloc(strlen(name)+1);
NULL_CHECK(info_ptr->name, JVMTI_ERROR_OUT_OF_MEMORY);
- strcpy(info_ptr->name, n);
+ strcpy(info_ptr->name, name);
} else {
info_ptr->name = NULL;
}
@@ -2139,7 +2137,7 @@
}
if (generic_ptr != NULL) {
*generic_ptr = NULL;
- if (!isPrimitive && k->oop_is_instance()) {
+ if (!isPrimitive && k->is_instance_klass()) {
Symbol* soo = InstanceKlass::cast(k)->generic_signature();
if (soo != NULL) {
const char *gen_sig = soo->as_C_string();
@@ -2188,7 +2186,7 @@
Klass* k_klass = java_lang_Class::as_Klass(k_mirror);
NULL_CHECK(k_klass, JVMTI_ERROR_INVALID_CLASS);
- if (!k_klass->oop_is_instance()) {
+ if (!k_klass->is_instance_klass()) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
@@ -2256,7 +2254,7 @@
return JVMTI_ERROR_CLASS_NOT_PREPARED;
}
- if (!k->oop_is_instance()) {
+ if (!k->is_instance_klass()) {
*method_count_ptr = 0;
*methods_ptr = (jmethodID*) jvmtiMalloc(0 * sizeof(jmethodID));
return JVMTI_ERROR_NONE;
@@ -2340,7 +2338,7 @@
return JVMTI_ERROR_CLASS_NOT_PREPARED;
}
- if (!k->oop_is_instance()) {
+ if (!k->is_instance_klass()) {
*field_count_ptr = 0;
*fields_ptr = (jfieldID*) jvmtiMalloc(0 * sizeof(jfieldID));
return JVMTI_ERROR_NONE;
@@ -2394,7 +2392,7 @@
if (!(k->jvmti_class_status() & (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY) ))
return JVMTI_ERROR_CLASS_NOT_PREPARED;
- if (!k->oop_is_instance()) {
+ if (!k->is_instance_klass()) {
*interface_count_ptr = 0;
*interfaces_ptr = (jclass*) jvmtiMalloc(0 * sizeof(jclass));
return JVMTI_ERROR_NONE;
@@ -2528,7 +2526,7 @@
bool result = false;
if (!java_lang_Class::is_primitive(k_mirror)) {
Klass* k = java_lang_Class::as_Klass(k_mirror);
- if (k != NULL && k->oop_is_array()) {
+ if (k != NULL && k->is_array_klass()) {
result = true;
}
}
@@ -2576,7 +2574,7 @@
}
Klass* k = java_lang_Class::as_Klass(k_mirror);
NULL_CHECK(k, JVMTI_ERROR_INVALID_CLASS);
- if (!k->oop_is_instance()) {
+ if (!k->is_instance_klass()) {
return JVMTI_ERROR_ABSENT_INFORMATION;
}
char* sde = InstanceKlass::cast(k)->source_debug_extension();
@@ -3064,7 +3062,7 @@
// in thread.cpp.
JvmtiPendingMonitors::enter(rmonitor);
} else {
- int r;
+ int r = 0;
Thread* thread = Thread::current();
if (thread->is_Java_thread()) {
@@ -3127,7 +3125,7 @@
err = JVMTI_ERROR_NOT_MONITOR_OWNER;
}
} else {
- int r;
+ int r = 0;
Thread* thread = Thread::current();
if (thread->is_Java_thread()) {
@@ -3161,7 +3159,7 @@
// rmonitor - pre-checked for validity
jvmtiError
JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {
- int r;
+ int r = 0;
Thread* thread = Thread::current();
if (thread->is_Java_thread()) {
@@ -3220,7 +3218,7 @@
// rmonitor - pre-checked for validity
jvmtiError
JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
- int r;
+ int r = 0;
Thread* thread = Thread::current();
if (thread->is_Java_thread()) {
@@ -3251,7 +3249,7 @@
// rmonitor - pre-checked for validity
jvmtiError
JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {
- int r;
+ int r = 0;
Thread* thread = Thread::current();
if (thread->is_Java_thread()) {
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -512,7 +512,7 @@
// mean much better out of memory handling
unsigned char *
JvmtiEnvBase::jvmtiMalloc(jlong size) {
- unsigned char* mem;
+ unsigned char* mem = NULL;
jvmtiError result = allocate(size, &mem);
assert(result == JVMTI_ERROR_NONE, "Allocate failed");
return mem;
@@ -1032,7 +1032,7 @@
// implied else: entry_count == 0
}
- jint nWant, nWait;
+ jint nWant = 0, nWait = 0;
if (mon != NULL) {
// this object has a heavyweight monitor
nWant = mon->contentions(); // # of threads contending for monitor
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -104,7 +104,7 @@
ClassLoaderData* cld = _scratch_classes[i]->class_loader_data();
// Free the memory for this class at class unloading time. Not before
// because CMS might think this is still live.
- cld->add_to_deallocate_list((InstanceKlass*)_scratch_classes[i]);
+ cld->add_to_deallocate_list(InstanceKlass::cast(_scratch_classes[i]));
}
}
// Free os::malloc allocated memory in load_new_class_version.
@@ -199,7 +199,7 @@
}
Klass* the_class_oop = java_lang_Class::as_Klass(klass_mirror);
// classes for arrays cannot be redefined
- if (the_class_oop == NULL || !the_class_oop->oop_is_instance()) {
+ if (the_class_oop == NULL || !the_class_oop->is_instance_klass()) {
return false;
}
return true;
@@ -216,7 +216,7 @@
// referenced CP entries may already exist in *merge_cp_p in which case
// there is nothing extra to append and only the current entry is
// appended.
-void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
+void VM_RedefineClasses::append_entry(const constantPoolHandle& scratch_cp,
int scratch_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p,
TRAPS) {
@@ -336,7 +336,7 @@
int new_name_and_type_ref_i = find_or_append_indirect_entry(scratch_cp, name_and_type_ref_i,
merge_cp_p, merge_cp_length_p, THREAD);
- const char *entry_name;
+ const char *entry_name = NULL;
switch (scratch_cp->tag_at(scratch_i).value()) {
case JVM_CONSTANT_Fieldref:
entry_name = "Fieldref";
@@ -475,7 +475,7 @@
} // end append_entry()
-int VM_RedefineClasses::find_or_append_indirect_entry(constantPoolHandle scratch_cp,
+int VM_RedefineClasses::find_or_append_indirect_entry(const constantPoolHandle& scratch_cp,
int ref_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
int new_ref_i = ref_i;
@@ -507,7 +507,7 @@
// Append a bootstrap specifier into the merge_cp operands that is semantically equal
// to the scratch_cp operands bootstrap specifier passed by the old_bs_i index.
// Recursively append new merge_cp entries referenced by the new bootstrap specifier.
-void VM_RedefineClasses::append_operand(constantPoolHandle scratch_cp, int old_bs_i,
+void VM_RedefineClasses::append_operand(const constantPoolHandle& scratch_cp, int old_bs_i,
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
int old_ref_i = scratch_cp->operand_bootstrap_method_ref_index_at(old_bs_i);
@@ -551,7 +551,7 @@
} // end append_operand()
-int VM_RedefineClasses::find_or_append_operand(constantPoolHandle scratch_cp,
+int VM_RedefineClasses::find_or_append_operand(const constantPoolHandle& scratch_cp,
int old_bs_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS) {
int new_bs_i = old_bs_i; // bootstrap specifier index
@@ -577,7 +577,7 @@
} // end find_or_append_operand()
-void VM_RedefineClasses::finalize_operands_merge(constantPoolHandle merge_cp, TRAPS) {
+void VM_RedefineClasses::finalize_operands_merge(const constantPoolHandle& merge_cp, TRAPS) {
if (merge_cp->operands() == NULL) {
return;
}
@@ -910,8 +910,8 @@
// Returns true if the current mismatch is due to a resolved/unresolved
// class pair. Otherwise, returns false.
-bool VM_RedefineClasses::is_unresolved_class_mismatch(constantPoolHandle cp1,
- int index1, constantPoolHandle cp2, int index2) {
+bool VM_RedefineClasses::is_unresolved_class_mismatch(const constantPoolHandle& cp1,
+ int index1, const constantPoolHandle& cp2, int index2) {
jbyte t1 = cp1->tag_at(index1).value();
if (t1 != JVM_CONSTANT_Class && t1 != JVM_CONSTANT_UnresolvedClass) {
@@ -1149,7 +1149,7 @@
// Map old_index to new_index as needed. scratch_cp is only needed
// for RC_TRACE() calls.
-void VM_RedefineClasses::map_index(constantPoolHandle scratch_cp,
+void VM_RedefineClasses::map_index(const constantPoolHandle& scratch_cp,
int old_index, int new_index) {
if (find_new_index(old_index) != 0) {
// old_index is already mapped
@@ -1195,8 +1195,8 @@
// scratch_cp to the corresponding entry in *merge_cp_p. Index map
// entries are only created for entries in scratch_cp that occupy a
// different location in *merged_cp_p.
-bool VM_RedefineClasses::merge_constant_pools(constantPoolHandle old_cp,
- constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p,
+bool VM_RedefineClasses::merge_constant_pools(const constantPoolHandle& old_cp,
+ const constantPoolHandle& scratch_cp, constantPoolHandle *merge_cp_p,
int *merge_cp_length_p, TRAPS) {
if (merge_cp_p == NULL) {
@@ -1892,7 +1892,7 @@
}
u2 type_index = rewrite_cp_ref_in_annotation_data(annotations_typeArray,
- byte_i_ref, "mapped old type_index=%d", THREAD);
+ byte_i_ref, "type_index", THREAD);
u2 num_element_value_pairs = Bytes::get_Java_u2((address)
annotations_typeArray->adr_at(byte_i_ref));
@@ -1915,7 +1915,7 @@
u2 element_name_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref,
- "mapped old element_name_index=%d", THREAD);
+ "element_name_index", THREAD);
RC_TRACE_WITH_THREAD(0x02000000, THREAD,
("element_name_index=%d", element_name_index));
@@ -1939,8 +1939,6 @@
// annotations_typeArray if needed. Returns the original constant
// pool reference if a rewrite was not needed or the new constant
// pool reference if a rewrite was needed.
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED
u2 VM_RedefineClasses::rewrite_cp_ref_in_annotation_data(
AnnotationArray* annotations_typeArray, int &byte_i_ref,
const char * trace_mesg, TRAPS) {
@@ -1950,14 +1948,13 @@
u2 old_cp_index = Bytes::get_Java_u2(cp_index_addr);
u2 new_cp_index = find_new_index(old_cp_index);
if (new_cp_index != 0) {
- RC_TRACE_WITH_THREAD(0x02000000, THREAD, (trace_mesg, old_cp_index));
+ RC_TRACE_WITH_THREAD(0x02000000, THREAD, ("mapped old %s=%d", trace_mesg, old_cp_index));
Bytes::put_Java_u2(cp_index_addr, new_cp_index);
old_cp_index = new_cp_index;
}
byte_i_ref += 2;
return old_cp_index;
}
-PRAGMA_DIAG_POP
// Rewrite constant pool references in the element_value portion of an
@@ -2022,7 +2019,7 @@
u2 const_value_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref,
- "mapped old const_value_index=%d", THREAD);
+ "const_value_index", THREAD);
RC_TRACE_WITH_THREAD(0x02000000, THREAD,
("const_value_index=%d", const_value_index));
@@ -2041,11 +2038,11 @@
u2 type_name_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref,
- "mapped old type_name_index=%d", THREAD);
+ "type_name_index", THREAD);
u2 const_name_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref,
- "mapped old const_name_index=%d", THREAD);
+ "const_name_index", THREAD);
RC_TRACE_WITH_THREAD(0x02000000, THREAD,
("type_name_index=%d const_name_index=%d", type_name_index,
@@ -2065,7 +2062,7 @@
u2 class_info_index = rewrite_cp_ref_in_annotation_data(
annotations_typeArray, byte_i_ref,
- "mapped old class_info_index=%d", THREAD);
+ "class_info_index", THREAD);
RC_TRACE_WITH_THREAD(0x02000000, THREAD,
("class_info_index=%d", class_info_index));
@@ -2867,7 +2864,7 @@
// }
//
void VM_RedefineClasses::rewrite_cp_refs_in_stack_map_table(
- methodHandle method, TRAPS) {
+ const methodHandle& method, TRAPS) {
if (!method->has_stackmap_table()) {
return;
@@ -3339,10 +3336,10 @@
// If the class being redefined is java.lang.Object, we need to fix all
// array class vtables also
- if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) {
+ if (k->is_array_klass() && _the_class_oop == SystemDictionary::Object_klass()) {
k->vtable()->adjust_method_entries(the_class, &trace_name_printed);
- } else if (k->oop_is_instance()) {
+ } else if (k->is_instance_klass()) {
HandleMark hm(_thread);
InstanceKlass *ik = InstanceKlass::cast(k);
@@ -3379,7 +3376,7 @@
// default_vtable_indices for methods already in the vtable.
// If redefining Unsafe, walk all the vtables looking for entries.
if (ik->vtable_length() > 0 && (_the_class_oop->is_interface()
- || _the_class_oop == SystemDictionary::misc_Unsafe_klass()
+ || _the_class_oop == SystemDictionary::internal_Unsafe_klass()
|| ik->is_subtype_of(_the_class_oop))) {
// ik->vtable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread);
@@ -3396,7 +3393,7 @@
// subclass relationship between an interface and an InstanceKlass.
// If redefining Unsafe, walk all the itables looking for entries.
if (ik->itable_length() > 0 && (_the_class_oop->is_interface()
- || _the_class_oop == SystemDictionary::misc_Unsafe_klass()
+ || _the_class_oop == SystemDictionary::internal_Unsafe_klass()
|| ik->is_subclass_of(_the_class_oop))) {
// ik->itable() creates a wrapper object; rm cleans it up
ResourceMark rm(_thread);
@@ -3443,7 +3440,7 @@
// Clean method data for this class
void VM_RedefineClasses::MethodDataCleaner::do_klass(Klass* k) {
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
InstanceKlass *ik = InstanceKlass::cast(k);
// Clean MethodData of this class's methods so they don't refer to
// old methods that are no longer running.
@@ -4131,9 +4128,9 @@
for (Klass *subk = ik->subklass(); subk != NULL;
subk = subk->next_sibling()) {
- if (subk->oop_is_instance()) {
+ if (subk->is_instance_klass()) {
// Only update instanceKlasses
- InstanceKlass *subik = (InstanceKlass*)subk;
+ InstanceKlass *subik = InstanceKlass::cast(subk);
// recursively do subclasses of the current subclass
increment_class_counter(subik, THREAD);
}
@@ -4158,7 +4155,7 @@
no_old_methods = false;
}
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
HandleMark hm(_thread);
InstanceKlass *ik = InstanceKlass::cast(k);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -420,23 +420,23 @@
void increment_class_counter(InstanceKlass *ik, TRAPS);
// Support for constant pool merging (these routines are in alpha order):
- void append_entry(constantPoolHandle scratch_cp, int scratch_i,
+ void append_entry(const constantPoolHandle& scratch_cp, int scratch_i,
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
- void append_operand(constantPoolHandle scratch_cp, int scratch_bootstrap_spec_index,
+ void append_operand(const constantPoolHandle& scratch_cp, int scratch_bootstrap_spec_index,
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
- void finalize_operands_merge(constantPoolHandle merge_cp, TRAPS);
- int find_or_append_indirect_entry(constantPoolHandle scratch_cp, int scratch_i,
+ void finalize_operands_merge(const constantPoolHandle& merge_cp, TRAPS);
+ int find_or_append_indirect_entry(const constantPoolHandle& scratch_cp, int scratch_i,
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
- int find_or_append_operand(constantPoolHandle scratch_cp, int scratch_bootstrap_spec_index,
+ int find_or_append_operand(const constantPoolHandle& scratch_cp, int scratch_bootstrap_spec_index,
constantPoolHandle *merge_cp_p, int *merge_cp_length_p, TRAPS);
int find_new_index(int old_index);
int find_new_operand_index(int old_bootstrap_spec_index);
- bool is_unresolved_class_mismatch(constantPoolHandle cp1, int index1,
- constantPoolHandle cp2, int index2);
- void map_index(constantPoolHandle scratch_cp, int old_index, int new_index);
+ bool is_unresolved_class_mismatch(const constantPoolHandle& cp1, int index1,
+ const constantPoolHandle& cp2, int index2);
+ void map_index(const constantPoolHandle& scratch_cp, int old_index, int new_index);
void map_operand_index(int old_bootstrap_spec_index, int new_bootstrap_spec_index);
- bool merge_constant_pools(constantPoolHandle old_cp,
- constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p,
+ bool merge_constant_pools(const constantPoolHandle& old_cp,
+ const constantPoolHandle& scratch_cp, constantPoolHandle *merge_cp_p,
int *merge_cp_length_p, TRAPS);
jvmtiError merge_cp_and_rewrite(instanceKlassHandle the_class,
instanceKlassHandle scratch_class, TRAPS);
@@ -480,7 +480,7 @@
instanceKlassHandle scratch_class, TRAPS);
bool rewrite_cp_refs_in_methods_type_annotations(
instanceKlassHandle scratch_class, TRAPS);
- void rewrite_cp_refs_in_stack_map_table(methodHandle method, TRAPS);
+ void rewrite_cp_refs_in_stack_map_table(const methodHandle& method, TRAPS);
void rewrite_cp_refs_in_verification_type_info(
address& stackmap_addr_ref, address stackmap_end, u2 frame_i,
u1 frame_size, TRAPS);
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -588,7 +588,7 @@
_obj_tag = (_entry == NULL) ? 0 : _entry->tag();
// get the class and the class's tag value
- assert(InstanceKlass::cast(SystemDictionary::Class_klass())->is_mirror_instance_klass(), "Is not?");
+ assert(SystemDictionary::Class_klass()->is_mirror_instance_klass(), "Is not?");
_klass_tag = tag_for(tag_map, _o->klass()->java_mirror());
}
@@ -1057,21 +1057,36 @@
// get the string value and length
// (string value may be offset from the base)
int s_len = java_lang_String::length(str);
- int s_offset = java_lang_String::offset(str);
+ bool is_latin1 = java_lang_String::is_latin1(str);
jchar* value;
if (s_len > 0) {
- value = s_value->char_at_addr(s_offset);
+ if (!is_latin1) {
+ value = s_value->char_at_addr(0);
+ } else {
+ // Inflate latin1 encoded string to UTF16
+ jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len, mtInternal);
+ for (int i = 0; i < s_len; i++) {
+ buf[i] = ((jchar) s_value->byte_at(i)) & 0xff;
+ }
+ value = &buf[0];
+ }
} else {
+ // Don't use char_at_addr(0) if length is 0
value = (jchar*) s_value->base(T_CHAR);
}
// invoke the callback
- return (*cb)(wrapper->klass_tag(),
- wrapper->obj_size(),
- wrapper->obj_tag_p(),
- value,
- (jint)s_len,
- user_data);
+ jint res = (*cb)(wrapper->klass_tag(),
+ wrapper->obj_size(),
+ wrapper->obj_tag_p(),
+ value,
+ (jint)s_len,
+ user_data);
+
+ if (is_latin1 && s_len > 0) {
+ FREE_C_HEAP_ARRAY(jchar, value);
+ }
+ return res;
}
// helper function to invoke string primitive value callback
@@ -1118,7 +1133,7 @@
Klass* klass = java_lang_Class::as_Klass(obj);
// ignore classes for object and type arrays
- if (!klass->oop_is_instance()) {
+ if (!klass->is_instance_klass()) {
return 0;
}
@@ -2569,7 +2584,7 @@
// SystemDictionary::always_strong_oops_do reports the application
// class loader as a root. We want this root to be reported as
// a root kind of "OTHER" rather than "SYSTEM_CLASS".
- if (!o->is_instanceMirror()) {
+ if (!o->is_instance() || !InstanceKlass::cast(o->klass())->is_mirror_instance_klass()) {
kind = JVMTI_HEAP_REFERENCE_OTHER;
}
}
@@ -2821,7 +2836,7 @@
int i;
Klass* klass = java_lang_Class::as_Klass(java_class);
- if (klass->oop_is_instance()) {
+ if (klass->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(klass);
// Ignore the class if it hasn't been initialized yet
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -148,7 +148,7 @@
oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
int slot = java_lang_reflect_Field::slot(target_oop); // fd.index()
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
- if (!k.is_null() && k->oop_is_instance()) {
+ if (!k.is_null() && k->is_instance_klass()) {
fieldDescriptor fd(InstanceKlass::cast(k()), slot);
oop mname2 = init_field_MemberName(mname, fd);
if (mname2 != NULL) {
@@ -164,7 +164,7 @@
oop clazz = java_lang_reflect_Method::clazz(target_oop);
int slot = java_lang_reflect_Method::slot(target_oop);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
- if (!k.is_null() && k->oop_is_instance()) {
+ if (!k.is_null() && k->is_instance_klass()) {
Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
if (m == NULL || is_signature_polymorphic(m->intrinsic_id()))
return NULL; // do not resolve unless there is a concrete signature
@@ -175,7 +175,7 @@
oop clazz = java_lang_reflect_Constructor::clazz(target_oop);
int slot = java_lang_reflect_Constructor::slot(target_oop);
KlassHandle k(thread, java_lang_Class::as_Klass(clazz));
- if (!k.is_null() && k->oop_is_instance()) {
+ if (!k.is_null() && k->is_instance_klass()) {
Method* m = InstanceKlass::cast(k())->method_with_idnum(slot);
if (m == NULL) return NULL;
CallInfo info(m, k());
@@ -637,8 +637,8 @@
{
Klass* defc_klass = java_lang_Class::as_Klass(defc_oop());
if (defc_klass == NULL) return empty; // a primitive; no resolution possible
- if (!defc_klass->oop_is_instance()) {
- if (!defc_klass->oop_is_array()) return empty;
+ if (!defc_klass->is_instance_klass()) {
+ if (!defc_klass->is_array_klass()) return empty;
defc_klass = SystemDictionary::Object_klass();
}
defc = instanceKlassHandle(THREAD, defc_klass);
@@ -804,7 +804,7 @@
case IS_FIELD:
{
assert(vmtarget->is_klass(), "field vmtarget is Klass*");
- if (!((Klass*) vmtarget)->oop_is_instance()) break;
+ if (!((Klass*) vmtarget)->is_instance_klass()) break;
instanceKlassHandle defc(THREAD, (Klass*) vmtarget);
DEBUG_ONLY(vmtarget = NULL); // safety
bool is_static = ((flags & JVM_ACC_STATIC) != 0);
@@ -841,7 +841,7 @@
Thread* thread = Thread::current();
- if (k.is_null() || !k->oop_is_instance()) return -1;
+ if (k.is_null() || !k->is_instance_klass()) return -1;
int rfill = 0, rlimit = results->length(), rskip = skip;
// overflow measurement:
@@ -1164,12 +1164,12 @@
if (VerifyMethodHandles && caller_jh != NULL &&
java_lang_invoke_MemberName::clazz(mname()) != NULL) {
Klass* reference_klass = java_lang_Class::as_Klass(java_lang_invoke_MemberName::clazz(mname()));
- if (reference_klass != NULL && reference_klass->oop_is_objArray()) {
+ if (reference_klass != NULL && reference_klass->is_objArray_klass()) {
reference_klass = ObjArrayKlass::cast(reference_klass)->bottom_klass();
}
// Reflection::verify_class_access can only handle instance classes.
- if (reference_klass != NULL && reference_klass->oop_is_instance()) {
+ if (reference_klass != NULL && reference_klass->is_instance_klass()) {
// Emulate LinkResolver::check_klass_accessability.
Klass* caller = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(caller_jh));
if (!Reflection::verify_class_access(caller,
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -67,7 +67,7 @@
}
-char* NativeLookup::pure_jni_name(methodHandle method) {
+char* NativeLookup::pure_jni_name(const methodHandle& method) {
stringStream st;
// Prefix
st.print("Java_");
@@ -80,7 +80,7 @@
}
-char* NativeLookup::critical_jni_name(methodHandle method) {
+char* NativeLookup::critical_jni_name(const methodHandle& method) {
stringStream st;
// Prefix
st.print("JavaCritical_");
@@ -93,7 +93,7 @@
}
-char* NativeLookup::long_jni_name(methodHandle method) {
+char* NativeLookup::long_jni_name(const methodHandle& method) {
// Signature ignore the wrapping parenteses and the trailing return type
stringStream st;
Symbol* signature = method->signature();
@@ -121,6 +121,7 @@
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
static JNINativeMethod lookup_special_native_methods[] = {
+ { CC"Java_jdk_internal_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
{ CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
{ CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
{ CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) },
@@ -142,7 +143,7 @@
return NULL;
}
-address NativeLookup::lookup_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
+address NativeLookup::lookup_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
address entry;
// Compute complete JNI name for style
stringStream st;
@@ -199,7 +200,7 @@
}
-address NativeLookup::lookup_critical_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style) {
+address NativeLookup::lookup_critical_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style) {
if (!method->has_native_function()) {
return NULL;
}
@@ -229,7 +230,7 @@
// Check all the formats of native implementation name to see if there is one
// for the specified method.
-address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) {
+address NativeLookup::lookup_entry(const methodHandle& method, bool& in_base_library, TRAPS) {
address entry = NULL;
in_base_library = false;
// Compute pure name
@@ -264,7 +265,7 @@
// Check all the formats of native implementation name to see if there is one
// for the specified method.
-address NativeLookup::lookup_critical_entry(methodHandle method) {
+address NativeLookup::lookup_critical_entry(const methodHandle& method) {
if (!CriticalJNINatives) return NULL;
if (method->is_synchronized() ||
@@ -318,7 +319,7 @@
// If any are found, remove them before attemping the look up of the
// native implementation again.
// See SetNativeMethodPrefix in the JVM TI Spec for more details.
-address NativeLookup::lookup_entry_prefixed(methodHandle method, bool& in_base_library, TRAPS) {
+address NativeLookup::lookup_entry_prefixed(const methodHandle& method, bool& in_base_library, TRAPS) {
#if INCLUDE_JVMTI
ResourceMark rm(THREAD);
@@ -354,7 +355,7 @@
return NULL;
}
-address NativeLookup::lookup_base(methodHandle method, bool& in_base_library, TRAPS) {
+address NativeLookup::lookup_base(const methodHandle& method, bool& in_base_library, TRAPS) {
address entry = NULL;
ResourceMark rm(THREAD);
@@ -372,7 +373,7 @@
}
-address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
+address NativeLookup::lookup(const methodHandle& method, bool& in_base_library, TRAPS) {
if (!method->has_native_function()) {
address entry = lookup_base(method, in_base_library, CHECK_NULL);
method->set_native_function(entry,
--- a/hotspot/src/share/vm/prims/nativeLookup.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/nativeLookup.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,20 +34,20 @@
class NativeLookup : AllStatic {
private:
// JNI name computation
- static char* pure_jni_name(methodHandle method);
- static char* long_jni_name(methodHandle method);
- static char* critical_jni_name(methodHandle method);
+ static char* pure_jni_name(const methodHandle& method);
+ static char* long_jni_name(const methodHandle& method);
+ static char* critical_jni_name(const methodHandle& method);
// Style specific lookup
- static address lookup_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS);
- static address lookup_critical_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style);
- static address lookup_base (methodHandle method, bool& in_base_library, TRAPS);
- static address lookup_entry(methodHandle method, bool& in_base_library, TRAPS);
- static address lookup_entry_prefixed(methodHandle method, bool& in_base_library, TRAPS);
+ static address lookup_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS);
+ static address lookup_critical_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style);
+ static address lookup_base (const methodHandle& method, bool& in_base_library, TRAPS);
+ static address lookup_entry(const methodHandle& method, bool& in_base_library, TRAPS);
+ static address lookup_entry_prefixed(const methodHandle& method, bool& in_base_library, TRAPS);
public:
// Lookup native function. May throw UnsatisfiedLinkError.
- static address lookup(methodHandle method, bool& in_base_library, TRAPS);
- static address lookup_critical_entry(methodHandle method);
+ static address lookup(const methodHandle& method, bool& in_base_library, TRAPS);
+ static address lookup_critical_entry(const methodHandle& method);
// Lookup native functions in base library.
static address base_library_lookup(const char* class_name, const char* method_name, const char* signature);
--- a/hotspot/src/share/vm/prims/unsafe.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -45,7 +45,7 @@
#endif // INCLUDE_ALL_GCS
/*
- * Implementation of class sun.misc.Unsafe
+ * Implementation of class Unsafe
*/
@@ -766,12 +766,12 @@
}
oop mirror = JNIHandles::resolve_non_null(acls);
Klass* k = java_lang_Class::as_Klass(mirror);
- if (k == NULL || !k->oop_is_array()) {
+ if (k == NULL || !k->is_array_klass()) {
THROW(vmSymbols::java_lang_InvalidClassException());
- } else if (k->oop_is_objArray()) {
+ } else if (k->is_objArray_klass()) {
base = arrayOopDesc::base_offset_in_bytes(T_OBJECT);
scale = heapOopSize;
- } else if (k->oop_is_typeArray()) {
+ } else if (k->is_typeArray_klass()) {
TypeArrayKlass* tak = TypeArrayKlass::cast(k);
base = tak->array_header_in_bytes();
assert(base == arrayOopDesc::base_offset_in_bytes(tak->element_type()), "array_header_size semantics ok");
@@ -783,7 +783,7 @@
UNSAFE_ENTRY(jint, Unsafe_ArrayBaseOffset(JNIEnv *env, jobject unsafe, jclass acls))
UnsafeWrapper("Unsafe_ArrayBaseOffset");
- int base, scale;
+ int base = 0, scale = 0;
getBaseAndScale(base, scale, acls, CHECK_0);
return field_offset_from_byte_offset(base);
UNSAFE_END
@@ -791,7 +791,7 @@
UNSAFE_ENTRY(jint, Unsafe_ArrayIndexScale(JNIEnv *env, jobject unsafe, jclass acls))
UnsafeWrapper("Unsafe_ArrayIndexScale");
- int base, scale;
+ int base = 0, scale = 0;
getBaseAndScale(base, scale, acls, CHECK_0);
// This VM packs both fields and array elements down to the byte.
// But watch out: If this changes, so that array references for
--- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1028,17 +1028,19 @@
CodeBlobStub(const CodeBlob* blob) :
name(os::strdup(blob->name())),
size(blob->size()),
- blob_type(WhiteBox::get_blob_type(blob)) { }
+ blob_type(WhiteBox::get_blob_type(blob)),
+ address((jlong) blob) { }
~CodeBlobStub() { os::free((void*) name); }
const char* const name;
- const int size;
- const int blob_type;
+ const jint size;
+ const jint blob_type;
+ const jlong address;
};
static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) {
jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
CHECK_JNI_EXCEPTION_(env, NULL);
- jobjectArray result = env->NewObjectArray(3, clazz, NULL);
+ jobjectArray result = env->NewObjectArray(4, clazz, NULL);
jstring name = env->NewStringUTF(cb->name);
CHECK_JNI_EXCEPTION_(env, NULL);
@@ -1052,6 +1054,10 @@
CHECK_JNI_EXCEPTION_(env, NULL);
env->SetObjectArrayElement(result, 2, obj);
+ obj = longBox(thread, env, cb->address);
+ CHECK_JNI_EXCEPTION_(env, NULL);
+ env->SetObjectArrayElement(result, 3, obj);
+
return result;
}
@@ -1092,9 +1098,9 @@
CHECK_JNI_EXCEPTION_(env, NULL);
env->SetObjectArrayElement(result, 3, id);
- jobject address = longBox(thread, env, (jlong) code);
+ jobject entry_point = longBox(thread, env, (jlong) code->entry_point());
CHECK_JNI_EXCEPTION_(env, NULL);
- env->SetObjectArrayElement(result, 4, address);
+ env->SetObjectArrayElement(result, 4, entry_point);
return result;
WB_END
@@ -1275,9 +1281,9 @@
VMThread::execute(&force_safepoint_op);
WB_END
-WB_ENTRY(long, WB_GetConstantPool(JNIEnv* env, jobject wb, jclass klass))
+WB_ENTRY(jlong, WB_GetConstantPool(JNIEnv* env, jobject wb, jclass klass))
instanceKlassHandle ikh(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
- return (long) ikh->constants();
+ return (jlong) ikh->constants();
WB_END
template <typename T>
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -467,14 +467,14 @@
}
// Update the rate and submit compile
-void AdvancedThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
+void AdvancedThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
update_rate(os::javaTimeMillis(), mh());
CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
}
// Handle the invocation event.
-void AdvancedThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
+void AdvancedThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
CompLevel level, nmethod* nm, JavaThread* thread) {
if (should_create_mdo(mh(), level)) {
create_mdo(mh, thread);
@@ -489,7 +489,7 @@
// Handle the back branch event. Notice that we can compile the method
// with a regular entry from here.
-void AdvancedThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
+void AdvancedThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
if (should_create_mdo(mh(), level)) {
create_mdo(mh, thread);
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -213,11 +213,11 @@
jlong start_time() const { return _start_time; }
// Submit a given method for compilation (and update the rate).
- virtual void submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
+ virtual void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
// event() from SimpleThresholdPolicy would call these.
- virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
+ virtual void method_invocation_event(const methodHandle& method, const methodHandle& inlinee,
CompLevel level, nmethod* nm, JavaThread* thread);
- virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
+ virtual void method_back_branch_event(const methodHandle& method, const methodHandle& inlinee,
int bci, CompLevel level, nmethod* nm, JavaThread* thread);
public:
AdvancedThresholdPolicy() : _start_time(0) { }
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1120,7 +1120,7 @@
Flag::Flags origin) {
JDK_Version since = JDK_Version();
- if (parse_argument(arg, origin) || ignore_unrecognized) {
+ if (parse_argument(arg, origin)) {
return true;
}
@@ -1156,7 +1156,7 @@
Flag* found_flag = Flag::find_flag((const char*)argname, arg_len, true, true);
if (found_flag != NULL) {
char locked_message_buf[BUFLEN];
- found_flag->get_locked_message(locked_message_buf, BUFLEN);
+ Flag::MsgType msg_type = found_flag->get_locked_message(locked_message_buf, BUFLEN);
if (strlen(locked_message_buf) == 0) {
if (found_flag->is_bool() && !has_plus_minus) {
jio_fprintf(defaultStream::error_stream(),
@@ -1169,9 +1169,19 @@
"Improperly specified VM option '%s'\n", argname);
}
} else {
+#ifdef PRODUCT
+ bool mismatched = ((msg_type == Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD) ||
+ (msg_type == Flag::DEVELOPER_FLAG_BUT_PRODUCT_BUILD));
+ if (ignore_unrecognized && mismatched) {
+ return true;
+ }
+#endif
jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf);
}
} else {
+ if (ignore_unrecognized) {
+ return true;
+ }
jio_fprintf(defaultStream::error_stream(),
"Unrecognized VM option '%s'\n", argname);
Flag* fuzzy_matched = Flag::fuzzy_match((const char*)argname, arg_len, true);
@@ -2469,16 +2479,6 @@
}
}
- // Note: only executed in non-PRODUCT mode
- if (!UseAsyncConcMarkSweepGC &&
- (ExplicitGCInvokesConcurrent ||
- ExplicitGCInvokesConcurrentAndUnloadsClasses)) {
- jio_fprintf(defaultStream::error_stream(),
- "error: +ExplicitGCInvokesConcurrent[AndUnloadsClasses] conflicts"
- " with -UseAsyncConcMarkSweepGC");
- status = false;
- }
-
if (PrintNMTStatistics) {
#if INCLUDE_NMT
if (MemTracker::tracking_level() == NMT_off) {
@@ -3481,33 +3481,8 @@
sprintf(path, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
#if INCLUDE_JVMCI
- jint res = JVMCIRuntime::save_options(_system_properties);
- if (res != JNI_OK) {
- return res;
- }
-
if (EnableJVMCI) {
- // Append lib/jvmci/*.jar to boot class path
- char jvmciDir[JVM_MAXPATHLEN];
- const char* fileSep = os::file_separator();
- jio_snprintf(jvmciDir, sizeof(jvmciDir), "%s%slib%sjvmci", Arguments::get_java_home(), fileSep, fileSep);
- DIR* dir = os::opendir(jvmciDir);
- if (dir != NULL) {
- struct dirent *entry;
- char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(jvmciDir), mtInternal);
- while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
- const char* name = entry->d_name;
- const char* ext = name + strlen(name) - 4;
- if (ext > name && strcmp(ext, ".jar") == 0) {
- char fileName[JVM_MAXPATHLEN];
- jio_snprintf(fileName, sizeof(fileName), "%s%s%s", jvmciDir, fileSep, name);
- scp_p->add_suffix(fileName);
- scp_assembly_required = true;
- }
- }
- FREE_C_HEAP_ARRAY(char, dbuf);
- os::closedir(dir);
- }
+ JVMCIRuntime::save_options(_system_properties);
}
#endif // INCLUDE_JVMCI
@@ -3858,6 +3833,7 @@
JavaVMOption option;
option.optionString = opt_hd;
+ option.extraInfo = NULL;
options->append(option); // Fill in option
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -218,7 +218,7 @@
return 0;
}
-void NonTieredCompPolicy::reset_counter_for_invocation_event(methodHandle m) {
+void NonTieredCompPolicy::reset_counter_for_invocation_event(const methodHandle& m) {
// Make sure invocation and backedge counter doesn't overflow again right away
// as would be the case for native methods.
@@ -232,7 +232,7 @@
assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed");
}
-void NonTieredCompPolicy::reset_counter_for_back_branch_event(methodHandle m) {
+void NonTieredCompPolicy::reset_counter_for_back_branch_event(const methodHandle& m) {
// Delay next back-branch event but pump up invocation counter to trigger
// whole method compilation.
MethodCounters* mcs = m->method_counters();
@@ -283,7 +283,7 @@
CounterHalfLifeTime);
for (int i = 0; i < classes_per_tick; i++) {
Klass* k = SystemDictionary::try_get_next_class();
- if (k != NULL && k->oop_is_instance()) {
+ if (k != NULL && k->is_instance_klass()) {
InstanceKlass::cast(k)->methods_do(do_method);
}
}
@@ -357,7 +357,7 @@
return (current >= initial + target);
}
-nmethod* NonTieredCompPolicy::event(methodHandle method, methodHandle inlinee, int branch_bci,
+nmethod* NonTieredCompPolicy::event(const methodHandle& method, const methodHandle& inlinee, int branch_bci,
int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
assert(comp_level == CompLevel_none, "This should be only called from the interpreter");
NOT_PRODUCT(trace_frequency_counter_overflow(method, branch_bci, bci));
@@ -416,22 +416,18 @@
}
#ifndef PRODUCT
-PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
-void NonTieredCompPolicy::trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci) {
+void NonTieredCompPolicy::trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci) {
if (TraceInvocationCounterOverflow) {
MethodCounters* mcs = m->method_counters();
assert(mcs != NULL, "MethodCounters cannot be NULL for profiling");
InvocationCounter* ic = mcs->invocation_counter();
InvocationCounter* bc = mcs->backedge_counter();
ResourceMark rm;
- const char* msg =
- bci == InvocationEntryBci
- ? "comp-policy cntr ovfl @ %d in entry of "
- : "comp-policy cntr ovfl @ %d in loop of ";
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
- tty->print(msg, bci);
-PRAGMA_DIAG_POP
+ if (bci == InvocationEntryBci) {
+ tty->print("comp-policy cntr ovfl @ %d in entry of ", bci);
+ } else {
+ tty->print("comp-policy cntr ovfl @ %d in loop of ", bci);
+ }
m->print_value();
tty->cr();
ic->print();
@@ -448,7 +444,7 @@
}
}
-void NonTieredCompPolicy::trace_osr_request(methodHandle method, nmethod* osr, int bci) {
+void NonTieredCompPolicy::trace_osr_request(const methodHandle& method, nmethod* osr, int bci) {
if (TraceOnStackReplacement) {
ResourceMark rm;
tty->print(osr != NULL ? "Reused OSR entry for " : "Requesting OSR entry for ");
@@ -460,7 +456,7 @@
// SimpleCompPolicy - compile current method
-void SimpleCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
+void SimpleCompPolicy::method_invocation_event(const methodHandle& m, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
@@ -474,7 +470,7 @@
}
}
-void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
+void SimpleCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->backedge_count();
const char* comment = "backedge_count";
@@ -491,7 +487,7 @@
// Consider m for compilation
-void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
+void StackWalkCompPolicy::method_invocation_event(const methodHandle& m, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
@@ -530,7 +526,7 @@
}
}
-void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
+void StackWalkCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->backedge_count();
const char* comment = "backedge_count";
@@ -663,7 +659,7 @@
}
-const char* StackWalkCompPolicy::shouldInline(methodHandle m, float freq, int cnt) {
+const char* StackWalkCompPolicy::shouldInline(const methodHandle& m, float freq, int cnt) {
// Allows targeted inlining
// positive filter: should send be inlined? returns NULL (--> yes)
// or rejection msg
@@ -690,7 +686,7 @@
}
-const char* StackWalkCompPolicy::shouldNotInline(methodHandle m) {
+const char* StackWalkCompPolicy::shouldNotInline(const methodHandle& m) {
// negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
if (m->is_abstract()) return (_msg = "abstract method");
// note: we allow ik->is_abstract()
--- a/hotspot/src/share/vm/runtime/compilationPolicy.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,7 +66,7 @@
virtual int compiler_count(CompLevel comp_level) = 0;
// main notification entry, return a pointer to an nmethod if the OSR is required,
// returns NULL otherwise.
- virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) = 0;
+ virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) = 0;
// safepoint() is called at the end of the safepoint
virtual void do_safepoint_work() = 0;
// reprofile request
@@ -91,11 +91,11 @@
class NonTieredCompPolicy : public CompilationPolicy {
int _compiler_count;
protected:
- static void trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci);
- static void trace_osr_request(methodHandle method, nmethod* osr, int bci);
+ static void trace_frequency_counter_overflow(const methodHandle& m, int branch_bci, int bci);
+ static void trace_osr_request(const methodHandle& method, nmethod* osr, int bci);
static void trace_osr_completion(nmethod* osr_nm);
- void reset_counter_for_invocation_event(methodHandle method);
- void reset_counter_for_back_branch_event(methodHandle method);
+ void reset_counter_for_invocation_event(const methodHandle& method);
+ void reset_counter_for_back_branch_event(const methodHandle& method);
public:
NonTieredCompPolicy() : _compiler_count(0) { }
virtual CompLevel initial_compile_level() { return CompLevel_highest_tier; }
@@ -107,15 +107,15 @@
virtual bool is_mature(Method* method);
virtual void initialize();
virtual CompileTask* select_task(CompileQueue* compile_queue);
- virtual nmethod* event(methodHandle method, methodHandle inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
- virtual void method_invocation_event(methodHandle m, JavaThread* thread) = 0;
- virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread) = 0;
+ virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee, int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
+ virtual void method_invocation_event(const methodHandle& m, JavaThread* thread) = 0;
+ virtual void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) = 0;
};
class SimpleCompPolicy : public NonTieredCompPolicy {
public:
- virtual void method_invocation_event(methodHandle m, JavaThread* thread);
- virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread);
+ virtual void method_invocation_event(const methodHandle& m, JavaThread* thread);
+ virtual void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
};
// StackWalkCompPolicy - existing C2 policy
@@ -123,8 +123,8 @@
#ifdef COMPILER2
class StackWalkCompPolicy : public NonTieredCompPolicy {
public:
- virtual void method_invocation_event(methodHandle m, JavaThread* thread);
- virtual void method_back_branch_event(methodHandle m, int bci, JavaThread* thread);
+ virtual void method_invocation_event(const methodHandle& m, JavaThread* thread);
+ virtual void method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread);
private:
RFrame* findTopInlinableFrame(GrowableArray<RFrame*>* stack);
@@ -134,9 +134,9 @@
// they are used for performance debugging only (print better messages)
static const char* _msg; // reason for not inlining
- static const char* shouldInline (methodHandle callee, float frequency, int cnt);
+ static const char* shouldInline (const methodHandle& callee, float frequency, int cnt);
// positive filter: should send be inlined? returns NULL (--> yes) or rejection msg
- static const char* shouldNotInline(methodHandle callee);
+ static const char* shouldNotInline(const methodHandle& callee);
// negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg
};
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -758,15 +758,15 @@
KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()()));
oop obj = NULL;
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(k());
obj = ik->allocate_instance(THREAD);
- } else if (k->oop_is_typeArray()) {
+ } else if (k->is_typeArray_klass()) {
TypeArrayKlass* ak = TypeArrayKlass::cast(k());
assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length");
int len = sv->field_size() / type2size[ak->element_type()];
obj = ak->allocate(len, THREAD);
- } else if (k->oop_is_objArray()) {
+ } else if (k->is_objArray_klass()) {
ObjArrayKlass* ak = ObjArrayKlass::cast(k());
obj = ak->allocate(sv->field_size(), THREAD);
}
@@ -1010,13 +1010,13 @@
continue;
}
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(k());
reassign_fields_by_klass(ik, fr, reg_map, sv, 0, obj(), skip_internal);
- } else if (k->oop_is_typeArray()) {
+ } else if (k->is_typeArray_klass()) {
TypeArrayKlass* ak = TypeArrayKlass::cast(k());
reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type());
- } else if (k->oop_is_objArray()) {
+ } else if (k->is_objArray_klass()) {
reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj());
}
}
@@ -1345,7 +1345,7 @@
}
#if defined(COMPILER2) || defined(SHARK) || INCLUDE_JVMCI
-void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) {
+void Deoptimization::load_class_by_index(const constantPoolHandle& constant_pool, int index, TRAPS) {
// in case of an unresolved klass entry, load the class.
if (constant_pool->tag_at(index).is_unresolved_klass()) {
Klass* tk = constant_pool->klass_at_ignore_error(index, CHECK);
@@ -1376,7 +1376,7 @@
}
-void Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index) {
+void Deoptimization::load_class_by_index(const constantPoolHandle& constant_pool, int index) {
EXCEPTION_MARK;
load_class_by_index(constant_pool, index, THREAD);
if (HAS_PENDING_EXCEPTION) {
@@ -1461,14 +1461,14 @@
oop speculation_log = nm->speculation_log();
if (speculation_log != NULL) {
if (TraceDeoptimization || TraceUncollectedSpeculations) {
- if (SpeculationLog::lastFailed(speculation_log) != NULL) {
+ if (HotSpotSpeculationLog::lastFailed(speculation_log) != NULL) {
tty->print_cr("A speculation that was not collected by the compiler is being overwritten");
}
}
if (TraceDeoptimization) {
tty->print_cr("Saving speculation to speculation log");
}
- SpeculationLog::set_lastFailed(speculation_log, speculation);
+ HotSpotSpeculationLog::set_lastFailed(speculation_log, speculation);
} else {
if (TraceDeoptimization) {
tty->print_cr("Speculation present but no speculation log");
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -420,8 +420,8 @@
bool& ret_maybe_prior_trap,
bool& ret_maybe_prior_recompile);
// class loading support for uncommon trap
- static void load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS);
- static void load_class_by_index(constantPoolHandle constant_pool, int index);
+ static void load_class_by_index(const constantPoolHandle& constant_pool, int index, TRAPS);
+ static void load_class_by_index(const constantPoolHandle& constant_pool, int index);
static UnrollBlock* fetch_unroll_info_helper(JavaThread* thread);
--- a/hotspot/src/share/vm/runtime/frame.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/frame.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -442,6 +442,14 @@
char* description;
int owner;
int priority;
+
+ FrameValue() {
+ location = NULL;
+ description = NULL;
+ owner = -1;
+ priority = 0;
+ }
+
};
--- a/hotspot/src/share/vm/runtime/globals.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/globals.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -306,35 +306,36 @@
_flags = Flags(_flags & ~KIND_DIAGNOSTIC);
}
-// Get custom message for this locked flag, or return NULL if
-// none is available.
-void Flag::get_locked_message(char* buf, int buflen) const {
+// Get custom message for this locked flag, or NULL if
+// none is available. Returns message type produced.
+Flag::MsgType Flag::get_locked_message(char* buf, int buflen) const {
buf[0] = '\0';
if (is_diagnostic() && !is_unlocked()) {
jio_snprintf(buf, buflen,
"Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n"
"Error: The unlock option must precede '%s'.\n",
_name, _name);
- return;
+ return Flag::DIAGNOSTIC_FLAG_BUT_LOCKED;
}
if (is_experimental() && !is_unlocked()) {
jio_snprintf(buf, buflen,
"Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n"
"Error: The unlock option must precede '%s'.\n",
_name, _name);
- return;
+ return Flag::EXPERIMENTAL_FLAG_BUT_LOCKED;
}
if (is_develop() && is_product_build()) {
jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n",
_name);
- return;
+ return Flag::DEVELOPER_FLAG_BUT_PRODUCT_BUILD;
}
if (is_notproduct() && is_product_build()) {
jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
_name);
- return;
+ return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD;
}
get_locked_message_ext(buf, buflen);
+ return Flag::NONE;
}
bool Flag::is_writeable() const {
@@ -348,11 +349,6 @@
return is_manageable() || is_external_ext();
}
-
-// Length of format string (e.g. "%.1234s") for printing ccstr below
-#define FORMAT_BUFFER_LEN 16
-
-PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
// Don't print notproduct and develop flags in a product build.
if (is_constant_in_binary()) {
@@ -384,14 +380,8 @@
if (cp != NULL) {
const char* eol;
while ((eol = strchr(cp, '\n')) != NULL) {
- char format_buffer[FORMAT_BUFFER_LEN];
size_t llen = pointer_delta(eol, cp, sizeof(char));
- jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
- "%%." SIZE_FORMAT "s", llen);
- PRAGMA_DIAG_PUSH
- PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
- st->print(format_buffer, cp);
- PRAGMA_DIAG_POP
+ st->print("%.*s", (int)llen, cp);
st->cr();
cp = eol+1;
st->print("%5s %-35s += ", "", _name);
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -282,6 +282,14 @@
ERR_OTHER
};
+ enum MsgType {
+ NONE = 0,
+ DIAGNOSTIC_FLAG_BUT_LOCKED,
+ EXPERIMENTAL_FLAG_BUT_LOCKED,
+ DEVELOPER_FLAG_BUT_PRODUCT_BUILD,
+ NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD
+ };
+
const char* _type;
const char* _name;
void* _addr;
@@ -367,7 +375,7 @@
void unlock_diagnostic();
- void get_locked_message(char*, int) const;
+ Flag::MsgType get_locked_message(char*, int) const;
void get_locked_message_ext(char*, int) const;
// printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
@@ -804,7 +812,7 @@
"Inline Thread.currentThread, etc") \
\
develop(bool, InlineUnsafeOps, true, \
- "Inline memory ops (native methods) from sun.misc.Unsafe") \
+ "Inline memory ops (native methods) from Unsafe") \
\
product(bool, CriticalJNINatives, true, \
"Check for critical JNI entry points") \
@@ -1622,12 +1630,6 @@
"Number of times to retry allocations when " \
"blocked by the GC locker") \
\
- develop(bool, UseCMSAdaptiveFreeLists, true, \
- "Use adaptive free lists in the CMS generation") \
- \
- develop(bool, UseAsyncConcMarkSweepGC, true, \
- "Use Asynchronous Concurrent Mark-Sweep GC in the old generation")\
- \
product(bool, UseCMSBestFit, true, \
"Use CMS best fit allocation strategy") \
\
@@ -1822,10 +1824,6 @@
"When CMS class unloading is enabled, the maximum CMS cycle " \
"count for which classes may not be unloaded") \
\
- develop(intx, CMSDictionaryChoice, 0, \
- "Use BinaryTreeDictionary as default in the CMS generation") \
- range(0, 2) \
- \
product(uintx, CMSIndexedFreeListReplenish, 4, \
"Replenish an indexed free list with this number of chunks") \
range(1, max_uintx) \
@@ -1840,9 +1838,6 @@
product(bool, CMSLoopWarn, false, \
"Warn in case of excessive CMS looping") \
\
- develop(bool, CMSOverflowEarlyRestoration, false, \
- "Restore preserved marks early") \
- \
/* where does the range max value of (max_jint - 1) come from? */ \
product(size_t, MarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M), \
"Maximum size of marking stack") \
@@ -2080,10 +2075,6 @@
"unloading of classes when class unloading is enabled") \
range(0, 100) \
\
- develop(bool, CMSTestInFreeList, false, \
- "Check if the coalesced range is already in the " \
- "free lists as claimed") \
- \
notproduct(bool, CMSVerifyReturnedBytes, false, \
"Check that all the garbage collected was returned to the " \
"free lists") \
@@ -2889,6 +2880,9 @@
product(bool, AggressiveOpts, false, \
"Enable aggressive optimizations - see arguments.cpp") \
\
+ product_pd(bool, CompactStrings, \
+ "Enable Strings to use single byte chars in backing store") \
+ \
product_pd(uintx, TypeProfileLevel, \
"=XYZ, with Z: Type profiling of arguments at call; " \
"Y: Type profiling of return value at call; " \
@@ -4253,7 +4247,7 @@
"Use locked-tracing when doing event-based tracing") \
\
diagnostic(bool, UseUnalignedAccesses, false, \
- "Use unaligned memory accesses in sun.misc.Unsafe") \
+ "Use unaligned memory accesses in Unsafe") \
\
product_pd(bool, PreserveFramePointer, \
"Use the FP register for holding the frame pointer " \
--- a/hotspot/src/share/vm/runtime/handles.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/handles.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -212,7 +212,8 @@
}
bool instanceKlassHandle::is_instanceKlass(const Klass* k) {
- return k->oop_is_instance();
+ // Need this to avoid circular include dependency
+ return k->is_instance_klass();
}
#endif
--- a/hotspot/src/share/vm/runtime/java.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/java.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -575,6 +575,11 @@
void vm_abort(bool dump_core) {
vm_perform_shutdown_actions();
os::wait_for_keypress_at_exit();
+
+ // Flush stdout and stderr before abort.
+ fflush(stdout);
+ fflush(stderr);
+
os::abort(dump_core);
ShouldNotReachHere();
}
--- a/hotspot/src/share/vm/runtime/javaCalls.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/javaCalls.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -289,21 +289,20 @@
// Implementation of JavaCalls (low level)
-void JavaCalls::call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS) {
+void JavaCalls::call(JavaValue* result, const methodHandle& method, JavaCallArguments* args, TRAPS) {
// Check if we need to wrap a potential OS exception handler around thread
// This is used for e.g. Win32 structured exception handlers
assert(THREAD->is_Java_thread(), "only JavaThreads can make JavaCalls");
// Need to wrap each and every time, since there might be native code down the
// stack that has installed its own exception handlers
- os::os_exception_wrapper(call_helper, result, &method, args, THREAD);
+ os::os_exception_wrapper(call_helper, result, method, args, THREAD);
}
-void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) {
+void JavaCalls::call_helper(JavaValue* result, const methodHandle& method, JavaCallArguments* args, TRAPS) {
// During dumping, Java execution environment is not fully initialized. Also, Java execution
// may cause undesirable side-effects in the class metadata.
assert(!DumpSharedSpaces, "must not execute Java bytecodes when dumping");
- methodHandle method = *m;
JavaThread* thread = (JavaThread*)THREAD;
assert(thread->is_Java_thread(), "must be called by a java thread");
assert(method.not_null(), "must have a method to call");
@@ -546,7 +545,7 @@
};
-void JavaCallArguments::verify(methodHandle method, BasicType return_type,
+void JavaCallArguments::verify(const methodHandle& method, BasicType return_type,
Thread *thread) {
guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
--- a/hotspot/src/share/vm/runtime/javaCalls.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/javaCalls.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -189,7 +189,7 @@
int size_of_parameters() const { return _size; }
// Verify that pushed arguments fits a given method
- void verify(methodHandle method, BasicType return_type, Thread *thread);
+ void verify(const methodHandle& method, BasicType return_type, Thread *thread);
};
// All calls to Java have to go via JavaCalls. Sets up the stack frame
@@ -197,7 +197,7 @@
//
class JavaCalls: AllStatic {
- static void call_helper(JavaValue* result, methodHandle* method, JavaCallArguments* args, TRAPS);
+ static void call_helper(JavaValue* result, const methodHandle& method, JavaCallArguments* args, TRAPS);
public:
// call_special
// ------------
@@ -227,7 +227,7 @@
static void call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS);
// Low-level interface
- static void call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS);
+ static void call(JavaValue* result, const methodHandle& method, JavaCallArguments* args, TRAPS);
};
#endif // SHARE_VM_RUNTIME_JAVACALLS_HPP
--- a/hotspot/src/share/vm/runtime/os.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/os.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -96,8 +96,7 @@
// Output will be of the form "YYYY-MM-DDThh:mm:ss.mmm+zzzz\0"
// 1 2
// 12345678901234567890123456789
- static const char* iso8601_format =
- "%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d";
+ // format string: "%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d"
static const size_t needed_buffer = 29;
// Sanity check the arguments
@@ -158,7 +157,8 @@
// Print an ISO 8601 date and time stamp into the buffer
const int year = 1900 + time_struct.tm_year;
const int month = 1 + time_struct.tm_mon;
- const int printed = jio_snprintf(buffer, buffer_length, iso8601_format,
+ const int printed = jio_snprintf(buffer, buffer_length,
+ "%04d-%02d-%02dT%02d:%02d:%02d.%03d%c%02d%02d",
year,
month,
time_struct.tm_mday,
@@ -1394,7 +1394,7 @@
// Returns true if the current stack pointer is above the stack shadow
// pages, false otherwise.
-bool os::stack_shadow_pages_available(Thread *thread, methodHandle method) {
+bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method) {
assert(StackRedPages > 0 && StackYellowPages > 0,"Sanity check");
address sp = current_stack_pointer();
// Check if we have StackShadowPages above the yellow zone. This parameter
--- a/hotspot/src/share/vm/runtime/os.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/os.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -96,7 +96,7 @@
const bool ExecMem = true;
// Typedef for structured exception handling support
-typedef void (*java_call_t)(JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
+typedef void (*java_call_t)(JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread);
class MallocTracker;
@@ -263,7 +263,7 @@
static bool uses_stack_guard_pages();
static bool allocate_stack_guard_pages();
static void bang_stack_shadow_pages();
- static bool stack_shadow_pages_available(Thread *thread, methodHandle method);
+ static bool stack_shadow_pages_available(Thread *thread, const methodHandle& method);
// OS interface to Virtual Memory
@@ -722,7 +722,7 @@
static void init_random(long initval); // initialize random sequence
// Structured OS Exception support
- static void os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread);
+ static void os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread);
// On Posix compatible OS it will simply check core dump limits while on Windows
// it will check if dump file can be created. Check or prepare a core dump to be
--- a/hotspot/src/share/vm/runtime/park.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/park.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -121,22 +121,13 @@
// Current association
Thread * AssociatedWith ;
- intptr_t RawThreadIdentity ; // LWPID etc
- volatile int Incarnation ;
-
- // diagnostic : keep track of last thread to wake this thread.
- // this is useful for construction of dependency graphs.
- void * LastWaker ;
public:
// MCS-CLH list linkage and Native Mutex/Monitor
ParkEvent * volatile ListNext ;
- ParkEvent * volatile ListPrev ;
volatile intptr_t OnList ;
volatile int TState ;
volatile int Notified ; // for native monitor construct
- volatile int IsWaiting ; // Enqueued on WaitSet
-
private:
static ParkEvent * volatile FreeList ;
@@ -155,11 +146,9 @@
AssociatedWith = NULL ;
FreeNext = NULL ;
ListNext = NULL ;
- ListPrev = NULL ;
OnList = 0 ;
TState = 0 ;
Notified = 0 ;
- IsWaiting = 0 ;
}
// We use placement-new to force ParkEvent instances to be
--- a/hotspot/src/share/vm/runtime/reflection.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -330,7 +330,7 @@
return TypeArrayKlass::cast(tak)->allocate(length, THREAD);
} else {
Klass* k = java_lang_Class::as_Klass(element_mirror);
- if (k->oop_is_array() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
+ if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
}
return oopFactory::new_objArray(k, length, THREAD);
@@ -366,7 +366,7 @@
klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL);
} else {
klass = java_lang_Class::as_Klass(element_mirror);
- if (klass->oop_is_array()) {
+ if (klass->is_array_klass()) {
int k_dim = ArrayKlass::cast(klass)->dimension();
if (k_dim + len > MAX_DIM) {
THROW_0(vmSymbols::java_lang_IllegalArgumentException());
@@ -387,7 +387,7 @@
}
Klass* klass = java_lang_Class::as_Klass(mirror);
- if (!klass->oop_is_array()) {
+ if (!klass->is_array_klass()) {
return NULL;
}
@@ -395,14 +395,14 @@
#ifdef ASSERT
oop result2 = NULL;
if (ArrayKlass::cast(klass)->dimension() == 1) {
- if (klass->oop_is_typeArray()) {
+ if (klass->is_typeArray_klass()) {
result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL);
} else {
result2 = ObjArrayKlass::cast(klass)->element_klass()->java_mirror();
}
} else {
Klass* lower_dim = ArrayKlass::cast(klass)->lower_dimension();
- assert(lower_dim->oop_is_array(), "just checking");
+ assert(lower_dim->is_array_klass(), "just checking");
result2 = lower_dim->java_mirror();
}
assert(result == result2, "results must be consistent");
@@ -495,7 +495,7 @@
}
Klass* host_class = current_class;
- while (host_class->oop_is_instance() &&
+ while (host_class->is_instance_klass() &&
InstanceKlass::cast(host_class)->is_anonymous()) {
Klass* next_host_class = InstanceKlass::cast(host_class)->host_klass();
if (next_host_class == NULL) break;
@@ -612,7 +612,7 @@
}
-objArrayHandle Reflection::get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS) {
+objArrayHandle Reflection::get_parameter_types(const methodHandle& method, int parameter_count, oop* return_type, TRAPS) {
// Allocate array holding parameter types (java.lang.Class instances)
objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
objArrayHandle mirrors (THREAD, m);
@@ -635,7 +635,7 @@
return mirrors;
}
-objArrayHandle Reflection::get_exception_types(methodHandle method, TRAPS) {
+objArrayHandle Reflection::get_exception_types(const methodHandle& method, TRAPS) {
return method->resolved_checked_exceptions(THREAD);
}
@@ -647,11 +647,9 @@
return Handle(THREAD, Universe::java_mirror(type));
}
- oop loader = InstanceKlass::cast(k())->class_loader();
- oop protection_domain = k()->protection_domain();
Klass* result = SystemDictionary::resolve_or_fail(signature,
- Handle(THREAD, loader),
- Handle(THREAD, protection_domain),
+ Handle(THREAD, k->class_loader()),
+ Handle(THREAD, k->protection_domain()),
true, CHECK_(Handle()));
if (TraceClassResolution) {
@@ -663,7 +661,7 @@
}
-oop Reflection::new_method(methodHandle method, bool for_constant_pool_access, TRAPS) {
+oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
// Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
assert(!method()->is_initializer() ||
(for_constant_pool_access && method()->is_static()),
@@ -726,7 +724,7 @@
}
-oop Reflection::new_constructor(methodHandle method, TRAPS) {
+oop Reflection::new_constructor(const methodHandle& method, TRAPS) {
assert(method()->is_initializer(), "should call new_method instead");
instanceKlassHandle holder (THREAD, method->method_holder());
@@ -824,7 +822,7 @@
}
-methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
+methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, const methodHandle& method,
KlassHandle recv_klass, Handle receiver, TRAPS) {
assert(!method.is_null() , "method should not be null");
@@ -839,7 +837,7 @@
}
-oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method,
+oop Reflection::invoke(instanceKlassHandle klass, const methodHandle& reflected_method,
Handle receiver, bool override, objArrayHandle ptypes,
BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) {
ResourceMark rm(THREAD);
--- a/hotspot/src/share/vm/runtime/reflection.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/reflection.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,8 +48,8 @@
static Klass* basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS);
static oop basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS);
- static objArrayHandle get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS);
- static objArrayHandle get_exception_types(methodHandle method, TRAPS);
+ static objArrayHandle get_parameter_types(const methodHandle& method, int parameter_count, oop* return_type, TRAPS);
+ static objArrayHandle get_exception_types(const methodHandle& method, TRAPS);
// Creating new java.lang.reflect.xxx wrappers
static Handle new_type(Symbol* signature, KlassHandle k, TRAPS);
@@ -110,9 +110,9 @@
//
// Create a java.lang.reflect.Method object based on a method
- static oop new_method(methodHandle method, bool for_constant_pool_access, TRAPS);
+ static oop new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS);
// Create a java.lang.reflect.Constructor object based on a method
- static oop new_constructor(methodHandle method, TRAPS);
+ static oop new_constructor(const methodHandle& method, TRAPS);
// Create a java.lang.reflect.Field object based on a field descriptor
static oop new_field(fieldDescriptor* fd, TRAPS);
// Create a java.lang.reflect.Parameter object based on a
@@ -122,9 +122,16 @@
private:
// method resolution for invoke
- static methodHandle resolve_interface_call(instanceKlassHandle klass, methodHandle method, KlassHandle recv_klass, Handle receiver, TRAPS);
+ static methodHandle resolve_interface_call(instanceKlassHandle klass, const methodHandle& method, KlassHandle recv_klass, Handle receiver, TRAPS);
// Method call (shared by invoke_method and invoke_constructor)
- static oop invoke(instanceKlassHandle klass, methodHandle method, Handle receiver, bool override, objArrayHandle ptypes, BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS);
+ static oop invoke(instanceKlassHandle klass,
+ const methodHandle& method,
+ Handle receiver,
+ bool override,
+ objArrayHandle ptypes,
+ BasicType rtype,
+ objArrayHandle args,
+ bool is_method_invoke, TRAPS);
// Narrowing of basic types. Used to create correct jvalues for
// boolean, byte, char and short return return values from interpreter
--- a/hotspot/src/share/vm/runtime/relocator.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/relocator.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,7 +125,7 @@
//-----------------------------------------------------------------------------------------------------------
// Relocator code
-Relocator::Relocator(methodHandle m, RelocatorListener* listener) {
+Relocator::Relocator(const methodHandle& m, RelocatorListener* listener) {
set_method(m);
set_code_length(method()->code_size());
set_code_array(NULL);
--- a/hotspot/src/share/vm/runtime/relocator.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/relocator.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,7 @@
class Relocator : public ResourceObj {
public:
- Relocator(methodHandle method, RelocatorListener* listener);
+ Relocator(const methodHandle& method, RelocatorListener* listener);
methodHandle insert_space_at(int bci, int space, u_char inst_buffer[], TRAPS);
// Callbacks from ChangeItem's
@@ -81,7 +81,7 @@
void set_compressed_line_number_table_size(int size) { _compressed_line_number_table_size = size; }
methodHandle method() const { return _method; }
- void set_method(methodHandle method) { _method = method; }
+ void set_method(const methodHandle& method) { _method = method; }
// This will return a raw bytecode, which is possibly rewritten.
Bytecodes::Code code_at(int bci) const { return (Bytecodes::Code) code_array()[bci]; }
--- a/hotspot/src/share/vm/runtime/safepoint.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -122,7 +122,7 @@
// Save the starting time, so that it can be compared to see if this has taken
// too long to complete.
- jlong safepoint_limit_time;
+ jlong safepoint_limit_time = 0;
timeout_error_printed = false;
// PrintSafepointStatisticsTimeout can be specified separately. When
@@ -901,7 +901,7 @@
void ThreadSafepointState::print_on(outputStream *st) const {
- const char *s;
+ const char *s = NULL;
switch(_type) {
case _running : s = "_running"; break;
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1142,7 +1142,7 @@
callee->is_method_handle_intrinsic() ||
callee->is_compiled_lambda_form(),
"actual receiver must be subclass of static receiver klass");
- if (receiver_klass->oop_is_instance()) {
+ if (receiver_klass->is_instance_klass()) {
if (InstanceKlass::cast(receiver_klass())->is_not_initialized()) {
tty->print_cr("ERROR: Klass not yet initialized!!");
receiver_klass()->print();
@@ -1697,7 +1697,7 @@
}
#ifdef ASSERT
-void SharedRuntime::check_member_name_argument_is_last_argument(methodHandle method,
+void SharedRuntime::check_member_name_argument_is_last_argument(const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) {
ResourceMark rm;
@@ -2430,7 +2430,7 @@
return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
}
-AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) {
+AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
// Use customized signature handler. Need to lock around updates to
// the AdapterHandlerTable (it is not safe for concurrent readers
// and a single writer: this could be fixed if it becomes a
@@ -2640,7 +2640,7 @@
* arguments, and transitions to native. On return from the native we transition
* back to java blocking if a safepoint is in progress.
*/
-void AdapterHandlerLibrary::create_native_wrapper(methodHandle method) {
+void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
ResourceMark rm;
nmethod* nm = NULL;
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -361,7 +361,7 @@
// return value is the maximum number of VMReg stack slots the convention will use.
static int java_calling_convention(const BasicType* sig_bt, VMRegPair* regs, int total_args_passed, int is_outgoing);
- static void check_member_name_argument_is_last_argument(methodHandle method,
+ static void check_member_name_argument_is_last_argument(const methodHandle& method,
const BasicType* sig_bt,
const VMRegPair* regs) NOT_DEBUG_RETURN;
@@ -472,7 +472,7 @@
// is a JNI critical method, or a compiled method handle adapter,
// such as _invokeBasic, _linkToVirtual, etc.
static nmethod* generate_native_wrapper(MacroAssembler* masm,
- methodHandle method,
+ const methodHandle& method,
int compile_id,
BasicType* sig_bt,
VMRegPair* regs,
@@ -680,8 +680,8 @@
static AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint,
address i2c_entry, address c2i_entry, address c2i_unverified_entry);
- static void create_native_wrapper(methodHandle method);
- static AdapterHandlerEntry* get_adapter(methodHandle method);
+ static void create_native_wrapper(const methodHandle& method);
+ static AdapterHandlerEntry* get_adapter(const methodHandle& method);
static void print_handler(const CodeBlob* b) { print_handler_on(tty, b); }
static void print_handler_on(outputStream* st, const CodeBlob* b);
--- a/hotspot/src/share/vm/runtime/signature.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/signature.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -242,7 +242,7 @@
void do_void() { ShouldNotReachHere(); }
- Fingerprinter(methodHandle method) : SignatureIterator(method->signature()) {
+ Fingerprinter(const methodHandle& method) : SignatureIterator(method->signature()) {
mh = method;
_fingerprint = 0;
}
@@ -320,7 +320,7 @@
virtual void pass_double() { pass_long(); } // may be same as long
#endif
- NativeSignatureIterator(methodHandle method) : SignatureIterator(method->signature()) {
+ NativeSignatureIterator(const methodHandle& method) : SignatureIterator(method->signature()) {
_method = method;
_offset = 0;
_jni_offset = 0;
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -185,7 +185,7 @@
}
}
-nmethod* SimpleThresholdPolicy::event(methodHandle method, methodHandle inlinee,
+nmethod* SimpleThresholdPolicy::event(const methodHandle& method, const methodHandle& inlinee,
int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread) {
if (comp_level == CompLevel_none &&
JvmtiExport::can_post_interpreter_events() &&
@@ -222,7 +222,7 @@
}
// Check if the method can be compiled, change level if necessary
-void SimpleThresholdPolicy::compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
+void SimpleThresholdPolicy::compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
assert(level <= TieredStopAtLevel, "Invalid compilation level");
if (level == CompLevel_none) {
return;
@@ -249,7 +249,7 @@
}
// Tell the broker to compile the method
-void SimpleThresholdPolicy::submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread) {
+void SimpleThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
}
@@ -377,7 +377,7 @@
// Handle the invocation event.
-void SimpleThresholdPolicy::method_invocation_event(methodHandle mh, methodHandle imh,
+void SimpleThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
CompLevel level, nmethod* nm, JavaThread* thread) {
if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
CompLevel next_level = call_event(mh(), level);
@@ -389,7 +389,7 @@
// Handle the back branch event. Notice that we can compile the method
// with a regular entry from here.
-void SimpleThresholdPolicy::method_back_branch_event(methodHandle mh, methodHandle imh,
+void SimpleThresholdPolicy::method_back_branch_event(const methodHandle& mh, const methodHandle& imh,
int bci, CompLevel level, nmethod* nm, JavaThread* thread) {
// If the method is already compiling, quickly bail out.
if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,9 +67,9 @@
// Print policy-specific information if necessary
virtual void print_specific(EventType type, methodHandle mh, methodHandle imh, int bci, CompLevel level) { }
// Check if the method can be compiled, change level if necessary
- void compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
+ void compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
// Submit a given method for compilation
- virtual void submit_compile(methodHandle mh, int bci, CompLevel level, JavaThread* thread);
+ virtual void submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread);
// Simple methods are as good being compiled with C1 as C2.
// This function tells if it's such a function.
inline bool is_trivial(Method* method);
@@ -87,9 +87,9 @@
}
return CompLevel_none;
}
- virtual void method_invocation_event(methodHandle method, methodHandle inlinee,
+ virtual void method_invocation_event(const methodHandle& method, const methodHandle& inlinee,
CompLevel level, nmethod* nm, JavaThread* thread);
- virtual void method_back_branch_event(methodHandle method, methodHandle inlinee,
+ virtual void method_back_branch_event(const methodHandle& method, const methodHandle& inlinee,
int bci, CompLevel level, nmethod* nm, JavaThread* thread);
public:
SimpleThresholdPolicy() : _c1_count(0), _c2_count(0) { }
@@ -103,7 +103,7 @@
virtual void delay_compilation(Method* method) { }
virtual void disable_compilation(Method* method) { }
virtual void reprofile(ScopeDesc* trap_scope, bool is_osr);
- virtual nmethod* event(methodHandle method, methodHandle inlinee,
+ virtual nmethod* event(const methodHandle& method, const methodHandle& inlinee,
int branch_bci, int bci, CompLevel comp_level, nmethod* nm, JavaThread* thread);
// Select task is called by CompileBroker. We should return a task or NULL.
virtual CompileTask* select_task(CompileQueue* compile_queue);
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.inline.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -68,6 +68,14 @@
method->is_constant_getter()) {
return true;
}
+#if INCLUDE_JVMCI
+ if (UseJVMCICompiler) {
+ if (TieredCompilation && CompileBroker::compiler(CompLevel_full_optimization) != NULL &&
+ CompileBroker::compiler(CompLevel_full_optimization)->is_trivial(method)) {
+ return true;
+ }
+ }
+#endif
if (method->has_loops() || method->code_size() >= 15) {
return false;
}
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -116,7 +116,7 @@
// global list of blocks of monitors
// gBlockList is really PaddedEnd<ObjectMonitor> *, but we don't
// want to expose the PaddedEnd template more than necessary.
-ObjectMonitor * ObjectSynchronizer::gBlockList = NULL;
+ObjectMonitor * volatile ObjectSynchronizer::gBlockList = NULL;
// global monitor free list
ObjectMonitor * volatile ObjectSynchronizer::gFreeList = NULL;
// global monitor in-use list, for moribund threads,
@@ -890,21 +890,22 @@
return NULL;
}
+
// Visitors ...
void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure) {
- PaddedEnd<ObjectMonitor> * block = (PaddedEnd<ObjectMonitor> *)gBlockList;
- ObjectMonitor* mid;
- while (block) {
+ PaddedEnd<ObjectMonitor> * block =
+ (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
+ while (block != NULL) {
assert(block->object() == CHAINMARKER, "must be a block header");
for (int i = _BLOCKSIZE - 1; i > 0; i--) {
- mid = (ObjectMonitor *)(block + i);
- oop object = (oop) mid->object();
+ ObjectMonitor* mid = (ObjectMonitor *)(block + i);
+ oop object = (oop)mid->object();
if (object != NULL) {
closure->do_monitor(mid);
}
}
- block = (PaddedEnd<ObjectMonitor> *) block->FreeNext;
+ block = (PaddedEnd<ObjectMonitor> *)block->FreeNext;
}
}
@@ -919,9 +920,9 @@
void ObjectSynchronizer::oops_do(OopClosure* f) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
- for (PaddedEnd<ObjectMonitor> * block =
- (PaddedEnd<ObjectMonitor> *)gBlockList; block != NULL;
- block = (PaddedEnd<ObjectMonitor> *)next(block)) {
+ PaddedEnd<ObjectMonitor> * block =
+ (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
+ for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
assert(block->object() == CHAINMARKER, "must be a block header");
for (int i = 1; i < _BLOCKSIZE; i++) {
ObjectMonitor* mid = (ObjectMonitor *)&block[i];
@@ -1139,7 +1140,9 @@
// The very first objectMonitor in a block is reserved and dedicated.
// It serves as blocklist "next" linkage.
temp[0].FreeNext = gBlockList;
- gBlockList = temp;
+ // There are lock-free uses of gBlockList so make sure that
+ // the previous stores happen before we update gBlockList.
+ OrderAccess::release_store_ptr(&gBlockList, temp);
// Add the new string of objectMonitors to the global free list
temp[_BLOCKSIZE - 1].FreeNext = gFreeList;
@@ -1621,31 +1624,33 @@
nInuse += gOmInUseCount;
}
- } else for (PaddedEnd<ObjectMonitor> * block =
- (PaddedEnd<ObjectMonitor> *)gBlockList; block != NULL;
- block = (PaddedEnd<ObjectMonitor> *)next(block)) {
- // Iterate over all extant monitors - Scavenge all idle monitors.
- assert(block->object() == CHAINMARKER, "must be a block header");
- nInCirculation += _BLOCKSIZE;
- for (int i = 1; i < _BLOCKSIZE; i++) {
- ObjectMonitor* mid = (ObjectMonitor*)&block[i];
- oop obj = (oop) mid->object();
+ } else {
+ PaddedEnd<ObjectMonitor> * block =
+ (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
+ for (; block != NULL; block = (PaddedEnd<ObjectMonitor> *)next(block)) {
+ // Iterate over all extant monitors - Scavenge all idle monitors.
+ assert(block->object() == CHAINMARKER, "must be a block header");
+ nInCirculation += _BLOCKSIZE;
+ for (int i = 1; i < _BLOCKSIZE; i++) {
+ ObjectMonitor* mid = (ObjectMonitor*)&block[i];
+ oop obj = (oop)mid->object();
- if (obj == NULL) {
- // The monitor is not associated with an object.
- // The monitor should either be a thread-specific private
- // free list or the global free list.
- // obj == NULL IMPLIES mid->is_busy() == 0
- guarantee(!mid->is_busy(), "invariant");
- continue;
- }
- deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp);
+ if (obj == NULL) {
+ // The monitor is not associated with an object.
+ // The monitor should either be a thread-specific private
+ // free list or the global free list.
+ // obj == NULL IMPLIES mid->is_busy() == 0
+ guarantee(!mid->is_busy(), "invariant");
+ continue;
+ }
+ deflated = deflate_monitor(mid, obj, &freeHeadp, &freeTailp);
- if (deflated) {
- mid->FreeNext = NULL;
- nScavenged++;
- } else {
- nInuse++;
+ if (deflated) {
+ mid->FreeNext = NULL;
+ nScavenged++;
+ } else {
+ nInuse++;
+ }
}
}
}
@@ -1789,18 +1794,18 @@
// Verify all monitors in the monitor cache, the verification is weak.
void ObjectSynchronizer::verify() {
- PaddedEnd<ObjectMonitor> * block = (PaddedEnd<ObjectMonitor> *)gBlockList;
- ObjectMonitor* mid;
- while (block) {
+ PaddedEnd<ObjectMonitor> * block =
+ (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
+ while (block != NULL) {
assert(block->object() == CHAINMARKER, "must be a block header");
for (int i = 1; i < _BLOCKSIZE; i++) {
- mid = (ObjectMonitor *)(block + i);
- oop object = (oop) mid->object();
+ ObjectMonitor* mid = (ObjectMonitor *)(block + i);
+ oop object = (oop)mid->object();
if (object != NULL) {
mid->verify();
}
}
- block = (PaddedEnd<ObjectMonitor> *) block->FreeNext;
+ block = (PaddedEnd<ObjectMonitor> *)block->FreeNext;
}
}
@@ -1809,19 +1814,19 @@
// the list of extant blocks without taking a lock.
int ObjectSynchronizer::verify_objmon_isinpool(ObjectMonitor *monitor) {
- PaddedEnd<ObjectMonitor> * block = (PaddedEnd<ObjectMonitor> *)gBlockList;
-
- while (block) {
+ PaddedEnd<ObjectMonitor> * block =
+ (PaddedEnd<ObjectMonitor> *)OrderAccess::load_ptr_acquire(&gBlockList);
+ while (block != NULL) {
assert(block->object() == CHAINMARKER, "must be a block header");
if (monitor > (ObjectMonitor *)&block[0] &&
monitor < (ObjectMonitor *)&block[_BLOCKSIZE]) {
- address mon = (address) monitor;
- address blk = (address) block;
+ address mon = (address)monitor;
+ address blk = (address)block;
size_t diff = mon - blk;
- assert((diff % sizeof(PaddedEnd<ObjectMonitor>)) == 0, "check");
+ assert((diff % sizeof(PaddedEnd<ObjectMonitor>)) == 0, "must be aligned");
return 1;
}
- block = (PaddedEnd<ObjectMonitor> *) block->FreeNext;
+ block = (PaddedEnd<ObjectMonitor> *)block->FreeNext;
}
return 0;
}
--- a/hotspot/src/share/vm/runtime/synchronizer.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/synchronizer.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -140,7 +140,7 @@
// global list of blocks of monitors
// gBlockList is really PaddedEnd<ObjectMonitor> *, but we don't
// want to expose the PaddedEnd template more than necessary.
- static ObjectMonitor * gBlockList;
+ static ObjectMonitor * volatile gBlockList;
// global monitor free list
static ObjectMonitor * volatile gFreeList;
// global monitor in-use list, for moribund threads,
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -2101,7 +2101,7 @@
frame f = last_frame();
tty->print(" (pc: " INTPTR_FORMAT " sp: " INTPTR_FORMAT " )", p2i(f.pc()), p2i(f.sp()));
}
- tty->print_cr(" of type: %s", InstanceKlass::cast(_pending_async_exception->klass())->external_name());
+ tty->print_cr(" of type: %s", _pending_async_exception->klass()->external_name());
}
_pending_async_exception = NULL;
clear_has_async_exception();
@@ -2219,10 +2219,10 @@
if (TraceExceptions) {
ResourceMark rm;
- tty->print_cr("Pending Async. exception installed of type: %s", InstanceKlass::cast(_pending_async_exception->klass())->external_name());
+ tty->print_cr("Pending Async. exception installed of type: %s", _pending_async_exception->klass()->external_name());
}
// for AbortVMOnException flag
- Exceptions::debug_check_abort(InstanceKlass::cast(_pending_async_exception->klass())->external_name());
+ Exceptions::debug_check_abort(_pending_async_exception->klass()->external_name());
}
}
@@ -2933,12 +2933,8 @@
if (thread_obj != NULL) {
oop thread_group = java_lang_Thread::threadGroup(thread_obj);
if (thread_group != NULL) {
- typeArrayOop name = java_lang_ThreadGroup::name(thread_group);
// ThreadGroup.name can be null
- if (name != NULL) {
- const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
- return str;
- }
+ return java_lang_ThreadGroup::name(thread_group);
}
}
return NULL;
@@ -2952,12 +2948,8 @@
if (thread_group != NULL) {
oop parent = java_lang_ThreadGroup::parent(thread_group);
if (parent != NULL) {
- typeArrayOop name = java_lang_ThreadGroup::name(parent);
// ThreadGroup.name can be null
- if (name != NULL) {
- const char* str = UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length());
- return str;
- }
+ return java_lang_ThreadGroup::name(parent);
}
}
}
@@ -3304,6 +3296,9 @@
initialize_class(vmSymbols::java_lang_String(), CHECK);
+ // Inject CompactStrings value after the static initializers for String ran.
+ java_lang_String::set_compact_strings(CompactStrings);
+
// Initialize java_lang.System (needed before creating the thread)
initialize_class(vmSymbols::java_lang_System(), CHECK);
// The VM creates & returns objects of this class. Make sure it's initialized.
@@ -3630,6 +3625,7 @@
if (jvmciCompiler != NULL) {
JVMCIRuntime::save_compiler(jvmciCompiler);
}
+ JVMCIRuntime::maybe_print_flags(CHECK_JNI_ERR);
}
#endif // INCLUDE_JVMCI
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -278,6 +278,7 @@
#define VM_STRUCTS(nonstatic_field, \
static_field, \
+ static_ptr_volatile_field, \
unchecked_nonstatic_field, \
volatile_nonstatic_field, \
nonproduct_nonstatic_field, \
@@ -681,42 +682,42 @@
static_field(SystemDictionary, _shared_dictionary, Dictionary*) \
static_field(SystemDictionary, _system_loader_lock_obj, oop) \
static_field(SystemDictionary, _loader_constraints, LoaderConstraintTable*) \
- static_field(SystemDictionary, WK_KLASS(Object_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(String_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Class_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Cloneable_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(ClassLoader_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Serializable_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(System_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Throwable_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(ThreadDeath_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Error_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Exception_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(RuntimeException_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(ClassNotFoundException_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(NoClassDefFoundError_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(LinkageError_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(ClassCastException_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(ArrayStoreException_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(VirtualMachineError_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(OutOfMemoryError_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(StackOverflowError_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(ProtectionDomain_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(AccessControlContext_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(SecureClassLoader_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Reference_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(SoftReference_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(WeakReference_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(FinalReference_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(PhantomReference_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Cleaner_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Finalizer_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Thread_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(ThreadGroup_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(Properties_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(StringBuffer_klass), Klass*) \
- static_field(SystemDictionary, WK_KLASS(MethodHandle_klass), Klass*) \
- static_field(SystemDictionary, _box_klasses[0], Klass*) \
+ static_field(SystemDictionary, WK_KLASS(Object_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(String_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Class_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Cloneable_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(ClassLoader_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Serializable_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(System_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Throwable_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(ThreadDeath_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Error_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Exception_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(RuntimeException_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(ClassNotFoundException_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(NoClassDefFoundError_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(LinkageError_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(ClassCastException_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(ArrayStoreException_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(VirtualMachineError_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(OutOfMemoryError_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(StackOverflowError_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(ProtectionDomain_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(AccessControlContext_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(SecureClassLoader_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Reference_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(SoftReference_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(WeakReference_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(FinalReference_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(PhantomReference_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Cleaner_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Finalizer_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Thread_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(ThreadGroup_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(Properties_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(StringBuffer_klass), InstanceKlass*) \
+ static_field(SystemDictionary, WK_KLASS(MethodHandle_klass), InstanceKlass*) \
+ static_field(SystemDictionary, _box_klasses[0], InstanceKlass*) \
static_field(SystemDictionary, _java_system_loader, oop) \
\
/*************/ \
@@ -1178,7 +1179,7 @@
volatile_nonstatic_field(BasicLock, _displaced_header, markOop) \
nonstatic_field(BasicObjectLock, _lock, BasicLock) \
nonstatic_field(BasicObjectLock, _obj, oop) \
- static_field(ObjectSynchronizer, gBlockList, ObjectMonitor*) \
+ static_ptr_volatile_field(ObjectSynchronizer, gBlockList, ObjectMonitor*) \
\
/*********************/ \
/* Matcher (C2 only) */ \
@@ -2897,6 +2898,11 @@
#define GENERATE_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
+// This macro generates a VMStructEntry line for a static pointer volatile field,
+// e.g.: "static ObjectMonitor * volatile gBlockList;"
+#define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
+ { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&typeName::fieldName },
+
// This macro generates a VMStructEntry line for an unchecked
// nonstatic field, in which the size of the type is also specified.
// The type string is given as NULL, indicating an "opaque" type.
@@ -2922,10 +2928,15 @@
#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{typedef type dummyvtype; typeName *dummyObj = NULL; volatile dummyvtype* dummy = &dummyObj->fieldName; }
-// This macro checks the type of a VMStructEntry by comparing pointer types
+// This macro checks the type of a static VMStructEntry by comparing pointer types
#define CHECK_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{type* dummy = &typeName::fieldName; }
+// This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types,
+// e.g.: "static ObjectMonitor * volatile gBlockList;"
+#define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
+ {type volatile * dummy = &typeName::fieldName; }
+
// This macro ensures the type of a field and its containing type are
// present in the type table. The assertion string is shorter than
// preferable because (incredibly) of a bug in Solstice NFS client
@@ -3136,6 +3147,7 @@
VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY,
+ GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY,
GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
@@ -3365,6 +3377,7 @@
VMStructs::init() {
VM_STRUCTS(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_STATIC_VM_STRUCT_ENTRY,
+ CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY,
CHECK_NO_OP,
CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
@@ -3486,9 +3499,11 @@
CHECK_NO_OP,
CHECK_NO_OP,
CHECK_NO_OP,
+ CHECK_NO_OP,
CHECK_NO_OP));
debug_only(VM_STRUCTS(CHECK_NO_OP,
ENSURE_FIELD_TYPE_PRESENT,
+ ENSURE_FIELD_TYPE_PRESENT,
CHECK_NO_OP,
ENSURE_FIELD_TYPE_PRESENT,
ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
--- a/hotspot/src/share/vm/services/classLoadingService.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/services/classLoadingService.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -164,7 +164,7 @@
class_size += k->size();
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
class_size += k->methods()->size();
// FIXME: Need to count the contents of methods
class_size += k->constants()->size();
--- a/hotspot/src/share/vm/services/heapDumper.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/services/heapDumper.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -722,7 +722,7 @@
o = oopDesc::load_decode_heap_oop((oop*)addr);
}
- // reflection and sun.misc.Unsafe classes may have a reference to a
+ // reflection and Unsafe classes may have a reference to a
// Klass* so filter it out.
assert(o->is_oop_or_null(), "Expected an oop or NULL at " PTR_FORMAT, p2i(o));
writer->write_objectID(o);
@@ -895,9 +895,7 @@
// creates HPROF_GC_CLASS_DUMP record for the given class and each of
// its array classes
void DumperSupport::dump_class_and_array_classes(DumpWriter* writer, Klass* k) {
- Klass* klass = k;
- assert(klass->oop_is_instance(), "not an InstanceKlass");
- InstanceKlass* ik = (InstanceKlass*)klass;
+ InstanceKlass* ik = InstanceKlass::cast(k);
// Ignore the class if it hasn't been initialized yet
if (!ik->is_linked()) {
@@ -939,10 +937,10 @@
dump_instance_field_descriptors(writer, k);
// array classes
- k = klass->array_klass_or_null();
+ k = k->array_klass_or_null();
while (k != NULL) {
Klass* klass = k;
- assert(klass->oop_is_objArray(), "not an ObjArrayKlass");
+ assert(klass->is_objArray_klass(), "not an ObjArrayKlass");
writer->write_u1(HPROF_GC_CLASS_DUMP);
writer->write_classID(klass);
@@ -1126,7 +1124,7 @@
writer->write_symbolID(m->name()); // method's name
writer->write_symbolID(m->signature()); // method's signature
- assert(m->method_holder()->oop_is_instance(), "not InstanceKlass");
+ assert(m->method_holder()->is_instance_klass(), "not InstanceKlass");
writer->write_symbolID(m->method_holder()->source_file_name()); // source file name
writer->write_u4(class_serial_num); // class serial number
writer->write_u4((u4) line_number); // line number
@@ -1248,7 +1246,7 @@
_writer = writer;
}
void do_klass(Klass* k) {
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
InstanceKlass* ik = InstanceKlass::cast(k);
writer()->write_u1(HPROF_GC_ROOT_STICKY_CLASS);
writer()->write_classID(ik);
@@ -1396,7 +1394,7 @@
if (oome) {
assert(!Thread::current()->is_VM_thread(), "Dump from OutOfMemoryError cannot be called by the VMThread");
// get OutOfMemoryError zero-parameter constructor
- InstanceKlass* oome_ik = InstanceKlass::cast(SystemDictionary::OutOfMemoryError_klass());
+ InstanceKlass* oome_ik = SystemDictionary::OutOfMemoryError_klass();
_oome_constructor = oome_ik->find_method(vmSymbols::object_initializer_name(),
vmSymbols::void_method_signature());
// get thread throwing OOME when generating the heap dump at OOME
@@ -1553,7 +1551,7 @@
// writes a HPROF_GC_CLASS_DUMP record for the given class
void VM_HeapDumper::do_class_dump(Klass* k) {
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
DumperSupport::dump_class_and_array_classes(writer(), k);
}
}
@@ -1850,7 +1848,6 @@
}
// dump the heap to given path.
-PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
int HeapDumper::dump(const char* path) {
assert(path != NULL && strlen(path) > 0, "path missing");
@@ -1888,13 +1885,8 @@
if (print_to_tty()) {
timer()->stop();
if (error() == NULL) {
- char msg[256];
- sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]",
- JLONG_FORMAT, timer()->seconds());
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
- tty->print_cr(msg, writer.bytes_written());
-PRAGMA_DIAG_POP
+ tty->print_cr("Heap dump file created [" JLONG_FORMAT " bytes in %3.3f secs]",
+ writer.bytes_written(), timer()->seconds());
} else {
tty->print_cr("Dump file is incomplete: %s", writer.error());
}
--- a/hotspot/src/share/vm/services/serviceUtil.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/services/serviceUtil.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -57,13 +57,13 @@
if (k->is_klass()) {
// if it's a class for an object, an object array, or
// primitive (type) array then it's visible.
- if (k->oop_is_instance()) {
+ if (k->is_instance_klass()) {
return true;
}
- if (k->oop_is_objArray()) {
+ if (k->is_objArray_klass()) {
return true;
}
- if (k->oop_is_typeArray()) {
+ if (k->is_typeArray_klass()) {
return true;
}
}
--- a/hotspot/src/share/vm/services/threadService.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/services/threadService.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -505,8 +505,7 @@
int len = (_locked_monitors != NULL ? _locked_monitors->length() : 0);
for (int i = 0; i < len; i++) {
oop o = _locked_monitors->at(i);
- InstanceKlass* ik = InstanceKlass::cast(o->klass());
- st->print_cr("\t- locked <" INTPTR_FORMAT "> (a %s)", p2i(o), ik->external_name());
+ st->print_cr("\t- locked <" INTPTR_FORMAT "> (a %s)", p2i(o), o->klass()->external_name());
}
}
@@ -729,8 +728,7 @@
for (int i = 0; i < locks->length(); i++) {
instanceOop obj = locks->at(i);
- InstanceKlass* ik = InstanceKlass::cast(obj->klass());
- st->print_cr("\t- <" INTPTR_FORMAT "> (a %s)", p2i(obj), ik->external_name());
+ st->print_cr("\t- <" INTPTR_FORMAT "> (a %s)", p2i(obj), obj->klass()->external_name());
}
st->cr();
}
@@ -887,7 +885,7 @@
oop obj = (oop)waitingToLockMonitor->object();
if (obj != NULL) {
st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
- (InstanceKlass::cast(obj->klass()))->external_name());
+ obj->klass()->external_name());
if (!currentThread->current_pending_monitor_is_from_java()) {
owner_desc = "\n in JNI, which is held by";
@@ -911,7 +909,7 @@
} else {
st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)",
p2i(waitingToLockBlocker),
- (InstanceKlass::cast(waitingToLockBlocker->klass()))->external_name());
+ waitingToLockBlocker->klass()->external_name());
assert(waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass()),
"Must be an AbstractOwnableSynchronizer");
oop ownerObj = java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(waitingToLockBlocker);
--- a/hotspot/src/share/vm/services/threadService.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/services/threadService.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -425,12 +425,12 @@
}
JavaThreadStatusChanger(JavaThread* java_thread,
- java_lang_Thread::ThreadStatus state) {
+ java_lang_Thread::ThreadStatus state) : _old_state(java_lang_Thread::NEW) {
save_old_state(java_thread);
set_thread_status(state);
}
- JavaThreadStatusChanger(JavaThread* java_thread) {
+ JavaThreadStatusChanger(JavaThread* java_thread) : _old_state(java_lang_Thread::NEW) {
save_old_state(java_thread);
}
@@ -527,7 +527,7 @@
// Current thread is the notifying thread which holds the monitor.
static bool wait_reenter_begin(JavaThread *java_thread, ObjectMonitor *obj_m) {
assert((java_thread != NULL), "Java thread should not be null here");
- bool active = false;
+ bool active = false;
if (is_alive(java_thread) && ServiceUtil::visible_oop((oop)obj_m->object())) {
active = contended_enter_begin(java_thread);
}
@@ -542,7 +542,7 @@
}
JavaThreadBlockedOnMonitorEnterState(JavaThread *java_thread, ObjectMonitor *obj_m) :
- JavaThreadStatusChanger(java_thread) {
+ _stat(NULL), _active(false), JavaThreadStatusChanger(java_thread) {
assert((java_thread != NULL), "Java thread should not be null here");
// Change thread status and collect contended enter stats for monitor contended
// enter done for external java world objects and it is contended. All other cases
--- a/hotspot/src/share/vm/services/writeableFlags.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/services/writeableFlags.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -57,7 +57,6 @@
}
}
-PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
static void print_flag_error_message_if_needed(Flag::Error error, const char* name, FormatBuffer<80>& err_msg) {
if (error == Flag::SUCCESS) {
return;
--- a/hotspot/src/share/vm/shark/sharkCompiler.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -223,7 +223,7 @@
}
nmethod* SharkCompiler::generate_native_wrapper(MacroAssembler* masm,
- methodHandle target,
+ const methodHandle& target,
int compile_id,
BasicType* arg_types,
BasicType return_type) {
--- a/hotspot/src/share/vm/shark/sharkCompiler.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/shark/sharkCompiler.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -47,7 +47,7 @@
// Missing feature tests
bool supports_native() { return true; }
bool supports_osr() { return true; }
- bool can_compile_method(methodHandle method) {
+ bool can_compile_method(const methodHandle& method) {
return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form());
}
@@ -62,7 +62,7 @@
// Generate a wrapper for a native (JNI) method
nmethod* generate_native_wrapper(MacroAssembler* masm,
- methodHandle target,
+ const methodHandle& target,
int compile_id,
BasicType* arg_types,
BasicType return_type);
--- a/hotspot/src/share/vm/shark/sharkIntrinsics.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/shark/sharkIntrinsics.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -65,7 +65,7 @@
case vmIntrinsics::_currentThread:
return true;
- // sun.misc.Unsafe
+ // Unsafe
case vmIntrinsics::_compareAndSwapInt:
return true;
@@ -139,7 +139,7 @@
do_Thread_currentThread();
break;
- // sun.misc.Unsafe
+ // Unsafe
case vmIntrinsics::_compareAndSwapInt:
do_Unsafe_compareAndSwapInt();
break;
--- a/hotspot/src/share/vm/utilities/exceptions.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -222,7 +222,7 @@
}
-void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) {
+void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, const methodHandle& method) {
Handle exception;
if (!THREAD->has_pending_exception()) {
Klass* k = SystemDictionary::StackOverflowError_klass();
@@ -502,5 +502,5 @@
message = java_lang_String::as_utf8_string(msg);
}
}
- debug_check_abort(InstanceKlass::cast(exception()->klass())->external_name(), message);
+ debug_check_abort(exception()->klass()->external_name(), message);
}
--- a/hotspot/src/share/vm/utilities/exceptions.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -163,7 +163,7 @@
const char* message,
ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
- static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method);
+ static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, const methodHandle& method);
// Exception counting for error files of interesting exceptions that may have
// caused a problem for the jvm
--- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -287,8 +287,6 @@
// Tested to work with clang version 3.1 and better.
#define PRAGMA_DIAG_PUSH _Pragma("GCC diagnostic push")
#define PRAGMA_DIAG_POP _Pragma("GCC diagnostic pop")
-#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
-#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED
// Hack to deal with gcc yammering about non-security format stuff
#else
@@ -297,8 +295,6 @@
// versions of the macro-pragma to obtain better checking with newer compilers.
#define PRAGMA_DIAG_PUSH
#define PRAGMA_DIAG_POP
-#define PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL PRAGMA_FORMAT_NONLITERAL_IGNORED
-#define PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
#endif
#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
--- a/hotspot/src/share/vm/utilities/utf8.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/utilities/utf8.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
// Assume the utf8 string is in legal form and has been
// checked in the class file parser/format checker.
-char* UTF8::next(const char* str, jchar* value) {
+template<typename T> char* UTF8::next(const char* str, T* value) {
unsigned const char *ptr = (const unsigned char *)str;
unsigned char ch, ch2, ch3;
int length = -1; /* bad length */
@@ -68,11 +68,11 @@
} /* end of switch */
if (length <= 0) {
- *value = ptr[0]; /* default bad result; */
+ *value = (T)ptr[0]; /* default bad result; */
return (char*)(ptr + 1); // make progress somehow
}
- *value = result;
+ *value = (T)result;
// The assert is correct but the .class file is wrong
// assert(UNICODE::utf8_size(result) == length, "checking reverse computation");
@@ -96,12 +96,22 @@
// Count bytes of the form 10xxxxxx and deduct this count
// from the total byte count. The utf8 string must be in
// legal form which has been verified in the format checker.
-int UTF8::unicode_length(const char* str, int len) {
+int UTF8::unicode_length(const char* str, int len, bool& is_latin1, bool& has_multibyte) {
int num_chars = len;
+ has_multibyte = false;
+ is_latin1 = true;
+ unsigned char prev = 0;
for (int i = 0; i < len; i++) {
- if ((str[i] & 0xC0) == 0x80) {
+ unsigned char c = str[i];
+ if ((c & 0xC0) == 0x80) {
+ // Multibyte, check if valid latin1 character.
+ has_multibyte = true;
+ if (prev > 0xC3) {
+ is_latin1 = false;
+ }
--num_chars;
}
+ prev = c;
}
return num_chars;
}
@@ -110,17 +120,28 @@
// 10xxxxxx which only appear in multibyte characters.
// The utf8 string must be in legal form and has been
// verified in the format checker.
-int UTF8::unicode_length(const char* str) {
+int UTF8::unicode_length(const char* str, bool& is_latin1, bool& has_multibyte) {
int num_chars = 0;
+ has_multibyte = false;
+ is_latin1 = true;
+ unsigned char prev = 0;
for (const char* p = str; *p; p++) {
- if (((*p) & 0xC0) != 0x80) {
+ unsigned char c = (*p);
+ if ((c & 0xC0) == 0x80) {
+ // Multibyte, check if valid latin1 character.
+ has_multibyte = true;
+ if (prev > 0xC3) {
+ is_latin1 = false;
+ }
+ } else {
num_chars++;
}
+ prev = c;
}
return num_chars;
}
-// Writes a jchar a utf8 and returns the end
+// Writes a jchar as utf8 and returns the end
static u_char* utf8_write(u_char* base, jchar ch) {
if ((ch != 0) && (ch <=0x7f)) {
base[0] = (u_char) ch;
@@ -145,7 +166,7 @@
return base + 3;
}
-void UTF8::convert_to_unicode(const char* utf8_str, jchar* unicode_str, int unicode_length) {
+template<typename T> void UTF8::convert_to_unicode(const char* utf8_str, T* unicode_str, int unicode_length) {
unsigned char ch;
const char *ptr = utf8_str;
int index = 0;
@@ -153,7 +174,7 @@
/* ASCII case loop optimization */
for (; index < unicode_length; index++) {
if((ch = ptr[0]) > 0x7F) { break; }
- unicode_str[index] = ch;
+ unicode_str[index] = (T)ch;
ptr = (const char *)(ptr + 1);
}
@@ -162,6 +183,12 @@
}
}
+// Explicit instantiation for all supported string types.
+template char* UTF8::next<jchar>(const char* str, jchar* value);
+template char* UTF8::next<jbyte>(const char* str, jbyte* value);
+template void UTF8::convert_to_unicode<jchar>(const char* utf8_str, jchar* unicode_str, int unicode_length);
+template void UTF8::convert_to_unicode<jbyte>(const char* utf8_str, jbyte* unicode_str, int unicode_length);
+
// returns the quoted ascii length of a 0-terminated utf8 string
int UTF8::quoted_ascii_length(const char* utf8_str, int utf8_length) {
const char *ptr = utf8_str;
@@ -306,9 +333,20 @@
+ ((str[4] & 0x0f) << 6) + (str[5] & 0x3f);
}
-
//-------------------------------------------------------------------------------------
+bool UNICODE::is_latin1(jchar c) {
+ return (c <= 0x00FF);
+}
+
+bool UNICODE::is_latin1(jchar* base, int length) {
+ for (int index = 0; index < length; index++) {
+ if (base[index] > 0x00FF) {
+ return false;
+ }
+ }
+ return true;
+}
int UNICODE::utf8_size(jchar c) {
if ((0x0001 <= c) && (c <= 0x007F)) return 1;
@@ -316,6 +354,11 @@
return 3;
}
+int UNICODE::utf8_size(jbyte c) {
+ if (c >= 0x0001) return 1;
+ return 2;
+}
+
int UNICODE::utf8_length(jchar* base, int length) {
int result = 0;
for (int index = 0; index < length; index++) {
@@ -327,6 +370,15 @@
return result;
}
+int UNICODE::utf8_length(jbyte* base, int length) {
+ int result = 0;
+ for (int index = 0; index < length; index++) {
+ jbyte c = base[index];
+ result += utf8_size(c);
+ }
+ return result;
+}
+
char* UNICODE::as_utf8(jchar* base, int length) {
int utf8_len = utf8_length(base, length);
u_char* buf = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1);
@@ -335,6 +387,26 @@
return result;
}
+char* UNICODE::as_utf8(jbyte* base, int length) {
+ int utf8_len = utf8_length(base, length);
+ u_char* result = NEW_RESOURCE_ARRAY(u_char, utf8_len + 1);
+ u_char* p = result;
+ if (utf8_len == length) {
+ for (int index = 0; index < length; index++) {
+ *p++ = base[index];
+ }
+ } else {
+ // Unicode string contains U+0000 which should
+ // be encoded as 0xC080 in "modified" UTF8.
+ for (int index = 0; index < length; index++) {
+ p = utf8_write(p, ((jchar) base[index]) & 0xff);
+ }
+ }
+ *p = '\0';
+ assert(p == &result[utf8_len], "length prediction must be correct");
+ return (char*) result;
+}
+
char* UNICODE::as_utf8(jchar* base, int length, char* buf, int buflen) {
u_char* p = (u_char*)buf;
for (int index = 0; index < length; index++) {
@@ -347,6 +419,26 @@
return buf;
}
+char* UNICODE::as_utf8(jbyte* base, int length, char* buf, int buflen) {
+ u_char* p = (u_char*)buf;
+ u_char* end = (u_char*)buf + buflen;
+ for (int index = 0; index < length; index++) {
+ jbyte c = base[index];
+ int sz = utf8_size(c);
+ buflen -= sz;
+ if (buflen <= 0) break; // string is truncated
+ if (sz == 1) {
+ *p++ = c;
+ } else {
+ // Unicode string contains U+0000 which should
+ // be encoded as 0xC080 in "modified" UTF8.
+ p = utf8_write(p, ((jchar) c) & 0xff);
+ }
+ }
+ *p = '\0';
+ return buf;
+}
+
void UNICODE::convert_to_utf8(const jchar* base, int length, char* utf8_buffer) {
for(int index = 0; index < length; index++) {
utf8_buffer = (char*)utf8_write((u_char*)utf8_buffer, base[index]);
@@ -355,10 +447,11 @@
}
// returns the quoted ascii length of a unicode string
-int UNICODE::quoted_ascii_length(jchar* base, int length) {
+template<typename T>
+int UNICODE::quoted_ascii_length(T* base, int length) {
int result = 0;
for (int i = 0; i < length; i++) {
- jchar c = base[i];
+ T c = base[i];
if (c >= 32 && c < 127) {
result++;
} else {
@@ -368,12 +461,13 @@
return result;
}
-// converts a utf8 string to quoted ascii
-void UNICODE::as_quoted_ascii(const jchar* base, int length, char* buf, int buflen) {
+// converts a unicode string to quoted ascii
+template<typename T>
+void UNICODE::as_quoted_ascii(const T* base, int length, char* buf, int buflen) {
char* p = buf;
char* end = buf + buflen;
for (int index = 0; index < length; index++) {
- jchar c = base[index];
+ T c = base[index];
if (c >= 32 && c < 127) {
if (p + 1 >= end) break; // string is truncated
*p++ = (char)c;
@@ -386,6 +480,13 @@
*p = '\0';
}
+// Explicit instantiation for all supported types.
+template int UNICODE::quoted_ascii_length<jbyte>(jbyte* base, int length);
+template int UNICODE::quoted_ascii_length<jchar>(jchar* base, int length);
+template void UNICODE::as_quoted_ascii<jbyte>(const jbyte* base, int length, char* buf, int buflen);
+template void UNICODE::as_quoted_ascii<jchar>(const jchar* base, int length, char* buf, int buflen);
+
+
#ifndef PRODUCT
void TestAsUtf8() {
char res[60];
--- a/hotspot/src/share/vm/utilities/utf8.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/utilities/utf8.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,13 +33,21 @@
class UTF8 : AllStatic {
public:
// returns the unicode length of a 0-terminated utf8 string
- static int unicode_length(const char* utf8_str);
+ static int unicode_length(const char* utf8_str) {
+ bool is_latin1, has_multibyte;
+ return unicode_length(utf8_str, is_latin1, has_multibyte);
+ }
+ static int unicode_length(const char* utf8_str, bool& is_latin1, bool& has_multibyte);
// returns the unicode length of a non-0-terminated utf8 string
- static int unicode_length(const char* utf8_str, int len);
+ static int unicode_length(const char* utf8_str, int len) {
+ bool is_latin1, has_multibyte;
+ return unicode_length(utf8_str, len, is_latin1, has_multibyte);
+ }
+ static int unicode_length(const char* utf8_str, int len, bool& is_latin1, bool& has_multibyte);
// converts a utf8 string to a unicode string
- static void convert_to_unicode(const char* utf8_str, jchar* unicode_buffer, int unicode_length);
+ template<typename T> static void convert_to_unicode(const char* utf8_str, T* unicode_str, int unicode_length);
// returns the quoted ascii length of a utf8 string
static int quoted_ascii_length(const char* utf8_str, int utf8_length);
@@ -53,7 +61,7 @@
// decodes the current utf8 character, stores the result in value,
// and returns the end of the current utf8 chararacter.
- static char* next(const char* str, jchar* value);
+ template<typename T> static char* next(const char* str, T* value);
// decodes the current utf8 character, gets the supplementary character instead of
// the surrogate pair when seeing a supplementary character in string,
@@ -76,11 +84,19 @@
class UNICODE : AllStatic {
public:
+ // checks if the given unicode character can be encoded as latin1
+ static bool is_latin1(jchar c);
+
+ // checks if the given string can be encoded as latin1
+ static bool is_latin1(jchar* base, int length);
+
// returns the utf8 size of a unicode character
static int utf8_size(jchar c);
+ static int utf8_size(jbyte c);
// returns the utf8 length of a unicode string
static int utf8_length(jchar* base, int length);
+ static int utf8_length(jbyte* base, int length);
// converts a unicode string to utf8 string
static void convert_to_utf8(const jchar* base, int length, char* utf8_buffer);
@@ -88,13 +104,15 @@
// converts a unicode string to a utf8 string; result is allocated
// in resource area unless a buffer is provided.
static char* as_utf8(jchar* base, int length);
+ static char* as_utf8(jbyte* base, int length);
static char* as_utf8(jchar* base, int length, char* buf, int buflen);
+ static char* as_utf8(jbyte* base, int length, char* buf, int buflen);
// returns the quoted ascii length of a unicode string
- static int quoted_ascii_length(jchar* base, int length);
+ template<typename T> static int quoted_ascii_length(T* base, int length);
- // converts a utf8 string to quoted ascii
- static void as_quoted_ascii(const jchar* base, int length, char* buf, int buflen);
+ // converts a unicode string to quoted ascii
+ template<typename T> static void as_quoted_ascii(const T* base, int length, char* buf, int buflen);
};
#endif // SHARE_VM_UTILITIES_UTF8_HPP
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/src/share/vm/utilities/xmlstream.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -340,6 +340,7 @@
print_raw_cr(">");
}
+// If you remove the PRAGMA, this fails to compile with clang-503.0.40.
PRAGMA_DIAG_PUSH
PRAGMA_FORMAT_NONLITERAL_IGNORED
// ------------------------------------------------------------------
--- a/hotspot/test/Makefile Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/Makefile Wed Jul 05 21:00:20 2017 +0200
@@ -243,6 +243,9 @@
$(ECHO) "Running tests: $@"
$(MAKE) -j 1 TEST_SELECTION=":$@" UNIQUE_DIR=$@ jtreg_tests;
+hotspot_internal:
+ $(ALT_OUTPUTDIR)/jdk/bin/java -XX:+ExecuteInternalVMTests -XX:+ShowMessageBoxOnError -version
+
# Prep for output
prep: clean
@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
--- a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOff.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOff.java Wed Jul 05 21:00:20 2017 +0200
@@ -33,11 +33,12 @@
* @build sun.hotspot.WhiteBox.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run testng/othervm -Xbootclasspath/a:. -XX:-PrintAssembly -XX:CompileCommand=option,*.helper,bool,PrintAssembly,false -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestCompilerDirectivesCompatibilityCommandOff
+ * @run testng/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:-PrintAssembly -XX:CompileCommand=option,*.helper,bool,PrintAssembly,false
+ * -XX:+WhiteBoxAPI TestCompilerDirectivesCompatibilityCommandOff
* @summary Test compiler control compatibility with compile command
*/
-// import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.dcmd.CommandExecutor;
import jdk.test.lib.dcmd.JMXExecutor;
--- a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOn.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityCommandOn.java Wed Jul 05 21:00:20 2017 +0200
@@ -33,11 +33,12 @@
* @build sun.hotspot.WhiteBox.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run testng/othervm -Xbootclasspath/a:. -XX:-PrintAssembly -XX:CompileCommand=print,*.* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestCompilerDirectivesCompatibilityCommandOn
+ * @run testng/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:-PrintAssembly -XX:CompileCommand=print,*.* -XX:+WhiteBoxAPI
+ * TestCompilerDirectivesCompatibilityCommandOn
* @summary Test compiler control compatibility with compile command
*/
-// import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.dcmd.CommandExecutor;
import jdk.test.lib.dcmd.JMXExecutor;
--- a/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityFlag.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/compilercontrol/TestCompilerDirectivesCompatibilityFlag.java Wed Jul 05 21:00:20 2017 +0200
@@ -33,7 +33,8 @@
* @build sun.hotspot.WhiteBox.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run testng/othervm -Xbootclasspath/a:. -XX:+PrintAssembly -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI TestCompilerDirectivesCompatibilityFlag
+ * @run testng/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
+ * -XX:+PrintAssembly -XX:+WhiteBoxAPI TestCompilerDirectivesCompatibilityFlag
* @summary Test compiler control compatibility with compile command
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/string/TestStringIntrinsics.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.Arrays;
+
+/*
+ * @test
+ * @bug 8054307
+ * @summary Tests correctness of string related intrinsics and C2 optimizations.
+ * @run main/timeout=240 TestStringIntrinsics
+ */
+public class TestStringIntrinsics {
+
+ public enum Operation {
+ ARR_EQUALS_B, ARR_EQUALS_C, EQUALS, COMPARE_TO, INDEX_OF, INDEX_OF_CON_U, INDEX_OF_CON_L,
+ INDEX_OF_CON_UL, CONCAT, CONCAT_C, CONCAT_I, CONCAT_M, INDEX_OF_CHAR
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ @interface Test {
+ Operation op();
+ String constString() default "";
+ String[] inStrings() default {};
+ char[] inChars() default {};
+ int[] inInts() default {};
+ String[] outStrings() default {};
+ }
+
+ public static void main(String[] args) throws Exception {
+ new TestStringIntrinsics().run();
+ }
+
+ public void run() throws Exception {
+ // Build latin1 and UTF16 strings
+ StringBuilder latin1Builder = new StringBuilder();
+ for (int i = 0; i <= 255; ++i) {
+ latin1Builder.append((char) i);
+ }
+ String latin1 = latin1Builder.toString();
+ StringBuilder utf16Builder = new StringBuilder();
+ for (int i = 0; i <= 10000; ++i) {
+ utf16Builder.append((char) i);
+ }
+ String utf16 = utf16Builder.toString();
+
+ // Invoke test methods
+ for (Method m : TestStringIntrinsics.class.getMethods()) {
+ if (m.isAnnotationPresent(Test.class)) {
+ System.out.print("Checking " + m.getName() + "... ");
+ Operation op = m.getAnnotation(Test.class).op();
+ Test antn = m.getAnnotation(Test.class);
+ if (isStringConcatTest(op)) {
+ checkStringConcat(op, m, antn);
+ } else {
+ checkIntrinsics(op, m, latin1, utf16, antn);
+ }
+ System.out.println("Done.");
+ }
+ }
+ }
+
+ private boolean isStringConcatTest(Operation op) {
+ return op == Operation.CONCAT ||
+ op == Operation.CONCAT_C ||
+ op == Operation.CONCAT_I ||
+ op == Operation.CONCAT_M;
+ }
+
+ /**
+ * Checks correctness of the String.equals, String.compareTo and String.indexOf intrinsics.
+ * -XX:SpecialStringEquals
+ * -XX:SpecialStringCompareTo
+ * -XX:SpecialStringIndexOf
+ */
+ private void checkIntrinsics(Operation op, Method m, String latin1, String utf16, Test antn) throws Exception {
+ for (int i = 0; i < 50_000; ++i) {
+ // Copy and permute latin1 and UTF16 string
+ char[] arrL = latin1.toCharArray();
+ int indexL = i % arrL.length;
+ int mod = (arrL.length - arrL[indexL]);
+ int incL = i % ((mod != 0) ? mod : 1);
+ arrL[indexL] = (char) ((int) arrL[indexL] + incL);
+ String latin1Copy = String.valueOf(arrL);
+
+ char[] arrU = utf16.toCharArray();
+ int indexU = i % arrU.length;
+ mod = (arrU.length - arrU[indexU]);
+ int incU = i % ((mod != 0) ? mod : 1);
+ arrU[indexU] = (char) ((int) arrU[indexU] + incU);
+ String utf16Copy = String.valueOf(arrU);
+
+ switch (op) {
+ case ARR_EQUALS_B:
+ invokeAndCheck(m, (incL == 0), latin1.getBytes("ISO-8859-1"), latin1Copy.getBytes("ISO-8859-1"));
+ invokeAndCheck(m, true, new byte[] {1, 2, 3}, new byte[] {1, 2, 3});
+ invokeAndCheck(m, true, new byte[] {1}, new byte[] {1});
+ invokeAndCheck(m, true, new byte[] {}, new byte[] {});
+ break;
+ case ARR_EQUALS_C:
+ invokeAndCheck(m, (incU == 0), utf16.toCharArray(), arrU);
+ break;
+ case EQUALS:
+ invokeAndCheck(m, (incL == 0), latin1, latin1Copy);
+ invokeAndCheck(m, false, latin1, "");
+ invokeAndCheck(m, false, "", latin1);
+
+ invokeAndCheck(m, (incU == 0), utf16, utf16Copy);
+ invokeAndCheck(m, false, utf16, "");
+ invokeAndCheck(m, false, "", utf16);
+
+ invokeAndCheck(m, false, latin1, utf16);
+ break;
+ case COMPARE_TO:
+ invokeAndCheck(m, -incL, latin1, latin1Copy);
+ invokeAndCheck(m, latin1.length(), latin1, "");
+
+ invokeAndCheck(m, -incU, utf16, utf16Copy);
+ invokeAndCheck(m, utf16.length(), utf16, "");
+
+ // Cross coder
+ char cL = latin1.charAt(indexL);
+ char cU = utf16.charAt(indexU);
+ invokeAndCheck(m, cL - cU, latin1, latin1.replace(cL, cU));
+ invokeAndCheck(m, cU - cL, utf16, utf16.replace(cU, cL));
+
+ // Different lengths
+ invokeAndCheck(m, 1, "ABCD", "ABC");
+ invokeAndCheck(m, -1, "\uff21\uff22\uff23", "\uff21\uff22\uff23\uff24");
+ invokeAndCheck(m, 1, "ABC\uff24", "ABC");
+ invokeAndCheck(m, 3, "ABC\uff24\uff25\uff26", "ABC");
+ invokeAndCheck(m, -1, "ABC","ABC\uff24");
+ invokeAndCheck(m, -3, "ABC","ABC\uff24\uff25\uff26");
+ break;
+ case INDEX_OF:
+ invokeAndCheck(m, indexL, latin1, latin1.substring(indexL), (indexL > 42) ? 42 : 0);
+ invokeAndCheck(m, 0, latin1, "", 0);
+
+ invokeAndCheck(m, indexU, utf16, utf16.substring(indexU), (indexU > 42) ? 42 : 0);
+ invokeAndCheck(m, 0, utf16, "", 0);
+
+ // Cross coder
+ invokeAndCheck(m, -1, latin1.substring(0, indexL), utf16.substring(indexU), (indexL > 42) ? 42 : 0);
+ // Skip latin1 chars in utf16 string
+ int start = 256;
+ int end = indexU > start ? indexU : start;
+ invokeAndCheck(m, end-start, utf16.substring(start, end) + latin1.substring(indexL), latin1.substring(indexL), 0);
+ break;
+ case INDEX_OF_CON_L:
+ invokeAndCheck(m, antn.constString(), latin1);
+ break;
+ case INDEX_OF_CON_U:
+ invokeAndCheck(m, antn.constString(), utf16);
+ break;
+ case INDEX_OF_CON_UL:
+ invokeAndCheck(m, antn.constString(), utf16);
+ break;
+ case INDEX_OF_CHAR:
+ invokeAndCheck(m, 7, "abcdefg\uD800\uDC00", 65536, 0);
+ invokeAndCheck(m, -1, "abcdefg\uD800\uDC01", 65536, 0);
+ invokeAndCheck(m, -1, "abcdefg\uD800", 65536, 0);
+ invokeAndCheck(m, 3, "abc\u0107", 263, 0);
+ invokeAndCheck(m, -1, "abc\u0108", 263, 0);
+ invokeAndCheck(m, 7, "abcdefg\u0107", 263, 0);
+ invokeAndCheck(m, 7, "abcdefg\u0107", 263, -1);
+ invokeAndCheck(m, 0, "\u0107", 263, 0);
+ break;
+ default:
+ throw new RuntimeException("Unexpected operation.");
+ }
+ }
+ }
+
+ /**
+ * Checks correctness of the C2 string concatenation optimization.
+ * -XX:OptimizeStringConcat
+ */
+ private void checkStringConcat(Operation op, Method m, Test antn) throws Exception {
+ for (int i = 0; i < 50_000; ++i) {
+ String[] result = antn.outStrings();
+ switch(op) {
+ case CONCAT:
+ String[] strs = antn.inStrings();
+ for (int j = 0; j < strs.length; ++j) {
+ invokeAndCheck(m, result[j], strs[j]);
+ }
+ break;
+ case CONCAT_C:
+ char[] ch = antn.inChars();
+ for (int j = 0; j < ch.length; ++j) {
+ invokeAndCheck(m, result[j], ch[j]);
+ }
+ break;
+ case CONCAT_I:
+ int[] k = antn.inInts();
+ for (int j = 0; j < k.length; ++j) {
+ invokeAndCheck(m, result[j], k[j]);
+ }
+ break;
+ case CONCAT_M:
+ strs = antn.inStrings();
+ ch = antn.inChars();
+ k = antn.inInts();
+ for (int j = 0; j < strs.length; ++j) {
+ invokeAndCheck(m, result[j], strs[j], ch[j], k[j]);
+ }
+ break;
+ default:
+ throw new RuntimeException("Unexpected operation.");
+ }
+ }
+ }
+
+ /**
+ * Invokes method 'm' by passing arguments 'args' and checks if the
+ * returned value equals 'expectedResult'.
+ */
+ private void invokeAndCheck(Method m, Object expectedResult, Object... args) throws Exception {
+ Object result = m.invoke(null, args);
+ if (!result.equals(expectedResult)) {
+// System.out.println("Expected:");
+// System.out.println(expectedResult);
+// System.out.println("Returned:");
+// System.out.println(result);
+ throw new RuntimeException("Result of '" + m.getName() + "' not equal to expected value.");
+ }
+ }
+
+ /*
+ * Constants
+ */
+ static final char charU = '\uff21';
+ static final char charL = 'A';
+ static final String emptyString = "";
+ static final String stringL = "abcdefghijklmnop";
+ static final String stringSmallL = "abc";
+ static final String stringU = "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28";
+ static final String stringSmallU = "\u0f21\u0f22\u0f23";
+ static final int constInt = 123;
+ static final int constIntNeg = -123;
+
+ /*
+ * Arrays.equals
+ */
+ @Test(op = Operation.ARR_EQUALS_B)
+ public static boolean arrayEqualsB(byte[] a, byte[] b) {
+ return Arrays.equals(a, b);
+ }
+
+ @Test(op = Operation.ARR_EQUALS_C)
+ public static boolean arrayEqualsC(char[] a, char[] b) {
+ return Arrays.equals(a, b);
+ }
+
+ /*
+ * String.equals
+ */
+ @Test(op = Operation.EQUALS)
+ public static boolean equals(String a, String b) {
+ return a.equals(b);
+ }
+
+ /*
+ * String.compareTo
+ */
+ @Test(op = Operation.COMPARE_TO)
+ public static int compareTo(String a, String b) {
+ return a.compareTo(b);
+ }
+
+ /*
+ * String.indexOf
+ */
+ @Test(op = Operation.INDEX_OF)
+ public static int indexOf(String a, String b, int from) {
+ return a.indexOf(b, from);
+ }
+
+ @Test(op = Operation.INDEX_OF_CON_U, constString = stringSmallU)
+ public static String indexOfConstU(String a) {
+ int result = a.indexOf(stringSmallU);
+ return a.substring(result, result + stringSmallU.length());
+ }
+
+ @Test(op = Operation.INDEX_OF_CON_U, constString = stringU)
+ public static String indexOfConstLargeU(String a) {
+ int result = a.indexOf(stringU);
+ return a.substring(result, result + stringU.length());
+ }
+
+ @Test(op = Operation.INDEX_OF_CON_U, constString = emptyString)
+ public static String indexOfConstEmptyU(String a) {
+ int result = a.indexOf(emptyString);
+ return a.substring(result, result + emptyString.length());
+ }
+
+ @Test(op = Operation.INDEX_OF_CON_L, constString = stringSmallL)
+ public static String indexOfConstL(String a) {
+ int result = a.indexOf(stringSmallL);
+ return a.substring(result, result + stringSmallL.length());
+ }
+
+ @Test(op = Operation.INDEX_OF_CON_L, constString = stringL)
+ public static String indexOfConstLargeL(String a) {
+ int result = a.indexOf(stringL);
+ return a.substring(result, result + stringL.length());
+ }
+
+ @Test(op = Operation.INDEX_OF_CON_L, constString = emptyString)
+ public static String indexOfConstEmptyL(String a) {
+ int result = a.indexOf(emptyString);
+ return a.substring(result, result + emptyString.length());
+ }
+
+ @Test(op = Operation.INDEX_OF_CON_UL, constString = stringSmallL)
+ public static String indexOfConstUL(String a) {
+ int result = a.indexOf(stringSmallL);
+ return a.substring(result, result + stringSmallL.length());
+ }
+
+ @Test(op = Operation.INDEX_OF_CON_UL, constString = stringL)
+ public static String indexOfConstLargeUL(String a) {
+ int result = a.indexOf(stringL);
+ return a.substring(result, result + stringL.length());
+ }
+
+ @Test(op = Operation.INDEX_OF_CHAR)
+ public static int indexOfChar(String a, int ch, int from) {
+ return a.indexOf(ch, from);
+ }
+
+ /*
+ * String concatenation optimization
+ */
+ @Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"ABC", "\uff21\uff22\uff23"})
+ public static String concatString(String a) {
+ return new StringBuilder().append(a).toString();
+ }
+
+ @Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {""})
+ public static String concatStringEmpty(String a) {
+ return new StringBuilder().toString();
+ }
+
+ @Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"null"})
+ public static String concatStringNull(String a) {
+ return new StringBuilder().append((String)null).toString();
+ }
+
+ @Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"abcdefghijklmnopABCabc", "abcdefghijklmnop\uff21\uff22\uff23abc"})
+ public static String concatStringConstL(String a) {
+ return new StringBuilder().append(stringL).append(a).append(stringSmallL).toString();
+ }
+
+ @Test(op = Operation.CONCAT, inStrings = {"ABC", "\uff21\uff22\uff23"}, outStrings = {"\u0f21\u0f22\u0f23ABC\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28", "\u0f21\u0f22\u0f23\uff21\uff22\uff23\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28"})
+ public static String concatStringConstU(String a) {
+ return new StringBuilder().append(stringSmallU).append(a).append(stringU).toString();
+ }
+
+ @Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"A", "\uff21"})
+ public static String concatChar(char a) {
+ return new StringBuilder().append(a).toString();
+ }
+
+ @Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"abcdefghijklmnopAabcA\uff21", "abcdefghijklmnop\uff21abcA\uff21"})
+ public static String concatCharConstL(char a) {
+ return new StringBuilder().append(stringL).append(a).append(stringSmallL).append(charL).append(charU).toString();
+ }
+
+ @Test(op = Operation.CONCAT_C, inChars = {'A', '\uff21'}, outStrings = {"\u0f21\u0f22\u0f23A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21A", "\u0f21\u0f22\u0f23\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21A"})
+ public static String concatCharConstU(char a) {
+ return new StringBuilder().append(stringSmallU).append(a).append(stringU).append(charU).append(charL).toString();
+ }
+
+ @Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"-2147483648", "-42", "42", "2147483647"})
+ public static String concatInt(int a) {
+ return new StringBuilder().append(a).toString();
+ }
+
+ @Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"abcdefghijklmnop-2147483648abc123-123", "abcdefghijklmnop-42abc123-123", "abcdefghijklmnop42abc123-123", "abcdefghijklmnop2147483647abc123-123"})
+ public static String concatIntConstL(int b) {
+ return new StringBuilder().append(stringL).append(b).append(stringSmallL).append(constInt).append(constIntNeg).toString();
+ }
+
+ @Test(op = Operation.CONCAT_I, inInts = {Integer.MIN_VALUE, -42, 42, Integer.MAX_VALUE}, outStrings = {"\u0f21\u0f22\u0f23-2147483648\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f23-42\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f2342\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123", "\u0f21\u0f22\u0f232147483647\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28123-123"})
+ public static String concatIntConstU(int b) {
+ return new StringBuilder().append(stringSmallU).append(b).append(stringU).append(constInt).append(constIntNeg).toString();
+ }
+
+ @Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"nullabcabcdefghijklmnopA123-123"})
+ public static String concatConstL(String a) {
+ return new StringBuilder().append((String)null).append(stringSmallL).append(stringL).append(charL).append(constInt).append(constIntNeg).toString();
+ }
+
+ @Test(op = Operation.CONCAT, inStrings = {""}, outStrings = {"nullabcabcdefghijklmnop\u0f21\u0f22\u0f23\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A\uff21123-123"})
+ public static String concatConstU(String a) {
+ return new StringBuilder().append((String)null).append(stringSmallL).append(stringL).append(stringSmallU).append(stringU).append(charL).append(charU).append(constInt).append(constIntNeg).toString();
+ }
+
+ @Test(op = Operation.CONCAT_M,
+ inStrings = {"ABCDEFG", "ABCDEFG", "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28", "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28"},
+ inChars = {'A', '\uff21', 'A', '\uff21'},
+ inInts = {Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE},
+ outStrings = {"ABCDEFGA-2147483648nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21ABCDEFGA-2147483648null",
+ "ABCDEFG\uff212147483647nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21ABCDEFG\uff212147483647null",
+ "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A-2147483648nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28A-2147483648null",
+ "\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff212147483647nullabcdefghijklmnop123-123A\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff21\u0f21\u0f22\u0f23\u0f24\u0f25\u0f26\u0f27\u0f28\uff212147483647null"})
+ public static String concatMixed(String a, char b, int c) {
+ return new StringBuilder().append(a).append(b).append(c).append((String)null)
+ .append(stringL).append(constInt).append(constIntNeg).append(charL).append(stringU).append(charU)
+ .append(a).append(b).append(c).append((String)null).toString();
+ }
+}
--- a/hotspot/test/compiler/intrinsics/unsafe/HeapByteBufferTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/intrinsics/unsafe/HeapByteBufferTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -23,21 +23,22 @@
//
//
-import jdk.test.lib.Utils;
-import static java.lang.Math.abs;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
import static java.nio.ByteOrder.BIG_ENDIAN;
import static java.nio.ByteOrder.LITTLE_ENDIAN;
+import java.nio.ByteOrder;
+import java.util.Arrays;
import java.util.Random;
-import java.util.Arrays;
+import jdk.test.lib.Utils;
/**
* @test
* @bug 8026049
* @library /testlibrary
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:-UseUnalignedAccesses HeapByteBufferTest
- * @run main/othervm HeapByteBufferTest
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:-UseUnalignedAccesses -Djdk.test.lib.random.seed=0 HeapByteBufferTest
+ * @run main/othervm -Djdk.test.lib.random.seed=0 HeapByteBufferTest
* @summary Verify that byte buffers are correctly accessed.
*/
@@ -345,7 +346,149 @@
return result;
}
+ enum PrimitiveType {
+ BYTE(1), CHAR(2), SHORT(2), INT(4), LONG(8), FLOAT(4), DOUBLE(8);
+
+ public final int size;
+ PrimitiveType(int size) {
+ this.size = size;
+ }
+ }
+
+ void getOne(ByteBuffer b, PrimitiveType t) {
+ switch (t) {
+ case BYTE: b.get(); break;
+ case CHAR: b.getChar(); break;
+ case SHORT: b.getShort(); break;
+ case INT: b.getInt(); break;
+ case LONG: b.getLong(); break;
+ case FLOAT: b.getFloat(); break;
+ case DOUBLE: b.getDouble(); break;
+ }
+ }
+
+ void putOne(ByteBuffer b, PrimitiveType t) {
+ switch (t) {
+ case BYTE: b.put((byte)0); break;
+ case CHAR: b.putChar('0'); break;
+ case SHORT: b.putShort((short)0); break;
+ case INT: b.putInt(0); break;
+ case LONG: b.putLong(0); break;
+ case FLOAT: b.putFloat(0); break;
+ case DOUBLE: b.putDouble(0); break;
+ }
+ }
+
+ void getOne(ByteBuffer b, PrimitiveType t, int index) {
+ switch (t) {
+ case BYTE: b.get(index); break;
+ case CHAR: b.getChar(index); break;
+ case SHORT: b.getShort(index); break;
+ case INT: b.getInt(index); break;
+ case LONG: b.getLong(index); break;
+ case FLOAT: b.getFloat(index); break;
+ case DOUBLE: b.getDouble(index); break;
+ }
+ }
+
+ void putOne(ByteBuffer b, PrimitiveType t, int index) {
+ switch (t) {
+ case BYTE: b.put(index, (byte)0); break;
+ case CHAR: b.putChar(index, '0'); break;
+ case SHORT: b.putShort(index, (short)0); break;
+ case INT: b.putInt(index, 0); break;
+ case LONG: b.putLong(index, 0); break;
+ case FLOAT: b.putFloat(index, 0); break;
+ case DOUBLE: b.putDouble(index, 0); break;
+ }
+ }
+
+ void checkBoundaryConditions() {
+ for (int i = 0; i < 100; i++) {
+ int bufSize = random.nextInt(16);
+ byte[] bytes = new byte[bufSize];
+ ByteBuffer buf = ByteBuffer.wrap(bytes);
+ for (int j = 0; j < 100; j++) {
+ int offset = random.nextInt(32) - 8;
+ for (PrimitiveType t : PrimitiveType.values()) {
+ int threw = 0;
+ try {
+ try {
+ buf.position(offset);
+ getOne(buf, t);
+ } catch (BufferUnderflowException e) {
+ if (offset + t.size < bufSize)
+ throw new RuntimeException
+ ("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
+ threw++;
+ } catch (IllegalArgumentException e) {
+ if (offset >= 0 && offset + t.size < bufSize)
+ throw new RuntimeException
+ ("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
+ threw++;
+ }
+
+ try {
+ buf.position(offset);
+ putOne(buf, t);
+ } catch (BufferOverflowException e) {
+ if (offset + t.size < bufSize)
+ throw new RuntimeException
+ ("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
+ threw++;
+ } catch (IllegalArgumentException e) {
+ if (offset >= 0 && offset + t.size < bufSize)
+ throw new RuntimeException
+ ("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
+ threw++;
+ }
+
+ try {
+ putOne(buf, t, offset);
+ } catch (IndexOutOfBoundsException e) {
+ if (offset >= 0 && offset + t.size < bufSize)
+ throw new RuntimeException
+ ("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
+ threw++;
+ }
+
+ try {
+ getOne(buf, t, offset);
+ } catch (IndexOutOfBoundsException e) {
+ if (offset >= 0 && offset + t.size < bufSize)
+ throw new RuntimeException
+ ("type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, e);
+ threw++;
+ }
+
+ if (threw == 0) {
+ // Make sure that we should not have thrown.
+ if (offset < 0 || offset + t.size > bufSize) {
+ throw new RuntimeException
+ ("should have thrown but did not, type = " + t
+ + ", offset = " + offset + ", bufSize = " + bufSize);
+ }
+ } else if (threw != 4) {
+ // If one of the {get,put} operations threw
+ // due to an invalid offset then all four of
+ // them should have thrown.
+ throw new RuntimeException
+ ("should have thrown but at least one did not, type = " + t
+ + ", offset = " + offset + ", bufSize = " + bufSize);
+ }
+ } catch (Throwable th) {
+ throw new RuntimeException
+ ("unexpected throw: type = " + t + ", offset = " + offset + ", bufSize = " + bufSize, th);
+
+ }
+ }
+ }
+ }
+ }
+
public void run() {
+ checkBoundaryConditions();
+
for (int i = 0; i < data.capacity(); i += 8) {
data.putLong(i, random.nextLong());
}
--- a/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,32 +27,41 @@
* @bug 8136421
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
* @library /testlibrary /../../test/lib /
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ * @compile ./common/CompilerToVMHelper.java
+ * @run main ClassFileInstaller jdk.vm.ci.hotspot.CompilerToVMHelper
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -Xbootclasspath/a:.
+ * -XX:+EnableJVMCI
* compiler.jvmci.SecurityRestrictionsTest
* NO_SEC_MAN
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -Xbootclasspath/a:.
+ * -XX:+EnableJVMCI
* compiler.jvmci.SecurityRestrictionsTest
* NO_PERM
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -Xbootclasspath/a:.
+ * -XX:+EnableJVMCI
* compiler.jvmci.SecurityRestrictionsTest
* ALL_PERM
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -Xbootclasspath/a:.
+ * -XX:+EnableJVMCI
* compiler.jvmci.SecurityRestrictionsTest
* NO_JVMCI_ACCESS_PERM
- * @run main/othervm -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -Xbootclasspath/a:.
+ * -XX:-EnableJVMCI
* compiler.jvmci.SecurityRestrictionsTest
* NO_JVMCI
*/
package compiler.jvmci;
-import jdk.vm.ci.hotspot.CompilerToVM;
import jdk.test.lib.Utils;
import java.lang.InternalError;
+import java.lang.reflect.Constructor;
import java.security.AccessControlException;
import java.security.Permission;
import java.util.PropertyPermission;
import java.util.function.Consumer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
public class SecurityRestrictionsTest {
@@ -164,7 +173,14 @@
}
}
};
- Utils.runAndCheckException(CompilerToVM::new, exceptionCheck);
+ Utils.runAndCheckException(() -> {
+ try {
+ // CompilerToVM::<cinit> provokes CompilerToVM::<init>
+ Class.forName("jdk.vm.ci.hotspot.CompilerToVMHelper");
+ } catch (ClassNotFoundException e) {
+ throw new Error("TESTBUG : " + e, e);
+ }
+ }, exceptionCheck);
}
public SecurityManager getSecurityManager() {
--- a/hotspot/test/compiler/jvmci/common/CTVMUtilities.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/common/CTVMUtilities.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,15 +27,16 @@
import java.lang.reflect.Executable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
public class CTVMUtilities {
/*
* A method to return HotSpotResolvedJavaMethod object using class object
* and method as input
*/
- public static HotSpotResolvedJavaMethodImpl getResolvedMethod(Class<?> cls,
+ public static HotSpotResolvedJavaMethod getResolvedMethod(Class<?> cls,
Executable method) {
if (!(method instanceof Method || method instanceof Constructor)) {
throw new Error("wrong executable type " + method.getClass());
@@ -54,8 +55,20 @@
return CompilerToVMHelper.getResolvedJavaMethodAtSlot(cls, slot);
}
- public static HotSpotResolvedJavaMethodImpl getResolvedMethod(
+ public static HotSpotResolvedJavaMethod getResolvedMethod(
Executable method) {
return getResolvedMethod(method.getDeclaringClass(), method);
}
+
+ public static InstalledCode getInstalledCode(String name, long address,
+ long entryPoint) {
+ return new InstalledCodeStub(name, address, entryPoint);
+ }
+ private static class InstalledCodeStub extends InstalledCode {
+ private InstalledCodeStub(String name, long address, long entryPoint) {
+ super(name);
+ this.address = address;
+ this.entryPoint = entryPoint;
+ }
+ }
}
--- a/hotspot/test/compiler/jvmci/common/CompilerToVMHelper.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/common/CompilerToVMHelper.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,115 +26,120 @@
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.SpeculationLog;
-/*
+/**
* A simple "proxy" class to get test access to CompilerToVM package-private methods
*/
public class CompilerToVMHelper {
public static final CompilerToVM CTVM = new CompilerToVM();
- public static byte[] getBytecode(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.getBytecode(method);
+ public static byte[] getBytecode(HotSpotResolvedJavaMethod method) {
+ return CTVM.getBytecode((HotSpotResolvedJavaMethodImpl)method);
}
- public static int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.getExceptionTableLength(method);
+ public static int getExceptionTableLength(HotSpotResolvedJavaMethod method) {
+ return CTVM.getExceptionTableLength((HotSpotResolvedJavaMethodImpl)method);
}
- public static long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.getExceptionTableStart(method);
+ public static long getExceptionTableStart(HotSpotResolvedJavaMethod method) {
+ return CTVM.getExceptionTableStart((HotSpotResolvedJavaMethodImpl)method);
}
- public static boolean canInlineMethod(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.canInlineMethod(method);
+ public static boolean canInlineMethod(HotSpotResolvedJavaMethod method) {
+ return CTVM.canInlineMethod((HotSpotResolvedJavaMethodImpl)method);
}
- public static boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.shouldInlineMethod(method);
+ public static boolean shouldInlineMethod(HotSpotResolvedJavaMethod method) {
+ return CTVM.shouldInlineMethod((HotSpotResolvedJavaMethodImpl)method);
}
- public static HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(
- HotSpotResolvedObjectTypeImpl actualHolderType,
- HotSpotResolvedJavaMethodImpl method) {
- return CTVM.findUniqueConcreteMethod(actualHolderType, method);
+ public static HotSpotResolvedJavaMethod findUniqueConcreteMethod(
+ HotSpotResolvedObjectType actualHolderType,
+ HotSpotResolvedJavaMethod method) {
+ return CTVM.findUniqueConcreteMethod((HotSpotResolvedObjectTypeImpl) actualHolderType, (HotSpotResolvedJavaMethodImpl)method);
}
- public static HotSpotResolvedObjectTypeImpl getImplementor(HotSpotResolvedObjectTypeImpl type) {
- return CTVM.getImplementor(type);
+ public static HotSpotResolvedObjectType getImplementor(HotSpotResolvedObjectType type) {
+ return CTVM.getImplementor((HotSpotResolvedObjectTypeImpl) type);
}
- public static boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.methodIsIgnoredBySecurityStackWalk(method);
+ public static boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethod method) {
+ return CTVM.methodIsIgnoredBySecurityStackWalk((HotSpotResolvedJavaMethodImpl)method);
}
- public static HotSpotResolvedObjectTypeImpl lookupType(String name,
+ public static HotSpotResolvedObjectType lookupType(String name,
Class<?> accessingClass, boolean resolve) {
return CTVM.lookupType(name, accessingClass, resolve);
}
- public static Object resolveConstantInPool(HotSpotConstantPool constantPool, int cpi) {
- return CTVM.resolveConstantInPool(constantPool, cpi);
+ public static Object resolveConstantInPool(ConstantPool constantPool, int cpi) {
+ return CTVM.resolveConstantInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static Object resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi) {
- return CTVM.resolvePossiblyCachedConstantInPool(constantPool, cpi);
+ public static Object resolvePossiblyCachedConstantInPool(ConstantPool constantPool, int cpi) {
+ return CTVM.resolvePossiblyCachedConstantInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int cpi) {
- return CTVM.lookupNameAndTypeRefIndexInPool(constantPool, cpi);
+ public static int lookupNameAndTypeRefIndexInPool(ConstantPool constantPool, int cpi) {
+ return CTVM.lookupNameAndTypeRefIndexInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static String lookupNameInPool(HotSpotConstantPool constantPool, int cpi) {
- return CTVM.lookupNameInPool(constantPool, cpi);
+ public static String lookupNameInPool(ConstantPool constantPool, int cpi) {
+ return CTVM.lookupNameInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static String lookupSignatureInPool(HotSpotConstantPool constantPool, int cpi) {
- return CTVM.lookupSignatureInPool(constantPool, cpi);
+ public static String lookupSignatureInPool(ConstantPool constantPool, int cpi) {
+ return CTVM.lookupSignatureInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int cpi) {
- return CTVM.lookupKlassRefIndexInPool(constantPool, cpi);
+ public static int lookupKlassRefIndexInPool(ConstantPool constantPool, int cpi) {
+ return CTVM.lookupKlassRefIndexInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi) {
- return CTVM.lookupKlassInPool(constantPool, cpi);
+ public static Object lookupKlassInPool(ConstantPool constantPool, int cpi) {
+ return CTVM.lookupKlassInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static HotSpotResolvedJavaMethodImpl lookupMethodInPool(
- HotSpotConstantPool constantPool, int cpi, byte opcode) {
- return CTVM.lookupMethodInPool(constantPool, cpi, opcode);
+ public static HotSpotResolvedJavaMethod lookupMethodInPool(
+ ConstantPool constantPool, int cpi, byte opcode) {
+ return CTVM.lookupMethodInPool((HotSpotConstantPool) constantPool, cpi, opcode);
}
- public static void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi) {
- CTVM.resolveInvokeDynamicInPool(constantPool, cpi);
+ public static void resolveInvokeDynamicInPool(
+ ConstantPool constantPool, int cpi) {
+ CTVM.resolveInvokeDynamicInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi) {
- CTVM.resolveInvokeHandleInPool(constantPool, cpi);
+ public static void resolveInvokeHandleInPool(
+ ConstantPool constantPool, int cpi) {
+ CTVM.resolveInvokeHandleInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static HotSpotResolvedObjectTypeImpl resolveTypeInPool(
- HotSpotConstantPool constantPool, int cpi) throws LinkageError {
- return CTVM.resolveTypeInPool(constantPool, cpi);
+ public static HotSpotResolvedObjectType resolveTypeInPool(
+ ConstantPool constantPool, int cpi) {
+ return CTVM.resolveTypeInPool((HotSpotConstantPool) constantPool, cpi);
}
- public static HotSpotResolvedObjectTypeImpl resolveFieldInPool(
- HotSpotConstantPool constantPool, int cpi, byte opcode, long[] info) {
- return CTVM.resolveFieldInPool(constantPool, cpi, opcode, info);
+ public static HotSpotResolvedObjectType resolveFieldInPool(
+ ConstantPool constantPool, int cpi, byte opcode, long[] info) {
+ return CTVM.resolveFieldInPool((HotSpotConstantPool) constantPool, cpi, opcode, info);
}
public static int constantPoolRemapInstructionOperandFromCache(
- HotSpotConstantPool constantPool, int cpci) {
- return CTVM.constantPoolRemapInstructionOperandFromCache(constantPool, cpci);
+ ConstantPool constantPool, int cpci) {
+ return CTVM.constantPoolRemapInstructionOperandFromCache((HotSpotConstantPool) constantPool, cpci);
}
- public static Object lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi) {
- return CTVM.lookupAppendixInPool(constantPool, cpi);
+ public static Object lookupAppendixInPool(
+ ConstantPool constantPool, int cpi) {
+ return CTVM.lookupAppendixInPool((HotSpotConstantPool) constantPool, cpi);
}
public static int installCode(TargetDescription target,
- HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog) {
+ HotSpotCompiledCode compiledCode, InstalledCode code, HotSpotSpeculationLog speculationLog) {
return CTVM.installCode(target, compiledCode, code, speculationLog);
}
@@ -144,10 +149,10 @@
}
public static void notifyCompilationStatistics(int id,
- HotSpotResolvedJavaMethodImpl method, boolean osr,
+ HotSpotResolvedJavaMethod method, boolean osr,
int processedBytecodes, long time, long timeUnitsPerSecond,
InstalledCode installedCode) {
- CTVM.notifyCompilationStatistics(id, method, osr, processedBytecodes,
+ CTVM.notifyCompilationStatistics(id, (HotSpotResolvedJavaMethodImpl) method, osr, processedBytecodes,
time, timeUnitsPerSecond, installedCode);
}
@@ -155,28 +160,28 @@
CTVM.resetCompilationStatistics();
}
- public static long initializeConfiguration() {
- return CTVM.initializeConfiguration();
+ public static long initializeConfiguration(HotSpotVMConfig config) {
+ return CTVM.initializeConfiguration(config);
}
- public static HotSpotResolvedJavaMethodImpl resolveMethod(
- HotSpotResolvedObjectTypeImpl exactReceiver,
- HotSpotResolvedJavaMethodImpl method,
- HotSpotResolvedObjectTypeImpl caller) {
- return CTVM.resolveMethod(exactReceiver, method, caller);
+ public static HotSpotResolvedJavaMethod resolveMethod(
+ HotSpotResolvedObjectType exactReceiver,
+ HotSpotResolvedJavaMethod method,
+ HotSpotResolvedObjectType caller) {
+ return CTVM.resolveMethod((HotSpotResolvedObjectTypeImpl) exactReceiver, (HotSpotResolvedJavaMethodImpl) method, (HotSpotResolvedObjectTypeImpl) caller);
}
- public static HotSpotResolvedJavaMethodImpl getClassInitializer(
- HotSpotResolvedObjectTypeImpl type) {
- return CTVM.getClassInitializer(type);
+ public static HotSpotResolvedJavaMethod getClassInitializer(
+ HotSpotResolvedObjectType type) {
+ return CTVM.getClassInitializer((HotSpotResolvedObjectTypeImpl) type);
}
- public static boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl type) {
- return CTVM.hasFinalizableSubclass(type);
+ public static boolean hasFinalizableSubclass(HotSpotResolvedObjectType type) {
+ return CTVM.hasFinalizableSubclass((HotSpotResolvedObjectTypeImpl) type);
}
- public static HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot(Class<?> holder,
- int slot) {
+ public static HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot(
+ Class<?> holder, int slot) {
return CTVM.getResolvedJavaMethodAtSlot(holder, slot);
}
@@ -184,13 +189,13 @@
return CTVM.getMaxCallTargetOffset(address);
}
- public static String disassembleCodeBlob(long codeBlob) {
+ public static String disassembleCodeBlob(InstalledCode codeBlob) {
return CTVM.disassembleCodeBlob(codeBlob);
}
public static StackTraceElement getStackTraceElement(
- HotSpotResolvedJavaMethodImpl method, int bci) {
- return CTVM.getStackTraceElement(method, bci);
+ HotSpotResolvedJavaMethod method, int bci) {
+ return CTVM.getStackTraceElement((HotSpotResolvedJavaMethodImpl)method, bci);
}
public static Object executeInstalledCode(Object[] args,
@@ -198,28 +203,28 @@
return CTVM.executeInstalledCode(args, installedCode);
}
- public static long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.getLineNumberTable(method);
+ public static long[] getLineNumberTable(HotSpotResolvedJavaMethod method) {
+ return CTVM.getLineNumberTable((HotSpotResolvedJavaMethodImpl)method);
}
- public static int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.getLocalVariableTableLength(method);
+ public static int getLocalVariableTableLength(HotSpotResolvedJavaMethod method) {
+ return CTVM.getLocalVariableTableLength((HotSpotResolvedJavaMethodImpl)method);
}
- public static long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method) {
- return CTVM.getLocalVariableTableStart(method);
+ public static long getLocalVariableTableStart(HotSpotResolvedJavaMethod method) {
+ return CTVM.getLocalVariableTableStart((HotSpotResolvedJavaMethodImpl)method);
}
public static Object readUncompressedOop(long address) {
return CTVM.readUncompressedOop(address);
}
- public static void doNotInlineOrCompile(HotSpotResolvedJavaMethodImpl method) {
- CTVM.doNotInlineOrCompile(method);
+ public static void doNotInlineOrCompile(HotSpotResolvedJavaMethod method) {
+ CTVM.doNotInlineOrCompile((HotSpotResolvedJavaMethodImpl)method);
}
- public static void reprofile(HotSpotResolvedJavaMethodImpl method) {
- CTVM.reprofile(method);
+ public static void reprofile(HotSpotResolvedJavaMethod method) {
+ CTVM.reprofile((HotSpotResolvedJavaMethodImpl)method);
}
public static void invalidateInstalledCode(InstalledCode installedCode) {
@@ -234,14 +239,14 @@
return CTVM.isMature(metaspaceMethodData);
}
- public static int allocateCompileId(HotSpotResolvedJavaMethodImpl method,
+ public static int allocateCompileId(HotSpotResolvedJavaMethod method,
int entryBCI) {
- return CTVM.allocateCompileId(method, entryBCI);
+ return CTVM.allocateCompileId((HotSpotResolvedJavaMethodImpl) method, entryBCI);
}
public static boolean hasCompiledCodeForOSR(
- HotSpotResolvedJavaMethodImpl method, int entryBCI, int level) {
- return CTVM.hasCompiledCodeForOSR(method, entryBCI, level);
+ HotSpotResolvedJavaMethod method, int entryBCI, int level) {
+ return CTVM.hasCompiledCodeForOSR((HotSpotResolvedJavaMethodImpl) method, entryBCI, level);
}
public static String getSymbol(long metaspaceSymbol) {
@@ -250,7 +255,7 @@
public static HotSpotStackFrameReference getNextStackFrame(
HotSpotStackFrameReference frame,
- HotSpotResolvedJavaMethodImpl[] methods, int initialSkip) {
+ ResolvedJavaMethod[] methods, int initialSkip) {
return CTVM.getNextStackFrame(frame, methods, initialSkip);
}
@@ -259,9 +264,9 @@
CTVM.materializeVirtualObjects(stackFrame, invalidate);
}
- public static int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectTypeImpl type,
- HotSpotResolvedJavaMethodImpl method) {
- return CTVM.getVtableIndexForInterfaceMethod(type, method);
+ public static int getVtableIndexForInterfaceMethod(HotSpotResolvedObjectType type,
+ HotSpotResolvedJavaMethod method) {
+ return CTVM.getVtableIndexForInterfaceMethod((HotSpotResolvedObjectTypeImpl) type, (HotSpotResolvedJavaMethodImpl) method);
}
public static boolean shouldDebugNonSafepoints() {
@@ -276,7 +281,7 @@
CTVM.flushDebugOutput();
}
- public static HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base,
+ public static HotSpotResolvedJavaMethod getResolvedJavaMethod(Object base,
long displacement) {
return CTVM.getResolvedJavaMethod(base, displacement);
}
@@ -285,8 +290,24 @@
return CTVM.getConstantPool(base, displacement);
}
- public static HotSpotResolvedObjectTypeImpl getResolvedJavaType(Object base,
+ public static HotSpotResolvedObjectType getResolvedJavaType(Object base,
long displacement, boolean compressed) {
return CTVM.getResolvedJavaType(base, displacement, compressed);
}
+
+ public static long getMetaspacePointer(Object o) {
+ return ((MetaspaceWrapperObject) o).getMetaspacePointer();
+ }
+
+ public static Class<?> CompilerToVMClass() {
+ return CompilerToVM.class;
+ }
+
+ public static Class<?> HotSpotConstantPoolClass() {
+ return HotSpotConstantPool.class;
+ }
+
+ public static Class<?> getMirror(HotSpotResolvedObjectType type) {
+ return ((HotSpotResolvedJavaType) type).mirror();
+ }
}
--- a/hotspot/test/compiler/jvmci/common/JVMCIHelpers.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/common/JVMCIHelpers.java Wed Jul 05 21:00:20 2017 +0200
@@ -24,10 +24,11 @@
package compiler.jvmci.common;
import jdk.vm.ci.code.Architecture;
+import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.hotspot.HotSpotVMEventListener;
-import jdk.vm.ci.compiler.Compiler;
-import jdk.vm.ci.compiler.CompilerFactory;
import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.runtime.JVMCICompiler;
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
import jdk.vm.ci.runtime.JVMCIRuntime;
/*
@@ -39,16 +40,15 @@
// just empty, using default interface methods
}
- public static class EmptyHotspotCompiler implements Compiler {
+ public static class EmptyHotspotCompiler implements JVMCICompiler {
@Override
- public void compileMethod(ResolvedJavaMethod method, int entryBCI,
- long jvmciEnv, int id) {
+ public void compileMethod(CompilationRequest request) {
// do nothing
}
}
- public static class EmptyCompilerFactory implements CompilerFactory {
+ public static class EmptyCompilerFactory implements JVMCICompilerFactory {
@Override
public String getCompilerName() {
@@ -56,12 +56,7 @@
}
@Override
- public Architecture initializeArchitecture(Architecture arch) {
- return arch;
- }
-
- @Override
- public Compiler createCompiler(JVMCIRuntime runtime) {
+ public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
return new EmptyHotspotCompiler();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/PublicMetaspaceWrapperObject.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.vm.ci.hotspot;
+
+/**
+ * A public available version of MetaspaceWrapperObject interface.
+ */
+public interface PublicMetaspaceWrapperObject extends MetaspaceWrapperObject { }
--- a/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.compiler.Compiler Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
--- a/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.compiler.CompilerFactory Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.JVMCICompiler Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,1 @@
+compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.JVMCICompilerFactory Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,1 @@
+compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
--- a/hotspot/test/compiler/jvmci/compilerToVM/AllocateCompileIdTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/AllocateCompileIdTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -34,6 +34,7 @@
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
* -XX:-BackgroundCompilation
+ -XX:+LogCompilation
* compiler.jvmci.compilerToVM.AllocateCompileIdTest
*/
@@ -51,7 +52,7 @@
import compiler.jvmci.common.testcases.TestCase;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.test.lib.Asserts;
import jdk.test.lib.Pair;
import jdk.test.lib.Utils;
@@ -74,8 +75,9 @@
try {
Class<?> aClass = DummyClass.class;
Method method = aClass.getMethod("withLoop");
- result.add(new CompileCodeTestCase(method, 17));
- result.add(new CompileCodeTestCase(method, -1));
+ Object receiver = new DummyClass();
+ result.add(new CompileCodeTestCase(receiver, method, 17));
+ result.add(new CompileCodeTestCase(receiver, method, -1));
} catch (NoSuchMethodException e) {
throw new Error("TEST BUG : " + e, e);
}
@@ -90,16 +92,19 @@
try {
Class<?> aClass = DummyClass.class;
+ Object receiver = new DummyClass();
Method method = aClass.getMethod("dummyInstanceFunction");
// greater than bytecode.length
int[] bcis = new int[] {30, 50, 200};
for (int bci : bcis) {
- result.add(new Pair<>(new CompileCodeTestCase(method, bci),
+ result.add(new Pair<>(
+ new CompileCodeTestCase(receiver, method, bci),
IllegalArgumentException.class));
}
bcis = new int[] {-4, -50, -200};
for (int bci : bcis) {
- result.add(new Pair<>(new CompileCodeTestCase(method, bci),
+ result.add(new Pair<>(
+ new CompileCodeTestCase(receiver, method, bci),
IllegalArgumentException.class));
}
} catch (NoSuchMethodException e) {
@@ -111,8 +116,10 @@
private void runSanityCorrectTest(CompileCodeTestCase testCase) {
System.out.println(testCase);
Executable aMethod = testCase.executable;
+ // to generate ciTypeFlow
+ System.out.println(testCase.invoke(Utils.getNullValues(aMethod.getParameterTypes())));
int bci = testCase.bci;
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
int wbCompileID = getWBCompileID(testCase);
int id = CompilerToVMHelper.allocateCompileId(method, bci);
@@ -140,7 +147,7 @@
Class<? extends Throwable> exception = testCase.second;
Executable aMethod = testCase.first.executable;
int bci = testCase.first.bci;
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
Utils.runAndCheckException(
() -> CompilerToVMHelper.allocateCompileId(method, bci),
--- a/hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/CanInlineMethodTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -45,7 +45,7 @@
import java.util.Arrays;
import java.util.List;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.test.lib.Asserts;
import sun.hotspot.WhiteBox;
@@ -59,7 +59,7 @@
}
private static void runSanityTest(Executable aMethod) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
boolean canInline = CompilerToVMHelper.canInlineMethod(method);
boolean expectedCanInline = !WB.testSetDontInlineMethod(aMethod,
--- a/hotspot/test/compiler/jvmci/compilerToVM/CompileCodeTestCase.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/CompileCodeTestCase.java Wed Jul 05 21:00:20 2017 +0200
@@ -24,12 +24,17 @@
package compiler.jvmci.compilerToVM;
+import compiler.jvmci.common.CTVMUtilities;
import compiler.testlibrary.CompilerUtils;
import jdk.test.lib.Utils;
+import jdk.vm.ci.code.InstalledCode;
import sun.hotspot.WhiteBox;
import sun.hotspot.code.NMethod;
import java.lang.reflect.Executable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
@@ -37,12 +42,12 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import jdk.test.lib.Pair;
/**
* A test case for tests which require compiled code.
*/
-public final class CompileCodeTestCase {
- public static final Map<Class<?>, Object> RECEIVERS;
+public class CompileCodeTestCase {
private static final WhiteBox WB = WhiteBox.getWhiteBox();
private static final int COMP_LEVEL;
static {
@@ -56,21 +61,51 @@
Interface.class,
Dummy.class,
DummyEx.class};
+ private static final Map<Class<?>, Object> RECEIVERS;
+ public final Object receiver;
public final Executable executable;
public final int bci;
private final boolean isOsr;
- public CompileCodeTestCase(Executable executable, int bci) {
+ public CompileCodeTestCase(Object receiver, Executable executable,
+ int bci) {
+ this.receiver = receiver;
this.executable = executable;
this.bci = bci;
- isOsr = bci >= 0;
+ isOsr = (bci >= 0);
}
public NMethod compile() {
return compile(COMP_LEVEL);
}
+ public Pair<Object, ? extends Throwable> invoke(Object[] args) {
+ boolean old = executable.isAccessible();
+ executable.setAccessible(true);
+ try {
+ try {
+ if (executable instanceof Method) {
+ Method m = (Method) executable;
+ return new Pair<>(m.invoke(receiver, args), null);
+ }
+
+ if (executable instanceof Constructor) {
+ Constructor c = (Constructor) executable;
+ return new Pair<>(c.newInstance(args), null);
+ }
+ } catch (InvocationTargetException e) {
+ return new Pair<>(null, e.getCause());
+ } catch (Throwable e) {
+ return new Pair<>(null, e);
+ }
+ } finally {
+ executable.setAccessible(old);
+ }
+ throw new Error(executable + " has unsupported type "
+ + executable.getClass());
+ }
+
public NMethod compile(int level) {
boolean enqueued = WB.enqueueMethodForCompilation(executable,
level, bci);
@@ -86,13 +121,17 @@
public static List<CompileCodeTestCase> generate(int bci) {
ArrayList<CompileCodeTestCase> result = new ArrayList<>();
for (Class<?> aClass : CLASSES) {
+ Object receiver = RECEIVERS.get(aClass);
+ if (receiver == null) {
+ throw new Error("TESTBUG : no receiver for class " + aClass);
+ }
for (Executable m : aClass.getDeclaredConstructors()) {
- result.add(new CompileCodeTestCase(m, bci));
+ result.add(new CompileCodeTestCase(receiver, m, bci));
}
Arrays.stream(aClass.getDeclaredMethods())
.filter(m -> !Modifier.isAbstract(m.getModifiers()))
.filter(m -> !Modifier.isNative(m.getModifiers()))
- .map(m -> new CompileCodeTestCase(m, bci))
+ .map(m -> new CompileCodeTestCase(receiver, m, bci))
.forEach(result::add);
}
return result;
@@ -102,6 +141,14 @@
return NMethod.get(executable, isOsr);
}
+ public InstalledCode toInstalledCode() {
+ NMethod nmethod = toNMethod();
+ long address = nmethod == null ? 0L : nmethod.address;
+ long entryPoint = nmethod == null ? 0L : nmethod.entry_point;
+ return CTVMUtilities.getInstalledCode(
+ executable.getName(), address, entryPoint);
+ }
+
@Override
public String toString() {
return "CompileCodeTestCase{" +
--- a/hotspot/test/compiler/jvmci/compilerToVM/ConstantPoolTestCase.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ConstantPoolTestCase.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,8 +26,7 @@
import java.util.HashMap;
import java.util.Map;
-import jdk.vm.ci.hotspot.HotSpotConstantPool;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.internal.misc.SharedSecrets;
import sun.reflect.ConstantPool;
@@ -35,15 +34,15 @@
* Common class for jdk.vm.ci.hotspot.CompilerToVM constant pool tests
*/
public class ConstantPoolTestCase {
-
private final Map<ConstantPoolTestsHelper.ConstantTypes, Validator> typeTests;
public static interface Validator {
- void validate(HotSpotConstantPool constantPoolCTVM, ConstantPool constantPoolSS,
+ void validate(jdk.vm.ci.meta.ConstantPool constantPoolCTVM,
+ ConstantPool constantPoolSS,
ConstantPoolTestsHelper.DummyClasses dummyClass, int index);
}
- public ConstantPoolTestCase(Map<ConstantPoolTestsHelper.ConstantTypes, Validator> typeTests) {
+ public ConstantPoolTestCase(Map<ConstantPoolTestsHelper.ConstantTypes,Validator> typeTests) {
this.typeTests = new HashMap<>();
this.typeTests.putAll(typeTests);
}
@@ -120,9 +119,10 @@
for (ConstantPoolTestsHelper.DummyClasses dummyClass
: ConstantPoolTestsHelper.DummyClasses.values()) {
System.out.printf("%nTesting dummy %s%n", dummyClass.klass);
- HotSpotResolvedObjectTypeImpl holder = HotSpotResolvedObjectTypeImpl
+ HotSpotResolvedObjectType holder = HotSpotResolvedObjectType
.fromObjectClass(dummyClass.klass);
- HotSpotConstantPool constantPoolCTVM = holder.getConstantPool();
+ jdk.vm.ci.meta.ConstantPool constantPoolCTVM
+ = holder.getConstantPool();
ConstantPool constantPoolSS = SharedSecrets.getJavaLangAccess().
getConstantPool(dummyClass.klass);
for (Integer i : dummyClass.cp.keySet()) {
--- a/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -42,10 +42,12 @@
package compiler.jvmci.compilerToVM;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.code.InstalledCode;
import jdk.test.lib.Asserts;
import sun.hotspot.code.NMethod;
import java.util.List;
+import jdk.test.lib.Utils;
public class DisassembleCodeBlobTest {
@@ -56,12 +58,23 @@
= CompileCodeTestCase.generate(/* bci = */ -1);
testCases.addAll(CompileCodeTestCase.generate(/* bci = */ 0));
testCases.forEach(test::check);
+ testCases.stream().findAny().ifPresent(test::checkZero);
test.checkNull();
}
private void checkNull() {
- String str = CompilerToVMHelper.disassembleCodeBlob(0L);
- Asserts.assertNull(str, "not null string returned for null pointer");
+ Utils.runAndCheckException(
+ () -> CompilerToVMHelper.disassembleCodeBlob(null),
+ NullPointerException.class);
+ }
+
+ private void checkZero(CompileCodeTestCase testCase) {
+ System.out.println("checkZero for " + testCase);
+ testCase.deoptimize();
+ InstalledCode installedCode = testCase.toInstalledCode();
+ String str = CompilerToVMHelper.disassembleCodeBlob(installedCode);
+ Asserts.assertNull(str, testCase
+ + " : non-null return value for invalid installCode");
}
private void check(CompileCodeTestCase testCase) {
@@ -71,12 +84,13 @@
if (nMethod == null) {
throw new Error(testCase + " : method is not compiled");
}
- String str = CompilerToVMHelper.disassembleCodeBlob(nMethod.address);
+ InstalledCode installedCode = testCase.toInstalledCode();
+ String str = CompilerToVMHelper.disassembleCodeBlob(installedCode);
if (str != null) {
Asserts.assertGT(str.length(), 0,
testCase + " : returned string has to be non-zero length");
}
- String str2 = CompilerToVMHelper.disassembleCodeBlob(nMethod.address);
+ String str2 = CompilerToVMHelper.disassembleCodeBlob(installedCode);
Asserts.assertEQ(str, str2,
testCase + " : 2nd invocation returned different value");
}
--- a/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DoNotInlineOrCompileTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -45,7 +45,7 @@
import java.util.Arrays;
import java.util.List;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.test.lib.Asserts;
import sun.hotspot.WhiteBox;
@@ -59,7 +59,7 @@
}
private static void runSanityTest(Executable aMethod) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
boolean canInline = CompilerToVMHelper.canInlineMethod(method);
Asserts.assertTrue(canInline, "Unexpected initial " +
--- a/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -4,6 +4,7 @@
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
import jdk.test.lib.Pair;
import sun.hotspot.code.NMethod;
@@ -35,7 +36,6 @@
public class ExecuteInstalledCodeTest {
-
public static void main(String[] args) {
ExecuteInstalledCodeTest test = new ExecuteInstalledCodeTest();
List<CompileCodeTestCase> testCases = new ArrayList<>();
@@ -54,15 +54,14 @@
// to have a clean state
testCase.deoptimize();
Pair<Object, ? extends Throwable> reflectionResult;
- Object[] args = getArguments(testCase.executable);
- reflectionResult = invoke(testCase, args);
+ Object[] args = Utils.getNullValues(
+ testCase.executable.getParameterTypes());
+ reflectionResult = testCase.invoke(args);
NMethod nMethod = testCase.compile();
if (nMethod == null) {
throw new Error(testCase + " : nmethod is null");
}
- InstalledCode installedCode = new InstalledCode(
- testCase.executable.getName());
- installedCode.setAddress(nMethod.address);
+ InstalledCode installedCode = testCase.toInstalledCode();
Object result = null;
Throwable expectedException = reflectionResult.second;
boolean gotException = true;
@@ -107,70 +106,10 @@
if (!Modifier.isStatic(testCase.executable.getModifiers())) {
// add instance as 0th arg
Object[] newArgs = new Object[args.length + 1];
- newArgs[0] = getReciever(testCase);
+ newArgs[0] = testCase.receiver;
System.arraycopy(args, 0, newArgs, 1, args.length);
args = newArgs;
}
return args;
}
-
- private Object getReciever(CompileCodeTestCase testCase) {
- return CompileCodeTestCase.RECEIVERS.get(
- testCase.executable.getDeclaringClass());
- }
-
- public Pair<Object, ? extends Throwable> invoke(
- CompileCodeTestCase testCase, Object[] args) {
- Executable executable = testCase.executable;
- boolean old = executable.isAccessible();
- executable.setAccessible(true);
- try {
- try {
- if (executable instanceof Method) {
- Method m = (Method) executable;
- return new Pair<>(m.invoke(getReciever(testCase), args), null);
- }
-
- if (executable instanceof Constructor) {
- Constructor c = (Constructor) executable;
- return new Pair<>(c.newInstance(args), null);
- }
- } catch (InvocationTargetException e) {
- return new Pair<>(null, e.getCause());
- } catch (Throwable e) {
- return new Pair<>(null, e);
- }
- } finally {
- executable.setAccessible(old);
- }
- throw new Error(executable + " has unsupported type "
- + executable.getClass());
- }
-
- private Object[] getArguments(Executable method) {
- Class<?>[] params = method.getParameterTypes();
- Object[] result = new Object[params.length];
- int i = 0;
- for (Class<?> aClass : params) {
- result[i++] = getArgument(aClass);
- }
- return result;
- }
- private static Map<Class<?>, Object> DEFAULT_VALUES = new HashMap<>();
- static {
- DEFAULT_VALUES.put(boolean.class, false);
- DEFAULT_VALUES.put(byte.class, (byte) 0);
- DEFAULT_VALUES.put(short.class, (short) 0);
- DEFAULT_VALUES.put(char.class, '\0');
- DEFAULT_VALUES.put(int.class, 0);
- DEFAULT_VALUES.put(long.class, 0L);
- DEFAULT_VALUES.put(float.class, 0.0f);
- DEFAULT_VALUES.put(double.class, 0.0d);
- }
- private Object getArgument(Class<?> aClass) {
- if (aClass.isPrimitive()) {
- return DEFAULT_VALUES.get(aClass);
- }
- return null;
- }
}
--- a/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/FindUniqueConcreteMethodTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -45,8 +45,8 @@
import java.util.HashSet;
import java.util.Set;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
@@ -97,26 +97,26 @@
private void runTest(TestCase tcase) throws NoSuchMethodException {
System.out.println(tcase);
Method method = tcase.holder.getDeclaredMethod(tcase.methodName);
- HotSpotResolvedJavaMethodImpl testMethod = CTVMUtilities
- .getResolvedMethod(tcase.reciever, method);
- HotSpotResolvedObjectTypeImpl resolvedType = CompilerToVMHelper
- .lookupType(Utils.toJVMTypeSignature(tcase.reciever), getClass(),
+ HotSpotResolvedJavaMethod testMethod = CTVMUtilities
+ .getResolvedMethod(tcase.receiver, method);
+ HotSpotResolvedObjectType resolvedType = CompilerToVMHelper
+ .lookupType(Utils.toJVMTypeSignature(tcase.receiver), getClass(),
/* resolve = */ true);
- HotSpotResolvedJavaMethodImpl concreteMethod = CompilerToVMHelper
+ HotSpotResolvedJavaMethod concreteMethod = CompilerToVMHelper
.findUniqueConcreteMethod(resolvedType, testMethod);
Asserts.assertEQ(concreteMethod, tcase.isPositive ? testMethod : null,
"Unexpected concrete method for " + tcase.methodName);
}
private static class TestCase {
- public final Class<?> reciever;
+ public final Class<?> receiver;
public final Class<?> holder;
public final String methodName;
public final boolean isPositive;
public TestCase(boolean isPositive, Class<?> clazz, Class<?> holder,
String methodName) {
- this.reciever = clazz;
+ this.receiver = clazz;
this.methodName = methodName;
this.isPositive = isPositive;
this.holder = holder;
@@ -124,8 +124,8 @@
@Override
public String toString() {
- return String.format("CASE: reciever=%s, holder=%s, method=%s,"
- + " isPositive=%s", reciever.getName(),
+ return String.format("CASE: receiver=%s, holder=%s, method=%s,"
+ + " isPositive=%s", receiver.getName(),
holder.getName(), methodName, isPositive);
}
}
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetBytecodeTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -40,7 +40,7 @@
import compiler.jvmci.common.testcases.TestCase;
import java.lang.reflect.Executable;
import java.lang.reflect.Modifier;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.test.lib.Asserts;
@@ -53,7 +53,7 @@
}
private static void runSanityTest(Executable aMethod) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
byte[] bytecode = CompilerToVMHelper.getBytecode(method);
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetClassInitializerTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -44,8 +44,8 @@
import java.util.HashSet;
import java.util.Set;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
@@ -78,10 +78,10 @@
private void runTest(TestCase tcase) {
System.out.println(tcase);
String className = tcase.holder.getName();
- HotSpotResolvedObjectTypeImpl resolvedClazz = CompilerToVMHelper
+ HotSpotResolvedObjectType resolvedClazz = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(tcase.holder),
getClass(), /* resolve = */ true);
- HotSpotResolvedJavaMethodImpl initializer = CompilerToVMHelper
+ HotSpotResolvedJavaMethod initializer = CompilerToVMHelper
.getClassInitializer(resolvedClazz);
if (tcase.isPositive) {
Asserts.assertNotNull(initializer, "Couldn't get initializer for "
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetConstantPoolTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,12 +27,13 @@
* @bug 8136421
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
* @library /testlibrary /../../test/lib /
- * @compile ../common/CompilerToVMHelper.java
+ * @compile ../common/CompilerToVMHelper.java ../common/PublicMetaspaceWrapperObject.java
* @build sun.hotspot.WhiteBox
* compiler.jvmci.compilerToVM.GetConstantPoolTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* jdk.vm.ci.hotspot.CompilerToVMHelper
+ * jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions
* -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetConstantPoolTest
@@ -40,11 +41,11 @@
package compiler.jvmci.compilerToVM;
import java.lang.reflect.Field;
+import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotConstantPool;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
-import jdk.vm.ci.hotspot.MetaspaceWrapperObject;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
+import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject;
import jdk.test.lib.Utils;
import sun.hotspot.WhiteBox;
import sun.misc.Unsafe;
@@ -56,25 +57,26 @@
private static enum TestCase {
NULL_BASE {
@Override
- HotSpotConstantPool getConstantPool() {
+ ConstantPool getConstantPool() {
return CompilerToVMHelper.getConstantPool(null,
getPtrToCpAddress());
}
},
JAVA_METHOD_BASE {
@Override
- HotSpotConstantPool getConstantPool() {
- HotSpotResolvedJavaMethodImpl methodInstance
+ ConstantPool getConstantPool() {
+ HotSpotResolvedJavaMethod methodInstance
= CompilerToVMHelper.getResolvedJavaMethodAtSlot(
TEST_CLASS, 0);
Field field;
try {
- field = HotSpotResolvedJavaMethodImpl
- .class.getDeclaredField("metaspaceMethod");
+ // jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.metaspaceMethod
+ field = methodInstance.getClass()
+ .getDeclaredField("metaspaceMethod");
field.setAccessible(true);
field.set(methodInstance, getPtrToCpAddress());
} catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
+ throw new Error("TESTBUG : " + e, e);
}
return CompilerToVMHelper.getConstantPool(methodInstance, 0L);
@@ -82,12 +84,12 @@
},
CONSTANT_POOL_BASE {
@Override
- HotSpotConstantPool getConstantPool() {
- HotSpotConstantPool cpInst;
+ ConstantPool getConstantPool() {
+ ConstantPool cpInst;
try {
cpInst = CompilerToVMHelper.getConstantPool(null,
getPtrToCpAddress());
- Field field = HotSpotConstantPool.class
+ Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, getPtrToCpAddress());
@@ -99,12 +101,12 @@
},
CONSTANT_POOL_BASE_IN_TWO {
@Override
- HotSpotConstantPool getConstantPool() {
+ ConstantPool getConstantPool() {
long ptr = getPtrToCpAddress();
- HotSpotConstantPool cpInst;
+ ConstantPool cpInst;
try {
cpInst = CompilerToVMHelper.getConstantPool(null, ptr);
- Field field = HotSpotConstantPool.class
+ Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, ptr / 2L);
@@ -117,12 +119,12 @@
},
CONSTANT_POOL_BASE_ZERO {
@Override
- HotSpotConstantPool getConstantPool() {
+ ConstantPool getConstantPool() {
long ptr = getPtrToCpAddress();
- HotSpotConstantPool cpInst;
+ ConstantPool cpInst;
try {
cpInst = CompilerToVMHelper.getConstantPool(null, ptr);
- Field field = HotSpotConstantPool.class
+ Field field = CompilerToVMHelper.HotSpotConstantPoolClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, 0L);
@@ -134,9 +136,9 @@
},
OBJECT_TYPE_BASE {
@Override
- HotSpotConstantPool getConstantPool() {
- HotSpotResolvedObjectTypeImpl type
- = HotSpotResolvedObjectTypeImpl.fromObjectClass(
+ ConstantPool getConstantPool() {
+ HotSpotResolvedObjectType type
+ = HotSpotResolvedObjectType.fromObjectClass(
OBJECT_TYPE_BASE.getClass());
long ptrToClass = UNSAFE.getKlassPointer(OBJECT_TYPE_BASE);
return CompilerToVMHelper.getConstantPool(type,
@@ -144,26 +146,28 @@
}
},
;
- abstract HotSpotConstantPool getConstantPool();
+ abstract ConstantPool getConstantPool();
}
private static final WhiteBox WB = WhiteBox.getWhiteBox();
private static final Unsafe UNSAFE = Utils.getUnsafe();
+
private static final Class TEST_CLASS = GetConstantPoolTest.class;
private static final long CP_ADDRESS
= WB.getConstantPool(GetConstantPoolTest.class);
public void test(TestCase testCase) {
System.out.println(testCase.name());
- HotSpotConstantPool cp = testCase.getConstantPool();
+ ConstantPool cp = testCase.getConstantPool();
String cpStringRep = cp.toString();
- if (!cpStringRep.contains(HotSpotConstantPool.class.getSimpleName())
+ String cpClassSimpleName
+ = CompilerToVMHelper.HotSpotConstantPoolClass().getSimpleName();
+ if (!cpStringRep.contains(cpClassSimpleName)
|| !cpStringRep.contains(TEST_CLASS.getName())) {
String msg = String.format("%s : "
+ " Constant pool is not valid."
+ " String representation should contain \"%s\" and \"%s\"",
- testCase.name(),
- HotSpotConstantPool.class.getSimpleName(),
+ testCase.name(), cpClassSimpleName,
TEST_CLASS.getName());
throw new AssertionError(msg);
}
@@ -180,8 +184,7 @@
private static void testObjectBase() {
try {
- HotSpotConstantPool cp
- = CompilerToVMHelper.getConstantPool(new Object(), 0L);
+ Object cp = CompilerToVMHelper.getConstantPool(new Object(), 0L);
throw new AssertionError("Test OBJECT_BASE."
+ " Expected IllegalArgumentException has not been caught");
} catch (IllegalArgumentException iae) {
@@ -190,8 +193,8 @@
}
private static void testMetaspaceWrapperBase() {
try {
- HotSpotConstantPool cp = CompilerToVMHelper.getConstantPool(
- new MetaspaceWrapperObject() {
+ Object cp = CompilerToVMHelper.getConstantPool(
+ new PublicMetaspaceWrapperObject() {
@Override
public long getMetaspacePointer() {
return getPtrToCpAddress();
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetExceptionTableTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -42,7 +42,7 @@
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
@@ -76,7 +76,7 @@
private static void runSanityTest(Executable aMethod,
Integer expectedTableLength) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
int tableLength = CompilerToVMHelper.getExceptionTableLength(method);
Asserts.assertEQ(tableLength, expectedTableLength, aMethod
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetImplementorTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetImplementorTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -51,7 +51,7 @@
import java.util.Set;
import java.util.stream.Stream;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
@@ -98,12 +98,12 @@
private void runTest(TestCase tcase) {
System.out.println(tcase);
- HotSpotResolvedObjectTypeImpl resolvedIface = CompilerToVMHelper
+ HotSpotResolvedObjectType resolvedIface = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(tcase.anInterface),
getClass(), /* resolve = */ true);
- HotSpotResolvedObjectTypeImpl resolvedImplementer = CompilerToVMHelper
+ HotSpotResolvedObjectType resolvedImplementer = CompilerToVMHelper
.getImplementor(resolvedIface);
- HotSpotResolvedObjectTypeImpl resolvedExpected = null;
+ HotSpotResolvedObjectType resolvedExpected = null;
if (tcase.expectedImplementer != null) {
resolvedExpected = CompilerToVMHelper.lookupType(Utils
.toJVMTypeSignature(tcase.expectedImplementer),
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetLineNumberTableTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -39,7 +39,7 @@
import compiler.jvmci.common.CTVMUtilities;
import compiler.jvmci.common.testcases.TestCase;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
@@ -67,7 +67,7 @@
}
public static void runSanityTest(Executable aMethod) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
long[] lineNumbers = CompilerToVMHelper.getLineNumberTable(method);
long[] expectedLineNumbers = getExpectedLineNumbers(aMethod);
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetLocalVariableTableTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -42,7 +42,7 @@
package compiler.jvmci.compilerToVM;
import compiler.jvmci.common.CTVMUtilities;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
@@ -100,7 +100,7 @@
private static void runSanityTest(Executable aMethod,
Integer expectedTableLength) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
int tblLength = CompilerToVMHelper.getLocalVariableTableLength(method);
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetNextStackFrameTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -37,20 +37,19 @@
import compiler.jvmci.common.CTVMUtilities;
import java.lang.reflect.Method;
-import jdk.vm.ci.hotspot.CompilerToVM;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
import jdk.vm.ci.hotspot.HotSpotStackFrameReference;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.test.lib.Asserts;
public class GetNextStackFrameTest {
private static final int RECURSION_AMOUNT = 3;
- private static final HotSpotResolvedJavaMethodImpl REC_FRAME_METHOD;
- private static final HotSpotResolvedJavaMethodImpl FRAME1_METHOD;
- private static final HotSpotResolvedJavaMethodImpl FRAME2_METHOD;
- private static final HotSpotResolvedJavaMethodImpl FRAME3_METHOD;
- private static final HotSpotResolvedJavaMethodImpl FRAME4_METHOD;
- private static final HotSpotResolvedJavaMethodImpl RUN_METHOD;
+ private static final ResolvedJavaMethod REC_FRAME_METHOD;
+ private static final ResolvedJavaMethod FRAME1_METHOD;
+ private static final ResolvedJavaMethod FRAME2_METHOD;
+ private static final ResolvedJavaMethod FRAME3_METHOD;
+ private static final ResolvedJavaMethod FRAME4_METHOD;
+ private static final ResolvedJavaMethod RUN_METHOD;
static {
Method method;
@@ -69,7 +68,7 @@
method = Thread.class.getDeclaredMethod("run");
RUN_METHOD = CTVMUtilities.getResolvedMethod(Thread.class, method);
} catch (NoSuchMethodException e) {
- throw new Error("TEST BUG: can't find a test method", e);
+ throw new Error("TEST BUG: can't find a test method : " + e, e);
}
}
@@ -126,7 +125,7 @@
*/
private void findFirst() {
checkNextFrameFor(null /* topmost frame */,
- new HotSpotResolvedJavaMethodImpl[]
+ new ResolvedJavaMethod[]
{FRAME2_METHOD, FRAME3_METHOD, FRAME4_METHOD},
FRAME4_METHOD, 0);
}
@@ -139,26 +138,26 @@
// Check that we would get a frame 4 starting from the topmost frame
HotSpotStackFrameReference nextStackFrame = checkNextFrameFor(
null /* topmost frame */,
- new HotSpotResolvedJavaMethodImpl[] {FRAME4_METHOD},
+ new ResolvedJavaMethod[] {FRAME4_METHOD},
FRAME4_METHOD, 0);
// Check that we would get a frame 3 starting from frame 4 when we try
// to search one of the next two frames
nextStackFrame = checkNextFrameFor(nextStackFrame,
- new HotSpotResolvedJavaMethodImpl[] {FRAME3_METHOD,
+ new ResolvedJavaMethod[] {FRAME3_METHOD,
FRAME2_METHOD},
FRAME3_METHOD, 0);
// Check that we would get a frame 1
nextStackFrame = checkNextFrameFor(nextStackFrame,
- new HotSpotResolvedJavaMethodImpl[] {FRAME1_METHOD},
+ new ResolvedJavaMethod[] {FRAME1_METHOD},
FRAME1_METHOD, 0);
// Check that we would skip (RECURSION_AMOUNT - 1) methods and find a
// recursionFrame starting from frame 1
nextStackFrame = checkNextFrameFor(nextStackFrame,
- new HotSpotResolvedJavaMethodImpl[] {REC_FRAME_METHOD},
+ new ResolvedJavaMethod[] {REC_FRAME_METHOD},
REC_FRAME_METHOD, RECURSION_AMOUNT - 1);
// Check that we would get a Thread::run method frame;
nextStackFrame = checkNextFrameFor(nextStackFrame,
- new HotSpotResolvedJavaMethodImpl[] {RUN_METHOD},
+ new ResolvedJavaMethod[] {RUN_METHOD},
RUN_METHOD, 0);
// Check that there are no more frames after thread's run method
nextStackFrame = CompilerToVMHelper.getNextStackFrame(nextStackFrame,
@@ -187,7 +186,7 @@
// Get frame 4
HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper
.getNextStackFrame(null /* topmost frame */,
- new HotSpotResolvedJavaMethodImpl[] {FRAME4_METHOD}, 0);
+ new ResolvedJavaMethod[] {FRAME4_METHOD}, 0);
// Get frame 2 by skipping one method starting from frame 4
checkNextFrameFor(nextStackFrame, null /* any */,
FRAME2_METHOD , 1 /* skip one */);
@@ -198,15 +197,18 @@
*/
private void findYourself() {
Method method;
+ Class<?> aClass = CompilerToVMHelper.CompilerToVMClass();
try {
- method = CompilerToVM.class.getDeclaredMethod("getNextStackFrame",
- HotSpotStackFrameReference.class,
- HotSpotResolvedJavaMethodImpl[].class, int.class);
+ method = aClass.getDeclaredMethod(
+ "getNextStackFrame",
+ HotSpotStackFrameReference.class,
+ ResolvedJavaMethod[].class,
+ int.class);
} catch (NoSuchMethodException e) {
- throw new Error("TEST BUG: can't find getNextStackFrame method");
+ throw new Error("TEST BUG: can't find getNextStackFrame : " + e, e);
}
- HotSpotResolvedJavaMethodImpl self
- = CTVMUtilities.getResolvedMethod(CompilerToVM.class, method);
+ ResolvedJavaMethod self
+ = CTVMUtilities.getResolvedMethod(aClass, method);
checkNextFrameFor(null /* topmost frame */, null /* any */, self, 0);
}
@@ -221,8 +223,8 @@
*/
private HotSpotStackFrameReference checkNextFrameFor(
HotSpotStackFrameReference currentFrame,
- HotSpotResolvedJavaMethodImpl[] searchMethods,
- HotSpotResolvedJavaMethodImpl expected,
+ ResolvedJavaMethod[] searchMethods,
+ ResolvedJavaMethod expected,
int skip) {
HotSpotStackFrameReference nextStackFrame = CompilerToVMHelper
.getNextStackFrame(currentFrame, searchMethods, skip);
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodAtSlotTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodAtSlotTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -36,7 +36,7 @@
package compiler.jvmci.compilerToVM;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
import java.util.HashMap;
@@ -94,7 +94,7 @@
}
private static void testSlotBigger(Class<?> holder) {
- HotSpotResolvedJavaMethodImpl method
+ HotSpotResolvedJavaMethod method
= CompilerToVMHelper.getResolvedJavaMethodAtSlot(holder, 50);
Asserts.assertNull(method, "Got method for non existing slot 50 in "
+ holder);
@@ -102,10 +102,14 @@
private static void testCorrectMethods(Class<?> holder, int methodsNumber) {
for (int i = 0; i < methodsNumber; i++) {
- HotSpotResolvedJavaMethodImpl method = CompilerToVMHelper
+ String caseName = String.format("slot %d in %s",
+ i, holder.getCanonicalName());
+ HotSpotResolvedJavaMethod method = CompilerToVMHelper
.getResolvedJavaMethodAtSlot(holder, i);
- Asserts.assertNotNull(method, "Did not got method for slot " + i
- + " in class " + holder.getCanonicalName());
+ Asserts.assertNotNull(method, caseName + " did not got method");
+ Asserts.assertEQ(holder,
+ CompilerToVMHelper.getMirror(method.getDeclaringClass()),
+ caseName + " : unexpected declaring class");
}
}
}
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,11 +27,13 @@
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
* @library / /testlibrary /../../test/lib
* @compile ../common/CompilerToVMHelper.java
+ * ../common/PublicMetaspaceWrapperObject.java
* @build compiler.jvmci.compilerToVM.GetResolvedJavaMethodTest
* @run main ClassFileInstaller
* sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* jdk.vm.ci.hotspot.CompilerToVMHelper
+ * jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
* -XX:+EnableJVMCI -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* compiler.jvmci.compilerToVM.GetResolvedJavaMethodTest
@@ -40,8 +42,8 @@
package compiler.jvmci.compilerToVM;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
-import jdk.vm.ci.hotspot.MetaspaceWrapperObject;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
import sun.hotspot.WhiteBox;
@@ -53,23 +55,20 @@
private static enum TestCase {
NULL_BASE {
@Override
- HotSpotResolvedJavaMethodImpl getResolvedJavaMethod() {
+ HotSpotResolvedJavaMethod getResolvedJavaMethod() {
return CompilerToVMHelper.getResolvedJavaMethod(
null, getPtrToMethod());
}
},
JAVA_METHOD_BASE {
@Override
- HotSpotResolvedJavaMethodImpl getResolvedJavaMethod() {
- HotSpotResolvedJavaMethodImpl methodInstance
+ HotSpotResolvedJavaMethod getResolvedJavaMethod() {
+ HotSpotResolvedJavaMethod methodInstance
= CompilerToVMHelper.getResolvedJavaMethodAtSlot(
- TEST_CLASS, 0);
- Field field;
+ TEST_CLASS, 0);
try {
- field = HotSpotResolvedJavaMethodImpl
- .class.getDeclaredField("metaspaceMethod");
- field.setAccessible(true);
- field.set(methodInstance, getPtrToMethod());
+ METASPACE_METHOD_FIELD.set(methodInstance,
+ getPtrToMethod());
} catch (ReflectiveOperationException e) {
throw new Error("TEST BUG : " + e, e);
}
@@ -79,19 +78,15 @@
},
JAVA_METHOD_BASE_IN_TWO {
@Override
- HotSpotResolvedJavaMethodImpl getResolvedJavaMethod() {
+ HotSpotResolvedJavaMethod getResolvedJavaMethod() {
long ptr = getPtrToMethod();
- HotSpotResolvedJavaMethodImpl methodInstance
+ HotSpotResolvedJavaMethod methodInstance
= CompilerToVMHelper.getResolvedJavaMethodAtSlot(
TEST_CLASS, 0);
- Field field;
try {
- field = HotSpotResolvedJavaMethodImpl
- .class.getDeclaredField("metaspaceMethod");
- field.setAccessible(true);
- field.set(methodInstance, ptr / 2L);
+ METASPACE_METHOD_FIELD.set(methodInstance, ptr / 2L);
} catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
+ throw new Error("TESTBUG : " + e, e);
}
return CompilerToVMHelper.getResolvedJavaMethod(methodInstance,
ptr - ptr / 2L);
@@ -99,36 +94,42 @@
},
JAVA_METHOD_BASE_ZERO {
@Override
- HotSpotResolvedJavaMethodImpl getResolvedJavaMethod() {
+ HotSpotResolvedJavaMethod getResolvedJavaMethod() {
long ptr = getPtrToMethod();
- HotSpotResolvedJavaMethodImpl methodInstance
+ HotSpotResolvedJavaMethod methodInstance
= CompilerToVMHelper.getResolvedJavaMethodAtSlot(
TEST_CLASS, 0);
- Field field;
try {
- field = HotSpotResolvedJavaMethodImpl
- .class.getDeclaredField("metaspaceMethod");
- field.setAccessible(true);
- field.set(methodInstance, 0L);
+ METASPACE_METHOD_FIELD.set(methodInstance, 0L);
} catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
+ throw new Error("TESTBUG : " + e, e);
}
return CompilerToVMHelper.getResolvedJavaMethod(methodInstance,
ptr);
}
}
;
- abstract HotSpotResolvedJavaMethodImpl getResolvedJavaMethod();
+ abstract HotSpotResolvedJavaMethod getResolvedJavaMethod();
}
private static final Unsafe UNSAFE = Utils.getUnsafe();
private static final WhiteBox WB = WhiteBox.getWhiteBox();
+ private static final Field METASPACE_METHOD_FIELD;
private static final Class<?> TEST_CLASS = GetResolvedJavaMethodTest.class;
private static final long PTR;
static {
- HotSpotResolvedJavaMethodImpl method
+ HotSpotResolvedJavaMethod method
= CompilerToVMHelper.getResolvedJavaMethodAtSlot(TEST_CLASS, 0);
- PTR = method.getMetaspacePointer();
+ try {
+ // jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.metaspaceMethod
+ METASPACE_METHOD_FIELD = method.getClass()
+ .getDeclaredField("metaspaceMethod");
+ METASPACE_METHOD_FIELD.setAccessible(true);
+ PTR = (long) METASPACE_METHOD_FIELD.get(method);
+ } catch (ReflectiveOperationException e) {
+ throw new Error("TESTBUG : " + e, e);
+ }
+
}
private static long getPtrToMethod() {
@@ -144,10 +145,11 @@
public void test(TestCase testCase) {
System.out.println(testCase.name());
- HotSpotResolvedJavaMethodImpl result = testCase.getResolvedJavaMethod();
+ HotSpotResolvedJavaMethod result = testCase.getResolvedJavaMethod();
Asserts.assertNotNull(result, testCase + " : got null");
- Asserts.assertEQ(result.getDeclaringClass().mirror(), TEST_CLASS,
- testCase + " : returned method has unexpected declaring class");
+ Asserts.assertEQ(TEST_CLASS,
+ CompilerToVMHelper.getMirror(result.getDeclaringClass()),
+ testCase + " : unexpected declaring class");
}
public static void main(String[] args) {
@@ -161,9 +163,9 @@
private static void testMetaspaceWrapperBase() {
try {
- HotSpotResolvedJavaMethodImpl method
+ HotSpotResolvedJavaMethod method
= CompilerToVMHelper.getResolvedJavaMethod(
- new MetaspaceWrapperObject() {
+ new PublicMetaspaceWrapperObject() {
@Override
public long getMetaspacePointer() {
return getPtrToMethod();
@@ -171,18 +173,18 @@
}, 0L);
throw new AssertionError("Test METASPACE_WRAPPER_BASE."
+ " Expected IllegalArgumentException has not been caught");
- } catch (IllegalArgumentException iae) {
+ } catch (IllegalArgumentException e) {
// expected
}
}
private static void testObjectBase() {
try {
- HotSpotResolvedJavaMethodImpl method
+ HotSpotResolvedJavaMethod method
= CompilerToVMHelper.getResolvedJavaMethod(new Object(), 0L);
throw new AssertionError("Test OBJECT_BASE."
+ " Expected IllegalArgumentException has not been caught");
- } catch (IllegalArgumentException iae) {
+ } catch (IllegalArgumentException e) {
// expected
}
}
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,11 +27,13 @@
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
* @library / /testlibrary /../../test/lib
* @compile ../common/CompilerToVMHelper.java
+ * ../common/PublicMetaspaceWrapperObject.java
* @build compiler.jvmci.compilerToVM.GetResolvedJavaTypeTest
* @run main ClassFileInstaller
* sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* jdk.vm.ci.hotspot.CompilerToVMHelper
+ * jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions
* -XX:+EnableJVMCI -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:+UseCompressedOops
@@ -45,11 +47,11 @@
package compiler.jvmci.compilerToVM;
import java.lang.reflect.Field;
+import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotConstantPool;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
-import jdk.vm.ci.hotspot.MetaspaceWrapperObject;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
+import jdk.vm.ci.hotspot.PublicMetaspaceWrapperObject;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
import sun.hotspot.WhiteBox;
@@ -59,21 +61,22 @@
private static enum TestCase {
NULL_BASE {
@Override
- HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+ HotSpotResolvedObjectType getResolvedJavaType() {
return CompilerToVMHelper.getResolvedJavaType(
null, getPtrToKlass(), COMPRESSED);
}
},
JAVA_METHOD_BASE {
@Override
- HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
- HotSpotResolvedJavaMethodImpl methodInstance
+ HotSpotResolvedObjectType getResolvedJavaType() {
+ HotSpotResolvedJavaMethod methodInstance
= CompilerToVMHelper.getResolvedJavaMethodAtSlot(
TEST_CLASS, 0);
Field field;
try {
- field = HotSpotResolvedJavaMethodImpl
- .class.getDeclaredField("metaspaceMethod");
+ // jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.metaspaceMethod
+ field = methodInstance.getClass()
+ .getDeclaredField("metaspaceMethod");
field.setAccessible(true);
field.set(methodInstance, getPtrToKlass());
} catch (ReflectiveOperationException e) {
@@ -86,17 +89,18 @@
},
CONSTANT_POOL_BASE {
@Override
- HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
- HotSpotConstantPool cpInst;
+ HotSpotResolvedObjectType getResolvedJavaType() {
+ ConstantPool cpInst;
try {
cpInst = CompilerToVMHelper.getConstantPool(null,
getPtrToKlass());
- Field field = HotSpotConstantPool.class
+ // jdk.vm.ci.hotspot.HotSpotConstantPool.metaspaceConstantPool
+ Field field = cpInst.getClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, getPtrToKlass());
} catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
+ throw new Error("TESTBUG : " + e, e);
}
return CompilerToVMHelper.getResolvedJavaType(cpInst,
0L, COMPRESSED);
@@ -104,17 +108,18 @@
},
CONSTANT_POOL_BASE_IN_TWO {
@Override
- HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+ HotSpotResolvedObjectType getResolvedJavaType() {
long ptr = getPtrToKlass();
- HotSpotConstantPool cpInst = HotSpotResolvedObjectTypeImpl
- .fromObjectClass(TEST_CLASS).getConstantPool();
+ ConstantPool cpInst = HotSpotResolvedObjectType
+ .fromObjectClass(TEST_CLASS)
+ .getConstantPool();
try {
- Field field = HotSpotConstantPool.class
+ Field field = cpInst.getClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, ptr / 2L);
} catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
+ throw new Error("TESTBUG : " + e, e);
}
return CompilerToVMHelper.getResolvedJavaType(cpInst,
ptr - ptr / 2L, COMPRESSED);
@@ -122,17 +127,18 @@
},
CONSTANT_POOL_BASE_ZERO {
@Override
- HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
+ HotSpotResolvedObjectType getResolvedJavaType() {
long ptr = getPtrToKlass();
- HotSpotConstantPool cpInst = HotSpotResolvedObjectTypeImpl
- .fromObjectClass(TEST_CLASS).getConstantPool();
+ ConstantPool cpInst = HotSpotResolvedObjectType
+ .fromObjectClass(TEST_CLASS)
+ .getConstantPool();
try {
- Field field = HotSpotConstantPool.class
+ Field field = cpInst.getClass()
.getDeclaredField("metaspaceConstantPool");
field.setAccessible(true);
field.set(cpInst, 0L);
} catch (ReflectiveOperationException e) {
- throw new Error("TESTBUG : " + e.getMessage(), e);
+ throw new Error("TESTBUG : " + e, e);
}
return CompilerToVMHelper.getResolvedJavaType(cpInst,
ptr, COMPRESSED);
@@ -140,9 +146,9 @@
},
OBJECT_TYPE_BASE {
@Override
- HotSpotResolvedObjectTypeImpl getResolvedJavaType() {
- HotSpotResolvedObjectTypeImpl type
- = HotSpotResolvedObjectTypeImpl.fromObjectClass(
+ HotSpotResolvedObjectType getResolvedJavaType() {
+ HotSpotResolvedObjectType type
+ = HotSpotResolvedObjectType.fromObjectClass(
OBJECT_TYPE_BASE.getClass());
long ptrToClass = UNSAFE.getKlassPointer(OBJECT_TYPE_BASE);
return CompilerToVMHelper.getResolvedJavaType(type,
@@ -150,7 +156,7 @@
}
},
;
- abstract HotSpotResolvedObjectTypeImpl getResolvedJavaType();
+ abstract HotSpotResolvedObjectType getResolvedJavaType();
}
private static final Unsafe UNSAFE = Utils.getUnsafe();
@@ -176,9 +182,10 @@
public void test(TestCase testCase) {
System.out.println(testCase.name());
- HotSpotResolvedObjectTypeImpl type = testCase.getResolvedJavaType();
- Asserts.assertEQ(type.mirror(), TEST_CLASS, testCase +
- " Unexpected Class returned by getResolvedJavaType");
+ HotSpotResolvedObjectType type = testCase.getResolvedJavaType();
+ Asserts.assertEQ(TEST_CLASS,
+ CompilerToVMHelper.getMirror(type),
+ testCase + " : unexpected class returned");
}
public static void main(String[] args) {
@@ -192,9 +199,9 @@
private static void testMetaspaceWrapperBase() {
try {
- HotSpotResolvedObjectTypeImpl type
+ HotSpotResolvedObjectType type
= CompilerToVMHelper.getResolvedJavaType(
- new MetaspaceWrapperObject() {
+ new PublicMetaspaceWrapperObject() {
@Override
public long getMetaspacePointer() {
return getPtrToKlass();
@@ -209,7 +216,7 @@
private static void testObjectBase() {
try {
- HotSpotResolvedObjectTypeImpl type
+ HotSpotResolvedObjectType type
= CompilerToVMHelper.getResolvedJavaType(new Object(), 0L,
COMPRESSED);
throw new AssertionError("Test OBJECT_BASE."
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -41,7 +41,7 @@
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
@@ -53,7 +53,7 @@
}
private static void runSanityTest(Executable aMethod, int[] bcis) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
String className = aMethod.getDeclaringClass().getName();
int lastDot = className.lastIndexOf('.');
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetSymbolTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetSymbolTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -52,7 +52,7 @@
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.meta.ConstantPool;
import jdk.test.lib.Utils;
@@ -76,7 +76,7 @@
} catch (NoSuchMethodException e) {
throw new Error("TEST BUG: can't find test method", e);
}
- HotSpotResolvedJavaMethodImpl resolvedMethod
+ HotSpotResolvedJavaMethod resolvedMethod
= CTVMUtilities.getResolvedMethod(aClass, method);
List<String> symbols;
try {
@@ -101,7 +101,7 @@
}
}
- private List<String> getSymbols(HotSpotResolvedJavaMethodImpl
+ private List<String> getSymbols(HotSpotResolvedJavaMethod
metaspaceMethod) throws ReflectiveOperationException {
List<String> symbols = new ArrayList<>();
ConstantPool pool = metaspaceMethod.getConstantPool();
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetVtableIndexForInterfaceTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -53,8 +53,8 @@
import java.util.Set;
import java.util.stream.Stream;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
@@ -125,10 +125,10 @@
private void runTest(TestCase tcase) throws NoSuchMethodException {
System.out.println(tcase);
Method method = tcase.holder.getDeclaredMethod(tcase.methodName);
- HotSpotResolvedObjectTypeImpl metaspaceKlass = CompilerToVMHelper
+ HotSpotResolvedObjectType metaspaceKlass = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(tcase.receiver),
getClass(), /* resolve = */ true);
- HotSpotResolvedJavaMethodImpl metaspaceMethod = CTVMUtilities
+ HotSpotResolvedJavaMethod metaspaceMethod = CTVMUtilities
.getResolvedMethod(tcase.holder, method);
int index = 0;
try {
--- a/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -43,22 +43,19 @@
import compiler.jvmci.common.CTVMUtilities;
import java.lang.reflect.Executable;
-import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import compiler.testlibrary.CompilerUtils;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
-import sun.hotspot.WhiteBox;
+import jdk.test.lib.Utils;
import sun.hotspot.code.NMethod;
public class HasCompiledCodeForOSRTest {
public static void main(String[] args) {
- List<CompileCodeTestCase>testCases = createTestCases();
+ List<CompileCodeTestCase> testCases = createTestCases();
testCases.forEach(HasCompiledCodeForOSRTest::runSanityTest);
}
@@ -67,7 +64,8 @@
try {
Class<?> aClass = DummyClass.class;
- testCases.add(new CompileCodeTestCase(
+ Object receiver = new DummyClass();
+ testCases.add(new CompileCodeTestCase(receiver,
aClass.getMethod("withLoop"), 17));
} catch (NoSuchMethodException e) {
throw new Error("TEST BUG : " + e.getMessage(), e);
@@ -78,8 +76,9 @@
private static void runSanityTest(CompileCodeTestCase testCase) {
System.out.println(testCase);
Executable aMethod = testCase.executable;
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
+ testCase.invoke(Utils.getNullValues(aMethod.getParameterTypes()));
testCase.deoptimize();
int[] levels = CompilerUtils.getAvailableCompilationLevels();
// not compiled
@@ -98,7 +97,9 @@
boolean isCompiled;
int level = nm.comp_level;
- for (int i : levels) {
+ int[] someLevels = new int[] {-4, 0, 1, 2, 3, 4, 5, 45};
+ // check levels
+ for (int i : someLevels) {
isCompiled = CompilerToVMHelper.hasCompiledCodeForOSR(
method, testCase.bci, i);
Asserts.assertEQ(isCompiled, level == i, String.format(
@@ -106,8 +107,20 @@
+ "level %d", testCase, i));
}
- for (int i : new int[] {-1, +1}) {
- int bci = testCase.bci + i;
+ // check bci
+ byte[] bytecode = CompilerToVMHelper.getBytecode(CTVMUtilities
+ .getResolvedMethod(testCase.executable));
+ int[] incorrectBci = new int[] {
+ testCase.bci + 1,
+ testCase.bci - 1,
+ -200,
+ -10,
+ bytecode.length,
+ bytecode.length + 1,
+ bytecode.length + 4,
+ bytecode.length + 200
+ };
+ for (int bci : incorrectBci) {
isCompiled = CompilerToVMHelper.hasCompiledCodeForOSR(
method, bci, level);
Asserts.assertFalse(isCompiled, String.format(
--- a/hotspot/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/HasFinalizableSubclassTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -45,7 +45,7 @@
import java.util.Set;
import java.util.stream.Stream;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
@@ -81,7 +81,7 @@
private void runTest(TestCase tcase) {
System.out.println(tcase);
- HotSpotResolvedObjectTypeImpl metaspaceKlass = CompilerToVMHelper
+ HotSpotResolvedObjectType metaspaceKlass = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(tcase.aClass),
getClass(), /* resolve = */ true);
Asserts.assertEQ(tcase.expected,
--- a/hotspot/test/compiler/jvmci/compilerToVM/InitializeConfigurationTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/InitializeConfigurationTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -44,6 +44,7 @@
import java.util.Objects;
import java.util.function.Consumer;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
import sun.misc.Unsafe;
@@ -72,7 +73,7 @@
private void runTest(List<TestCase> tcases) {
VMStructDataReader reader = new VMStructDataReader(
- CompilerToVMHelper.initializeConfiguration());
+ CompilerToVMHelper.initializeConfiguration(HotSpotJVMCIRuntime.runtime().getConfig()));
while (reader.hasNext()) {
VMFieldData data = reader.next();
for (TestCase tcase : tcases) {
--- a/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -41,14 +41,25 @@
package compiler.jvmci.compilerToVM;
+import compiler.jvmci.common.CTVMUtilities;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
import sun.hotspot.code.NMethod;
import java.util.List;
+import jdk.vm.ci.code.CodeCacheProvider;
+import jdk.vm.ci.code.CompilationResult;
+import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
public class InvalidateInstalledCodeTest {
+ private static final CodeCacheProvider CACHE_PROVIDER
+ = HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend()
+ .getCodeCache();
+
public static void main(String[] args) {
InvalidateInstalledCodeTest test
= new InvalidateInstalledCodeTest();
@@ -60,26 +71,37 @@
}
private void checkNull() {
- InstalledCode installedCode = new InstalledCode("<null>");
- installedCode.setAddress(0);
- CompilerToVMHelper.invalidateInstalledCode(installedCode);
+ Utils.runAndCheckException(
+ () -> CompilerToVMHelper.invalidateInstalledCode(null),
+ NullPointerException.class);
}
private void check(CompileCodeTestCase testCase) {
System.out.println(testCase);
- // to have a clean state
- NMethod beforeInvalidation = testCase.deoptimizeAndCompile();
- if (beforeInvalidation == null) {
- throw new Error("method is not compiled, testCase " + testCase);
+ HotSpotResolvedJavaMethod javaMethod
+ = CTVMUtilities.getResolvedMethod(testCase.executable);
+ HotSpotCompilationRequest compRequest = new HotSpotCompilationRequest(
+ javaMethod, testCase.bci, /* jvmciEnv = */ 0L);
+ String name = testCase.executable.getName();
+ CompilationResult compResult = new CompilationResult(name);
+ // to pass sanity check of default -1
+ compResult.setTotalFrameSize(0);
+ InstalledCode installedCode = CACHE_PROVIDER.installCode(
+ compRequest, compResult,
+ new InstalledCode(name), /* speculationLog = */ null,
+ /* isDefault = */ false);
+ Asserts.assertTrue(installedCode.isValid(), testCase
+ + " : code is invalid even before invalidation");
+
+ NMethod beforeInvalidation = testCase.toNMethod();
+ if (beforeInvalidation != null) {
+ throw new Error("TESTBUG : " + testCase + " : nmethod isn't found");
}
-
// run twice to verify how it works if method is already invalidated
for (int i = 0; i < 2; ++i) {
- InstalledCode installedCode = new InstalledCode(
- testCase.executable.getName());
- installedCode.setAddress(beforeInvalidation.address);
-
CompilerToVMHelper.invalidateInstalledCode(installedCode);
+ Asserts.assertFalse(installedCode.isValid(), testCase
+ + " : code is valid after invalidation, i = " + i);
NMethod afterInvalidation = testCase.toNMethod();
if (afterInvalidation != null) {
System.err.println("before: " + beforeInvalidation);
@@ -87,8 +109,6 @@
throw new AssertionError(testCase
+ " : method hasn't been invalidated, i = " + i);
}
- Asserts.assertFalse(installedCode.isValid(), testCase
- + " : code is valid after invalidation, i = " + i);
}
}
}
--- a/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*
*/
-/**
+/*
* @test
* @bug 8136421
* @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
@@ -40,7 +40,6 @@
package compiler.jvmci.compilerToVM;
-import jdk.vm.ci.hotspot.CompilerToVM;
import jdk.vm.ci.runtime.JVMCI;
import jdk.test.lib.Asserts;
@@ -88,9 +87,12 @@
private JVM_RegisterJVMCINatives() {
Method method;
try {
- method = CompilerToVM.class.getDeclaredMethod("registerNatives");
+ method = Class.forName("jdk.vm.ci.hotspot.CompilerToVM",
+ /* initialize = */ false,
+ this.getClass().getClassLoader())
+ .getDeclaredMethod("registerNatives");
method.setAccessible(true);
- } catch (NoSuchMethodException e) {
+ } catch (ReflectiveOperationException e) {
throw new Error("can't find CompilerToVM::registerNatives", e);
}
registerNatives = method;
--- a/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupKlassInPoolTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -44,8 +44,7 @@
import java.util.HashMap;
import java.util.Map;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotConstantPool;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import sun.reflect.ConstantPool;
/**
@@ -62,16 +61,16 @@
testCase.test();
}
- public static void validate(HotSpotConstantPool constantPoolCTVM,
+ public static void validate(jdk.vm.ci.meta.ConstantPool constantPoolCTVM,
ConstantPool constantPoolSS,
ConstantPoolTestsHelper.DummyClasses dummyClass, int i) {
Object classToVerify = CompilerToVMHelper
.lookupKlassInPool(constantPoolCTVM, i);
- if (!(classToVerify instanceof HotSpotResolvedObjectTypeImpl)
+ if (!(classToVerify instanceof HotSpotResolvedObjectType)
&& !(classToVerify instanceof String)) {
String msg = String.format("Output of method"
+ " CTVM.lookupKlassInPool is neither"
- + " a HotSpotResolvedObjectTypeImpl, nor a String");
+ + " a HotSpotResolvedObjectType, nor a String");
throw new AssertionError(msg);
}
int classNameIndex = (int) dummyClass.cp.get(i).value;
--- a/hotspot/test/compiler/jvmci/compilerToVM/LookupTypeTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/LookupTypeTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -42,7 +42,7 @@
import java.util.HashSet;
import java.util.Set;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
@@ -86,7 +86,7 @@
private void runTest(TestCase tcase) {
System.out.println(tcase);
- HotSpotResolvedObjectTypeImpl metaspaceKlass;
+ HotSpotResolvedObjectType metaspaceKlass;
try {
metaspaceKlass = CompilerToVMHelper.lookupType(tcase.className,
tcase.accessing, tcase.resolve);
--- a/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -46,19 +46,21 @@
package compiler.jvmci.compilerToVM;
-import compiler.jvmci.common.CTVMUtilities;
-import compiler.testlibrary.CompilerUtils;
+import java.lang.reflect.Method;
+import jdk.vm.ci.hotspot.HotSpotStackFrameReference;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
+
+import compiler.jvmci.common.CTVMUtilities;
+import compiler.testlibrary.CompilerUtils;
+
import sun.hotspot.WhiteBox;
-import java.lang.reflect.Method;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
-import jdk.vm.ci.hotspot.HotSpotStackFrameReference;
public class MaterializeVirtualObjectTest {
private static final WhiteBox WB = WhiteBox.getWhiteBox();
private static final Method METHOD;
- private static final HotSpotResolvedJavaMethodImpl RESOLVED_METHOD;
+ private static final ResolvedJavaMethod RESOLVED_METHOD;
private static final boolean INVALIDATE = Boolean.getBoolean(
"compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate");
@@ -113,7 +115,7 @@
if (materialize) {
HotSpotStackFrameReference hsFrame = CompilerToVMHelper
.getNextStackFrame(/* topmost frame */ null,
- new HotSpotResolvedJavaMethodImpl[]{
+ new ResolvedJavaMethod[]{
RESOLVED_METHOD}, /* don't skip any */ 0);
Asserts.assertNotNull(hsFrame, getName() + " : got null frame");
Asserts.assertTrue(WB.isMethodCompiled(METHOD), getName()
--- a/hotspot/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/MethodIsIgnoredBySecurityStackWalkTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -41,7 +41,7 @@
import java.lang.reflect.Executable;
import java.util.HashMap;
import java.util.Map;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.test.lib.Asserts;
@@ -54,7 +54,7 @@
}
private static void runSanityTest(Executable aMethod, Boolean expected) {
- HotSpotResolvedJavaMethodImpl method
+ HotSpotResolvedJavaMethod method
= CTVMUtilities.getResolvedMethod(aMethod);
boolean isIgnored = CompilerToVMHelper
.methodIsIgnoredBySecurityStackWalk(method);
--- a/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -46,7 +46,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.test.lib.Asserts;
@@ -78,7 +78,7 @@
}
private static void runSanityTest(Method aMethod) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
ProfilingInfo startProfile = method.getProfilingInfo();
Asserts.assertFalse(startProfile.isMature(), aMethod
--- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveConstantInPoolTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -42,7 +42,6 @@
import java.util.HashMap;
import java.util.Map;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotConstantPool;
import jdk.test.lib.Asserts;
import sun.reflect.ConstantPool;
@@ -62,7 +61,8 @@
testCase.test();
}
- private static void validateMethodHandle(HotSpotConstantPool constantPoolCTVM,
+ private static void validateMethodHandle(
+ jdk.vm.ci.meta.ConstantPool constantPoolCTVM,
ConstantPool constantPoolSS,
ConstantPoolTestsHelper.DummyClasses dummyClass, int index) {
Object constantInPool = CompilerToVMHelper
@@ -77,7 +77,8 @@
}
}
- private static void validateMethodType(HotSpotConstantPool constantPoolCTVM,
+ private static void validateMethodType(
+ jdk.vm.ci.meta.ConstantPool constantPoolCTVM,
ConstantPool constantPoolSS,
ConstantPoolTestsHelper.DummyClasses dummyClass, int index) {
Object constantInPool = CompilerToVMHelper
--- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveMethodTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -49,8 +49,8 @@
import java.util.HashSet;
import java.util.Set;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
import sun.misc.Unsafe;
@@ -125,16 +125,16 @@
private void runTest(TestCase tcase) throws NoSuchMethodException {
System.out.println(tcase);
- HotSpotResolvedJavaMethodImpl metaspaceMethod = CTVMUtilities
+ HotSpotResolvedJavaMethod metaspaceMethod = CTVMUtilities
.getResolvedMethod(tcase.holder,
tcase.holder.getDeclaredMethod(tcase.methodName));
- HotSpotResolvedObjectTypeImpl holderMetaspace = CompilerToVMHelper
+ HotSpotResolvedObjectType holderMetaspace = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(tcase.holder),
getClass(), /* resolve = */ true);
- HotSpotResolvedObjectTypeImpl callerMetaspace = CompilerToVMHelper
+ HotSpotResolvedObjectType callerMetaspace = CompilerToVMHelper
.lookupType(Utils.toJVMTypeSignature(tcase.caller),
getClass(), /* resolve = */ true);
- HotSpotResolvedJavaMethodImpl resolvedMetaspaceMethod
+ HotSpotResolvedJavaMethod resolvedMetaspaceMethod
= CompilerToVMHelper.resolveMethod(holderMetaspace,
metaspaceMethod, callerMetaspace);
if (tcase.isPositive) {
--- a/hotspot/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ResolveTypeInPoolTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -44,8 +44,7 @@
import java.util.HashMap;
import java.util.Map;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotConstantPool;
-import jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
import sun.reflect.ConstantPool;
/**
@@ -62,10 +61,11 @@
testCase.test();
}
- public static void validate(HotSpotConstantPool constantPoolCTVM,
+ public static void validate(
+ jdk.vm.ci.meta.ConstantPool constantPoolCTVM,
ConstantPool constantPoolSS,
ConstantPoolTestsHelper.DummyClasses dummyClass, int i) {
- HotSpotResolvedObjectTypeImpl typeToVerify = CompilerToVMHelper
+ HotSpotResolvedObjectType typeToVerify = CompilerToVMHelper
.resolveTypeInPool(constantPoolCTVM, i);
int classNameIndex = (int) dummyClass.cp.get(i).value;
String classNameToRefer = constantPoolSS.getUTF8At(classNameIndex);
--- a/hotspot/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ShouldInlineMethodTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -45,7 +45,7 @@
import java.util.Arrays;
import java.util.List;
import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.test.lib.Asserts;
import sun.hotspot.WhiteBox;
@@ -59,7 +59,7 @@
}
private static void runSanityTest(Executable aMethod) {
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
boolean shouldInline = CompilerToVMHelper.shouldInlineMethod(method);
boolean expectedShouldInline = WB.testSetForceInlineMethod(aMethod,
--- a/hotspot/test/compiler/jvmci/events/JvmciCompleteInitializationTest.config Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-compiler.jvmci.events.JvmciCompleteInitializationTest
--- a/hotspot/test/compiler/jvmci/events/JvmciCompleteInitializationTest.java Thu Nov 12 18:27:55 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 8136421
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64"
- * @library / /testlibrary
- * @build compiler.jvmci.common.JVMCIHelpers
- * compiler.jvmci.events.JvmciCompleteInitializationTest
- * @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
- * @run main jdk.test.lib.FileInstaller ./JvmciCompleteInitializationTest.config
- * ./META-INF/services/jdk.vm.ci.hotspot.HotSpotVMEventListener
- * @run main ClassFileInstaller
- * compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
- * compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
- * compiler.jvmci.events.JvmciCompleteInitializationTest
- * jdk.test.lib.Asserts
- * @run main/othervm -XX:+UnlockExperimentalVMOptions
- * -Xbootclasspath/a:.
- * -XX:+EnableJVMCI
- * -Dcompiler.jvmci.events.JvmciCompleteInitializationTest.positive=true
- * compiler.jvmci.events.JvmciCompleteInitializationTest
- * @run main/othervm -XX:+UnlockExperimentalVMOptions
- * -Xbootclasspath/a:.
- * -XX:-EnableJVMCI
- * -Dcompiler.jvmci.events.JvmciCompleteInitializationTest.positive=false
- * compiler.jvmci.events.JvmciCompleteInitializationTest
- */
-
-package compiler.jvmci.events;
-
-import jdk.test.lib.Asserts;
-import jdk.vm.ci.hotspot.HotSpotVMEventListener;
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-
-public class JvmciCompleteInitializationTest implements HotSpotVMEventListener {
- private static final boolean IS_POSITIVE = Boolean.getBoolean(
- "compiler.jvmci.events.JvmciCompleteInitializationTest.positive");
- private static volatile int completeInitializationCount = 0;
- private static volatile String errorMessage = "";
-
- public static void main(String args[]) {
- if (completeInitializationCount != 0) {
- throw new Error("Unexpected completeInitialization events"
- + " count at start");
- }
- initializeRuntime();
- int expectedEventCount = IS_POSITIVE ? 1 : 0;
- Asserts.assertEQ(completeInitializationCount, expectedEventCount,
- "Unexpected completeInitialization events count"
- + " after JVMCI init");
- initializeRuntime();
- Asserts.assertEQ(completeInitializationCount, expectedEventCount,
- "Unexpected completeInitialization events count"
- + " after 2nd JVMCI init");
- Asserts.assertTrue(errorMessage.isEmpty(), errorMessage);
- }
-
- private static void initializeRuntime() {
- Error t = null;
- try {
- /* in case JVMCI disabled, an InternalError on initialization
- and NoClassDefFound on 2nd try */
- HotSpotJVMCIRuntime.runtime();
- } catch (Error e) {
- t = e;
- }
- if (IS_POSITIVE) {
- Asserts.assertNull(t, "Caught unexpected exception");
- } else {
- Asserts.assertNotNull(t, "Got no expected error");
- }
- }
-
- @Override
- public void completeInitialization(HotSpotJVMCIRuntime
- hotSpotJVMCIRuntime) {
- completeInitializationCount++;
- if (hotSpotJVMCIRuntime == null) {
- errorMessage += " HotSpotJVMCIRuntime is null.";
- }
- }
-}
--- a/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -61,8 +61,9 @@
import jdk.vm.ci.code.CompilationResult;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
+import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl;
+import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
public class JvmciNotifyInstallEventTest implements HotSpotVMEventListener {
private static final String METHOD_NAME = "testMethod";
@@ -99,17 +100,18 @@
} catch (NoSuchMethodException e) {
throw new Error("TEST BUG: Can't find " + METHOD_NAME, e);
}
- HotSpotResolvedJavaMethodImpl method = CTVMUtilities
+ HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(SimpleClass.class, testMethod);
CompilationResult compResult = new CompilationResult(METHOD_NAME);
+ HotSpotCompilationRequest compRequest = new HotSpotCompilationRequest(method, -1, 0L);
// to pass sanity check of default -1
compResult.setTotalFrameSize(0);
- codeCache.installMethod(method, compResult, /* jvmciEnv = */ 0L,
+ codeCache.installCode(compRequest, compResult, /* installedCode = */ null, /* speculationLog = */ null,
/* isDefault = */ false);
Asserts.assertEQ(gotInstallNotification, 1,
"Got unexpected event count after 1st install attempt");
// since "empty" compilation result is ok, a second attempt should be ok
- codeCache.installMethod(method, compResult, /* jvmciEnv = */ 0L,
+ codeCache.installCode(compRequest, compResult, /* installedCode = */ null, /* speculationLog = */ null,
/* isDefault = */ false);
Asserts.assertEQ(gotInstallNotification, 2,
"Got unexpected event count after 2nd install attempt");
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.options.test/src/jdk/vm/ci/options/test/NestedBooleanOptionValueTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.options.test/src/jdk/vm/ci/options/test/NestedBooleanOptionValueTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,12 +29,20 @@
package jdk.vm.ci.options.test;
-import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.*;
-import static org.junit.Assert.*;
-import jdk.vm.ci.options.*;
-import jdk.vm.ci.options.OptionValue.*;
+import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.Master0;
+import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.Master1;
+import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.Master2;
+import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.NestedOption0;
+import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.NestedOption1;
+import static jdk.vm.ci.options.test.NestedBooleanOptionValueTest.Options.NestedOption2;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import jdk.vm.ci.options.NestedBooleanOptionValue;
+import jdk.vm.ci.options.OptionDescriptor;
+import jdk.vm.ci.options.OptionValue;
+import jdk.vm.ci.options.OptionValue.OverrideScope;
-import org.junit.*;
+import org.junit.Test;
public class NestedBooleanOptionValueTest {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.options.test/src/jdk/vm/ci/options/test/TestOptionValue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.options.test/src/jdk/vm/ci/options/test/TestOptionValue.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,15 +29,21 @@
package jdk.vm.ci.options.test;
-import static jdk.vm.ci.options.test.TestOptionValue.Options.*;
-import static org.junit.Assert.*;
-
-import java.util.*;
+import static jdk.vm.ci.options.test.TestOptionValue.Options.Mutable;
+import static jdk.vm.ci.options.test.TestOptionValue.Options.SecondMutable;
+import static jdk.vm.ci.options.test.TestOptionValue.Options.Stable;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
-import jdk.vm.ci.options.*;
-import jdk.vm.ci.options.OptionValue.*;
+import java.util.Arrays;
-import org.junit.*;
+import jdk.vm.ci.options.OptionDescriptor;
+import jdk.vm.ci.options.OptionValue;
+import jdk.vm.ci.options.OptionValue.OverrideScope;
+import jdk.vm.ci.options.StableOptionValue;
+
+import org.junit.Test;
@SuppressWarnings("try")
public class TestOptionValue {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,9 +30,11 @@
package jdk.vm.ci.runtime.test;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
-import org.junit.*;
+import org.junit.Assert;
+import org.junit.Test;
public class ConstantTest extends FieldUniverse {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/FieldUniverse.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/FieldUniverse.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,11 @@
*/
package jdk.vm.ci.runtime.test;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ResolvedJavaField;
/**
* Context for field related tests.
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/MethodUniverse.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/MethodUniverse.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,10 +22,12 @@
*/
package jdk.vm.ci.runtime.test;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Context for method related tests.
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/NameAndSignature.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/NameAndSignature.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,11 +22,14 @@
*/
package jdk.vm.ci.runtime.test;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.reflect.Method;
+import java.util.Arrays;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.runtime.*;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
+import jdk.vm.ci.runtime.JVMCI;
class NameAndSignature {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/RedefineClassTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,22 +30,31 @@
package jdk.vm.ci.runtime.test;
-import static org.junit.Assume.*;
+import static org.junit.Assume.assumeTrue;
-import java.io.*;
-import java.lang.instrument.*;
-import java.lang.management.*;
-import java.lang.reflect.*;
-import java.nio.file.*;
-import java.security.*;
-import java.util.*;
-import java.util.jar.*;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.instrument.Instrumentation;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
-import javax.tools.*;
+import javax.tools.ToolProvider;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
-import org.junit.*;
+import org.junit.Assert;
+import org.junit.Test;
/**
* Tests that {@link ResolvedJavaMethod}s are safe in the context of class redefinition being used
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveConcreteMethodTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,11 +29,14 @@
package jdk.vm.ci.runtime.test;
-import static org.junit.Assert.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.runtime.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.runtime.JVMCI;
-import org.junit.*;
+import org.junit.Test;
public class ResolvedJavaTypeResolveConcreteMethodTest {
public final MetaAccessProvider metaAccess;
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ResolvedJavaTypeResolveMethodTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,11 +29,14 @@
package jdk.vm.ci.runtime.test;
-import static org.junit.Assert.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.runtime.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.runtime.JVMCI;
-import org.junit.*;
+import org.junit.Test;
public class ResolvedJavaTypeResolveMethodTest {
public final MetaAccessProvider metaAccess;
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestConstantReflectionProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,14 +30,20 @@
package jdk.vm.ci.runtime.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.reflect.Array;
+import java.util.List;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
-import org.junit.*;
+import org.junit.Test;
/**
* Tests for {@link ConstantReflectionProvider}. It assumes an implementation of the interface that
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaField.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,14 +30,19 @@
package jdk.vm.ci.runtime.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.Map;
-import java.lang.reflect.*;
-import java.util.*;
+import jdk.vm.ci.meta.JavaField;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.*;
-
-import org.junit.*;
+import org.junit.Test;
/**
* Tests for {@link JavaField}.
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaMethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,14 +30,17 @@
package jdk.vm.ci.runtime.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.Map;
-import java.lang.reflect.*;
-import java.util.*;
+import jdk.vm.ci.meta.JavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.*;
-
-import org.junit.*;
+import org.junit.Test;
/**
* Tests for {@link JavaMethod}.
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestJavaType.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,10 +30,11 @@
package jdk.vm.ci.runtime.test;
-import jdk.vm.ci.meta.*;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.JavaType;
-import org.junit.*;
+import org.junit.Test;
/**
* Tests for {@link JavaType}.
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,14 +30,22 @@
package jdk.vm.ci.runtime.test;
-import static jdk.vm.ci.meta.MetaUtil.*;
-import static org.junit.Assert.*;
+import static jdk.vm.ci.meta.MetaUtil.toInternalName;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
-import java.lang.reflect.*;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.*;
-
-import org.junit.*;
+import org.junit.Test;
/**
* Tests for {@link MetaAccessProvider}.
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,15 +30,27 @@
package jdk.vm.ci.runtime.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.LocationIdentity;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
-import org.junit.*;
+import org.junit.Test;
/**
* Tests for {@link ResolvedJavaField}.
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,16 +30,35 @@
package jdk.vm.ci.runtime.test;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
-import java.lang.annotation.*;
-import java.lang.invoke.*;
-import java.lang.reflect.*;
-import java.util.*;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
-import jdk.vm.ci.meta.*;
+import jdk.vm.ci.meta.ConstantPool;
+import jdk.vm.ci.meta.ExceptionHandler;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
-import org.junit.*;
+import org.junit.Assert;
+import org.junit.Test;
/**
* Tests for {@link ResolvedJavaMethod}.
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,19 +30,42 @@
package jdk.vm.ci.runtime.test;
-import static java.lang.reflect.Modifier.*;
-import static org.junit.Assert.*;
+import static java.lang.reflect.Modifier.isAbstract;
+import static java.lang.reflect.Modifier.isFinal;
+import static java.lang.reflect.Modifier.isPrivate;
+import static java.lang.reflect.Modifier.isProtected;
+import static java.lang.reflect.Modifier.isPublic;
+import static java.lang.reflect.Modifier.isStatic;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.util.*;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
-import jdk.vm.ci.common.*;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.meta.Assumptions.*;
+import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.meta.Assumptions.AssumptionResult;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ModifiersProvider;
+import jdk.vm.ci.meta.ResolvedJavaField;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.TrustedInterface;
-import org.junit.*;
+import org.junit.Test;
import sun.reflect.ConstantPool;
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,20 +22,42 @@
*/
package jdk.vm.ci.runtime.test;
-import static java.lang.reflect.Modifier.*;
+import static java.lang.reflect.Modifier.isFinal;
+import static java.lang.reflect.Modifier.isStatic;
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.AbstractCollection;
+import java.util.AbstractList;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
import java.util.Queue;
-import java.util.stream.*;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
-import jdk.vm.ci.meta.*;
-import jdk.vm.ci.runtime.*;
+import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaField;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.TrustedInterface;
+import jdk.vm.ci.runtime.JVMCI;
-import org.junit.*;
+import org.junit.Test;
-import sun.misc.*;
+import sun.misc.Unsafe;
//JaCoCo Exclude
--- a/hotspot/test/compiler/membars/DekkerTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/membars/DekkerTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,9 +25,9 @@
* @test
* @bug 8007898
* @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
* @author Martin Doerr martin DOT doerr AT sap DOT com
*
* Run 3 times since the failure is intermittent.
--- a/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/compiler/unsafe/UnsafeGetConstantField.java Wed Jul 05 21:00:20 2017 +0200
@@ -43,13 +43,13 @@
import jdk.internal.org.objectweb.asm.*;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static jdk.internal.org.objectweb.asm.Opcodes.*;
public class UnsafeGetConstantField {
static final Class<?> THIS_CLASS = UnsafeGetConstantField.class;
- static final Unsafe U = Utils.getUnsafe();
+ static final Unsafe U = Unsafe.getUnsafe();
public static void main(String[] args) {
testUnsafeGetAddress();
--- a/hotspot/test/gc/g1/TestGCLogMessages.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/gc/g1/TestGCLogMessages.java Wed Jul 05 21:00:20 2017 +0200
@@ -79,6 +79,7 @@
// Misc Top-level
new LogMessageWithLevel("Code Root Purge", Level.FINER),
new LogMessageWithLevel("String Dedup Fixup", Level.FINER),
+ new LogMessageWithLevel("Expand Heap After Collection", Level.FINER),
// Free CSet
new LogMessageWithLevel("Young Free CSet", Level.FINEST),
new LogMessageWithLevel("Non-Young Free CSet", Level.FINEST),
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Annotations/TestAnnotatedStringEncoding.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+
+/*
+ * @test
+ * @bug 8054307
+ * @summary Tests the correct encoding of latin1/UTF16 Strings used in annotations.
+ */
+public class TestAnnotatedStringEncoding {
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ @interface Test {
+ String str();
+ int index();
+ }
+
+ public static void main(String[] args) throws Exception {
+ new TestAnnotatedStringEncoding().run();
+ }
+
+ public void run() {
+ // Iterate over annotated methods and retrieve the string
+ for (Method m : this.getClass().getMethods()) {
+ if (m.isAnnotationPresent(Test.class)) {
+ // Check if string equals expected value
+ Test test = m.getAnnotation(Test.class);
+ String str = test.str();
+ int index = test.index();
+ if (!str.equals(strValue[index])) {
+ throw new RuntimeException(m.getName() + " failed: \"" + str + "\" (0x" + Integer.toHexString(str.charAt(0)) +
+ ") does not equal \"" + strValue[index] + "\" (0x" + Integer.toHexString(strValue[index].charAt(0)) + ") .");
+ }
+ }
+ }
+ System.out.println("Test passed.");
+ }
+
+ public static String[] strValue = {
+ "\u0000", "\u0020", "\u0021", "\u0080",
+ "\u00FF", "\u0100", "\u017F", "\u01FF",
+ "\u07FF", "\u0800", "\uC280", "\uC2BF",
+ "\uC380", "\uC3BF", "\uC5BF", "\uFFFF",
+ "\u10000", "\u1FFFFF", "\u200000",
+ "\u3FFFFFF", "\u4000000", "\u7FFFFFFF",
+ "ab\uff23\uff24ef\uff27", "\uff21\uff22cd\uff25g", "\u00FF\u00FF\u00FF", "\u00A1\u00A1\u00A1\u00A1", ""};
+
+ @Test(str = "\u0000", index = 0)
+ public static void check0() { }
+
+ @Test(str = "\u0020", index = 1)
+ public static void check1() { }
+
+ @Test(str = "\u0021", index = 2)
+ public static void check2() { }
+
+ @Test(str = "\u0080", index = 3)
+ public static void check3() { }
+
+ @Test(str = "\u00FF", index = 4)
+ public static void check4() { }
+
+ @Test(str = "\u0100", index = 5)
+ public static void check5() { }
+
+ @Test(str = "\u017F", index = 6)
+ public static void check6() { }
+
+ @Test(str = "\u01FF", index = 7)
+ public static void check7() { }
+
+ @Test(str = "\u07FF", index = 8)
+ public static void check8() { }
+
+ @Test(str = "\u0800", index = 9)
+ public static void check9() { }
+
+ @Test(str = "\uC280", index = 10)
+ public static void check10() { }
+
+ @Test(str = "\uC2BF", index = 11)
+ public static void check11() { }
+
+ @Test(str = "\uC380", index = 12)
+ public static void check12() { }
+
+ @Test(str = "\uC3BF", index = 13)
+ public static void check13() { }
+
+ @Test(str = "\uC5BF", index = 14)
+ public static void check14() { }
+
+ @Test(str = "\uFFFF", index = 15)
+ public static void check15() { }
+
+ @Test(str = "\u10000", index = 16)
+ public static void check16() { }
+
+ @Test(str = "\u1FFFFF", index = 17)
+ public static void check17() { }
+
+ @Test(str = "\u200000", index = 18)
+ public static void check18() { }
+
+ @Test(str = "\u3FFFFFF", index = 19)
+ public static void check19() { }
+
+ @Test(str = "\u4000000", index = 20)
+ public static void check20() { }
+
+ @Test(str = "\u7FFFFFFF", index = 21)
+ public static void check21() { }
+
+ @Test(str = "ab\uff23\uff24ef\uff27", index = 22)
+ public static void check22() { }
+
+ @Test(str = "\uff21\uff22cd\uff25g", index = 23)
+ public static void check23() { }
+
+ @Test(str = "\u00FF\u00FF\u00FF", index = 24)
+ public static void check24() { }
+
+ @Test(str = "\u00A1\u00A1\u00A1\u00A1", index = 25)
+ public static void check25() { }
+
+ @Test(str = "", index = 26)
+ public static void check26() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import jdk.test.lib.*;
+
+/*
+ * @test
+ * @bug 8129855
+ * @summary -XX:+IgnoreUnrecognizedVMOptions should work according to the spec from JDK-8129855
+ *
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ * java.management
+ * @run main IgnoreUnrecognizedVMOptions
+ */
+public class IgnoreUnrecognizedVMOptions {
+
+ private static void runJavaAndCheckExitValue(boolean shouldSucceed, String... args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ if (shouldSucceed) {
+ output.shouldHaveExitValue(0);
+ } else {
+ output.shouldHaveExitValue(1);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ boolean product = !Platform.isDebugBuild();
+
+ /*
+ #1.1 wrong value and non-existing flag:
+ exists, invalid value does not exist
+ -XX:MinHeapFreeRatio=notnum -XX:THIS_FLAG_DOESNT_EXIST
+ -IgnoreUnrecognizedVMOptions ERR ERR
+ +IgnoreUnrecognizedVMOptions ERR OK
+ */
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:MinHeapFreeRatio=notnum", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:THIS_FLAG_DOESNT_EXIST", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:MinHeapFreeRatio=notnum", "-version");
+ runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:THIS_FLAG_DOESNT_EXIST", "-version");
+
+ /*
+ #1.2 normal flag with ranges:
+ exists, in range exists, out of range
+ -XX:StackRedPages=1 -XX:StackRedPages=0
+ -IgnoreUnrecognizedVMOptions OK ERR
+ +IgnoreUnrecognizedVMOptions OK ERR
+ */
+ runJavaAndCheckExitValue(true, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:StackRedPages=1", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:StackRedPages=0", "-version");
+ runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:StackRedPages=1", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:StackRedPages=0", "-version");
+
+ /*
+ #1.3 develop & notproduct flag on debug VM:
+ develop & !product_build notproduct & !product_build
+ -XX:+DeoptimizeALot -XX:+VerifyCodeCache
+ -IgnoreUnrecognizedVMOptions OK OK
+ +IgnoreUnrecognizedVMOptions OK OK
+ */
+ if (!product) {
+ runJavaAndCheckExitValue(true, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:+DeoptimizeALot", "-version");
+ runJavaAndCheckExitValue(true, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:+VerifyCodeCache", "-version");
+ runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+DeoptimizeALot", "-version");
+ runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+VerifyCodeCache", "-version");
+ }
+
+ /*
+ #1.4 develop & notproduct flag on product VM:
+ develop & !product_build notproduct & product_build
+ -XX:+DeoptimizeALot -XX:+VerifyCodeCache
+ -IgnoreUnrecognizedVMOptions ERR ERR
+ +IgnoreUnrecognizedVMOptions OK OK
+ */
+ if (product) {
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:+DeoptimizeALot", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:+VerifyCodeCache", "-version");
+ runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+DeoptimizeALot", "-version");
+ runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+VerifyCodeCache", "-version");
+ }
+
+
+ /*
+ #1.5 malformed develop & notproduct flag on debug VM:
+ develop & !product_build notproduct & !product_build
+ -XX:DeoptimizeALot -XX:VerifyCodeCache
+ -IgnoreUnrecognizedVMOptions ERR ERR
+ +IgnoreUnrecognizedVMOptions ERR ERR
+ */
+ if (!product) {
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:DeoptimizeALot", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:VerifyCodeCache", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:DeoptimizeALot", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:VerifyCodeCache", "-version");
+ }
+
+ /*
+ #1.6 malformed develop & notproduct flag on product VM:
+ develop & !product_build notproduct & product_build
+ -XX:DeoptimizeALot -XX:VerifyCodeCache
+ -IgnoreUnrecognizedVMOptions ERR ERR
+ +IgnoreUnrecognizedVMOptions OK OK
+ */
+ if (product) {
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:DeoptimizeALot", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:VerifyCodeCache", "-version");
+ runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:DeoptimizeALot", "-version");
+ runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:VerifyCodeCache", "-version");
+ }
+
+ /*
+ #1.7 locked flag:
+ diagnostic & locked experimental & locked commercial & locked
+ -XX:-UnlockDiagnosticVMOptions -XX:-UnlockExperimentalVMOptions -XX:-UnlockCommercialFeatures
+ -XX:+PrintInlining -XX:+AlwaysSafeConstructors -XX:+FlightRecorder
+ -IgnoreUnrecognizedVMOptions ERR ERR ERR
+ +IgnoreUnrecognizedVMOptions ERR ERR ERR
+ */
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:+PrintInlining", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:+AlwaysSafeConstructors", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:+FlightRecorder", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:+PrintInlining", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:+AlwaysSafeConstructors", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:+FlightRecorder", "-version");
+
+ /*
+ #1.8 malformed locked flag:
+ diagnostic & locked experimental & locked commercial & locked
+ -XX:-UnlockDiagnosticVMOptions -XX:-UnlockExperimentalVMOptions -XX:-UnlockCommercialFeatures
+ -XX:PrintInlining -XX:AlwaysSafeConstructors -XX:FlightRecorder
+ -IgnoreUnrecognizedVMOptions ERR ERR ERR
+ +IgnoreUnrecognizedVMOptions ERR ERR ERR
+ */
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:PrintInlining", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:AlwaysSafeConstructors", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:FlightRecorder", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:PrintInlining", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:AlwaysSafeConstructors", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:FlightRecorder", "-version");
+
+ /*
+ #1.9 malformed unlocked flag:
+ diagnostic & locked experimental & locked commercial & locked
+ -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UnlockCommercialFeatures
+ -XX:PrintInlining -XX:AlwaysSafeConstructors -XX:FlightRecorder
+ -IgnoreUnrecognizedVMOptions ERR ERR ERR
+ +IgnoreUnrecognizedVMOptions ERR ERR ERR
+ */
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:PrintInlining", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:AlwaysSafeConstructors", "-version");
+ runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:FlightRecorder", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:PrintInlining", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:AlwaysSafeConstructors", "-version");
+ runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:FlightRecorder", "-version");
+ }
+}
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,7 +29,7 @@
* java.management
* jdk.attach
* jdk.management/sun.tools.attach
- * @run main/othervm/timeout=600 TestOptionsWithRanges
+ * @run main/othervm/timeout=780 TestOptionsWithRanges
*/
import java.util.ArrayList;
@@ -70,6 +70,8 @@
allOptionsAsMap.remove("G1ConcRefinementThreads");
allOptionsAsMap.remove("G1RSetRegionEntries");
allOptionsAsMap.remove("G1RSetSparseRegionEntries");
+ allOptionsAsMap.remove("G1UpdateBufferSize");
+ allOptionsAsMap.remove("InitialBootClassLoaderMetaspaceSize");
/*
* Remove parameters controlling the code cache. As these
--- a/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java Wed Jul 05 21:00:20 2017 +0200
@@ -116,20 +116,6 @@
}
/**
- * Add dependency for option depending on it's type. E.g. run the JVM in
- * compilation mode for compiler options.
- *
- * @param option option
- * @param type type of the option
- */
- private static void addTypeDependency(JVMOption option, String type) {
- if (type.contains("C1") || type.contains("C2")) {
- /* Run in compiler mode for compiler flags */
- option.addPrepend("-Xcomp");
- }
- }
-
- /**
* Parse JVM Options. Get input from "inputReader". Parse using
* "-XX:+PrintFlagsRanges" output format.
*
@@ -214,7 +200,6 @@
token = token.substring(1, token.indexOf("}"));
if (acceptOrigin.test(token)) {
- addTypeDependency(option, token);
addNameDependency(option);
allOptions.put(name, option);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsDifferentCompactStrings.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ * @test CdsDifferentCompactStrings
+ * @summary CDS (class data sharing) requires the same -XX:[+-]CompactStrings
+ * setting between archive creation time and load time.
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ * java.management
+ */
+
+import jdk.test.lib.*;
+
+public class CdsDifferentCompactStrings {
+ public static void main(String[] args) throws Exception {
+ createAndLoadSharedArchive("+", "-");
+ createAndLoadSharedArchive("-", "+");
+ }
+
+ private static void createAndLoadSharedArchive(String create, String load)
+ throws Exception
+ {
+ String createCompactStringsArgument = "-XX:" + create + "CompactStrings";
+ String loadCompactStringsArgument = "-XX:" + load + "CompactStrings";
+
+ String filename = "./CdsDifferentCompactStrings" + create + ".jsa";
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=" + filename,
+ "-Xshare:dump",
+ createCompactStringsArgument);
+
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Loading classes to share");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder(
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:SharedArchiveFile=" + filename,
+ "-Xshare:on",
+ loadCompactStringsArgument,
+ "-version");
+
+ output = new OutputAnalyzer(pb.start());
+ try {
+ output.shouldContain("The shared archive file's CompactStrings " +
+ "setting .* does not equal the current CompactStrings setting");
+ } catch (RuntimeException e) {
+ output.shouldContain("Unable to use shared archive");
+ }
+ output.shouldHaveExitValue(1);
+ }
+}
--- a/hotspot/test/testlibrary/jdk/test/lib/Utils.java Thu Nov 12 18:27:55 2015 -0800
+++ b/hotspot/test/testlibrary/jdk/test/lib/Utils.java Wed Jul 05 21:00:20 2017 +0200
@@ -41,6 +41,8 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.function.BooleanSupplier;
@@ -594,5 +596,25 @@
}
return result;
}
+
+ public static Object[] getNullValues(Class<?>... types) {
+ Object[] result = new Object[types.length];
+ int i = 0;
+ for (Class<?> type : types) {
+ result[i++] = NULL_VALUES.get(type);
+ }
+ return result;
+ }
+ private static Map<Class<?>, Object> NULL_VALUES = new HashMap<>();
+ static {
+ NULL_VALUES.put(boolean.class, false);
+ NULL_VALUES.put(byte.class, (byte) 0);
+ NULL_VALUES.put(short.class, (short) 0);
+ NULL_VALUES.put(char.class, '\0');
+ NULL_VALUES.put(int.class, 0);
+ NULL_VALUES.put(long.class, 0L);
+ NULL_VALUES.put(float.class, 0.0f);
+ NULL_VALUES.put(double.class, 0.0d);
+ }
}
--- a/jdk/.hgtags Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/.hgtags Wed Jul 05 21:00:20 2017 +0200
@@ -334,3 +334,4 @@
0d0a63b325592607974612f9cfb48590975aa2d6 jdk9-b89
b433e4dfb830fea60e5187e4580791b62cc362d2 jdk9-b90
97624df5026a2fb191793697dbd2c604c4d5c66e jdk9-b91
+6a5c99506f44538b879d8635a3979849ed587130 jdk9-b92
--- a/jdk/make/Import.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/Import.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -45,8 +45,16 @@
#
# Import hotspot
#
+
+# Don't import jsig library for static builds
+ifneq ($(STATIC_BUILD), true)
+ JSIG_IMPORT = jsig.*
+else
+ JSIG_IMPORT =
+endif
+
HOTSPOT_BASE_IMPORT_FILES := \
- $(addprefix $(LIBRARY_PREFIX), jvm.* jsig.* jvm_db.* jvm_dtrace.*) \
+ $(addprefix $(LIBRARY_PREFIX), jvm.* $(JSIG_IMPORT) jvm_db.* jvm_dtrace.*) \
Xusage.txt \
#
@@ -79,32 +87,34 @@
################################################################################
-ifeq ($(OPENJDK_TARGET_OS), macosx)
- JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \
- $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
-else
- JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
- $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
-endif
+ifneq ($(STATIC_BUILD), true)
+ ifeq ($(OPENJDK_TARGET_OS), macosx)
+ JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \
+ $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
+ else
+ JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
+ $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
+ endif
-ifneq ($(OPENJDK_TARGET_OS), windows)
- ifeq ($(JVM_VARIANT_SERVER), true)
- BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
- ifneq (, $(JSIG_DEBUGINFO))
- BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+ ifneq ($(OPENJDK_TARGET_OS), windows)
+ ifeq ($(JVM_VARIANT_SERVER), true)
+ BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
+ ifneq (, $(JSIG_DEBUGINFO))
+ BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/server/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+ endif
endif
- endif
- ifeq ($(JVM_VARIANT_CLIENT), true)
- BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
- ifneq (, $(JSIG_DEBUGINFO))
- BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+ ifeq ($(JVM_VARIANT_CLIENT), true)
+ BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
+ ifneq (, $(JSIG_DEBUGINFO))
+ BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/client/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+ endif
endif
- endif
- ifneq ($(OPENJDK_TARGET_OS), macosx)
- ifeq ($(JVM_VARIANT_MINIMAL1), true)
- BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
- ifneq (,$(JSIG_DEBUGINFO))
- BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+ ifneq ($(OPENJDK_TARGET_OS), macosx)
+ ifeq ($(JVM_VARIANT_MINIMAL1), true)
+ BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(LIBRARY_PREFIX)jsig$(SHARED_LIBRARY_SUFFIX)
+ ifneq (,$(JSIG_DEBUGINFO))
+ BASE_TARGETS += $(BASE_INSTALL_LIBRARIES_HERE)/minimal/$(foreach I,$(JSIG_DEBUGINFO),$(notdir $I))
+ endif
endif
endif
endif
--- a/jdk/make/data/charsetmapping/DoubleByte-X.java.template Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/data/charsetmapping/DoubleByte-X.java.template Wed Jul 05 21:00:20 2017 +0200
@@ -50,12 +50,12 @@
public CharsetDecoder newDecoder() {
initb2c();
- return new DoubleByte.Decoder$DECTYPE$(this, b2c, b2cSB, $B2MIN$, $B2MAX$);
+ return new DoubleByte.Decoder$DECTYPE$(this, b2c, b2cSB, $B2MIN$, $B2MAX$, $ASCIICOMPATIBLE$);
}
public CharsetEncoder newEncoder() {
initc2b();
- return new DoubleByte.Encoder$ENCTYPE$(this, $ENC_REPLACEMENT$ c2b, c2bIndex);
+ return new DoubleByte.Encoder$ENCTYPE$(this, $ENC_REPLACEMENT$ c2b, c2bIndex, $ASCIICOMPATIBLE$);
}
$B2C$
--- a/jdk/make/data/charsetmapping/SingleByte-X.java.template Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/data/charsetmapping/SingleByte-X.java.template Wed Jul 05 21:00:20 2017 +0200
@@ -48,11 +48,11 @@
}
public CharsetDecoder newDecoder() {
- return new SingleByte.Decoder(this, b2c);
+ return new SingleByte.Decoder(this, b2c, $ASCIICOMPATIBLE$);
}
public CharsetEncoder newEncoder() {
- return new SingleByte.Encoder(this, c2b, c2bIndex);
+ return new SingleByte.Encoder(this, c2b, c2bIndex, $ASCIICOMPATIBLE$);
}
private final static String b2cTable = $B2CTABLE$
--- a/jdk/make/gensrc/Gensrc-java.base.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/Gensrc-java.base.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -38,15 +38,15 @@
include GensrcProperties.gmk
-$(eval $(call SetupCompileProperties,LIST_RESOURCE_BUNDLE, \
- $(filter %.properties, \
- $(call CacheFind, $(JDK_TOPDIR)/src/java.base/share/classes/sun/launcher/resources)), \
- ListResourceBundle))
+$(eval $(call SetupCompileProperties, LIST_RESOURCE_BUNDLE, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/classes/sun/launcher/resources, \
+ CLASS := ListResourceBundle, \
+))
-$(eval $(call SetupCompileProperties,SUN_UTIL, \
- $(filter %.properties, \
- $(call CacheFind, $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/resources)), \
- sun.util.resources.LocaleNamesBundle))
+$(eval $(call SetupCompileProperties, SUN_UTIL, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/resources, \
+ CLASS := sun.util.resources.LocaleNamesBundle, \
+))
GENSRC_JAVA_BASE += $(LIST_RESOURCE_BUNDLE) $(SUN_UTIL)
--- a/jdk/make/gensrc/Gensrc-java.desktop.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/Gensrc-java.desktop.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -66,11 +66,11 @@
PROP_SRC_DIRS += $(JDK_TOPDIR)/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/resources
endif
-PROP_SRC_FILES := $(filter-out %cursors.properties, \
- $(filter %.properties, $(call CacheFind, $(PROP_SRC_DIRS))))
-
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
- $(PROP_SRC_FILES), ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+ SRC_DIRS := $(PROP_SRC_DIRS), \
+ EXCLUDE := %cursors.properties, \
+ CLASS := ListResourceBundle, \
+))
GENSRC_JAVA_DESKTOP += $(COMPILE_PROPERTIES)
--- a/jdk/make/gensrc/Gensrc-java.logging.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/Gensrc-java.logging.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -29,10 +29,10 @@
include GensrcProperties.gmk
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
- $(filter %.properties, \
- $(call CacheFind, $(JDK_TOPDIR)/src/java.logging/share/classes/sun/util/logging/resources)), \
- ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/java.logging/share/classes/sun/util/logging/resources, \
+ CLASS := ListResourceBundle, \
+))
TARGETS += $(COMPILE_PROPERTIES)
--- a/jdk/make/gensrc/Gensrc-java.management.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/Gensrc-java.management.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -32,10 +32,10 @@
include GensrcProperties.gmk
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
- $(filter %.properties, \
- $(call CacheFind, $(JDK_TOPDIR)/src/java.management/share/classes/sun/management/resources)), \
- ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/java.management/share/classes/sun/management/resources, \
+ CLASS := ListResourceBundle, \
+))
TARGETS += $(COMPILE_PROPERTIES)
--- a/jdk/make/gensrc/Gensrc-jdk.dev.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/Gensrc-jdk.dev.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -29,11 +29,10 @@
include GensrcProperties.gmk
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
- $(filter %.properties, \
- $(call CacheFind, \
- $(JDK_TOPDIR)/src/jdk.dev/share/classes/jdk/tools/jimage/resources)), \
- ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/jdk.dev/share/classes/jdk/tools/jimage/resources, \
+ CLASS := ListResourceBundle, \
+))
TARGETS += $(COMPILE_PROPERTIES)
--- a/jdk/make/gensrc/Gensrc-jdk.jartool.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/Gensrc-jdk.jartool.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -29,11 +29,10 @@
include GensrcProperties.gmk
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
- $(filter %.properties, \
- $(call CacheFind, \
- $(JDK_TOPDIR)/src/jdk.jartool/share/classes/sun/tools/jar/resources)), \
- ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/jdk.jartool/share/classes/sun/tools/jar/resources, \
+ CLASS := ListResourceBundle, \
+))
TARGETS += $(COMPILE_PROPERTIES)
--- a/jdk/make/gensrc/Gensrc-jdk.jdi.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/Gensrc-jdk.jdi.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
JAVA_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/com/sun/tools/jdi/JDWP.java
# Both the header and java file are created using the same recipe. By declaring
-# this rule and adding header file to dependencies for java file, both are
+# this rule and adding header file to dependencies for java file, both are
# rebuilt if either is missing
$(HEADER_FILE): $(JDWP_SPEC_FILE) $(BUILD_TOOLS_JDK)
@@ -90,10 +90,10 @@
include GensrcProperties.gmk
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
- $(filter %.properties, \
- $(call CacheFind, $(JDK_TOPDIR)/src/jdk.jdi/share/classes/com/sun/tools/jdi/resources)), \
- ListResourceBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/jdk.jdi/share/classes/com/sun/tools/jdi/resources, \
+ CLASS := ListResourceBundle, \
+))
GENSRC_JDK_JDI += $(COMPILE_PROPERTIES)
--- a/jdk/make/gensrc/Gensrc-jdk.localedata.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/Gensrc-jdk.localedata.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -35,10 +35,10 @@
include GensrcProperties.gmk
-$(eval $(call SetupCompileProperties,COMPILE_PROPERTIES, \
- $(filter %.properties, \
- $(call CacheFind, $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/resources)), \
- sun.util.resources.LocaleNamesBundle))
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/jdk.localedata/share/classes/sun/util/resources, \
+ CLASS := sun.util.resources.LocaleNamesBundle, \
+))
# Skip generating zh_HK from zh_TW for this module.
GENSRC_JDK_LOCALEDATA += $(filter-out %_zh_HK.java, $(COMPILE_PROPERTIES))
--- a/jdk/make/gensrc/GensrcProperties.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/gensrc/GensrcProperties.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -49,30 +49,40 @@
endef
################################################################################
-# Creates a rule that runs CompileProperties on a set of properties files.
-# Param 1 - Variable to add targets to, must not contain space
-# Param 2 - Properties files to process
-# Param 3 - The super class for the generated classes
-# Param 4 - Module path root, defaults to $(JDK_TOPDIR)/src
-define SetupCompileProperties
- $1_SRCS := $2
- $1_CLASS := $3
- $1_MODULE_PATH_ROOT := $4
-
+# Setup make rules that runs CompileProperties on a set of properties files.
+#
+# Parameter 1 is the name of the rule. This name is used as variable prefix,
+# and the targets generated are listed in a variable by that name.
+#
+# Remaining parameters are named arguments. These include:
+# SRC_DIRS Directories containing properties files to process.
+# EXCLUDE Exclude files matching this pattern.
+# CLASS The super class for the generated classes.
+# MODULE_PATH_ROOT Module path root, defaults to $(JDK_TOPDIR)/src.
+SetupCompileProperties = $(NamedParamsMacroTemplate)
+define SetupCompilePropertiesBody
+ # Set default value unless overridden
ifeq ($$($1_MODULE_PATH_ROOT), )
$1_MODULE_PATH_ROOT := $(JDK_TOPDIR)/src
endif
+ # Locate all properties files in the given source dirs.
+ $1_SRC_FILES := $$(filter %.properties, $$(call CacheFind, $$($1_SRC_DIRS)))
+
+ ifneq ($$($1_EXCLUDE), )
+ $1_SRC_FILES := $$(filter-out $$($1_EXCLUDE), $$($1_SRC_FILES))
+ endif
+
# Convert .../src/<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties
# to .../support/gensrc/<module>/com/sun/tools/javac/resources/javac_zh_CN.java
- # Strip away prefix and suffix, leaving for example only:
+ # Strip away prefix and suffix, leaving for example only:
# "<module>/share/classes/com/sun/tools/javac/resources/javac_zh_CN"
$1_JAVAS := $$(patsubst $$($1_MODULE_PATH_ROOT)/%, \
$(SUPPORT_OUTPUTDIR)/gensrc/%, \
$$(patsubst %.properties, %.java, \
$$(subst /$(OPENJDK_TARGET_OS)/classes,, \
$$(subst /$(OPENJDK_TARGET_OS_TYPE)/classes,, \
- $$(subst /share/classes,, $$($1_SRCS))))))
+ $$(subst /share/classes,, $$($1_SRC_FILES))))))
# Generate the package dirs for the to be generated java files. Sort to remove
# duplicates.
@@ -82,22 +92,22 @@
# "-compile ...javac_zh_CN.properties ...javac_zh_CN.java java.util.ListResourceBundle"
# suitable to be fed into the CompileProperties command.
$1_CMDLINE := $$(subst _SPACE_, $(SPACE), \
- $$(join $$(addprefix -compile_SPACE_, $$($1_SRCS)), \
+ $$(join $$(addprefix -compile_SPACE_, $$($1_SRC_FILES)), \
$$(addsuffix _SPACE_$$($1_CLASS), \
$$(addprefix _SPACE_, $$($1_JAVAS)))))
- $1_TARGET := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the.$1.done
+ $1_TARGET := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the.$1.marker
$1_CMDLINE_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/$(MODULE)/_the.$1.cmdline
# Now setup the rule for the generation of the resource bundles.
- $$($1_TARGET): $$($1_SRCS) $$($1_JAVAS) $(BUILD_TOOLS_JDK)
+ $$($1_TARGET): $$($1_SRC_FILES) $$($1_JAVAS) $(BUILD_TOOLS_JDK)
$(MKDIR) -p $$(@D) $$($1_DIRS)
- $(ECHO) Compiling $$(words $$($1_SRCS)) properties into resource bundles for $(MODULE)
+ $(ECHO) Compiling $$(words $$($1_SRC_FILES)) properties into resource bundles for $(MODULE)
$$(eval $$(call ListPathsSafely, $1_CMDLINE, $$($1_CMDLINE_FILE)))
$(TOOL_COMPILEPROPERTIES) -quiet @$$($1_CMDLINE_FILE)
$(TOUCH) $$@
- $$($1_JAVAS): $$($1_SRCS)
+ $$($1_JAVAS): $$($1_SRC_FILES)
# Create zh_HK versions of all zh_TW files created above
$$(eval $$(call SetupCopy-zh_HK,$1_HK,$$(filter %_zh_TW.java, $$($1_JAVAS))))
--- a/jdk/make/launcher/LauncherCommon.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/launcher/LauncherCommon.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -122,8 +122,23 @@
endif
$1_CFLAGS += -DPACKAGE_PATH='"$(PACKAGE_PATH)"'
- $1_LDFLAGS += -Wl,-all_load $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a \
+ $1_LDFLAGS += -Wl,-all_load \
-sectcreate __TEXT __info_plist $(MACOSX_PLIST_DIR)/$$($1_PLIST_FILE)
+ ifeq ($(STATIC_BUILD), true)
+ $1_LDFLAGS += -exported_symbols_list \
+ $(SUPPORT_OUTPUTDIR)/build-static/exported.symbols
+ $1_LIBS += \
+ $(shell $(FIND) $(SUPPORT_OUTPUTDIR)/modules_libs/java.base -name "*.a") \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/libdt_socket.a \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/libjdwp.a \
+ $(SUPPORT_OUTPUTDIR)/native/java.base/$(LIBRARY_PREFIX)fdlibm$(STATIC_LIBRARY_SUFFIX) \
+ -framework CoreFoundation \
+ -framework Foundation \
+ -framework SystemConfiguration \
+ -lstdc++ -liconv
+ else
+ $1_LIBS += $(SUPPORT_OUTPUTDIR)/native/java.base/libjli_static.a
+ endif
$1_LIBS += -framework Cocoa -framework Security \
-framework ApplicationServices
endif
--- a/jdk/make/lib/Awt2dLibraries.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/lib/Awt2dLibraries.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -476,7 +476,7 @@
ifeq ($(USE_EXTERNAL_LIBJPEG), true)
LIBJPEG_LIBS := -ljpeg
BUILD_LIBJAVAJPEG_INCLUDE_FILES := \
- imageIOJPEG.c \
+ imageioJPEG.c \
jpegdecoder.c
BUILD_LIBJAVAJPEG_HEADERS :=
else
--- a/jdk/make/lib/CoreLibraries.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/lib/CoreLibraries.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -435,10 +435,14 @@
OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static, \
DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
- $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static.a: $(BUILD_LIBJLI_STATIC)
+ ifeq ($(STATIC_BUILD), true)
+ TARGETS += $(BUILD_LIBJLI_STATIC)
+ else
+ $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static.a: $(BUILD_LIBJLI_STATIC)
$(call install-file)
- TARGETS += $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static.a
+ TARGETS += $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjli_static.a
+ endif
else ifeq ($(OPENJDK_TARGET_OS), aix)
# AIX also requires a static libjli because the compiler doesn't support '-rpath'
--- a/jdk/make/lib/Lib-java.base.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/lib/Lib-java.base.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,3 +33,29 @@
include NetworkingLibraries.gmk
include NioLibraries.gmk
include SecurityLibraries.gmk
+
+ifeq ($(STATIC_BUILD), true)
+ JAVA_BASE_EXPORT_SYMBOLS_SRC := \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/jli/$(LIBRARY_PREFIX)jli.symbols \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)java.symbols \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)net.symbols \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)nio.symbols \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)verify.symbols \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)zip.symbols \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/$(LIBRARY_PREFIX)jimage.symbols \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/server/$(LIBRARY_PREFIX)jvm.symbols \
+ #
+
+ JAVA_BASE_EXPORT_SYMBOL_FILE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base/java.base.symbols
+
+ $(JAVA_BASE_EXPORT_SYMBOL_FILE): $(JAVA_BASE_EXPORT_SYMBOLS_SRC)
+ $(ECHO) $(LOG_INFO) "Generating java.base.symbols file"
+ $(CAT) $^ > $@
+
+ # The individual symbol files is generated when the respective lib is built
+ $(JAVA_BASE_EXPORT_SYMBOLS_SRC): $(BUILD_LIBJLI) $(BUILD_LIBJAVA) \
+ $(BUILD_LIBNET) $(BUILD_LIBNIO) $(BUILD_LIBVERIFY) $(BUILD_LIBZIP) \
+ $(BUILD_LIBJIMAGE)
+
+ TARGETS += $(JAVA_BASE_EXPORT_SYMBOL_FILE)
+endif
--- a/jdk/make/lib/Lib-jdk.jdwp.agent.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/lib/Lib-jdk.jdwp.agent.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -102,3 +102,23 @@
TARGETS += $(BUILD_LIBJDWP)
################################################################################
+
+ifeq ($(STATIC_BUILD), true)
+ JDK_JDWP_AGENT_EXPORT_SYMBOLS_SRC := \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/$(LIBRARY_PREFIX)dt_socket.symbols \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/$(LIBRARY_PREFIX)jdwp.symbols
+
+ JDK_JDWP_AGENT_EXPORT_SYMBOL_FILE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.jdwp.agent/jdk.jdwp.agent.symbols
+
+ $(JDK_JDWP_AGENT_EXPORT_SYMBOL_FILE): $(JDK_JDWP_AGENT_EXPORT_SYMBOLS_SRC)
+ $(ECHO) $(LOG_INFO) "Generating jdk.jdwp.agent symbols file"
+ $(CAT) $^ > $@
+
+ # The individual symbol files is generated when the respective lib is built
+ $(JDK_JDWP_AGENT_EXPORT_SYMBOLS_SRC): $(BUILD_LIBDT_SOCKET) $(BUILD_LIBJDWP)
+
+ TARGETS += $(JDK_JDWP_AGENT_EXPORT_SYMBOL_FILE)
+
+endif
+
+################################################################################
--- a/jdk/make/lib/SecurityLibraries.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/lib/SecurityLibraries.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -26,38 +26,41 @@
include LibCommon.gmk
ifeq ($(OPENJDK_TARGET_OS), macosx)
+ # JavaNativeFoundation framework not supported in static builds
+ ifneq ($(STATIC_BUILD), true)
################################################################################
- LIBOSXSECURITY_DIRS := $(JDK_TOPDIR)/src/java.base/macosx/native/libosxsecurity
- LIBOSXSECURITY_CFLAGS := -I$(LIBOSXSECURITY_DIRS) \
- $(LIBJAVA_HEADER_FLAGS) \
- -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
+ LIBOSXSECURITY_DIRS := $(JDK_TOPDIR)/src/java.base/macosx/native/libosxsecurity
+ LIBOSXSECURITY_CFLAGS := -I$(LIBOSXSECURITY_DIRS) \
+ $(LIBJAVA_HEADER_FLAGS) \
+ -I$(SUPPORT_OUTPUTDIR)/headers/java.base \
- $(eval $(call SetupNativeCompilation,BUILD_LIBOSXSECURITY, \
- LIBRARY := osxsecurity, \
- OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(LIBOSXSECURITY_DIRS), \
- OPTIMIZATION := LOW, \
- CFLAGS := $(CFLAGS_JDKLIB) \
- $(LIBOSXSECURITY_CFLAGS), \
- DISABLED_WARNINGS_clang := deprecated-declarations, \
- LDFLAGS := $(LDFLAGS_JDKLIB) \
- -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base \
- $(call SET_SHARED_LIBRARY_ORIGIN) \
- -fobjc-link-runtime, \
- LIBS := \
- -framework JavaNativeFoundation \
- -framework CoreServices \
- -framework Security \
- $(JDKLIB_LIBS), \
- OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxsecurity, \
- DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
+ $(eval $(call SetupNativeCompilation,BUILD_LIBOSXSECURITY, \
+ LIBRARY := osxsecurity, \
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ SRC := $(LIBOSXSECURITY_DIRS), \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) \
+ $(LIBOSXSECURITY_CFLAGS), \
+ DISABLED_WARNINGS_clang := deprecated-declarations, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ -L$(SUPPORT_OUTPUTDIR)/modules_libs/java.base \
+ $(call SET_SHARED_LIBRARY_ORIGIN) \
+ -fobjc-link-runtime, \
+ LIBS := \
+ -framework JavaNativeFoundation \
+ -framework CoreServices \
+ -framework Security \
+ $(JDKLIB_LIBS), \
+ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libosxsecurity, \
+ DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
- $(BUILD_LIBOSXSECURITY): $(BUILD_LIBJAVA)
+ $(BUILD_LIBOSXSECURITY): $(BUILD_LIBJAVA)
- TARGETS += $(BUILD_LIBOSXSECURITY)
+ TARGETS += $(BUILD_LIBOSXSECURITY)
################################################################################
+ endif
endif
--- a/jdk/make/mapfiles/libjava/mapfile-vers Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/mapfiles/libjava/mapfile-vers Wed Jul 05 21:00:20 2017 +0200
@@ -211,6 +211,7 @@
Java_java_lang_SecurityManager_getClassContext;
Java_java_lang_Shutdown_halt0;
Java_java_lang_String_intern;
+ Java_java_lang_StringUTF16_isBigEndian;
Java_java_lang_System_identityHashCode;
Java_java_lang_System_initProperties;
Java_java_lang_System_mapLibraryName;
--- a/jdk/make/mapfiles/libjava/reorder-sparc Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/mapfiles/libjava/reorder-sparc Wed Jul 05 21:00:20 2017 +0200
@@ -57,6 +57,7 @@
text: .text%JNU_ClassString;
text: .text%JNU_CopyObjectArray;
text: .text%Java_java_lang_String_intern;
+text: .text%Java_java_lang_StringUTF16_isBigEndian;
text: .text%Java_java_lang_ClassLoader_findLoadedClass0;
text: .text%Java_java_lang_ClassLoader_findBootstrapClass;
text: .text%Java_java_lang_Throwable_fillInStackTrace;
--- a/jdk/make/mapfiles/libjava/reorder-sparcv9 Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/mapfiles/libjava/reorder-sparcv9 Wed Jul 05 21:00:20 2017 +0200
@@ -29,6 +29,7 @@
text: .text%Java_sun_reflect_Reflection_getCallerClass__I;
text: .text%Java_java_lang_Class_forName0;
text: .text%Java_java_lang_String_intern;
+text: .text%Java_java_lang_StringUTF16_isBigEndian;
text: .text%Java_java_lang_Float_floatToRawIntBits;
text: .text%Java_java_lang_Double_doubleToRawLongBits;
text: .text%Java_java_lang_ClassLoader_findLoadedClass0;
--- a/jdk/make/mapfiles/libjava/reorder-x86 Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/mapfiles/libjava/reorder-x86 Wed Jul 05 21:00:20 2017 +0200
@@ -31,6 +31,7 @@
text: .text%Java_sun_reflect_Reflection_getCallerClass__I;
text: .text%Java_java_lang_Class_forName0;
text: .text%Java_java_lang_String_intern;
+text: .text%Java_java_lang_StringUTF16_isBigEndian;
text: .text%Java_sun_reflect_NativeConstructorAccessorImpl_newInstance0;
text: .text%Java_java_lang_Throwable_fillInStackTrace;
text: .text%Java_java_lang_System_setOut0;
--- a/jdk/make/mapfiles/libnio/mapfile-macosx Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/mapfiles/libnio/mapfile-macosx Wed Jul 05 21:00:20 2017 +0200
@@ -75,6 +75,7 @@
Java_sun_nio_ch_IOUtil_makePipe;
Java_sun_nio_ch_IOUtil_randomBytes;
Java_sun_nio_ch_IOUtil_setfdVal;
+ Java_sun_nio_ch_IOUtil_iovMax;
Java_sun_nio_ch_KQueue_kqueue;
Java_sun_nio_ch_KQueue_keventRegister;
Java_sun_nio_ch_KQueue_keventPoll;
--- a/jdk/make/src/classes/build/tools/charsetmapping/DBCS.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/src/classes/build/tools/charsetmapping/DBCS.java Wed Jul 05 21:00:20 2017 +0200
@@ -197,6 +197,7 @@
.replace("$B1MAX$" , "0x" + Integer.toString(b1Max, 16))
.replace("$B2MIN$" , "0x" + Integer.toString(b2Min, 16))
.replace("$B2MAX$" , "0x" + Integer.toString(b2Max, 16))
+ .replace("$ASCIICOMPATIBLE$", isASCII ? "true" : "false")
.replace("$B2C$", b2c)
.replace("$C2BLENGTH$", "0x" + Integer.toString(c2bOff, 16))
.replace("$NONROUNDTRIP_B2C$", b2cNR)
--- a/jdk/make/src/classes/build/tools/charsetmapping/SBCS.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/src/classes/build/tools/charsetmapping/SBCS.java Wed Jul 05 21:00:20 2017 +0200
@@ -175,6 +175,9 @@
else
line = " return (cs instanceof " + clzName + ");";
}
+ if (line.indexOf("$ASCIICOMPATIBLE$") != -1) {
+ line = line.replace("$ASCIICOMPATIBLE$", isASCII ? "true" : "false");
+ }
if (line.indexOf("$B2CTABLE$") != -1) {
line = line.replace("$B2CTABLE$", b2c);
}
--- a/jdk/make/src/classes/build/tools/x11wrappergen/WrapperGenerator.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/make/src/classes/build/tools/x11wrappergen/WrapperGenerator.java Wed Jul 05 21:00:20 2017 +0200
@@ -841,7 +841,7 @@
pw.println("// This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead !\n" );
pw.println("package "+package_name+";\n");
- pw.println("import sun.misc.*;\n");
+ pw.println("import jdk.internal.misc.Unsafe;\n");
pw.println("import sun.util.logging.PlatformLogger;");
String baseClass = stp.getBaseClass();
if (baseClass == null) {
@@ -941,7 +941,7 @@
pw.println("// This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead !\n" );
pw.println("package "+package_name+";\n");
- pw.println("import sun.misc.Unsafe;\n");
+ pw.println("import jdk.internal.misc.Unsafe;\n");
pw.println("class " + ft.getName() + " {");
pw.println("\tprivate static Unsafe unsafe = XlibWrapper.unsafe;");
pw.println("\tprivate boolean __executed = false;");
--- a/jdk/src/demo/share/jvmti/agent_util/agent_util.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/agent_util/agent_util.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -65,6 +65,51 @@
void *allocate(jvmtiEnv *jvmti, jint len);
void add_demo_jar_to_bootclasspath(jvmtiEnv *jvmti, char *demo_name);
+#ifdef STATIC_BUILD
+/* Macros for handling declaration of static/dynamic
+ * Agent library Load/Attach/Unload functions
+ *
+ * DEF_Agent_OnLoad, DEF_Agent_OnAttach or DEF_Agent_OnUnload
+ * generate the appropriate entrypoint names based on static
+ * versus dynamic builds.
+ *
+ * STATIC_BUILD must be defined to build static versions of these libraries.
+ * LIBRARY_NAME must be set to the name of the library for static builds.
+ */
+#define ADD_LIB_NAME3(name, lib) name ## lib
+#define ADD_LIB_NAME2(name, lib) ADD_LIB_NAME3(name, lib)
+#define ADD_LIB_NAME(entry) ADD_LIB_NAME2(entry, LIBRARY_NAME)
+
+#define DEF_Agent_OnLoad \
+ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) \
+{ \
+ jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)(JavaVM *vm, char *options, void *reserved); \
+ return ADD_LIB_NAME(Agent_OnLoad_dynamic_)(vm, options, reserved); \
+} \
+jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)
+
+#define DEF_Agent_OnAttach \
+ADD_LIB_NAME(Agent_OnAttach_)(JavaVM *vm, char *options, void *reserved) \
+{ \
+ jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)(JavaVM *vm, char *options, void *reserved); \
+ return ADD_LIB_NAME(Agent_OnAttach_dynamic_)(vm, options, reserved); \
+} \
+jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)
+
+#define DEF_Agent_OnUnload \
+ADD_LIB_NAME(Agent_OnUnload_)(JavaVM *vm) \
+{ \
+ void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)(JavaVM *vm); \
+ ADD_LIB_NAME(Agent_OnUnload_dynamic_)(vm); \
+} \
+void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)
+
+#else
+#define DEF_Agent_OnLoad Agent_OnLoad
+#define DEF_Agent_OnAttach Agent_OnAttach
+#define DEF_Agent_OnUnload Agent_OnUnload
+#endif
+
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
--- a/jdk/src/demo/share/jvmti/compiledMethodLoad/compiledMethodLoad.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/compiledMethodLoad/compiledMethodLoad.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -225,7 +225,7 @@
* event here.
*/
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
jint rc;
jvmtiError err;
@@ -272,6 +272,6 @@
/* Agent_OnUnload() is called last */
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
{
}
--- a/jdk/src/demo/share/jvmti/gctest/gctest.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/gctest/gctest.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -148,7 +148,7 @@
/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
jint rc;
jvmtiError err;
@@ -193,6 +193,6 @@
/* Agent_OnUnload() is called last */
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
{
}
--- a/jdk/src/demo/share/jvmti/heapTracker/heapTracker.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/heapTracker/heapTracker.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -894,7 +894,7 @@
* loaded. This is the first code executed.
*/
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
static GlobalAgentData data;
jvmtiEnv *jvmti;
@@ -1010,7 +1010,7 @@
* unloaded. This is the last code executed.
*/
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
{
/* Skip any cleanup, VM is about to die anyway */
}
--- a/jdk/src/demo/share/jvmti/heapTracker/heapTracker.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/heapTracker/heapTracker.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -64,9 +64,4 @@
#include "agent_util.h"
-/* Agent library externals to export. */
-
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm);
-
#endif
--- a/jdk/src/demo/share/jvmti/heapViewer/heapViewer.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/heapViewer/heapViewer.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -235,7 +235,7 @@
/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
jint rc;
jvmtiError err;
@@ -283,6 +283,6 @@
/* Agent_OnUnload() is called last */
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
{
}
--- a/jdk/src/demo/share/jvmti/minst/minst.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/minst/minst.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -373,7 +373,7 @@
* loaded. This is the first code executed.
*/
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
static GlobalAgentData data;
jvmtiEnv *jvmti;
@@ -467,7 +467,7 @@
* unloaded. This is the last code executed.
*/
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
{
/* Make sure all malloc/calloc/strdup space is freed */
if ( gdata->include != NULL ) {
--- a/jdk/src/demo/share/jvmti/minst/minst.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/minst/minst.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -64,9 +64,4 @@
#include "agent_util.h"
-/* Agent library externals to export. */
-
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm);
-
#endif
--- a/jdk/src/demo/share/jvmti/mtrace/mtrace.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/mtrace/mtrace.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -697,7 +697,7 @@
* loaded. This is the first code executed.
*/
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
static GlobalAgentData data;
jvmtiEnv *jvmti;
@@ -795,7 +795,7 @@
* unloaded. This is the last code executed.
*/
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
{
/* Make sure all malloc/calloc/strdup space is freed */
if ( gdata->include != NULL ) {
--- a/jdk/src/demo/share/jvmti/mtrace/mtrace.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/mtrace/mtrace.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -64,9 +64,4 @@
#include "agent_util.h"
-/* Agent library externals to export. */
-
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *vm);
-
#endif
--- a/jdk/src/demo/share/jvmti/versionCheck/versionCheck.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/versionCheck/versionCheck.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -89,7 +89,7 @@
/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
jint rc;
jvmtiError err;
@@ -116,6 +116,6 @@
/* Agent_OnUnload() is called last */
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
{
}
--- a/jdk/src/demo/share/jvmti/waiters/Monitor.hpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/waiters/Monitor.hpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,6 +37,10 @@
* this sample code.
*/
+#ifdef STATIC_BUILD
+#define Monitor WaiterMonitor
+#endif
+
/* C++ Monitor class */
--- a/jdk/src/demo/share/jvmti/waiters/Thread.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/waiters/Thread.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,6 +37,9 @@
* this sample code.
*/
+#ifdef STATIC_BUILD
+#define Thread WaiterThread
+#endif
#include <stdio.h>
#include <stdlib.h>
--- a/jdk/src/demo/share/jvmti/waiters/waiters.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/demo/share/jvmti/waiters/waiters.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -243,7 +243,7 @@
/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
JNIEXPORT jint JNICALL
- Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+ DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
jvmtiEnv *jvmti;
jint rc;
@@ -288,7 +288,7 @@
/* Agent_OnUnload() is called last */
JNIEXPORT void JNICALL
- Agent_OnUnload(JavaVM *vm)
+ DEF_Agent_OnUnload(JavaVM *vm)
{
}
--- a/jdk/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/aix/classes/sun/nio/ch/AixPollPort.java Wed Jul 05 21:00:20 2017 +0200
@@ -34,7 +34,7 @@
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* AsynchronousChannelGroup implementation based on the AIX pollset framework.
--- a/jdk/src/java.base/linux/classes/sun/nio/ch/EPoll.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/linux/classes/sun/nio/ch/EPoll.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,7 +26,7 @@
package sun.nio.ch;
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Provides access to the Linux epoll facility.
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,7 +29,7 @@
import java.util.Map;
import java.util.Set;
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixNativeDispatcher.*;
import static sun.nio.fs.UnixConstants.*;
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,7 +29,7 @@
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixConstants.*;
import static sun.nio.fs.LinuxNativeDispatcher.*;
--- a/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/linux/classes/sun/nio/fs/LinuxWatchService.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,7 +30,7 @@
import java.security.PrivilegedAction;
import java.util.*;
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixNativeDispatcher.*;
import static sun.nio.fs.UnixConstants.*;
--- a/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/macosx/classes/sun/nio/ch/KQueue.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,7 +26,7 @@
package sun.nio.ch;
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Provides access to the BSD kqueue facility.
--- a/jdk/src/java.base/macosx/native/libjava/java_props_macosx.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/macosx/native/libjava/java_props_macosx.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,13 +35,15 @@
#include "java_props_macosx.h"
-
// need dlopen/dlsym trick to avoid pulling in JavaRuntimeSupport before libjava.dylib is loaded
static void *getJRSFramework() {
static void *jrsFwk = NULL;
+#ifndef STATIC_BUILD
+// JavaRuntimeSupport doesn't support static Java runtimes
if (jrsFwk == NULL) {
jrsFwk = dlopen("/System/Library/Frameworks/JavaVM.framework/Frameworks/JavaRuntimeSupport.framework/JavaRuntimeSupport", RTLD_LAZY | RTLD_LOCAL);
}
+#endif
return jrsFwk;
}
--- a/jdk/src/java.base/macosx/native/libjli/java_md_macosx.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/macosx/native/libjli/java_md_macosx.c Wed Jul 05 21:00:20 2017 +0200
@@ -245,6 +245,8 @@
return sExportedJNIFunctions = fxns;
}
+#ifndef STATIC_BUILD
+
JNIEXPORT jint JNICALL
JNI_GetDefaultJavaVMInitArgs(void *args) {
InvocationFunctions *ifn = GetExportedJNIFunctions();
@@ -265,6 +267,7 @@
if (ifn == NULL) return JNI_ERR;
return ifn->GetCreatedJavaVMs(vmBuf, bufLen, nVMs);
}
+#endif
/*
* Allow JLI-aware launchers to specify a client/server preference
@@ -303,7 +306,12 @@
objc_registerThreadWithCollector();
if (main_fptr == NULL) {
+#ifdef STATIC_BUILD
+ extern int main(int argc, char **argv);
+ main_fptr = &main;
+#else
main_fptr = (int (*)())dlsym(RTLD_DEFAULT, "main");
+#endif
if (main_fptr == NULL) {
JLI_ReportErrorMessageSys("error locating main entrypoint\n");
exit(1);
@@ -588,6 +596,9 @@
JLI_TraceLauncher("Does `%s' exist ... ", jvmpath);
+#ifdef STATIC_BUILD
+ return JNI_TRUE;
+#else
if (stat(jvmpath, &s) == 0) {
JLI_TraceLauncher("yes.\n");
return JNI_TRUE;
@@ -595,6 +606,7 @@
JLI_TraceLauncher("no.\n");
return JNI_FALSE;
}
+#endif
}
/*
@@ -607,10 +619,18 @@
if (GetApplicationHome(path, pathsize)) {
/* Is JRE co-located with the application? */
+#ifdef STATIC_BUILD
+ char jvm_cfg[MAXPATHLEN];
+ JLI_Snprintf(jvm_cfg, sizeof(jvm_cfg), "%s/lib/jvm.cfg", path);
+ if (access(jvm_cfg, F_OK) == 0) {
+ return JNI_TRUE;
+ }
+#else
JLI_Snprintf(libjava, sizeof(libjava), "%s/lib/" JAVA_DLL, path);
if (access(libjava, F_OK) == 0) {
return JNI_TRUE;
}
+#endif
/* ensure storage for path + /jre + NULL */
if ((JLI_StrLen(path) + 4 + 1) > (size_t) pathsize) {
JLI_TraceLauncher("Insufficient space to store JRE path\n");
@@ -629,6 +649,24 @@
Dl_info selfInfo;
dladdr(&GetJREPath, &selfInfo);
+#ifdef STATIC_BUILD
+ char jvm_cfg[MAXPATHLEN];
+ char *p = NULL;
+ strncpy(jvm_cfg, selfInfo.dli_fname, MAXPATHLEN);
+ p = strrchr(jvm_cfg, '/'); *p = '\0';
+ p = strrchr(jvm_cfg, '/');
+ if (strcmp(p, "/.") == 0) {
+ *p = '\0';
+ p = strrchr(jvm_cfg, '/'); *p = '\0';
+ }
+ else *p = '\0';
+ strncpy(path, jvm_cfg, pathsize);
+ strncat(jvm_cfg, "/lib/jvm.cfg", MAXPATHLEN);
+ if (access(jvm_cfg, F_OK) == 0) {
+ return JNI_TRUE;
+ }
+#endif
+
char *realPathToSelf = realpath(selfInfo.dli_fname, path);
if (realPathToSelf != path) {
return JNI_FALSE;
@@ -664,7 +702,11 @@
JLI_TraceLauncher("JVM path is %s\n", jvmpath);
+#ifndef STATIC_BUILD
libjvm = dlopen(jvmpath, RTLD_NOW + RTLD_GLOBAL);
+#else
+ libjvm = dlopen(NULL, RTLD_FIRST);
+#endif
if (libjvm == NULL) {
JLI_ReportErrorMessage(DLL_ERROR1, __LINE__);
JLI_ReportErrorMessage(DLL_ERROR2, jvmpath, dlerror());
@@ -714,9 +756,14 @@
char* exec_path = NULL;
{
Dl_info dlinfo;
+
+#ifdef STATIC_BUILD
+ void *fptr;
+ fptr = (void *)&SetExecname;
+#else
int (*fptr)();
-
fptr = (int (*)())dlsym(RTLD_DEFAULT, "main");
+#endif
if (fptr == NULL) {
JLI_ReportErrorMessage(DLL_ERROR3, dlerror());
return JNI_FALSE;
--- a/jdk/src/java.base/share/classes/java/io/File.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/io/File.java Wed Jul 05 21:00:20 2017 +0200
@@ -2184,10 +2184,10 @@
private static final long PATH_OFFSET;
private static final long PREFIX_LENGTH_OFFSET;
- private static final sun.misc.Unsafe UNSAFE;
+ private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
- sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
PATH_OFFSET = unsafe.objectFieldOffset(
File.class.getDeclaredField("path"));
PREFIX_LENGTH_OFFSET = unsafe.objectFieldOffset(
--- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java Wed Jul 05 21:00:20 2017 +0200
@@ -40,7 +40,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static java.io.ObjectStreamClass.processQueue;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.reflect.misc.ReflectUtil;
/**
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Wed Jul 05 21:00:20 2017 +0200
@@ -48,7 +48,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.ReflectionFactory;
--- a/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/AbstractStringBuilder.java Wed Jul 05 21:00:20 2017 +0200
@@ -31,6 +31,12 @@
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.String.UTF16;
+import static java.lang.String.LATIN1;
+import static java.lang.String.checkIndex;
+import static java.lang.String.checkOffset;
+
/**
* A mutable sequence of characters.
* <p>
@@ -51,7 +57,12 @@
/**
* The value is used for character storage.
*/
- char[] value;
+ byte[] value;
+
+ /**
+ * The id of the encoding used to encode the bytes in {@code value}.
+ */
+ byte coder;
/**
* The count is the number of characters used.
@@ -68,7 +79,13 @@
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
- value = new char[capacity];
+ if (COMPACT_STRINGS) {
+ value = new byte[capacity];
+ coder = LATIN1;
+ } else {
+ value = StringUTF16.newBytesFor(capacity);
+ coder = UTF16;
+ }
}
/**
@@ -90,7 +107,7 @@
* @return the current capacity
*/
public int capacity() {
- return value.length;
+ return value.length >> coder;
}
/**
@@ -110,8 +127,9 @@
* @param minimumCapacity the minimum desired capacity.
*/
public void ensureCapacity(int minimumCapacity) {
- if (minimumCapacity > 0)
+ if (minimumCapacity > 0) {
ensureCapacityInternal(minimumCapacity);
+ }
}
/**
@@ -120,24 +138,48 @@
*/
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
- if (minimumCapacity - value.length > 0)
+ int capacity = value.length >> coder;
+ if (minimumCapacity - capacity > 0) {
expandCapacity(minimumCapacity);
+ }
}
/**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
*/
- void expandCapacity(int minimumCapacity) {
- int newCapacity = value.length * 2 + 2;
- if (newCapacity - minimumCapacity < 0)
+ private void expandCapacity(int minimumCapacity) {
+ int newCapacity = (value.length >> coder) * 2 + 2;
+ if (newCapacity - minimumCapacity < 0) {
newCapacity = minimumCapacity;
+ }
if (newCapacity < 0) {
- if (minimumCapacity < 0) // overflow
+ if (minimumCapacity < 0) {// overflow
throw new OutOfMemoryError();
+ }
newCapacity = Integer.MAX_VALUE;
}
- value = Arrays.copyOf(value, newCapacity);
+ if (coder != LATIN1 && newCapacity > StringUTF16.MAX_LENGTH) {
+ if (minimumCapacity >= StringUTF16.MAX_LENGTH) {
+ throw new OutOfMemoryError();
+ }
+ newCapacity = StringUTF16.MAX_LENGTH;
+ }
+ this.value = Arrays.copyOf(value, newCapacity << coder);
+ }
+
+ /**
+ * If the coder is "isLatin1", this inflates the internal 8-bit storage
+ * to 16-bit <hi=0, low> pair storage.
+ */
+ private void inflate() {
+ if (!isLatin1()) {
+ return;
+ }
+ byte[] buf = StringUTF16.newBytesFor(value.length);
+ StringLatin1.inflateSB(value, buf, 0, count);
+ this.value = buf;
+ this.coder = UTF16;
}
/**
@@ -148,8 +190,9 @@
* returned by a subsequent call to the {@link #capacity()} method.
*/
public void trimToSize() {
- if (count < value.length) {
- value = Arrays.copyOf(value, count);
+ int length = count << coder;
+ if (length < value.length) {
+ value = Arrays.copyOf(value, length);
}
}
@@ -179,14 +222,17 @@
* {@code newLength} argument is negative.
*/
public void setLength(int newLength) {
- if (newLength < 0)
+ if (newLength < 0) {
throw new StringIndexOutOfBoundsException(newLength);
+ }
ensureCapacityInternal(newLength);
-
if (count < newLength) {
- Arrays.fill(value, count, newLength, '\0');
+ if (isLatin1()) {
+ StringLatin1.fillNull(value, count, newLength);
+ } else {
+ StringUTF16.fillNull(value, count, newLength);
+ }
}
-
count = newLength;
}
@@ -209,9 +255,11 @@
*/
@Override
public char charAt(int index) {
- if ((index < 0) || (index >= count))
- throw new StringIndexOutOfBoundsException(index);
- return value[index];
+ checkIndex(index, count);
+ if (isLatin1()) {
+ return (char)(value[index] & 0xff);
+ }
+ return StringUTF16.charAt(value, index);
}
/**
@@ -236,10 +284,11 @@
* sequence.
*/
public int codePointAt(int index) {
- if ((index < 0) || (index >= count)) {
- throw new StringIndexOutOfBoundsException(index);
+ checkIndex(index, count);
+ if (isLatin1()) {
+ return value[index] & 0xff;
}
- return Character.codePointAtImpl(value, index, count);
+ return StringUTF16.codePointAtSB(value, index, count);
}
/**
@@ -265,10 +314,13 @@
*/
public int codePointBefore(int index) {
int i = index - 1;
- if ((i < 0) || (i >= count)) {
+ if (i < 0 || i >= count) {
throw new StringIndexOutOfBoundsException(index);
}
- return Character.codePointBeforeImpl(value, index, 0);
+ if (isLatin1()) {
+ return value[i] & 0xff;
+ }
+ return StringUTF16.codePointBeforeSB(value, index);
}
/**
@@ -295,7 +347,10 @@
if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
throw new IndexOutOfBoundsException();
}
- return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
+ if (isLatin1()) {
+ return endIndex - beginIndex;
+ }
+ return StringUTF16.codePointCountSB(value, beginIndex, endIndex);
}
/**
@@ -321,8 +376,8 @@
if (index < 0 || index > count) {
throw new IndexOutOfBoundsException();
}
- return Character.offsetByCodePointsImpl(value, 0, count,
- index, codePointOffset);
+ return Character.offsetByCodePoints(this,
+ index, codePointOffset);
}
/**
@@ -355,13 +410,14 @@
*/
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
{
- if (srcBegin < 0)
- throw new StringIndexOutOfBoundsException(srcBegin);
- if ((srcEnd < 0) || (srcEnd > count))
- throw new StringIndexOutOfBoundsException(srcEnd);
- if (srcBegin > srcEnd)
- throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
- System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+ checkRangeSIOOBE(srcBegin, srcEnd, count); // compatible to old version
+ int n = srcEnd - srcBegin;
+ checkRange(dstBegin, dstBegin + n, dst.length);
+ if (isLatin1()) {
+ StringLatin1.getCharsSB(value, srcBegin, srcEnd, dst, dstBegin);
+ } else {
+ StringUTF16.getCharsSB(value, srcBegin, srcEnd, dst, dstBegin);
+ }
}
/**
@@ -379,9 +435,15 @@
* negative or greater than or equal to {@code length()}.
*/
public void setCharAt(int index, char ch) {
- if ((index < 0) || (index >= count))
- throw new StringIndexOutOfBoundsException(index);
- value[index] = ch;
+ checkIndex(index, count);
+ if (isLatin1() && StringLatin1.canEncode(ch)) {
+ value[index] = (byte)ch;
+ } else {
+ if (isLatin1()) {
+ inflate();
+ }
+ StringUTF16.putCharSB(value, index, ch);
+ }
}
/**
@@ -418,35 +480,34 @@
* @return a reference to this object.
*/
public AbstractStringBuilder append(String str) {
- if (str == null)
+ if (str == null) {
return appendNull();
+ }
int len = str.length();
ensureCapacityInternal(count + len);
- str.getChars(0, len, value, count);
+ putStringAt(count, str);
count += len;
return this;
}
// Documentation in subclasses because of synchro difference
public AbstractStringBuilder append(StringBuffer sb) {
- if (sb == null)
- return appendNull();
- int len = sb.length();
- ensureCapacityInternal(count + len);
- sb.getChars(0, len, value, count);
- count += len;
- return this;
+ return this.append((AbstractStringBuilder)sb);
}
/**
* @since 1.8
*/
AbstractStringBuilder append(AbstractStringBuilder asb) {
- if (asb == null)
+ if (asb == null) {
return appendNull();
+ }
int len = asb.length();
ensureCapacityInternal(count + len);
- asb.getChars(0, len, value, count);
+ if (getCoder() != asb.getCoder()) {
+ inflate();
+ }
+ asb.getBytes(value, count, coder);
count += len;
return this;
}
@@ -454,25 +515,35 @@
// Documentation in subclasses because of synchro difference
@Override
public AbstractStringBuilder append(CharSequence s) {
- if (s == null)
+ if (s == null) {
return appendNull();
- if (s instanceof String)
+ }
+ if (s instanceof String) {
return this.append((String)s);
- if (s instanceof AbstractStringBuilder)
+ }
+ if (s instanceof AbstractStringBuilder) {
return this.append((AbstractStringBuilder)s);
-
+ }
return this.append(s, 0, s.length());
}
private AbstractStringBuilder appendNull() {
- int c = count;
- ensureCapacityInternal(c + 4);
- final char[] value = this.value;
- value[c++] = 'n';
- value[c++] = 'u';
- value[c++] = 'l';
- value[c++] = 'l';
- count = c;
+ ensureCapacityInternal(count + 4);
+ int count = this.count;
+ byte[] val = this.value;
+ if (isLatin1()) {
+ val[count++] = 'n';
+ val[count++] = 'u';
+ val[count++] = 'l';
+ val[count++] = 'l';
+ } else {
+ checkOffset(count + 4, val.length >> 1);
+ StringUTF16.putChar(val, count++, 'n');
+ StringUTF16.putChar(val, count++, 'u');
+ StringUTF16.putChar(val, count++, 'l');
+ StringUTF16.putChar(val, count++, 'l');
+ }
+ this.count = count;
return this;
}
@@ -507,21 +578,13 @@
*/
@Override
public AbstractStringBuilder append(CharSequence s, int start, int end) {
- if (s == null)
+ if (s == null) {
s = "null";
- if ((start < 0) || (start > end) || (end > s.length()))
- throw new IndexOutOfBoundsException(
- "start " + start + ", end " + end + ", s.length() "
- + s.length());
+ }
+ checkRange(start, end, s.length());
int len = end - start;
ensureCapacityInternal(count + len);
- if (s instanceof String) {
- ((String)s).getChars(start, end, value, count);
- } else {
- for (int i = start, j = count; i < end; i++, j++)
- value[j] = s.charAt(i);
- }
- count += len;
+ appendChars(s, start, end);
return this;
}
@@ -544,8 +607,7 @@
public AbstractStringBuilder append(char[] str) {
int len = str.length;
ensureCapacityInternal(count + len);
- System.arraycopy(str, 0, value, count, len);
- count += len;
+ appendChars(str, 0, len);
return this;
}
@@ -572,10 +634,10 @@
* or {@code offset+len > str.length}
*/
public AbstractStringBuilder append(char str[], int offset, int len) {
- if (len > 0) // let arraycopy report AIOOBE for len < 0
- ensureCapacityInternal(count + len);
- System.arraycopy(str, offset, value, count, len);
- count += len;
+ int end = offset + len;
+ checkRange(offset, end, str.length);
+ ensureCapacityInternal(count + len);
+ appendChars(str, offset, end);
return this;
}
@@ -592,20 +654,39 @@
* @return a reference to this object.
*/
public AbstractStringBuilder append(boolean b) {
- if (b) {
- ensureCapacityInternal(count + 4);
- value[count++] = 't';
- value[count++] = 'r';
- value[count++] = 'u';
- value[count++] = 'e';
+ ensureCapacityInternal(count + (b ? 4 : 5));
+ int count = this.count;
+ byte[] val = this.value;
+ if (isLatin1()) {
+ if (b) {
+ val[count++] = 't';
+ val[count++] = 'r';
+ val[count++] = 'u';
+ val[count++] = 'e';
+ } else {
+ val[count++] = 'f';
+ val[count++] = 'a';
+ val[count++] = 'l';
+ val[count++] = 's';
+ val[count++] = 'e';
+ }
} else {
- ensureCapacityInternal(count + 5);
- value[count++] = 'f';
- value[count++] = 'a';
- value[count++] = 'l';
- value[count++] = 's';
- value[count++] = 'e';
+ if (b) {
+ checkOffset(count + 4, val.length >> 1);
+ StringUTF16.putChar(val, count++, 't');
+ StringUTF16.putChar(val, count++, 'r');
+ StringUTF16.putChar(val, count++, 'u');
+ StringUTF16.putChar(val, count++, 'e');
+ } else {
+ checkOffset(count + 5, val.length >> 1);
+ StringUTF16.putChar(val, count++, 'f');
+ StringUTF16.putChar(val, count++, 'a');
+ StringUTF16.putChar(val, count++, 'l');
+ StringUTF16.putChar(val, count++, 's');
+ StringUTF16.putChar(val, count++, 'e');
+ }
}
+ this.count = count;
return this;
}
@@ -627,7 +708,14 @@
@Override
public AbstractStringBuilder append(char c) {
ensureCapacityInternal(count + 1);
- value[count++] = c;
+ if (isLatin1() && StringLatin1.canEncode(c)) {
+ value[count++] = (byte)c;
+ } else {
+ if (isLatin1()) {
+ inflate();
+ }
+ StringUTF16.putCharSB(value, count++, c);
+ }
return this;
}
@@ -652,7 +740,13 @@
: Integer.stringSize(i);
int spaceNeeded = count + appendedLength;
ensureCapacityInternal(spaceNeeded);
- Integer.getChars(i, spaceNeeded, value);
+ if (isLatin1()) {
+ Integer.getChars(i, spaceNeeded, value);
+ } else {
+ byte[] val = this.value;
+ checkOffset(spaceNeeded, val.length >> 1);
+ Integer.getCharsUTF16(i, spaceNeeded, val);
+ }
count = spaceNeeded;
return this;
}
@@ -678,7 +772,13 @@
: Long.stringSize(l);
int spaceNeeded = count + appendedLength;
ensureCapacityInternal(spaceNeeded);
- Long.getChars(l, spaceNeeded, value);
+ if (isLatin1()) {
+ Long.getChars(l, spaceNeeded, value);
+ } else {
+ byte[] val = this.value;
+ checkOffset(spaceNeeded, val.length >> 1);
+ Long.getCharsUTF16(l, spaceNeeded, val);
+ }
count = spaceNeeded;
return this;
}
@@ -732,15 +832,13 @@
* greater than {@code end}.
*/
public AbstractStringBuilder delete(int start, int end) {
- if (start < 0)
- throw new StringIndexOutOfBoundsException(start);
- if (end > count)
+ if (end > count) {
end = count;
- if (start > end)
- throw new StringIndexOutOfBoundsException();
+ }
+ checkRangeSIOOBE(start, end, count);
int len = end - start;
if (len > 0) {
- System.arraycopy(value, start+len, value, start, count-end);
+ shift(end, -len);
count -= len;
}
return this;
@@ -766,20 +864,10 @@
* {@code codePoint} isn't a valid Unicode code point
*/
public AbstractStringBuilder appendCodePoint(int codePoint) {
- final int count = this.count;
-
if (Character.isBmpCodePoint(codePoint)) {
- ensureCapacityInternal(count + 1);
- value[count] = (char) codePoint;
- this.count = count + 1;
- } else if (Character.isValidCodePoint(codePoint)) {
- ensureCapacityInternal(count + 2);
- Character.toSurrogates(codePoint, value, count);
- this.count = count + 2;
- } else {
- throw new IllegalArgumentException();
+ return append((char)codePoint);
}
- return this;
+ return append(Character.toChars(codePoint));
}
/**
@@ -800,9 +888,8 @@
* {@code length()}.
*/
public AbstractStringBuilder deleteCharAt(int index) {
- if ((index < 0) || (index >= count))
- throw new StringIndexOutOfBoundsException(index);
- System.arraycopy(value, index+1, value, index, count-index-1);
+ checkIndex(index, count);
+ shift(index + 1, -1);
count--;
return this;
}
@@ -827,22 +914,16 @@
* greater than {@code end}.
*/
public AbstractStringBuilder replace(int start, int end, String str) {
- if (start < 0)
- throw new StringIndexOutOfBoundsException(start);
- if (start > count)
- throw new StringIndexOutOfBoundsException("start > length()");
- if (start > end)
- throw new StringIndexOutOfBoundsException("start > end");
-
- if (end > count)
+ if (end > count) {
end = count;
+ }
+ checkRangeSIOOBE(start, end, count);
int len = str.length();
int newCount = count + len - (end - start);
ensureCapacityInternal(newCount);
-
- System.arraycopy(value, end, value, start + len, count - end);
- str.getChars(value, start);
+ shift(end, newCount - count);
count = newCount;
+ putStringAt(start, str);
return this;
}
@@ -907,13 +988,16 @@
* greater than {@code end}.
*/
public String substring(int start, int end) {
- if (start < 0)
- throw new StringIndexOutOfBoundsException(start);
- if (end > count)
- throw new StringIndexOutOfBoundsException(end);
- if (start > end)
- throw new StringIndexOutOfBoundsException(end - start);
- return new String(value, start, end - start);
+ checkRangeSIOOBE(start, end, count);
+ if (isLatin1()) {
+ return StringLatin1.newString(value, start, end - start);
+ }
+ return StringUTF16.newStringSB(value, start, end - start);
+ }
+
+ private void shift(int offset, int n) {
+ System.arraycopy(value, offset << coder,
+ value, (offset + n) << coder, (count - offset) << coder);
}
/**
@@ -940,16 +1024,12 @@
public AbstractStringBuilder insert(int index, char[] str, int offset,
int len)
{
- if ((index < 0) || (index > length()))
- throw new StringIndexOutOfBoundsException(index);
- if ((offset < 0) || (len < 0) || (offset > str.length - len))
- throw new StringIndexOutOfBoundsException(
- "offset " + offset + ", len " + len + ", str.length "
- + str.length);
+ checkOffset(index, count);
+ checkRangeSIOOBE(offset, offset + len, str.length);
ensureCapacityInternal(count + len);
- System.arraycopy(value, index, value, index + len, count - index);
- System.arraycopy(str, offset, value, index, len);
+ shift(index, len);
count += len;
+ putCharsAt(index, str, offset, offset + len);
return this;
}
@@ -1008,15 +1088,15 @@
* @throws StringIndexOutOfBoundsException if the offset is invalid.
*/
public AbstractStringBuilder insert(int offset, String str) {
- if ((offset < 0) || (offset > length()))
- throw new StringIndexOutOfBoundsException(offset);
- if (str == null)
+ checkOffset(offset, count);
+ if (str == null) {
str = "null";
+ }
int len = str.length();
ensureCapacityInternal(count + len);
- System.arraycopy(value, offset, value, offset + len, count - offset);
- str.getChars(value, offset);
+ shift(offset, len);
count += len;
+ putStringAt(offset, str);
return this;
}
@@ -1045,13 +1125,12 @@
* @throws StringIndexOutOfBoundsException if the offset is invalid.
*/
public AbstractStringBuilder insert(int offset, char[] str) {
- if ((offset < 0) || (offset > length()))
- throw new StringIndexOutOfBoundsException(offset);
+ checkOffset(offset, count);
int len = str.length;
ensureCapacityInternal(count + len);
- System.arraycopy(value, offset, value, offset + len, count - offset);
- System.arraycopy(str, 0, value, offset, len);
+ shift(offset, len);
count += len;
+ putCharsAt(offset, str, 0, len);
return this;
}
@@ -1077,10 +1156,12 @@
* @throws IndexOutOfBoundsException if the offset is invalid.
*/
public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
- if (s == null)
+ if (s == null) {
s = "null";
- if (s instanceof String)
+ }
+ if (s instanceof String) {
return this.insert(dstOffset, (String)s);
+ }
return this.insert(dstOffset, s, 0, s.length());
}
@@ -1128,23 +1209,19 @@
* {@code start} is greater than {@code end} or
* {@code end} is greater than {@code s.length()}
*/
- public AbstractStringBuilder insert(int dstOffset, CharSequence s,
- int start, int end) {
- if (s == null)
+ public AbstractStringBuilder insert(int dstOffset, CharSequence s,
+ int start, int end)
+ {
+ if (s == null) {
s = "null";
- if ((dstOffset < 0) || (dstOffset > this.length()))
- throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
- if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
- throw new IndexOutOfBoundsException(
- "start " + start + ", end " + end + ", s.length() "
- + s.length());
+ }
+ checkOffset(dstOffset, count);
+ checkRange(start, end, s.length());
int len = end - start;
ensureCapacityInternal(count + len);
- System.arraycopy(value, dstOffset, value, dstOffset + len,
- count - dstOffset);
- for (int i=start; i<end; i++)
- value[dstOffset++] = s.charAt(i);
+ shift(dstOffset, len);
count += len;
+ putCharsAt(dstOffset, s, start, end);
return this;
}
@@ -1191,10 +1268,18 @@
* @throws IndexOutOfBoundsException if the offset is invalid.
*/
public AbstractStringBuilder insert(int offset, char c) {
+ checkOffset(offset, count);
ensureCapacityInternal(count + 1);
- System.arraycopy(value, offset, value, offset + 1, count - offset);
- value[offset] = c;
+ shift(offset, 1);
count += 1;
+ if (isLatin1() && StringLatin1.canEncode(c)) {
+ value[offset] = (byte)c;
+ } else {
+ if (isLatin1()) {
+ inflate();
+ }
+ StringUTF16.putCharSB(value, offset, c);
+ }
return this;
}
@@ -1326,7 +1411,7 @@
* or {@code -1} if there is no such occurrence.
*/
public int indexOf(String str, int fromIndex) {
- return String.indexOf(value, 0, count, str, fromIndex);
+ return String.indexOf(value, coder, count, str, fromIndex);
}
/**
@@ -1366,7 +1451,7 @@
* or {@code -1} if there is no such occurrence.
*/
public int lastIndexOf(String str, int fromIndex) {
- return String.lastIndexOf(value, 0, count, str, fromIndex);
+ return String.lastIndexOf(value, coder, count, str, fromIndex);
}
/**
@@ -1392,34 +1477,47 @@
* @return a reference to this object.
*/
public AbstractStringBuilder reverse() {
- boolean hasSurrogates = false;
+ byte[] val = this.value;
+ int count = this.count;
+ int coder = this.coder;
int n = count - 1;
- for (int j = (n-1) >> 1; j >= 0; j--) {
- int k = n - j;
- char cj = value[j];
- char ck = value[k];
- value[j] = ck;
- value[k] = cj;
- if (Character.isSurrogate(cj) ||
- Character.isSurrogate(ck)) {
- hasSurrogates = true;
+ if (COMPACT_STRINGS && coder == LATIN1) {
+ for (int j = (n-1) >> 1; j >= 0; j--) {
+ int k = n - j;
+ byte cj = val[j];
+ val[j] = val[k];
+ val[k] = cj;
}
- }
- if (hasSurrogates) {
- reverseAllValidSurrogatePairs();
+ } else {
+ checkOffset(count, val.length >> 1);
+ boolean hasSurrogates = false;
+ for (int j = (n-1) >> 1; j >= 0; j--) {
+ int k = n - j;
+ char cj = StringUTF16.getChar(val, j);
+ char ck = StringUTF16.getChar(val, k);
+ StringUTF16.putChar(val, j, ck);
+ StringUTF16.putChar(val, k, cj);
+ if (Character.isSurrogate(cj) ||
+ Character.isSurrogate(ck)) {
+ hasSurrogates = true;
+ }
+ }
+ if (hasSurrogates) {
+ reverseAllValidSurrogatePairs(val, count);
+ }
}
return this;
}
/** Outlined helper method for reverse() */
- private void reverseAllValidSurrogatePairs() {
+ private void reverseAllValidSurrogatePairs(byte[] val, int count) {
for (int i = 0; i < count - 1; i++) {
- char c2 = value[i];
+ char c2 = StringUTF16.getChar(val, i);
if (Character.isLowSurrogate(c2)) {
- char c1 = value[i + 1];
+ char c1 = StringUTF16.getChar(val, i + 1);
if (Character.isHighSurrogate(c1)) {
- value[i++] = c1;
- value[i] = c2;
+ StringUTF16.putChar(val, i++, c1);
+ StringUTF16.putChar(val, i, c2);
}
}
}
@@ -1444,10 +1542,13 @@
*/
@Override
public IntStream chars() {
+ byte[] val = this.value; int count = this.count; byte coder = this.coder;
+ checkOffset(count, val.length >> coder);
// Reuse String-based spliterator. This requires a supplier to
// capture the value and count when the terminal operation is executed
return StreamSupport.intStream(
- () -> new String.IntCharArraySpliterator(value, 0, count, 0),
+ () -> coder == LATIN1 ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
+ : new StringUTF16.CharsSpliterator(val, 0, count, 0),
Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED,
false);
}
@@ -1458,10 +1559,13 @@
*/
@Override
public IntStream codePoints() {
+ byte[] val = this.value; int count = this.count; byte coder = this.coder;
+ checkOffset(count, val.length >> coder);
// Reuse String-based spliterator. This requires a supplier to
// capture the value and count when the terminal operation is executed
return StreamSupport.intStream(
- () -> new String.CodePointsSpliterator(value, 0, count, 0),
+ () -> coder == LATIN1 ? new StringLatin1.CharsSpliterator(val, 0, count, 0)
+ : new StringUTF16.CodePointsSpliterator(val, 0, count, 0),
Spliterator.ORDERED,
false);
}
@@ -1469,8 +1573,147 @@
/**
* Needed by {@code String} for the contentEquals method.
*/
- final char[] getValue() {
+ final byte[] getValue() {
return value;
}
+ /*
+ * Invoker guarantees it is in UTF16 (inflate itself for asb), if two
+ * coders are different and the dstBegin has enough space
+ *
+ * @param dstBegin the char index, not offset of byte[]
+ * @param coder the coder of dst[]
+ */
+ protected void getBytes(byte dst[], int dstBegin, byte coder) {
+ if (this.coder == coder) {
+ System.arraycopy(value, 0, dst, dstBegin << coder, count << coder);
+ } else { // this.coder == LATIN && coder == UTF16
+ StringLatin1.inflateSB(value, dst, dstBegin, count);
+ }
+ }
+
+ /* for readObject() */
+ protected void initBytes(char[] value, int off, int len) {
+ if (String.COMPACT_STRINGS) {
+ this.value = StringUTF16.compress(value, off, len);
+ if (this.value != null) {
+ this.coder = LATIN1;
+ return;
+ }
+ }
+ this.coder = UTF16;
+ this.value = StringUTF16.toBytes(value, off, len);
+ }
+
+ final byte getCoder() {
+ return COMPACT_STRINGS ? coder : UTF16;
+ }
+
+ final boolean isLatin1() {
+ return COMPACT_STRINGS && coder == LATIN1;
+ }
+
+ private final void putCharsAt(int index, char[] s, int off, int end) {
+ if (isLatin1()) {
+ byte[] val = this.value;
+ for (int i = off, j = index; i < end; i++) {
+ char c = s[i];
+ if (StringLatin1.canEncode(c)) {
+ val[j++] = (byte)c;
+ } else {
+ inflate();
+ StringUTF16.putCharsSB(this.value, j, s, i, end);
+ return;
+ }
+ }
+ } else {
+ StringUTF16.putCharsSB(this.value, index, s, off, end);
+ }
+ }
+
+ private final void putCharsAt(int index, CharSequence s, int off, int end) {
+ if (isLatin1()) {
+ byte[] val = this.value;
+ for (int i = off, j = index; i < end; i++) {
+ char c = s.charAt(i);
+ if (StringLatin1.canEncode(c)) {
+ val[j++] = (byte)c;
+ } else {
+ inflate();
+ StringUTF16.putCharsSB(this.value, j, s, i, end);
+ return;
+ }
+ }
+ } else {
+ StringUTF16.putCharsSB(this.value, index, s, off, end);
+ }
+ }
+
+ private final void putStringAt(int index, String str) {
+ if (getCoder() != str.coder()) {
+ inflate();
+ }
+ byte[] val = this.value;
+ byte coder = this.coder;
+ checkOffset(index + str.length(), val.length >> coder);
+ str.getBytes(val, index, coder);
+ }
+
+ private final void appendChars(char[] s, int off, int end) {
+ if (isLatin1()) {
+ byte[] val = this.value;
+ for (int i = off, j = count; i < end; i++) {
+ char c = s[i];
+ if (StringLatin1.canEncode(c)) {
+ val[j++] = (byte)c;
+ } else {
+ count = j;
+ inflate();
+ StringUTF16.putCharsSB(this.value, j, s, i, end);
+ count += end - i;
+ return;
+ }
+ }
+ } else {
+ StringUTF16.putCharsSB(this.value, count, s, off, end);
+ }
+ count += end - off;
+ }
+
+ private final void appendChars(CharSequence s, int off, int end) {
+ if (isLatin1()) {
+ byte[] val = this.value;
+ for (int i = off, j = count; i < end; i++) {
+ char c = s.charAt(i);
+ if (StringLatin1.canEncode(c)) {
+ val[j++] = (byte)c;
+ } else {
+ count = j;
+ inflate();
+ StringUTF16.putCharsSB(this.value, j, s, i, end);
+ count += end - i;
+ return;
+ }
+ }
+ } else {
+ StringUTF16.putCharsSB(this.value, count, s, off, end);
+ }
+ count += end - off;
+ }
+
+ /* IndexOutOfBoundsException, if out of bounds */
+ private static void checkRange(int start, int end, int len) {
+ if (start < 0 || start > end || end > len) {
+ throw new IndexOutOfBoundsException(
+ "start " + start + ", end " + end + ", length " + len);
+ }
+ }
+
+ /* StringIndexOutOfBoundsException, if out of bounds */
+ private static void checkRangeSIOOBE(int start, int end, int len) {
+ if (start < 0 || start > end || end > len) {
+ throw new StringIndexOutOfBoundsException(
+ "start " + start + ", end " + end + ", length " + len);
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 05 21:00:20 2017 +0200
@@ -55,7 +55,7 @@
import java.util.HashMap;
import java.util.Objects;
import java.util.StringJoiner;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import jdk.internal.HotSpotIntrinsicCandidate;
import sun.reflect.CallerSensitive;
import sun.reflect.ConstantPool;
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,6 +29,10 @@
import java.util.Objects;
import jdk.internal.HotSpotIntrinsicCandidate;
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+
/**
* The {@code Integer} class wraps a value of the primitive type
* {@code int} in an object. An object of type {@code Integer}
@@ -138,25 +142,47 @@
return toString(i);
}
- char buf[] = new char[33];
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[33];
+ boolean negative = (i < 0);
+ int charPos = 32;
+
+ if (!negative) {
+ i = -i;
+ }
+
+ while (i <= -radix) {
+ buf[charPos--] = (byte)digits[-(i % radix)];
+ i = i / radix;
+ }
+ buf[charPos] = (byte)digits[-i];
+
+ if (negative) {
+ buf[--charPos] = '-';
+ }
+
+ return StringLatin1.newString(buf, charPos, (33 - charPos));
+ }
+ return toStringUTF16(i, radix);
+ }
+
+ private static String toStringUTF16(int i, int radix) {
+ byte[] buf = new byte[33 * 2];
boolean negative = (i < 0);
int charPos = 32;
-
if (!negative) {
i = -i;
}
-
while (i <= -radix) {
- buf[charPos--] = digits[-(i % radix)];
+ StringUTF16.putChar(buf, charPos--, digits[-(i % radix)]);
i = i / radix;
}
- buf[charPos] = digits[-i];
+ StringUTF16.putChar(buf, charPos, digits[-i]);
if (negative) {
- buf[--charPos] = '-';
+ StringUTF16.putChar(buf, --charPos, '-');
}
-
- return new String(buf, charPos, (33 - charPos));
+ return StringUTF16.newString(buf, charPos, (33 - charPos));
}
/**
@@ -312,12 +338,16 @@
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
- char[] buf = new char[chars];
- formatUnsignedInt(val, shift, buf, 0, chars);
-
- // Use special constructor which takes over "buf".
- return new String(buf, true);
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[chars];
+ formatUnsignedInt(val, shift, buf, 0, chars);
+ return new String(buf, LATIN1);
+ } else {
+ byte[] buf = new byte[chars * 2];
+ formatUnsignedIntUTF16(val, shift, buf, 0, chars);
+ return new String(buf, UTF16);
+ }
}
/**
@@ -331,7 +361,7 @@
* @param offset the offset in the destination buffer to start at
* @param len the number of characters to write
*/
- static void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
+ static void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
// assert offset >= 0 && offset < buf.length : "illegal offset";
// assert len > 0 && (offset + len) <= buf.length : "illegal length";
@@ -344,6 +374,28 @@
} while (charPos > offset);
}
+ /** byte[]/LATIN1 version */
+ static void formatUnsignedInt(int val, int shift, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ buf[--charPos] = (byte)Integer.digits[val & mask];
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
+ /** byte[]/UTF16 version */
+ static void formatUnsignedIntUTF16(int val, int shift, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ StringUTF16.putChar(buf, --charPos, Integer.digits[val & mask]);
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
static final char [] DigitTens = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
@@ -401,9 +453,15 @@
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
- char[] buf = new char[size];
- getChars(i, size, buf);
- return new String(buf, true);
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[size];
+ getChars(i, size, buf);
+ return new String(buf, LATIN1);
+ } else {
+ byte[] buf = new byte[size * 2];
+ getCharsUTF16(i, size, buf);
+ return new String(buf, UTF16);
+ }
}
/**
@@ -433,7 +491,7 @@
*
* Will fail if i == Integer.MIN_VALUE
*/
- static void getChars(int i, int index, char[] buf) {
+ static void getChars(int i, int index, byte[] buf) {
int q, r;
int charPos = index;
char sign = 0;
@@ -449,8 +507,8 @@
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
- buf [--charPos] = DigitOnes[r];
- buf [--charPos] = DigitTens[r];
+ buf [--charPos] = (byte)DigitOnes[r];
+ buf [--charPos] = (byte)DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
@@ -458,12 +516,46 @@
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
- buf [--charPos] = digits [r];
+ buf [--charPos] = (byte)digits [r];
i = q;
if (i == 0) break;
}
if (sign != 0) {
- buf [--charPos] = sign;
+ buf [--charPos] = (byte)sign;
+ }
+ }
+
+ static void getCharsUTF16(int i, int index, byte[] buf) {
+ int q, r;
+ int charPos = index;
+ char sign = 0;
+
+ if (i < 0) {
+ sign = '-';
+ i = -i;
+ }
+
+ // Generate two digits per iteration
+ while (i >= 65536) {
+ q = i / 100;
+ // really: r = i - (q * 100);
+ r = i - ((q << 6) + (q << 5) + (q << 2));
+ i = q;
+ StringUTF16.putChar(buf, --charPos, DigitOnes[r]);
+ StringUTF16.putChar(buf, --charPos, DigitTens[r]);
+ }
+
+ // Fall thru to fast mode for smaller numbers
+ // assert(i <= 65536, i);
+ for (;;) {
+ q = (i * 52429) >>> (16+3);
+ r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
+ StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
+ i = q;
+ if (i == 0) break;
+ }
+ if (sign != 0) {
+ StringUTF16.putChar(buf, --charPos, sign);
}
}
--- a/jdk/src/java.base/share/classes/java/lang/Long.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,6 +30,9 @@
import java.util.Objects;
import jdk.internal.HotSpotIntrinsicCandidate;
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
/**
* The {@code Long} class wraps a value of the primitive type {@code
@@ -124,25 +127,46 @@
radix = 10;
if (radix == 10)
return toString(i);
- char[] buf = new char[65];
+
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[65];
+ int charPos = 64;
+ boolean negative = (i < 0);
+
+ if (!negative) {
+ i = -i;
+ }
+
+ while (i <= -radix) {
+ buf[charPos--] = (byte)Integer.digits[(int)(-(i % radix))];
+ i = i / radix;
+ }
+ buf[charPos] = (byte)Integer.digits[(int)(-i)];
+
+ if (negative) {
+ buf[--charPos] = '-';
+ }
+ return StringLatin1.newString(buf, charPos, (65 - charPos));
+ }
+ return toStringUTF16(i, radix);
+ }
+
+ private static String toStringUTF16(long i, int radix) {
+ byte[] buf = new byte[65 * 2];
int charPos = 64;
boolean negative = (i < 0);
-
if (!negative) {
i = -i;
}
-
while (i <= -radix) {
- buf[charPos--] = Integer.digits[(int)(-(i % radix))];
+ StringUTF16.putChar(buf, charPos--, Integer.digits[(int)(-(i % radix))]);
i = i / radix;
}
- buf[charPos] = Integer.digits[(int)(-i)];
-
+ StringUTF16.putChar(buf, charPos, Integer.digits[(int)(-i)]);
if (negative) {
- buf[--charPos] = '-';
+ StringUTF16.putChar(buf, --charPos, '-');
}
-
- return new String(buf, charPos, (65 - charPos));
+ return StringUTF16.newString(buf, charPos, (65 - charPos));
}
/**
@@ -355,10 +379,16 @@
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Long.SIZE - Long.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
- char[] buf = new char[chars];
- formatUnsignedLong(val, shift, buf, 0, chars);
- return new String(buf, true);
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[chars];
+ formatUnsignedLong0(val, shift, buf, 0, chars);
+ return new String(buf, LATIN1);
+ } else {
+ byte[] buf = new byte[chars * 2];
+ formatUnsignedLong0UTF16(val, shift, buf, 0, chars);
+ return new String(buf, UTF16);
+ }
}
/**
@@ -385,6 +415,28 @@
} while (charPos > offset);
}
+ /** byte[]/LATIN1 version */
+ static void formatUnsignedLong0(long val, int shift, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ buf[--charPos] = (byte)Integer.digits[((int) val) & mask];
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
+ /** byte[]/UTF16 version */
+ static void formatUnsignedLong0UTF16(long val, int shift, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ StringUTF16.putChar(buf, --charPos, Integer.digits[((int) val) & mask]);
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
/**
* Returns a {@code String} object representing the specified
* {@code long}. The argument is converted to signed decimal
@@ -399,9 +451,15 @@
if (i == Long.MIN_VALUE)
return "-9223372036854775808";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
- char[] buf = new char[size];
- getChars(i, size, buf);
- return new String(buf, true);
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[size];
+ getChars(i, size, buf);
+ return new String(buf, LATIN1);
+ } else {
+ byte[] buf = new byte[size * 2];
+ getCharsUTF16(i, size, buf);
+ return new String(buf, UTF16);
+ }
}
/**
@@ -431,7 +489,7 @@
*
* Will fail if i == Long.MIN_VALUE
*/
- static void getChars(long i, int index, char[] buf) {
+ static void getChars(long i, int index, byte[] buf) {
long q;
int r;
int charPos = index;
@@ -448,8 +506,8 @@
// really: r = i - (q * 100);
r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
i = q;
- buf[--charPos] = Integer.DigitOnes[r];
- buf[--charPos] = Integer.DigitTens[r];
+ buf[--charPos] = (byte)Integer.DigitOnes[r];
+ buf[--charPos] = (byte)Integer.DigitTens[r];
}
// Get 2 digits/iteration using ints
@@ -460,8 +518,8 @@
// really: r = i2 - (q * 100);
r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
i2 = q2;
- buf[--charPos] = Integer.DigitOnes[r];
- buf[--charPos] = Integer.DigitTens[r];
+ buf[--charPos] = (byte)Integer.DigitOnes[r];
+ buf[--charPos] = (byte)Integer.DigitTens[r];
}
// Fall thru to fast mode for smaller numbers
@@ -469,12 +527,59 @@
for (;;) {
q2 = (i2 * 52429) >>> (16+3);
r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
- buf[--charPos] = Integer.digits[r];
+ buf[--charPos] = (byte)Integer.digits[r];
i2 = q2;
if (i2 == 0) break;
}
if (sign != 0) {
- buf[--charPos] = sign;
+ buf[--charPos] = (byte)sign;
+ }
+ }
+
+ static void getCharsUTF16(long i, int index, byte[] buf) {
+ long q;
+ int r;
+ int charPos = index;
+ char sign = 0;
+
+ if (i < 0) {
+ sign = '-';
+ i = -i;
+ }
+
+ // Get 2 digits/iteration using longs until quotient fits into an int
+ while (i > Integer.MAX_VALUE) {
+ q = i / 100;
+ // really: r = i - (q * 100);
+ r = (int)(i - ((q << 6) + (q << 5) + (q << 2)));
+ i = q;
+ StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
+ StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
+ }
+
+ // Get 2 digits/iteration using ints
+ int q2;
+ int i2 = (int)i;
+ while (i2 >= 65536) {
+ q2 = i2 / 100;
+ // really: r = i2 - (q * 100);
+ r = i2 - ((q2 << 6) + (q2 << 5) + (q2 << 2));
+ i2 = q2;
+ StringUTF16.putChar(buf, --charPos, Integer.DigitOnes[r]);
+ StringUTF16.putChar(buf, --charPos, Integer.DigitTens[r]);
+ }
+
+ // Fall thru to fast mode for smaller numbers
+ // assert(i2 <= 65536, i2);
+ for (;;) {
+ q2 = (i2 * 52429) >>> (16+3);
+ r = i2 - ((q2 << 3) + (q2 << 1)); // r = i2-(q2*10) ...
+ StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
+ i2 = q2;
+ if (i2 == 0) break;
+ }
+ if (sign != 0) {
+ StringUTF16.putChar(buf, --charPos, sign);
}
}
--- a/jdk/src/java.base/share/classes/java/lang/Process.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/Process.java Wed Jul 05 21:00:20 2017 +0200
@@ -83,7 +83,7 @@
* {@link #getPid() process id},
* {@link #info() information about the process},
* {@link #children() direct children}, and
- * {@link #allChildren() direct and indirect children} of the process.
+ * {@link #descendants() direct children plus descendants of those children} of the process.
* Delegating to the underlying Process or ProcessHandle is typically
* easiest and most efficient.
*
@@ -351,7 +351,7 @@
* The {@link java.util.concurrent.CompletableFuture} provides the ability
* to trigger dependent functions or actions that may be run synchronously
* or asynchronously upon process termination.
- * When the process terminates the CompletableFuture is
+ * When the process has terminated the CompletableFuture is
* {@link java.util.concurrent.CompletableFuture#complete completed} regardless
* of the exit status of the process.
* <p>
@@ -362,9 +362,6 @@
* {@link java.util.concurrent.CompletableFuture#cancel(boolean) Cancelling}
* the CompletableFuture does not affect the Process.
* <p>
- * If the process is {@link #isAlive not alive} the {@link CompletableFuture}
- * returned has been {@link java.util.concurrent.CompletableFuture#complete completed}.
- * <p>
* Processes returned from {@link ProcessBuilder#start} override the
* default implementation to provide an efficient mechanism to wait
* for process exit.
@@ -406,6 +403,9 @@
* return delegate.onExit().thenApply(p -> this);
* }
* }</pre>
+ * @apiNote
+ * The process may be observed to have terminated with {@link #isAlive}
+ * before the ComputableFuture is completed and dependent actions are invoked.
*
* @return a new {@code CompletableFuture<Process>} for the Process
*
@@ -464,7 +464,7 @@
* {@link java.lang.UnsupportedOperationException} and performs no other action.
* Subclasses should override this method to provide a ProcessHandle for the
* process. The methods {@link #getPid}, {@link #info}, {@link #children},
- * and {@link #allChildren}, unless overridden, operate on the ProcessHandle.
+ * and {@link #descendants}, unless overridden, operate on the ProcessHandle.
*
* @return Returns a ProcessHandle for the Process
* @throws UnsupportedOperationException if the Process implementation
@@ -481,9 +481,8 @@
/**
* Returns a snapshot of information about the process.
*
- * <p> An {@link ProcessHandle.Info} instance has various accessor methods
- * that return information about the process, if the process is alive and
- * the information is available, otherwise {@code null} is returned.
+ * <p> A {@link ProcessHandle.Info} instance has accessor methods
+ * that return information about the process if it is available.
*
* @implSpec
* This implementation returns information about the process as:
@@ -524,9 +523,9 @@
}
/**
- * Returns a snapshot of the direct and indirect children of the process.
- * An indirect child is one whose parent is either a direct child or
- * another indirect child.
+ * Returns a snapshot of the descendants of the process.
+ * The descendants of a process are the children of the process
+ * plus the descendants of those children, recursively.
* Typically, a process that is {@link #isAlive not alive} has no children.
* <p>
* <em>Note that processes are created and terminate asynchronously.
@@ -535,18 +534,18 @@
*
* @implSpec
* This implementation returns all children as:
- * {@link #toHandle toHandle().allChildren()}.
+ * {@link #toHandle toHandle().descendants()}.
*
- * @return a sequential Stream of ProcessHandles for processes that are
- * direct and indirect children of the process
+ * @return a sequential Stream of ProcessHandles for processes that
+ * are descendants of the process
* @throws UnsupportedOperationException if the Process implementation
* does not support this operation
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
* @since 1.9
*/
- public Stream<ProcessHandle> allChildren() {
- return toHandle().allChildren();
+ public Stream<ProcessHandle> descendants() {
+ return toHandle().descendants();
}
--- a/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandle.java Wed Jul 05 21:00:20 2017 +0200
@@ -54,7 +54,7 @@
* Each ProcessHandle identifies and allows control of a process in the native
* system. ProcessHandles are returned from the factory methods {@link #current()},
* {@link #of(long)},
- * {@link #children}, {@link #allChildren}, {@link #parent()} and
+ * {@link #children}, {@link #descendants}, {@link #parent()} and
* {@link #allProcesses()}.
* <p>
* The {@link Process} instances created by {@link ProcessBuilder} can be queried
@@ -164,21 +164,21 @@
Stream<ProcessHandle> children();
/**
- * Returns a snapshot of the current direct and indirect children of the process.
- * An indirect child is one whose parent is either a direct child or
- * another indirect child.
+ * Returns a snapshot of the descendants of the process.
+ * The descendants of a process are the children of the process
+ * plus the descendants of those children, recursively.
* Typically, a process that is {@link #isAlive not alive} has no children.
* <p>
* <em>Note that processes are created and terminate asynchronously.
* There is no guarantee that a process is {@link #isAlive alive}.
* </em>
*
- * @return a sequential Stream of ProcessHandles for processes that are
- * direct and indirect children of the process
+ * @return a sequential Stream of ProcessHandles for processes that
+ * are descendants of the process
* @throws SecurityException if a security manager has been installed and
* it denies RuntimePermission("manageProcess")
*/
- Stream<ProcessHandle> allChildren();
+ Stream<ProcessHandle> descendants();
/**
* Returns a snapshot of all processes visible to the current process.
@@ -201,9 +201,8 @@
/**
* Returns a snapshot of information about the process.
*
- * <p> An {@code Info} instance has various accessor methods that return
- * information about the process, if the process is alive and the
- * information is available.
+ * <p> A {@link ProcessHandle.Info} instance has accessor methods that return
+ * information about the process if it is available.
*
* @return a snapshot of information about the process, always non-null
*/
@@ -288,7 +287,7 @@
* The {@link java.util.concurrent.CompletableFuture} provides the ability
* to trigger dependent functions or actions that may be run synchronously
* or asynchronously upon process termination.
- * When the process terminates the CompletableFuture is
+ * When the process has terminated the CompletableFuture is
* {@link java.util.concurrent.CompletableFuture#complete completed} regardless
* of the exit status of the process.
* The {@code onExit} method can be called multiple times to invoke
@@ -300,9 +299,9 @@
* {@link java.util.concurrent.Future#get() wait} for it to terminate.
* {@link java.util.concurrent.Future#cancel(boolean) Cancelling}
* the CompleteableFuture does not affect the Process.
- * <p>
- * If the process is {@link #isAlive not alive} the {@link CompletableFuture}
- * returned has been {@link java.util.concurrent.CompletableFuture#complete completed}.
+ * @apiNote
+ * The process may be observed to have terminated with {@link #isAlive}
+ * before the ComputableFuture is completed and dependent actions are invoked.
*
* @return a new {@code CompletableFuture<ProcessHandle>} for the ProcessHandle
*
--- a/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/ProcessHandleImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -389,7 +389,7 @@
}
@Override
- public Stream<ProcessHandle> allChildren() {
+ public Stream<ProcessHandle> descendants() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("manageProcess"));
--- a/jdk/src/java.base/share/classes/java/lang/String.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/String.java Wed Jul 05 21:00:20 2017 +0200
@@ -36,7 +36,6 @@
import java.util.Objects;
import java.util.Spliterator;
import java.util.StringJoiner;
-import java.util.function.IntConsumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -119,8 +118,19 @@
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
+
/** The value is used for character storage. */
- private final char value[];
+ private final byte[] value;
+
+ /**
+ * The identifier of the encoding used to encode the bytes in
+ * {@code value}. The supported values in this implementation are
+ *
+ * LATIN1
+ * UTF16
+ *
+ */
+ private final byte coder;
/** Cache the hash code for the string */
private int hash; // Default to 0
@@ -129,6 +139,49 @@
private static final long serialVersionUID = -6849794470754667710L;
/**
+ * If String compaction is disabled, the bytes in {@code value} are
+ * always encoded in UTF16.
+ *
+ * For methods with several possible implementation paths, when String
+ * compaction is disabled, only one code path is taken.
+ *
+ * The instance field value is generally opaque to optimizing JIT
+ * compilers. Therefore, in performance-sensitive place, an explicit
+ * check of the static boolean {@code COMPACT_STRINGS} is done first
+ * before checking the {@code coder} field since the static boolean
+ * {@code COMPACT_STRINGS} would be constant folded away by an
+ * optimizing JIT compiler. The idioms for these cases are as follows.
+ *
+ * For code such as:
+ *
+ * if (coder == LATIN1) { ... }
+ *
+ * can be written more optimally as
+ *
+ * if (coder() == LATIN1) { ... }
+ *
+ * or:
+ *
+ * if (COMPACT_STRINGS && coder == LATIN1) { ... }
+ *
+ * An optimizing JIT compiler can fold the above conditional as:
+ *
+ * COMPACT_STRINGS == true => if (coder == LATIN1) { ... }
+ * COMPACT_STRINGS == false => if (false) { ... }
+ *
+ * @implNote
+ * The actual value for this field is injected by JVM. The static
+ * initialization block is used to set the value here to communicate
+ * that this static final field is not statically foldable, and to
+ * avoid any possible circular dependency during vm initialization.
+ */
+ static final boolean COMPACT_STRINGS;
+
+ static {
+ COMPACT_STRINGS = true;
+ }
+
+ /**
* Class String is special cased within the Serialization Stream Protocol.
*
* A String instance is written into an ObjectOutputStream according to
@@ -145,6 +198,7 @@
*/
public String() {
this.value = "".value;
+ this.coder = "".coder;
}
/**
@@ -160,6 +214,7 @@
@HotSpotIntrinsicCandidate
public String(String original) {
this.value = original.value;
+ this.coder = original.coder;
this.hash = original.hash;
}
@@ -173,7 +228,7 @@
* The initial value of the string
*/
public String(char value[]) {
- this.value = Arrays.copyOf(value, value.length);
+ this(value, 0, value.length, null);
}
/**
@@ -198,23 +253,12 @@
* {@code offset} is greater than {@code value.length - count}
*/
public String(char value[], int offset, int count) {
- if (offset < 0) {
- throw new StringIndexOutOfBoundsException(offset);
- }
- if (count <= 0) {
- if (count < 0) {
- throw new StringIndexOutOfBoundsException(count);
- }
- if (offset <= value.length) {
- this.value = "".value;
- return;
- }
- }
- // Note: offset or count might be near -1>>>1.
- if (offset > value.length - count) {
- throw new StringIndexOutOfBoundsException(offset + count);
- }
- this.value = Arrays.copyOfRange(value, offset, offset + count);
+ this(value, offset, count, rangeCheck(value, offset, count));
+ }
+
+ private static Void rangeCheck(char[] value, int offset, int count) {
+ checkBoundsOffCount(offset, count, value.length);
+ return null;
}
/**
@@ -246,48 +290,22 @@
* @since 1.5
*/
public String(int[] codePoints, int offset, int count) {
- if (offset < 0) {
- throw new StringIndexOutOfBoundsException(offset);
+ checkBoundsOffCount(offset, count, codePoints.length);
+ if (count == 0) {
+ this.value = "".value;
+ this.coder = "".coder;
+ return;
}
- if (count <= 0) {
- if (count < 0) {
- throw new StringIndexOutOfBoundsException(count);
- }
- if (offset <= codePoints.length) {
- this.value = "".value;
+ if (COMPACT_STRINGS) {
+ byte[] val = StringLatin1.toBytes(codePoints, offset, count);
+ if (val != null) {
+ this.coder = LATIN1;
+ this.value = val;
return;
}
}
- // Note: offset or count might be near -1>>>1.
- if (offset > codePoints.length - count) {
- throw new StringIndexOutOfBoundsException(offset + count);
- }
-
- final int end = offset + count;
-
- // Pass 1: Compute precise size of char[]
- int n = count;
- for (int i = offset; i < end; i++) {
- int c = codePoints[i];
- if (Character.isBmpCodePoint(c))
- continue;
- else if (Character.isValidCodePoint(c))
- n++;
- else throw new IllegalArgumentException(Integer.toString(c));
- }
-
- // Pass 2: Allocate and fill in char[]
- final char[] v = new char[n];
-
- for (int i = offset, j = 0; i < end; i++, j++) {
- int c = codePoints[i];
- if (Character.isBmpCodePoint(c))
- v[j] = (char)c;
- else
- Character.toSurrogates(c, v, j++);
- }
-
- this.value = v;
+ this.coder = UTF16;
+ this.value = StringUTF16.toBytes(codePoints, offset, count);
}
/**
@@ -332,20 +350,24 @@
*/
@Deprecated
public String(byte ascii[], int hibyte, int offset, int count) {
- checkBounds(ascii, offset, count);
- char[] value = new char[count];
-
- if (hibyte == 0) {
- for (int i = count; i-- > 0;) {
- value[i] = (char)(ascii[i + offset] & 0xff);
- }
+ checkBoundsOffCount(offset, count, ascii.length);
+ if (count == 0) {
+ this.value = "".value;
+ this.coder = "".coder;
+ return;
+ }
+ if (COMPACT_STRINGS && (byte)hibyte == 0) {
+ this.value = Arrays.copyOfRange(ascii, offset, offset + count);
+ this.coder = LATIN1;
} else {
hibyte <<= 8;
- for (int i = count; i-- > 0;) {
- value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
+ byte[] val = StringUTF16.newBytesFor(count);
+ for (int i = 0; i < count; i++) {
+ StringUTF16.putChar(val, i, hibyte | (ascii[offset++] & 0xff));
}
+ this.value = val;
+ this.coder = UTF16;
}
- this.value = value;
}
/**
@@ -383,19 +405,6 @@
this(ascii, hibyte, 0, ascii.length);
}
- /* Common private utility method used to bounds check the byte array
- * and requested offset & length values used by the String(byte[],..)
- * constructors.
- */
- private static void checkBounds(byte[] bytes, int offset, int length) {
- if (length < 0)
- throw new StringIndexOutOfBoundsException(length);
- if (offset < 0)
- throw new StringIndexOutOfBoundsException(offset);
- if (offset > bytes.length - length)
- throw new StringIndexOutOfBoundsException(offset + length);
- }
-
/**
* Constructs a new {@code String} by decoding the specified subarray of
* bytes using the specified charset. The length of the new {@code String}
@@ -433,8 +442,11 @@
throws UnsupportedEncodingException {
if (charsetName == null)
throw new NullPointerException("charsetName");
- checkBounds(bytes, offset, length);
- this.value = StringCoding.decode(charsetName, bytes, offset, length);
+ checkBoundsOffCount(offset, length, bytes.length);
+ StringCoding.Result ret =
+ StringCoding.decode(charsetName, bytes, offset, length);
+ this.value = ret.value;
+ this.coder = ret.coder;
}
/**
@@ -470,8 +482,11 @@
public String(byte bytes[], int offset, int length, Charset charset) {
if (charset == null)
throw new NullPointerException("charset");
- checkBounds(bytes, offset, length);
- this.value = StringCoding.decode(charset, bytes, offset, length);
+ checkBoundsOffCount(offset, length, bytes.length);
+ StringCoding.Result ret =
+ StringCoding.decode(charset, bytes, offset, length);
+ this.value = ret.value;
+ this.coder = ret.coder;
}
/**
@@ -553,8 +568,10 @@
* @since 1.1
*/
public String(byte bytes[], int offset, int length) {
- checkBounds(bytes, offset, length);
- this.value = StringCoding.decode(bytes, offset, length);
+ checkBoundsOffCount(offset, length, bytes.length);
+ StringCoding.Result ret = StringCoding.decode(bytes, offset, length);
+ this.value = ret.value;
+ this.coder = ret.coder;
}
/**
@@ -587,9 +604,7 @@
* A {@code StringBuffer}
*/
public String(StringBuffer buffer) {
- synchronized(buffer) {
- this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
- }
+ this(buffer.toString());
}
/**
@@ -608,18 +623,20 @@
* @since 1.5
*/
public String(StringBuilder builder) {
- this.value = Arrays.copyOf(builder.getValue(), builder.length());
+ this(builder, null);
}
- /*
+ /*
* Package private constructor which shares value array for speed.
* this constructor is always expected to be called with share==true.
* a separate constructor is needed because we already have a public
* String(char[]) constructor that makes a copy of the given char[].
*/
- String(char[] value, boolean share) {
+ // TBD: this is kept for package internal use (Thread/System),
+ // should be removed if they all have a byte[] version
+ String(char[] val, boolean share) {
// assert share : "unshared not supported";
- this.value = value;
+ this(val, 0, val.length, null);
}
/**
@@ -631,7 +648,7 @@
* object.
*/
public int length() {
- return value.length;
+ return value.length >> coder();
}
/**
@@ -665,10 +682,11 @@
* string.
*/
public char charAt(int index) {
- if ((index < 0) || (index >= value.length)) {
- throw new StringIndexOutOfBoundsException(index);
+ if (isLatin1()) {
+ return StringLatin1.charAt(value, index);
+ } else {
+ return StringUTF16.charAt(value, index);
}
- return value[index];
}
/**
@@ -694,10 +712,13 @@
* @since 1.5
*/
public int codePointAt(int index) {
- if ((index < 0) || (index >= value.length)) {
- throw new StringIndexOutOfBoundsException(index);
+ if (isLatin1()) {
+ checkIndex(index, value.length);
+ return value[index] & 0xff;
}
- return Character.codePointAtImpl(value, index, value.length);
+ int length = value.length >> 1;
+ checkIndex(index, length);
+ return StringUTF16.codePointAt(value, index, length);
}
/**
@@ -724,10 +745,13 @@
*/
public int codePointBefore(int index) {
int i = index - 1;
- if ((i < 0) || (i >= value.length)) {
+ if (i < 0 || i >= length()) {
throw new StringIndexOutOfBoundsException(index);
}
- return Character.codePointBeforeImpl(value, index, 0);
+ if (isLatin1()) {
+ return (value[i] & 0xff);
+ }
+ return StringUTF16.codePointBefore(value, index);
}
/**
@@ -752,10 +776,14 @@
* @since 1.5
*/
public int codePointCount(int beginIndex, int endIndex) {
- if (beginIndex < 0 || endIndex > value.length || beginIndex > endIndex) {
+ if (beginIndex < 0 || beginIndex > endIndex ||
+ endIndex > length()) {
throw new IndexOutOfBoundsException();
}
- return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex);
+ if (isLatin1()) {
+ return endIndex - beginIndex;
+ }
+ return StringUTF16.codePointCount(value, beginIndex, endIndex);
}
/**
@@ -779,19 +807,10 @@
* @since 1.5
*/
public int offsetByCodePoints(int index, int codePointOffset) {
- if (index < 0 || index > value.length) {
+ if (index < 0 || index > length()) {
throw new IndexOutOfBoundsException();
}
- return Character.offsetByCodePointsImpl(value, 0, value.length,
- index, codePointOffset);
- }
-
- /**
- * Copy characters from this string into dst starting at dstBegin.
- * This method doesn't perform any range checking.
- */
- void getChars(char dst[], int dstBegin) {
- System.arraycopy(value, 0, dst, dstBegin, value.length);
+ return Character.offsetByCodePoints(this, index, codePointOffset);
}
/**
@@ -825,16 +844,13 @@
* {@code dst.length}</ul>
*/
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
- if (srcBegin < 0) {
- throw new StringIndexOutOfBoundsException(srcBegin);
+ checkBoundsBeginEnd(srcBegin, srcEnd, length());
+ checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length);
+ if (isLatin1()) {
+ StringLatin1.getChars(value, srcBegin, srcEnd, dst, dstBegin);
+ } else {
+ StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin);
}
- if (srcEnd > value.length) {
- throw new StringIndexOutOfBoundsException(srcEnd);
- }
- if (srcBegin > srcEnd) {
- throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
- }
- System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
/**
@@ -882,24 +898,13 @@
*/
@Deprecated
public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) {
- if (srcBegin < 0) {
- throw new StringIndexOutOfBoundsException(srcBegin);
- }
- if (srcEnd > value.length) {
- throw new StringIndexOutOfBoundsException(srcEnd);
- }
- if (srcBegin > srcEnd) {
- throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
- }
+ checkBoundsBeginEnd(srcBegin, srcEnd, length());
Objects.requireNonNull(dst);
-
- int j = dstBegin;
- int n = srcEnd;
- int i = srcBegin;
- char[] val = value; /* avoid getfield opcode */
-
- while (i < n) {
- dst[j++] = (byte)val[i++];
+ checkBoundsOffCount(dstBegin, srcEnd - srcBegin, dst.length);
+ if (isLatin1()) {
+ StringLatin1.getBytes(value, srcBegin, srcEnd, dst, dstBegin);
+ } else {
+ StringUTF16.getBytes(value, srcBegin, srcEnd, dst, dstBegin);
}
}
@@ -926,7 +931,7 @@
public byte[] getBytes(String charsetName)
throws UnsupportedEncodingException {
if (charsetName == null) throw new NullPointerException();
- return StringCoding.encode(charsetName, value, 0, value.length);
+ return StringCoding.encode(charsetName, coder(), value);
}
/**
@@ -949,8 +954,8 @@
*/
public byte[] getBytes(Charset charset) {
if (charset == null) throw new NullPointerException();
- return StringCoding.encode(charset, value, 0, value.length);
- }
+ return StringCoding.encode(charset, coder(), value);
+ }
/**
* Encodes this {@code String} into a sequence of bytes using the
@@ -966,7 +971,7 @@
* @since 1.1
*/
public byte[] getBytes() {
- return StringCoding.encode(value, 0, value.length);
+ return StringCoding.encode(coder(), value);
}
/**
@@ -987,23 +992,15 @@
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
- @HotSpotIntrinsicCandidate
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
- char[] v1 = value;
- char[] v2 = ((String)anObject).value;
- int n = v1.length;
- if (n == v2.length) {
- int i = 0;
- while (n-- != 0) {
- if (v1[i] != v2[i])
- return false;
- i++;
- }
- return true;
+ String aString = (String)anObject;
+ if (coder() == aString.coder()) {
+ return isLatin1() ? StringLatin1.equals(value, aString.value)
+ : StringUTF16.equals(value, aString.value);
}
}
return false;
@@ -1032,16 +1029,28 @@
}
private boolean nonSyncContentEquals(AbstractStringBuilder sb) {
- char[] v1 = value;
- char[] v2 = sb.getValue();
- int n = v1.length;
- if (n != sb.length()) {
+ int len = length();
+ if (len != sb.length()) {
return false;
}
- for (int i = 0; i < n; i++) {
- if (v1[i] != v2[i]) {
+ byte v1[] = value;
+ byte v2[] = sb.getValue();
+ if (coder() == sb.getCoder()) {
+ int n = v1.length;
+ for (int i = 0; i < n; i++) {
+ if (v1[i] != v2[i]) {
+ return false;
+ }
+ }
+ } else {
+ if (!isLatin1()) { // utf16 str and latin1 abs can never be "equal"
return false;
}
+ for (int i = 0; i < len; i++) {
+ if ((char)(v1[i] & 0xff) != StringUTF16.getChar(v2, i)) {
+ return false;
+ }
+ }
}
return true;
}
@@ -1081,14 +1090,22 @@
return equals(cs);
}
// Argument is a generic CharSequence
- char[] v1 = value;
- int n = v1.length;
- if (n != cs.length()) {
+ int n = cs.length();
+ if (n != length()) {
return false;
}
- for (int i = 0; i < n; i++) {
- if (v1[i] != cs.charAt(i)) {
- return false;
+ byte[] val = this.value;
+ if (isLatin1()) {
+ for (int i = 0; i < n; i++) {
+ if ((val[i] & 0xff) != cs.charAt(i)) {
+ return false;
+ }
+ }
+ } else {
+ for (int i = 0; i < n; i++) {
+ if (StringUTF16.getChar(val, i) != cs.charAt(i)) {
+ return false;
+ }
}
}
return true;
@@ -1125,8 +1142,8 @@
public boolean equalsIgnoreCase(String anotherString) {
return (this == anotherString) ? true
: (anotherString != null)
- && (anotherString.value.length == value.length)
- && regionMatches(true, 0, anotherString, 0, value.length);
+ && (anotherString.length() == length())
+ && regionMatches(true, 0, anotherString, 0, length());
}
/**
@@ -1173,23 +1190,16 @@
* value greater than {@code 0} if this string is
* lexicographically greater than the string argument.
*/
- @HotSpotIntrinsicCandidate
public int compareTo(String anotherString) {
- char[] v1 = value;
- char[] v2 = anotherString.value;
- int len1 = v1.length;
- int len2 = v2.length;
- int lim = Math.min(len1, len2);
-
- for (int k = 0; k < lim; k++) {
- char c1 = v1[k];
- char c2 = v2[k];
- if (c1 != c2) {
- return c1 - c2;
- }
+ byte v1[] = value;
+ byte v2[] = anotherString.value;
+ if (coder() == anotherString.coder()) {
+ return isLatin1() ? StringLatin1.compareTo(v1, v2)
+ : StringUTF16.compareTo(v1, v2);
}
- return len1 - len2;
- }
+ return isLatin1() ? StringLatin1.compareToUTF16(v1, v2)
+ : StringUTF16.compareToLatin1(v1, v2);
+ }
/**
* A Comparator that orders {@code String} objects as by
@@ -1210,12 +1220,18 @@
private static final long serialVersionUID = 8575799808933029326L;
public int compare(String s1, String s2) {
+ byte v1[] = s1.value;
+ byte v2[] = s2.value;
int n1 = s1.length();
int n2 = s2.length();
+ boolean s1IsLatin1 = s1.isLatin1();
+ boolean s2IsLatin1 = s2.isLatin1();
int min = Math.min(n1, n2);
for (int i = 0; i < min; i++) {
- char c1 = s1.charAt(i);
- char c2 = s2.charAt(i);
+ char c1 = s1IsLatin1 ? StringLatin1.getChar(v1, i)
+ : StringUTF16.getChar(v1, i);
+ char c2 = s2IsLatin1 ? StringLatin1.getChar(v2, i)
+ : StringUTF16.getChar(v2, i);
if (c1 != c2) {
c1 = Character.toUpperCase(c1);
c2 = Character.toUpperCase(c2);
@@ -1294,21 +1310,41 @@
* exactly matches the specified subregion of the string argument;
* {@code false} otherwise.
*/
- public boolean regionMatches(int toffset, String other, int ooffset,
- int len) {
- char[] ta = value;
- int to = toffset;
- char[] pa = other.value;
- int po = ooffset;
+ public boolean regionMatches(int toffset, String other, int ooffset, int len) {
+ byte tv[] = value;
+ byte ov[] = other.value;
// Note: toffset, ooffset, or len might be near -1>>>1.
- if ((ooffset < 0) || (toffset < 0)
- || (toffset > (long)ta.length - len)
- || (ooffset > (long)pa.length - len)) {
+ if ((ooffset < 0) || (toffset < 0) ||
+ (toffset > (long)length() - len) ||
+ (ooffset > (long)other.length() - len)) {
return false;
}
- while (len-- > 0) {
- if (ta[to++] != pa[po++]) {
- return false;
+ if (coder() == other.coder()) {
+ if (!isLatin1() && (len > 0)) {
+ toffset = toffset << 1;
+ ooffset = ooffset << 1;
+ len = len << 1;
+ }
+ while (len-- > 0) {
+ if (tv[toffset++] != ov[ooffset++]) {
+ return false;
+ }
+ }
+ } else {
+ if (coder() == LATIN1) {
+ while (len-- > 0) {
+ if (StringLatin1.getChar(tv, toffset++) !=
+ StringUTF16.getChar(ov, ooffset++)) {
+ return false;
+ }
+ }
+ } else {
+ while (len-- > 0) {
+ if (StringUTF16.getChar(tv, toffset++) !=
+ StringLatin1.getChar(ov, ooffset++)) {
+ return false;
+ }
+ }
}
}
return true;
@@ -1366,43 +1402,25 @@
*/
public boolean regionMatches(boolean ignoreCase, int toffset,
String other, int ooffset, int len) {
- char[] ta = value;
- int to = toffset;
- char[] pa = other.value;
- int po = ooffset;
+ if (!ignoreCase) {
+ return regionMatches(toffset, other, ooffset, len);
+ }
// Note: toffset, ooffset, or len might be near -1>>>1.
if ((ooffset < 0) || (toffset < 0)
- || (toffset > (long)ta.length - len)
- || (ooffset > (long)pa.length - len)) {
+ || (toffset > (long)length() - len)
+ || (ooffset > (long)other.length() - len)) {
return false;
}
- while (len-- > 0) {
- char c1 = ta[to++];
- char c2 = pa[po++];
- if (c1 == c2) {
- continue;
- }
- if (ignoreCase) {
- // If characters don't match but case may be ignored,
- // 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;
+ byte tv[] = value;
+ byte ov[] = other.value;
+ if (coder() == other.coder()) {
+ return isLatin1()
+ ? StringLatin1.regionMatchesCI(tv, toffset, ov, ooffset, len)
+ : StringUTF16.regionMatchesCI(tv, toffset, ov, ooffset, len);
}
- return true;
+ return isLatin1()
+ ? StringLatin1.regionMatchesCI_UTF16(tv, toffset, ov, ooffset, len)
+ : StringUTF16.regionMatchesCI_Latin1(tv, toffset, ov, ooffset, len);
}
/**
@@ -1423,19 +1441,31 @@
* </pre>
*/
public boolean startsWith(String prefix, int toffset) {
- char[] ta = value;
- int to = toffset;
- char[] pa = prefix.value;
+ // Note: toffset might be near -1>>>1.
+ if (toffset < 0 || toffset > length() - prefix.length()) {
+ return false;
+ }
+ byte ta[] = value;
+ byte pa[] = prefix.value;
int po = 0;
int pc = pa.length;
- // Note: toffset might be near -1>>>1.
- if ((toffset < 0) || (toffset > ta.length - pc)) {
- return false;
- }
- while (--pc >= 0) {
- if (ta[to++] != pa[po++]) {
+ if (coder() == prefix.coder()) {
+ int to = isLatin1() ? toffset : toffset << 1;
+ while (po < pc) {
+ if (ta[to++] != pa[po++]) {
+ return false;
+ }
+ }
+ } else {
+ if (isLatin1()) { // && pcoder == UTF16
return false;
}
+ // coder == UTF16 && pcoder == LATIN1)
+ while (po < pc) {
+ if (StringUTF16.getChar(ta, toffset++) != (pa[po++] & 0xff)) {
+ return false;
+ }
+ }
}
return true;
}
@@ -1469,7 +1499,7 @@
* as determined by the {@link #equals(Object)} method.
*/
public boolean endsWith(String suffix) {
- return startsWith(suffix, value.length - suffix.value.length);
+ return startsWith(suffix, length() - suffix.length());
}
/**
@@ -1486,16 +1516,11 @@
* @return a hash code value for this object.
*/
public int hashCode() {
- int h = hash;
- if (h == 0) {
- for (char v : value) {
- h = 31 * h + v;
- }
- if (h != 0) {
- hash = h;
- }
+ if (hash == 0 && value.length > 0) {
+ hash = isLatin1() ? StringLatin1.hashCode(value)
+ : StringUTF16.hashCode(value);
}
- return h;
+ return hash;
}
/**
@@ -1566,45 +1591,8 @@
* if the character does not occur.
*/
public int indexOf(int ch, int fromIndex) {
- final int max = value.length;
- if (fromIndex < 0) {
- fromIndex = 0;
- } else if (fromIndex >= max) {
- // Note: fromIndex might be near -1>>>1.
- return -1;
- }
-
- if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- // handle most cases here (ch is a BMP code point or a
- // negative value (invalid code point))
- final char[] value = this.value;
- for (int i = fromIndex; i < max; i++) {
- if (value[i] == ch) {
- return i;
- }
- }
- return -1;
- } else {
- return indexOfSupplementary(ch, fromIndex);
- }
- }
-
- /**
- * Handles (rare) calls of indexOf with a supplementary character.
- */
- private int indexOfSupplementary(int ch, int fromIndex) {
- if (Character.isValidCodePoint(ch)) {
- final char[] value = this.value;
- final char hi = Character.highSurrogate(ch);
- final char lo = Character.lowSurrogate(ch);
- final int max = value.length - 1;
- for (int i = fromIndex; i < max; i++) {
- if (value[i] == hi && value[i + 1] == lo) {
- return i;
- }
- }
- }
- return -1;
+ return isLatin1() ? StringLatin1.indexOf(value, ch, fromIndex)
+ : StringUTF16.indexOf(value, ch, fromIndex);
}
/**
@@ -1631,7 +1619,7 @@
* {@code -1} if the character does not occur.
*/
public int lastIndexOf(int ch) {
- return lastIndexOf(ch, value.length - 1);
+ return lastIndexOf(ch, length() - 1);
}
/**
@@ -1669,38 +1657,8 @@
* if the character does not occur before that point.
*/
public int lastIndexOf(int ch, int fromIndex) {
- if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
- // handle most cases here (ch is a BMP code point or a
- // negative value (invalid code point))
- final char[] value = this.value;
- int i = Math.min(fromIndex, value.length - 1);
- for (; i >= 0; i--) {
- if (value[i] == ch) {
- return i;
- }
- }
- return -1;
- } else {
- return lastIndexOfSupplementary(ch, fromIndex);
- }
- }
-
- /**
- * Handles (rare) calls of lastIndexOf with a supplementary character.
- */
- private int lastIndexOfSupplementary(int ch, int fromIndex) {
- if (Character.isValidCodePoint(ch)) {
- final char[] value = this.value;
- char hi = Character.highSurrogate(ch);
- char lo = Character.lowSurrogate(ch);
- int i = Math.min(fromIndex, value.length - 2);
- for (; i >= 0; i--) {
- if (value[i] == hi && value[i + 1] == lo) {
- return i;
- }
- }
- }
- return -1;
+ return isLatin1() ? StringLatin1.lastIndexOf(value, ch, fromIndex)
+ : StringUTF16.lastIndexOf(value, ch, fromIndex);
}
/**
@@ -1717,9 +1675,15 @@
* @return the index of the first occurrence of the specified substring,
* or {@code -1} if there is no such occurrence.
*/
- @HotSpotIntrinsicCandidate
public int indexOf(String str) {
- return indexOf(str, 0);
+ if (coder() == str.coder()) {
+ return isLatin1() ? StringLatin1.indexOf(value, str.value)
+ : StringUTF16.indexOf(value, str.value);
+ }
+ if (coder() == LATIN1) { // str.coder == UTF16
+ return -1;
+ }
+ return StringUTF16.indexOfLatin1(value, str.value);
}
/**
@@ -1740,8 +1704,7 @@
* or {@code -1} if there is no such occurrence.
*/
public int indexOf(String str, int fromIndex) {
- return indexOf(value, 0, value.length,
- str.value, 0, str.value.length, fromIndex);
+ return indexOf(value, coder(), length(), str, fromIndex);
}
/**
@@ -1749,68 +1712,38 @@
* source is the character array being searched, and the target
* is the string being searched for.
*
- * @param source the characters being searched.
- * @param sourceOffset offset of the source string.
- * @param sourceCount count of the source string.
- * @param target the characters being searched for.
- * @param fromIndex the index to begin searching from.
+ * @param src the characters being searched.
+ * @param srcCoder the coder of the source string.
+ * @param srcCount length of the source string.
+ * @param tgtStr the characters being searched for.
+ * @param fromIndex the index to begin searching from.
*/
- static int indexOf(char[] source, int sourceOffset, int sourceCount,
- String target, int fromIndex) {
- return indexOf(source, sourceOffset, sourceCount,
- target.value, 0, target.value.length,
- fromIndex);
- }
+ static int indexOf(byte[] src, byte srcCoder, int srcCount,
+ String tgtStr, int fromIndex) {
- /**
- * Code shared by String and StringBuffer to do searches. The
- * source is the character array being searched, and the target
- * is the string being searched for.
- *
- * @param source the characters being searched.
- * @param sourceOffset offset of the source string.
- * @param sourceCount count of the source string.
- * @param target the characters being searched for.
- * @param targetOffset offset of the target string.
- * @param targetCount count of the target string.
- * @param fromIndex the index to begin searching from.
- */
- static int indexOf(char[] source, int sourceOffset, int sourceCount,
- char[] target, int targetOffset, int targetCount,
- int fromIndex) {
- if (fromIndex >= sourceCount) {
- return (targetCount == 0 ? sourceCount : -1);
+ byte[] tgt = tgtStr.value;
+ byte tgtCoder = tgtStr.coder();
+ int tgtCount = tgtStr.length();
+
+ if (fromIndex >= srcCount) {
+ return (tgtCount == 0 ? srcCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
- if (targetCount == 0) {
+ if (tgtCount == 0) {
return fromIndex;
}
-
- char first = target[targetOffset];
- int max = sourceOffset + (sourceCount - targetCount);
-
- for (int i = sourceOffset + fromIndex; i <= max; i++) {
- /* Look for first character. */
- if (source[i] != first) {
- while (++i <= max && source[i] != first);
- }
-
- /* Found first character, now look at the rest of v2 */
- if (i <= max) {
- int j = i + 1;
- int end = j + targetCount - 1;
- for (int k = targetOffset + 1; j < end && source[j]
- == target[k]; j++, k++);
-
- if (j == end) {
- /* Found whole string. */
- return i - sourceOffset;
- }
- }
+ if (srcCoder == tgtCoder) {
+ return srcCoder == LATIN1
+ ? StringLatin1.indexOf(src, srcCount, tgt, tgtCount, fromIndex)
+ : StringUTF16.indexOf(src, srcCount, tgt, tgtCount, fromIndex);
}
- return -1;
+ if (srcCoder == LATIN1) { // && tgtCoder == UTF16
+ return -1;
+ }
+ // srcCoder == UTF16 && tgtCoder == LATIN1) {
+ return StringUTF16.indexOfLatin1(src, srcCount, tgt, tgtCount, fromIndex);
}
/**
@@ -1829,7 +1762,7 @@
* or {@code -1} if there is no such occurrence.
*/
public int lastIndexOf(String str) {
- return lastIndexOf(str, value.length);
+ return lastIndexOf(str, length());
}
/**
@@ -1850,8 +1783,7 @@
* or {@code -1} if there is no such occurrence.
*/
public int lastIndexOf(String str, int fromIndex) {
- return lastIndexOf(value, 0, value.length,
- str.value, 0, str.value.length, fromIndex);
+ return lastIndexOf(value, coder(), length(), str, fromIndex);
}
/**
@@ -1859,40 +1791,22 @@
* source is the character array being searched, and the target
* is the string being searched for.
*
- * @param source the characters being searched.
- * @param sourceOffset offset of the source string.
- * @param sourceCount count of the source string.
- * @param target the characters being searched for.
- * @param fromIndex the index to begin searching from.
+ * @param src the characters being searched.
+ * @param srcCoder coder handles the mapping between bytes/chars
+ * @param srcCount count of the source string.
+ * @param tgt the characters being searched for.
+ * @param fromIndex the index to begin searching from.
*/
- static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
- String target, int fromIndex) {
- return lastIndexOf(source, sourceOffset, sourceCount,
- target.value, 0, target.value.length,
- fromIndex);
- }
-
- /**
- * Code shared by String and StringBuffer to do searches. The
- * source is the character array being searched, and the target
- * is the string being searched for.
- *
- * @param source the characters being searched.
- * @param sourceOffset offset of the source string.
- * @param sourceCount count of the source string.
- * @param target the characters being searched for.
- * @param targetOffset offset of the target string.
- * @param targetCount count of the target string.
- * @param fromIndex the index to begin searching from.
- */
- static int lastIndexOf(char[] source, int sourceOffset, int sourceCount,
- char[] target, int targetOffset, int targetCount,
- int fromIndex) {
+ static int lastIndexOf(byte[] src, byte srcCoder, int srcCount,
+ String tgtStr, int fromIndex) {
+ byte[] tgt = tgtStr.value;
+ byte tgtCoder = tgtStr.coder();
+ int tgtCount = tgtStr.length();
/*
* Check arguments; return immediately where possible. For
* consistency, don't check for null str.
*/
- int rightIndex = sourceCount - targetCount;
+ int rightIndex = srcCount - tgtCount;
if (fromIndex < 0) {
return -1;
}
@@ -1900,34 +1814,41 @@
fromIndex = rightIndex;
}
/* Empty string always matches. */
- if (targetCount == 0) {
+ if (tgtCount == 0) {
return fromIndex;
}
+ if (srcCoder == tgtCoder) {
+ return srcCoder == LATIN1
+ ? StringLatin1.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex)
+ : StringUTF16.lastIndexOf(src, srcCount, tgt, tgtCount, fromIndex);
+ }
+ if (srcCoder == LATIN1) { // && tgtCoder == UTF16
+ return -1;
+ }
+ // srcCoder == UTF16 && tgtCoder == LATIN1
+ int min = tgtCount - 1;
+ int i = min + fromIndex;
+ int strLastIndex = tgtCount - 1;
- int strLastIndex = targetOffset + targetCount - 1;
- char strLastChar = target[strLastIndex];
- int min = sourceOffset + targetCount - 1;
- int i = min + fromIndex;
-
+ char strLastChar = (char)(tgt[strLastIndex] & 0xff);
startSearchForLastChar:
while (true) {
- while (i >= min && source[i] != strLastChar) {
+ while (i >= min && StringUTF16.getChar(src, i) != strLastChar) {
i--;
}
if (i < min) {
return -1;
}
int j = i - 1;
- int start = j - (targetCount - 1);
+ int start = j - strLastIndex;
int k = strLastIndex - 1;
-
while (j > start) {
- if (source[j--] != target[k--]) {
+ if (StringUTF16.getChar(src, j--) != (tgt[k--] & 0xff)) {
i--;
continue startSearchForLastChar;
}
}
- return start - sourceOffset + 1;
+ return start + 1;
}
}
@@ -1949,17 +1870,18 @@
* length of this {@code String} object.
*/
public String substring(int beginIndex) {
- if (beginIndex <= 0) {
- if (beginIndex < 0) {
- throw new StringIndexOutOfBoundsException(beginIndex);
- }
- return this;
+ if (beginIndex < 0) {
+ throw new StringIndexOutOfBoundsException(beginIndex);
}
- int subLen = value.length - beginIndex;
+ int subLen = length() - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
- return new String(value, beginIndex, subLen);
+ if (beginIndex == 0) {
+ return this;
+ }
+ return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
+ : StringUTF16.newString(value, beginIndex, subLen);
}
/**
@@ -1985,22 +1907,14 @@
* {@code endIndex}.
*/
public String substring(int beginIndex, int endIndex) {
- if (beginIndex <= 0) {
- if (beginIndex < 0) {
- throw new StringIndexOutOfBoundsException(beginIndex);
- }
- if (endIndex == value.length) {
- return this;
- }
+ int length = length();
+ checkBoundsBeginEnd(beginIndex, endIndex, length);
+ int subLen = endIndex - beginIndex;
+ if (beginIndex == 0 && endIndex == length) {
+ return this;
}
- if (endIndex > value.length) {
- throw new StringIndexOutOfBoundsException(endIndex);
- }
- int subLen = endIndex - beginIndex;
- if (subLen < 0) {
- throw new StringIndexOutOfBoundsException(subLen);
- }
- return new String(value, beginIndex, subLen);
+ return isLatin1() ? StringLatin1.newString(value, beginIndex, subLen)
+ : StringUTF16.newString(value, beginIndex, subLen);
}
/**
@@ -2057,14 +1971,23 @@
* characters followed by the string argument's characters.
*/
public String concat(String str) {
- int otherLen = str.length();
- if (otherLen == 0) {
+ int olen = str.length();
+ if (olen == 0) {
return this;
}
- int len = value.length;
- char[] buf = Arrays.copyOf(value, len + otherLen);
- str.getChars(buf, len);
- return new String(buf, true);
+ if (coder() == str.coder()) {
+ byte[] val = this.value;
+ byte[] oval = str.value;
+ int len = val.length + oval.length;
+ byte[] buf = Arrays.copyOf(val, len);
+ System.arraycopy(oval, 0, buf, val.length, oval.length);
+ return new String(buf, coder);
+ }
+ int len = length();
+ byte[] buf = StringUTF16.newBytesFor(len + olen);
+ getBytes(buf, 0, UTF16);
+ str.getBytes(buf, len, UTF16);
+ return new String(buf, UTF16);
}
/**
@@ -2098,26 +2021,10 @@
*/
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
- char[] val = value; /* avoid getfield opcode */
- int len = val.length;
- int i = -1;
-
- while (++i < len) {
- if (val[i] == oldChar) {
- break;
- }
- }
- if (i < len) {
- char[] buf = new char[len];
- for (int j = 0; j < i; j++) {
- buf[j] = val[j];
- }
- while (i < len) {
- char c = val[i];
- buf[i] = (c == oldChar) ? newChar : c;
- i++;
- }
- return new String(buf, true);
+ String ret = isLatin1() ? StringLatin1.replace(value, oldChar, newChar)
+ : StringUTF16.replace(value, oldChar, newChar);
+ if (ret != null) {
+ return ret;
}
}
return this;
@@ -2269,29 +2176,27 @@
* @since 1.5
*/
public String replace(CharSequence target, CharSequence replacement) {
- String starget = target.toString();
- String srepl = replacement.toString();
- int j = indexOf(starget);
+ String tgtStr = target.toString();
+ String replStr = replacement.toString();
+ int j = indexOf(tgtStr);
if (j < 0) {
return this;
}
- int targLen = starget.length();
- int targLen1 = Math.max(targLen, 1);
- final char[] value = this.value;
- final char[] replValue = srepl.value;
- int newLenHint = value.length - targLen + replValue.length;
+ int tgtLen = tgtStr.length();
+ int tgtLen1 = Math.max(tgtLen, 1);
+ int thisLen = length();
+
+ int newLenHint = thisLen - tgtLen + replStr.length();
if (newLenHint < 0) {
throw new OutOfMemoryError();
}
StringBuilder sb = new StringBuilder(newLenHint);
int i = 0;
do {
- sb.append(value, i, j - i)
- .append(replValue);
- i = j + targLen;
- } while (j < value.length && (j = indexOf(starget, j + targLen1)) > 0);
-
- return sb.append(value, i, value.length - i).toString();
+ sb.append(this, i, j).append(replStr);
+ i = j + tgtLen;
+ } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);
+ return sb.append(this, i, thisLen).toString();
}
/**
@@ -2388,7 +2293,7 @@
the second is not the ascii digit or ascii letter.
*/
char ch = 0;
- if (((regex.value.length == 1 &&
+ if (((regex.length() == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
@@ -2408,8 +2313,9 @@
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
- list.add(substring(off, value.length));
- off = value.length;
+ int last = length();
+ list.add(substring(off, last));
+ off = last;
break;
}
}
@@ -2419,7 +2325,7 @@
// Add remaining segment
if (!limited || list.size() < limit)
- list.add(substring(off, value.length));
+ list.add(substring(off, length()));
// Construct result
int resultSize = list.size();
@@ -2613,95 +2519,8 @@
* @since 1.1
*/
public String toLowerCase(Locale locale) {
- if (locale == null) {
- throw new NullPointerException();
- }
- int first;
- boolean hasSurr = false;
- final int len = value.length;
-
- // Now check if there are any characters that need to be changed, or are surrogate
- for (first = 0 ; first < len; first++) {
- int cp = (int)value[first];
- if (Character.isSurrogate((char)cp)) {
- hasSurr = true;
- break;
- }
- if (cp != Character.toLowerCase(cp)) { // no need to check Character.ERROR
- break;
- }
- }
- if (first == len)
- return this;
- char[] result = new char[len];
- System.arraycopy(value, 0, result, 0, first); // Just copy the first few
- // lowerCase characters.
- String lang = locale.getLanguage();
- if (lang == "tr" || lang == "az" || lang == "lt") {
- return toLowerCaseEx(result, first, locale, true);
- }
- if (hasSurr) {
- return toLowerCaseEx(result, first, locale, false);
- }
- for (int i = first; i < len; i++) {
- int cp = (int)value[i];
- if (cp == '\u03A3' || // GREEK CAPITAL LETTER SIGMA
- Character.isSurrogate((char)cp)) {
- return toLowerCaseEx(result, i, locale, false);
- }
- if (cp == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
- return toLowerCaseEx(result, i, locale, true);
- }
- cp = Character.toLowerCase(cp);
- if (!Character.isBmpCodePoint(cp)) {
- return toLowerCaseEx(result, i, locale, false);
- }
- result[i] = (char)cp;
- }
- return new String(result, true);
- }
-
- private String toLowerCaseEx(char[] result, int first, Locale locale, boolean localeDependent) {
- int resultOffset = first;
- int srcCount;
- for (int i = first; i < value.length; i += srcCount) {
- int srcChar = (int)value[i];
- int lowerChar;
- char[] lowerCharArray;
- srcCount = 1;
- if (Character.isSurrogate((char)srcChar)) {
- srcChar = codePointAt(i);
- srcCount = Character.charCount(srcChar);
- }
- if (localeDependent || srcChar == '\u03A3') { // GREEK CAPITAL LETTER SIGMA
- lowerChar = ConditionalSpecialCasing.toLowerCaseEx(this, i, locale);
- } else {
- lowerChar = Character.toLowerCase(srcChar);
- }
- if (Character.isBmpCodePoint(lowerChar)) { // Character.ERROR is not a bmp
- result[resultOffset++] = (char)lowerChar;
- } else {
- if (lowerChar == Character.ERROR) {
- lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(this, i, locale);
- } else if (srcCount == 2) {
- resultOffset += Character.toChars(lowerChar, result, resultOffset);
- continue;
- } else {
- lowerCharArray = Character.toChars(lowerChar);
- }
- /* Grow result if needed */
- int mapLen = lowerCharArray.length;
- if (mapLen > srcCount) {
- char[] result2 = new char[result.length + mapLen - srcCount];
- System.arraycopy(result, 0, result2, 0, resultOffset);
- result = result2;
- }
- for (int x = 0; x < mapLen; ++x) {
- result[resultOffset++] = lowerCharArray[x];
- }
- }
- }
- return new String(result, 0, resultOffset);
+ return isLatin1() ? StringLatin1.toLowerCase(this, value, locale)
+ : StringUTF16.toLowerCase(this, value, locale);
}
/**
@@ -2776,98 +2595,8 @@
* @since 1.1
*/
public String toUpperCase(Locale locale) {
- if (locale == null) {
- throw new NullPointerException();
- }
- int first;
- boolean hasSurr = false;
- final int len = value.length;
-
- // Now check if there are any characters that need to be changed, or are surrogate
- for (first = 0 ; first < len; first++ ) {
- int cp = (int)value[first];
- if (Character.isSurrogate((char)cp)) {
- hasSurr = true;
- break;
- }
- if (cp != Character.toUpperCaseEx(cp)) { // no need to check Character.ERROR
- break;
- }
- }
- if (first == len) {
- return this;
- }
- char[] result = new char[len];
- System.arraycopy(value, 0, result, 0, first); // Just copy the first few
- // upperCase characters.
- String lang = locale.getLanguage();
- if (lang == "tr" || lang == "az" || lang == "lt") {
- return toUpperCaseEx(result, first, locale, true);
- }
- if (hasSurr) {
- return toUpperCaseEx(result, first, locale, false);
- }
- for (int i = first; i < len; i++) {
- int cp = (int)value[i];
- if (Character.isSurrogate((char)cp)) {
- return toUpperCaseEx(result, i, locale, false);
- }
- cp = Character.toUpperCaseEx(cp);
- if (!Character.isBmpCodePoint(cp)) { // Character.ERROR is not bmp
- return toUpperCaseEx(result, i, locale, false);
- }
- result[i] = (char)cp;
- }
- return new String(result, true);
- }
-
- private String toUpperCaseEx(char[] result, int first, Locale locale,
- boolean localeDependent) {
- int resultOffset = first;
- int srcCount;
- for (int i = first; i < value.length; i += srcCount) {
- int srcChar = (int)value[i];
- int upperChar;
- char[] upperCharArray;
- srcCount = 1;
- if (Character.isSurrogate((char)srcChar)) {
- srcChar = codePointAt(i);
- srcCount = Character.charCount(srcChar);
- }
- if (localeDependent) {
- upperChar = ConditionalSpecialCasing.toUpperCaseEx(this, i, locale);
- } else {
- upperChar = Character.toUpperCaseEx(srcChar);
- }
- if (Character.isBmpCodePoint(upperChar)) {
- result[resultOffset++] = (char)upperChar;
- } else {
- if (upperChar == Character.ERROR) {
- if (localeDependent) {
- upperCharArray =
- ConditionalSpecialCasing.toUpperCaseCharArray(this, i, locale);
- } else {
- upperCharArray = Character.toUpperCaseCharArray(srcChar);
- }
- } else if (srcCount == 2) {
- resultOffset += Character.toChars(upperChar, result, resultOffset);
- continue;
- } else {
- upperCharArray = Character.toChars(upperChar);
- }
- /* Grow result if needed */
- int mapLen = upperCharArray.length;
- if (mapLen > srcCount) {
- char[] result2 = new char[result.length + mapLen - srcCount];
- System.arraycopy(result, 0, result2, 0, resultOffset);
- result = result2;
- }
- for (int x = 0; x < mapLen; ++x) {
- result[resultOffset++] = upperCharArray[x];
- }
- }
- }
- return new String(result, 0, resultOffset);
+ return isLatin1() ? StringLatin1.toUpperCase(this, value, locale)
+ : StringUTF16.toUpperCase(this, value, locale);
}
/**
@@ -2925,17 +2654,9 @@
* trailing white space.
*/
public String trim() {
- char[] val = value; /* avoid getfield opcode */
- int end = val.length;
- int beg = 0;
-
- while ((beg < end) && (val[beg] <= ' ')) {
- beg++;
- }
- while ((beg < end) && (val[end - 1] <= ' ')) {
- end--;
- }
- return substring(beg, end);
+ String ret = isLatin1() ? StringLatin1.trim(value)
+ : StringUTF16.trim(value);
+ return ret == null ? this : ret;
}
/**
@@ -2947,63 +2668,6 @@
return this;
}
- static class IntCharArraySpliterator implements Spliterator.OfInt {
- private final char[] array;
- private int index; // current index, modified on advance/split
- private final int fence; // one past last index
- private final int cs;
-
- IntCharArraySpliterator(char[] array, int acs) {
- this(array, 0, array.length, acs);
- }
-
- IntCharArraySpliterator(char[] array, int origin, int fence, int acs) {
- this.array = array;
- this.index = origin;
- this.fence = fence;
- this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
- | Spliterator.SUBSIZED;
- }
-
- @Override
- public OfInt trySplit() {
- int lo = index, mid = (lo + fence) >>> 1;
- return (lo >= mid)
- ? null
- : new IntCharArraySpliterator(array, lo, index = mid, cs);
- }
-
- @Override
- public void forEachRemaining(IntConsumer action) {
- char[] a; int i, hi; // hoist accesses and checks from loop
- if (action == null)
- throw new NullPointerException();
- if ((a = array).length >= (hi = fence) &&
- (i = index) >= 0 && i < (index = hi)) {
- do { action.accept(a[i]); } while (++i < hi);
- }
- }
-
- @Override
- public boolean tryAdvance(IntConsumer action) {
- if (action == null)
- throw new NullPointerException();
- if (index >= 0 && index < fence) {
- action.accept(array[index++]);
- return true;
- }
- return false;
- }
-
- @Override
- public long estimateSize() { return (long)(fence - index); }
-
- @Override
- public int characteristics() {
- return cs;
- }
- }
-
/**
* Returns a stream of {@code int} zero-extending the {@code char} values
* from this sequence. Any char which maps to a <a
@@ -3016,93 +2680,11 @@
@Override
public IntStream chars() {
return StreamSupport.intStream(
- new IntCharArraySpliterator(value, Spliterator.IMMUTABLE), false);
+ isLatin1() ? new StringLatin1.CharsSpliterator(value, Spliterator.IMMUTABLE)
+ : new StringUTF16.CharsSpliterator(value, Spliterator.IMMUTABLE),
+ false);
}
- static class CodePointsSpliterator implements Spliterator.OfInt {
- private final char[] array;
- private int index; // current index, modified on advance/split
- private final int fence; // one past last index
- private final int cs;
-
- CodePointsSpliterator(char[] array, int acs) {
- this(array, 0, array.length, acs);
- }
-
- CodePointsSpliterator(char[] array, int origin, int fence, int acs) {
- this.array = array;
- this.index = origin;
- this.fence = fence;
- this.cs = acs | Spliterator.ORDERED;
- }
-
- @Override
- public OfInt trySplit() {
- int lo = index, mid = (lo + fence) >>> 1;
- if (lo >= mid)
- return null;
-
- int midOneLess;
- // If the mid-point intersects a surrogate pair
- if (Character.isLowSurrogate(array[mid]) &&
- Character.isHighSurrogate(array[midOneLess = (mid -1)])) {
- // If there is only one pair it cannot be split
- if (lo >= midOneLess)
- return null;
- // Shift the mid-point to align with the surrogate pair
- return new CodePointsSpliterator(array, lo, index = midOneLess, cs);
- }
- return new CodePointsSpliterator(array, lo, index = mid, cs);
- }
-
- @Override
- public void forEachRemaining(IntConsumer action) {
- char[] a; int i, hi; // hoist accesses and checks from loop
- if (action == null)
- throw new NullPointerException();
- if ((a = array).length >= (hi = fence) &&
- (i = index) >= 0 && i < (index = hi)) {
- do {
- i = advance(a, i, hi, action);
- } while (i < hi);
- }
- }
-
- @Override
- public boolean tryAdvance(IntConsumer action) {
- if (action == null)
- throw new NullPointerException();
- if (index >= 0 && index < fence) {
- index = advance(array, index, fence, action);
- return true;
- }
- return false;
- }
-
- // Advance one code point from the index, i, and return the next
- // index to advance from
- private static int advance(char[] a, int i, int hi, IntConsumer action) {
- char c1 = a[i++];
- int cp = c1;
- if (Character.isHighSurrogate(c1) && i < hi) {
- char c2 = a[i];
- if (Character.isLowSurrogate(c2)) {
- i++;
- cp = Character.toCodePoint(c1, c2);
- }
- }
- action.accept(cp);
- return i;
- }
-
- @Override
- public long estimateSize() { return (long)(fence - index); }
-
- @Override
- public int characteristics() {
- return cs;
- }
- }
/**
* Returns a stream of code point values from this sequence. Any surrogate
@@ -3118,7 +2700,9 @@
@Override
public IntStream codePoints() {
return StreamSupport.intStream(
- new CodePointsSpliterator(value, Spliterator.IMMUTABLE), false);
+ isLatin1() ? new StringLatin1.CharsSpliterator(value, Spliterator.IMMUTABLE)
+ : new StringUTF16.CodePointsSpliterator(value, Spliterator.IMMUTABLE),
+ false);
}
/**
@@ -3129,10 +2713,8 @@
* the character sequence represented by this string.
*/
public char[] toCharArray() {
- // Cannot use Arrays.copyOf because of class initialization order issues
- char[] result = new char[value.length];
- System.arraycopy(value, 0, result, 0, value.length);
- return result;
+ return isLatin1() ? StringLatin1.toChars(value)
+ : StringUTF16.toChars(value);
}
/**
@@ -3315,7 +2897,10 @@
* as its single character the argument {@code c}.
*/
public static String valueOf(char c) {
- return new String(new char[]{c}, true);
+ if (COMPACT_STRINGS && StringLatin1.canEncode(c)) {
+ return new String(StringLatin1.toBytes(c), LATIN1);
+ }
+ return new String(StringUTF16.toBytes(c), UTF16);
}
/**
@@ -3398,4 +2983,145 @@
* guaranteed to be from a pool of unique strings.
*/
public native String intern();
+
+ ////////////////////////////////////////////////////////////////
+
+ /**
+ * Copy character bytes from this string into dst starting at dstBegin.
+ * This method doesn't perform any range checking.
+ *
+ * Invoker guarantees: dst is in UTF16 (inflate itself for asb), if two
+ * coders are different, and dst is big enough (range check)
+ *
+ * @param dstBegin the char index, not offset of byte[]
+ * @param coder the coder of dst[]
+ */
+ void getBytes(byte dst[], int dstBegin, byte coder) {
+ if (coder() == coder) {
+ System.arraycopy(value, 0, dst, dstBegin << coder, value.length);
+ } else { // this.coder == LATIN && coder == UTF16
+ StringLatin1.inflate(value, 0, dst, dstBegin, value.length);
+ }
+ }
+
+ /*
+ * Package private constructor. Trailing Void argument is there for
+ * disambiguating it against other (public) constructors.
+ *
+ * Stores the char[] value into a byte[] that each byte represents
+ * the8 low-order bits of the corresponding character, if the char[]
+ * contains only latin1 character. Or a byte[] that stores all
+ * characters in their byte sequences defined by the {@code StringUTF16}.
+ */
+ String(char[] value, int off, int len, Void sig) {
+ if (len == 0) {
+ this.value = "".value;
+ this.coder = "".coder;
+ return;
+ }
+ if (COMPACT_STRINGS) {
+ byte[] val = StringUTF16.compress(value, off, len);
+ if (val != null) {
+ this.value = val;
+ this.coder = LATIN1;
+ return;
+ }
+ }
+ this.coder = UTF16;
+ this.value = StringUTF16.toBytes(value, off, len);
+ }
+
+ /*
+ * Package private constructor. Trailing Void argument is there for
+ * disambiguating it against other (public) constructors.
+ */
+ String(AbstractStringBuilder asb, Void sig) {
+ byte[] val = asb.getValue();
+ int length = asb.length();
+ if (asb.isLatin1()) {
+ this.coder = LATIN1;
+ this.value = Arrays.copyOfRange(val, 0, length);
+ } else {
+ if (COMPACT_STRINGS) {
+ byte[] buf = StringUTF16.compress(val, 0, length);
+ if (buf != null) {
+ this.coder = LATIN1;
+ this.value = buf;
+ return;
+ }
+ }
+ this.coder = UTF16;
+ this.value = Arrays.copyOfRange(val, 0, length << 1);
+ }
+ }
+
+ /*
+ * Package private constructor which shares value array for speed.
+ */
+ String(byte[] value, byte coder) {
+ this.value = value;
+ this.coder = coder;
+ }
+
+ byte coder() {
+ return COMPACT_STRINGS ? coder : UTF16;
+ }
+
+ private boolean isLatin1() {
+ return COMPACT_STRINGS && coder == LATIN1;
+ }
+
+ static final byte LATIN1 = 0;
+ static final byte UTF16 = 1;
+
+ /*
+ * StringIndexOutOfBoundsException if {@code index} is
+ * negative or greater than or equal to {@code length}.
+ */
+ static void checkIndex(int index, int length) {
+ if (index < 0 || index >= length) {
+ throw new StringIndexOutOfBoundsException("index " + index);
+ }
+ }
+
+ /*
+ * StringIndexOutOfBoundsException if {@code offset}
+ * is negative or greater than {@code length}.
+ */
+ static void checkOffset(int offset, int length) {
+ if (offset < 0 || offset > length) {
+ throw new StringIndexOutOfBoundsException("offset " + offset +
+ ",length " + length);
+ }
+ }
+
+ /*
+ * Check {@code offset}, {@code count} against {@code 0} and {@code length}
+ * bounds.
+ *
+ * @throws StringIndexOutOfBoundsException
+ * If {@code offset} is negative, {@code count} is negative,
+ * or {@code offset} is greater than {@code length - count}
+ */
+ private static void checkBoundsOffCount(int offset, int count, int length) {
+ if (offset < 0 || count < 0 || offset > length - count) {
+ throw new StringIndexOutOfBoundsException(
+ "offset " + offset + ", count " + count + ", length " + length);
+ }
+ }
+
+ /*
+ * Check {@code begin}, {@code end} against {@code 0} and {@code length}
+ * bounds.
+ *
+ * @throws StringIndexOutOfBoundsException
+ * If {@code begin} is negative, {@code begin} is greater than
+ * {@code end}, or {@code end} is greater than {@code length}.
+ */
+ private static void checkBoundsBeginEnd(int begin, int end, int length) {
+ if (begin < 0 || begin > end || end > length) {
+ throw new StringIndexOutOfBoundsException(
+ "begin " + begin + ", end " + end + ", length " + length);
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java Wed Jul 05 21:00:20 2017 +0200
@@ -104,7 +104,7 @@
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
- private transient char[] toStringCache;
+ private transient String toStringCache;
/** use serialVersionUID from JDK 1.0.2 for interoperability */
static final long serialVersionUID = 3388685877147921107L;
@@ -169,15 +169,13 @@
@Override
public synchronized int capacity() {
- return value.length;
+ return super.capacity();
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
- if (minimumCapacity > value.length) {
- expandCapacity(minimumCapacity);
- }
+ super.ensureCapacity(minimumCapacity);
}
/**
@@ -204,9 +202,7 @@
*/
@Override
public synchronized char charAt(int index) {
- if ((index < 0) || (index >= count))
- throw new StringIndexOutOfBoundsException(index);
- return value[index];
+ return super.charAt(index);
}
/**
@@ -261,10 +257,8 @@
*/
@Override
public synchronized void setCharAt(int index, char ch) {
- if ((index < 0) || (index >= count))
- throw new StringIndexOutOfBoundsException(index);
toStringCache = null;
- value[index] = ch;
+ super.setCharAt(index, ch);
}
@Override
@@ -680,9 +674,11 @@
@HotSpotIntrinsicCandidate
public synchronized String toString() {
if (toStringCache == null) {
- toStringCache = Arrays.copyOfRange(value, 0, count);
+ return toStringCache =
+ isLatin1() ? StringLatin1.newString(value, 0, count)
+ : StringUTF16.newString(value, 0, count);
}
- return new String(toStringCache, true);
+ return new String(toStringCache);
}
/**
@@ -710,7 +706,13 @@
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
java.io.ObjectOutputStream.PutField fields = s.putFields();
- fields.put("value", value);
+ char[] val = new char[capacity()];
+ if (isLatin1()) {
+ StringLatin1.getChars(value, 0, count, val, 0);
+ } else {
+ StringUTF16.getChars(value, 0, count, val, 0);
+ }
+ fields.put("value", val);
fields.put("count", count);
fields.put("shared", false);
s.writeFields();
@@ -723,7 +725,12 @@
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
java.io.ObjectInputStream.GetField fields = s.readFields();
- value = (char[])fields.get("value", null);
+ char[] val = (char[])fields.get("value", null);
+ initBytes(val, 0, val.length);
count = fields.get("count", 0);
}
+
+ protected synchronized void getBytes(byte dst[], int dstBegin, byte coder) {
+ super.getBytes(dst, dstBegin, coder);
+ }
}
--- a/jdk/src/java.base/share/classes/java/lang/StringBuilder.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/StringBuilder.java Wed Jul 05 21:00:20 2017 +0200
@@ -412,7 +412,8 @@
@HotSpotIntrinsicCandidate
public String toString() {
// Create a copy, don't share the array
- return new String(value, 0, count);
+ return isLatin1() ? StringLatin1.newString(value, 0, count)
+ : StringUTF16.newStringSB(value, 0, count);
}
/**
@@ -430,7 +431,13 @@
throws java.io.IOException {
s.defaultWriteObject();
s.writeInt(count);
- s.writeObject(value);
+ char[] val = new char[capacity()];
+ if (isLatin1()) {
+ StringLatin1.getChars(value, 0, count, val, 0);
+ } else {
+ StringUTF16.getChars(value, 0, count, val, 0);
+ }
+ s.writeObject(val);
}
/**
@@ -441,7 +448,8 @@
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
count = s.readInt();
- value = (char[]) s.readObject();
+ char[] val = (char[]) s.readObject();
+ initBytes(val, 0, val.length);
}
}
--- a/jdk/src/java.base/share/classes/java/lang/StringCoding.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/StringCoding.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,11 +38,19 @@
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Arrays;
+import jdk.internal.HotSpotIntrinsicCandidate;
import sun.misc.MessageUtils;
import sun.nio.cs.HistoricallyNamedCharset;
import sun.nio.cs.ArrayDecoder;
import sun.nio.cs.ArrayEncoder;
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+import static java.lang.String.COMPACT_STRINGS;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
/**
* Utility class for string encoding and decoding.
*/
@@ -72,23 +80,13 @@
// Trim the given byte array to the given length
//
- private static byte[] safeTrim(byte[] ba, int len, Charset cs, boolean isTrusted) {
+ private static byte[] safeTrim(byte[] ba, int len, boolean isTrusted) {
if (len == ba.length && (isTrusted || System.getSecurityManager() == null))
return ba;
else
return Arrays.copyOf(ba, len);
}
- // Trim the given char array to the given length
- //
- private static char[] safeTrim(char[] ca, int len,
- Charset cs, boolean isTrusted) {
- if (len == ca.length && (isTrusted || System.getSecurityManager() == null))
- return ca;
- else
- return Arrays.copyOf(ca, len);
- }
-
private static int scale(int len, float expansionFactor) {
// We need to perform double, not float, arithmetic; otherwise
// we lose low order bits when len is larger than 2**24.
@@ -117,21 +115,64 @@
}
}
+ static class Result {
+ byte[] value;
+ byte coder;
+
+ Result with() {
+ coder = COMPACT_STRINGS ? LATIN1 : UTF16;
+ value = new byte[0];
+ return this;
+ }
+
+ Result with(char[] val, int off, int len) {
+ if (String.COMPACT_STRINGS) {
+ byte[] bs = StringUTF16.compress(val, off, len);
+ if (bs != null) {
+ value = bs;
+ coder = LATIN1;
+ return this;
+ }
+ }
+ coder = UTF16;
+ value = StringUTF16.toBytes(val, off, len);
+ return this;
+ }
+
+ Result with(byte[] val, byte coder) {
+ this.coder = coder;
+ value = val;
+ return this;
+ }
+ }
+
+ @HotSpotIntrinsicCandidate
+ private static boolean hasNegatives(byte[] ba, int off, int len) {
+ for (int i = off; i < off + len; i++) {
+ if (ba[i] < 0) {
+ return true;
+ }
+ }
+ return false;
+ }
// -- Decoding --
- private static class StringDecoder {
+ static class StringDecoder {
private final String requestedCharsetName;
private final Charset cs;
+ private final boolean isASCIICompatible;
private final CharsetDecoder cd;
- private final boolean isTrusted;
+ protected final Result result;
- private StringDecoder(Charset cs, String rcn) {
+ StringDecoder(Charset cs, String rcn) {
this.requestedCharsetName = rcn;
this.cs = cs;
this.cd = cs.newDecoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
- this.isTrusted = (cs.getClass().getClassLoader0() == null);
+ this.result = new Result();
+ this.isASCIICompatible = (cd instanceof ArrayDecoder) &&
+ ((ArrayDecoder)cd).isASCIICompatible();
}
String charsetName() {
@@ -144,36 +185,58 @@
return requestedCharsetName;
}
- char[] decode(byte[] ba, int off, int len) {
+ Result decode(byte[] ba, int off, int len) {
+ if (len == 0) {
+ return result.with();
+ }
+ // fastpath for ascii compatible
+ if (isASCIICompatible && !hasNegatives(ba, off, len)) {
+ if (COMPACT_STRINGS) {
+ return result.with(Arrays.copyOfRange(ba, off, off + len),
+ LATIN1);
+ } else {
+ return result.with(StringLatin1.inflate(ba, off, len), UTF16);
+ }
+ }
int en = scale(len, cd.maxCharsPerByte());
char[] ca = new char[en];
- if (len == 0)
- return ca;
if (cd instanceof ArrayDecoder) {
int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
- return safeTrim(ca, clen, cs, isTrusted);
+ return result.with(ca, 0, clen);
+ }
+ cd.reset();
+ ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
+ CharBuffer cb = CharBuffer.wrap(ca);
+ try {
+ CoderResult cr = cd.decode(bb, cb, true);
+ if (!cr.isUnderflow())
+ cr.throwException();
+ cr = cd.flush(cb);
+ if (!cr.isUnderflow())
+ cr.throwException();
+ } catch (CharacterCodingException x) {
+ // Substitution is always enabled,
+ // so this shouldn't happen
+ throw new Error(x);
+ }
+ return result.with(ca, 0, cb.position());
+ }
+ }
+
+ private static class StringDecoder8859_1 extends StringDecoder {
+ StringDecoder8859_1(Charset cs, String rcn) {
+ super(cs, rcn);
+ }
+ Result decode(byte[] ba, int off, int len) {
+ if (COMPACT_STRINGS) {
+ return result.with(Arrays.copyOfRange(ba, off, off + len), LATIN1);
} else {
- cd.reset();
- ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
- CharBuffer cb = CharBuffer.wrap(ca);
- try {
- CoderResult cr = cd.decode(bb, cb, true);
- if (!cr.isUnderflow())
- cr.throwException();
- cr = cd.flush(cb);
- if (!cr.isUnderflow())
- cr.throwException();
- } catch (CharacterCodingException x) {
- // Substitution is always enabled,
- // so this shouldn't happen
- throw new Error(x);
- }
- return safeTrim(ca, cb.position(), cs, isTrusted);
+ return result.with(StringLatin1.inflate(ba, off, len), UTF16);
}
}
}
- static char[] decode(String charsetName, byte[] ba, int off, int len)
+ static Result decode(String charsetName, byte[] ba, int off, int len)
throws UnsupportedEncodingException
{
StringDecoder sd = deref(decoder);
@@ -183,8 +246,15 @@
sd = null;
try {
Charset cs = lookupCharset(csn);
- if (cs != null)
- sd = new StringDecoder(cs, csn);
+ if (cs != null) {
+ if (cs == UTF_8) {
+ sd = new StringDecoderUTF8(cs, csn);
+ } else if (cs == ISO_8859_1) {
+ sd = new StringDecoder8859_1(cs, csn);
+ } else {
+ sd = new StringDecoder(cs, csn);
+ }
+ }
} catch (IllegalCharsetNameException x) {}
if (sd == null)
throw new UnsupportedEncodingException(csn);
@@ -193,7 +263,7 @@
return sd.decode(ba, off, len);
}
- static char[] decode(Charset cs, byte[] ba, int off, int len) {
+ static Result decode(Charset cs, byte[] ba, int off, int len) {
// (1)We never cache the "external" cs, the only benefit of creating
// an additional StringDe/Encoder object to wrap it is to share the
// de/encode() method. These SD/E objects are short-lived, the young-gen
@@ -210,44 +280,57 @@
// check (... && (isTrusted || SM == null || getClassLoader0())) in trim
// but it then can be argued that the SM is null when the operation
// is started...
+ if (cs == UTF_8) {
+ return StringDecoderUTF8.decode(ba, off, len, new Result());
+ }
CharsetDecoder cd = cs.newDecoder();
+ // ascii fastpath
+ if (cs == ISO_8859_1 || ((cd instanceof ArrayDecoder) &&
+ ((ArrayDecoder)cd).isASCIICompatible() &&
+ !hasNegatives(ba, off, len))) {
+ if (COMPACT_STRINGS) {
+ return new Result().with(Arrays.copyOfRange(ba, off, off + len),
+ LATIN1);
+ } else {
+ return new Result().with(StringLatin1.inflate(ba, off, len), UTF16);
+ }
+ }
int en = scale(len, cd.maxCharsPerByte());
- char[] ca = new char[en];
- if (len == 0)
- return ca;
- boolean isTrusted = false;
- if (System.getSecurityManager() != null) {
- if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {
- ba = Arrays.copyOfRange(ba, off, off + len);
- off = 0;
- }
+ if (len == 0) {
+ return new Result().with();
+ }
+ if (System.getSecurityManager() != null &&
+ cs.getClass().getClassLoader0() != null) {
+ ba = Arrays.copyOfRange(ba, off, off + len);
+ off = 0;
}
cd.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.reset();
+
+ char[] ca = new char[en];
if (cd instanceof ArrayDecoder) {
int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
- return safeTrim(ca, clen, cs, isTrusted);
- } else {
- ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
- CharBuffer cb = CharBuffer.wrap(ca);
- try {
- CoderResult cr = cd.decode(bb, cb, true);
- if (!cr.isUnderflow())
- cr.throwException();
- cr = cd.flush(cb);
- if (!cr.isUnderflow())
- cr.throwException();
- } catch (CharacterCodingException x) {
- // Substitution is always enabled,
- // so this shouldn't happen
- throw new Error(x);
- }
- return safeTrim(ca, cb.position(), cs, isTrusted);
+ return new Result().with(ca, 0, clen);
}
+ ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
+ CharBuffer cb = CharBuffer.wrap(ca);
+ try {
+ CoderResult cr = cd.decode(bb, cb, true);
+ if (!cr.isUnderflow())
+ cr.throwException();
+ cr = cd.flush(cb);
+ if (!cr.isUnderflow())
+ cr.throwException();
+ } catch (CharacterCodingException x) {
+ // Substitution is always enabled,
+ // so this shouldn't happen
+ throw new Error(x);
+ }
+ return new Result().with(ca, 0, cb.position());
}
- static char[] decode(byte[] ba, int off, int len) {
+ static Result decode(byte[] ba, int off, int len) {
String csn = Charset.defaultCharset().name();
try {
// use charset name decode() variant which provides caching.
@@ -273,6 +356,7 @@
private static class StringEncoder {
private Charset cs;
private CharsetEncoder ce;
+ private final boolean isASCIICompatible;
private final String requestedCharsetName;
private final boolean isTrusted;
@@ -283,6 +367,8 @@
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
this.isTrusted = (cs.getClass().getClassLoader0() == null);
+ this.isASCIICompatible = (ce instanceof ArrayEncoder) &&
+ ((ArrayEncoder)ce).isASCIICompatible();
}
String charsetName() {
@@ -295,36 +381,186 @@
return requestedCharsetName;
}
- byte[] encode(char[] ca, int off, int len) {
+ byte[] encode(byte coder, byte[] val) {
+ // fastpath for ascii compatible
+ if (coder == LATIN1 && isASCIICompatible &&
+ !hasNegatives(val, 0, val.length)) {
+ return Arrays.copyOf(val, val.length);
+ }
+ int len = val.length >> coder; // assume LATIN1=0/UTF16=1;
int en = scale(len, ce.maxBytesPerChar());
byte[] ba = new byte[en];
- if (len == 0)
+ if (len == 0) {
return ba;
+ }
if (ce instanceof ArrayEncoder) {
- int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
- return safeTrim(ba, blen, cs, isTrusted);
- } else {
- ce.reset();
- ByteBuffer bb = ByteBuffer.wrap(ba);
- CharBuffer cb = CharBuffer.wrap(ca, off, len);
- try {
- CoderResult cr = ce.encode(cb, bb, true);
- if (!cr.isUnderflow())
- cr.throwException();
- cr = ce.flush(bb);
- if (!cr.isUnderflow())
- cr.throwException();
- } catch (CharacterCodingException x) {
- // Substitution is always enabled,
- // so this shouldn't happen
- throw new Error(x);
+ if (!isTrusted) {
+ val = Arrays.copyOf(val, val.length);
+ }
+ int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba)
+ : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba);
+ if (blen != -1) {
+ return safeTrim(ba, blen, isTrusted);
}
- return safeTrim(ba, bb.position(), cs, isTrusted);
}
+ char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val)
+ : StringUTF16.toChars(val);
+ ce.reset();
+ ByteBuffer bb = ByteBuffer.wrap(ba);
+ CharBuffer cb = CharBuffer.wrap(ca, 0, len);
+ try {
+ CoderResult cr = ce.encode(cb, bb, true);
+ if (!cr.isUnderflow())
+ cr.throwException();
+ cr = ce.flush(bb);
+ if (!cr.isUnderflow())
+ cr.throwException();
+ } catch (CharacterCodingException x) {
+ // Substitution is always enabled,
+ // so this shouldn't happen
+ throw new Error(x);
+ }
+ return safeTrim(ba, bb.position(), isTrusted);
}
}
- static byte[] encode(String charsetName, char[] ca, int off, int len)
+ @HotSpotIntrinsicCandidate
+ private static int implEncodeISOArray(byte[] sa, int sp,
+ byte[] da, int dp, int len) {
+ int i = 0;
+ for (; i < len; i++) {
+ char c = StringUTF16.getChar(sa, sp++);
+ if (c > '\u00FF')
+ break;
+ da[dp++] = (byte)c;
+ }
+ return i;
+ }
+
+ static byte[] encode8859_1(byte coder, byte[] val) {
+ if (coder == LATIN1) {
+ return Arrays.copyOf(val, val.length);
+ }
+ int len = val.length >> 1;
+ byte[] dst = new byte[len];
+ int dp = 0;
+ int sp = 0;
+ int sl = len;
+ while (sp < sl) {
+ int ret = implEncodeISOArray(val, sp, dst, dp, len);
+ sp = sp + ret;
+ dp = dp + ret;
+ if (ret != len) {
+ char c = StringUTF16.getChar(val, sp++);
+ if (Character.isHighSurrogate(c) && sp < sl &&
+ Character.isLowSurrogate(StringUTF16.getChar(val, sp))) {
+ sp++;
+ }
+ dst[dp++] = '?';
+ len = sl - sp;
+ }
+ }
+ if (dp == dst.length) {
+ return dst;
+ }
+ return Arrays.copyOf(dst, dp);
+ }
+
+ static byte[] encodeASCII(byte coder, byte[] val) {
+ if (coder == LATIN1) {
+ byte[] dst = new byte[val.length];
+ for (int i = 0; i < val.length; i++) {
+ if (val[i] < 0) {
+ dst[i] = '?';
+ } else {
+ dst[i] = val[i];
+ }
+ }
+ return dst;
+ }
+ int len = val.length >> 1;
+ byte[] dst = new byte[len];
+ int dp = 0;
+ for (int i = 0; i < len; i++) {
+ char c = StringUTF16.getChar(val, i);
+ if (c < 0x80) {
+ dst[dp++] = (byte)c;
+ continue;
+ }
+ if (Character.isHighSurrogate(c) && i + 1 < len &&
+ Character.isLowSurrogate(StringUTF16.getChar(val, i + 1))) {
+ i++;
+ }
+ dst[dp++] = '?';
+ }
+ if (len == dp) {
+ return dst;
+ }
+ return Arrays.copyOf(dst, dp);
+ }
+
+ static byte[] encodeUTF8(byte coder, byte[] val) {
+ int dp = 0;
+ byte[] dst;
+ if (coder == LATIN1) {
+ dst = new byte[val.length << 1];
+ for (int sp = 0; sp < val.length; sp++) {
+ byte c = val[sp];
+ if (c < 0) {
+ dst[dp++] = (byte)(0xc0 | ((c & 0xff) >> 6));
+ dst[dp++] = (byte)(0x80 | (c & 0x3f));
+ } else {
+ dst[dp++] = c;
+ }
+ }
+ } else {
+ int sp = 0;
+ int sl = val.length >> 1;
+ dst = new byte[sl * 3];
+ char c;
+ while (sp < sl && (c = StringUTF16.getChar(val, sp)) < '\u0080') {
+ // ascii fast loop;
+ dst[dp++] = (byte)c;
+ sp++;
+ }
+ while (sp < sl) {
+ c = StringUTF16.getChar(val, sp++);
+ if (c < 0x80) {
+ dst[dp++] = (byte)c;
+ } else if (c < 0x800) {
+ dst[dp++] = (byte)(0xc0 | (c >> 6));
+ dst[dp++] = (byte)(0x80 | (c & 0x3f));
+ } else if (Character.isSurrogate(c)) {
+ int uc = -1;
+ char c2;
+ if (Character.isHighSurrogate(c) && sp < sl &&
+ Character.isLowSurrogate(c2 = StringUTF16.getChar(val, sp))) {
+ uc = Character.toCodePoint(c, c2);
+ }
+ if (uc < 0) {
+ dst[dp++] = '?';
+ } else {
+ dst[dp++] = (byte)(0xf0 | ((uc >> 18)));
+ dst[dp++] = (byte)(0x80 | ((uc >> 12) & 0x3f));
+ dst[dp++] = (byte)(0x80 | ((uc >> 6) & 0x3f));
+ dst[dp++] = (byte)(0x80 | (uc & 0x3f));
+ sp++; // 2 chars
+ }
+ } else {
+ // 3 bytes, 16 bits
+ dst[dp++] = (byte)(0xe0 | ((c >> 12)));
+ dst[dp++] = (byte)(0x80 | ((c >> 6) & 0x3f));
+ dst[dp++] = (byte)(0x80 | (c & 0x3f));
+ }
+ }
+ }
+ if (dp == dst.length) {
+ return dst;
+ }
+ return Arrays.copyOf(dst, dp);
+ }
+
+ static byte[] encode(String charsetName, byte coder, byte[] val)
throws UnsupportedEncodingException
{
StringEncoder se = deref(encoder);
@@ -334,62 +570,88 @@
se = null;
try {
Charset cs = lookupCharset(csn);
- if (cs != null)
+ if (cs != null) {
+ if (cs == UTF_8) {
+ return encodeUTF8(coder, val);
+ } else if (cs == ISO_8859_1) {
+ return encode8859_1(coder, val);
+ } else if (cs == US_ASCII) {
+ return encodeASCII(coder, val);
+ }
se = new StringEncoder(cs, csn);
+ }
} catch (IllegalCharsetNameException x) {}
- if (se == null)
+ if (se == null) {
throw new UnsupportedEncodingException (csn);
+ }
set(encoder, se);
}
- return se.encode(ca, off, len);
+ return se.encode(coder, val);
}
- static byte[] encode(Charset cs, char[] ca, int off, int len) {
+ static byte[] encode(Charset cs, byte coder, byte[] val) {
+ if (cs == UTF_8) {
+ return encodeUTF8(coder, val);
+ } else if (cs == ISO_8859_1) {
+ return encode8859_1(coder, val);
+ } else if (cs == US_ASCII) {
+ return encodeASCII(coder, val);
+ }
CharsetEncoder ce = cs.newEncoder();
+ // fastpath for ascii compatible
+ if (coder == LATIN1 && (((ce instanceof ArrayEncoder) &&
+ ((ArrayEncoder)ce).isASCIICompatible() &&
+ !hasNegatives(val, 0, val.length)))) {
+ return Arrays.copyOf(val, val.length);
+ }
+ int len = val.length >> coder; // assume LATIN1=0/UTF16=1;
int en = scale(len, ce.maxBytesPerChar());
byte[] ba = new byte[en];
- if (len == 0)
+ if (len == 0) {
return ba;
- boolean isTrusted = false;
- if (System.getSecurityManager() != null) {
- if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {
- ca = Arrays.copyOfRange(ca, off, off + len);
- off = 0;
- }
}
+ boolean isTrusted = System.getSecurityManager() == null ||
+ cs.getClass().getClassLoader0() == null;
ce.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.reset();
if (ce instanceof ArrayEncoder) {
- int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
- return safeTrim(ba, blen, cs, isTrusted);
- } else {
- ByteBuffer bb = ByteBuffer.wrap(ba);
- CharBuffer cb = CharBuffer.wrap(ca, off, len);
- try {
- CoderResult cr = ce.encode(cb, bb, true);
- if (!cr.isUnderflow())
- cr.throwException();
- cr = ce.flush(bb);
- if (!cr.isUnderflow())
- cr.throwException();
- } catch (CharacterCodingException x) {
- throw new Error(x);
+ if (!isTrusted) {
+ val = Arrays.copyOf(val, val.length);
+ }
+ int blen = (coder == LATIN1 ) ? ((ArrayEncoder)ce).encodeFromLatin1(val, 0, len, ba)
+ : ((ArrayEncoder)ce).encodeFromUTF16(val, 0, len, ba);
+ if (blen != -1) {
+ return safeTrim(ba, blen, isTrusted);
}
- return safeTrim(ba, bb.position(), cs, isTrusted);
}
+ char[] ca = (coder == LATIN1 ) ? StringLatin1.toChars(val)
+ : StringUTF16.toChars(val);
+ ByteBuffer bb = ByteBuffer.wrap(ba);
+ CharBuffer cb = CharBuffer.wrap(ca, 0, len);
+ try {
+ CoderResult cr = ce.encode(cb, bb, true);
+ if (!cr.isUnderflow())
+ cr.throwException();
+ cr = ce.flush(bb);
+ if (!cr.isUnderflow())
+ cr.throwException();
+ } catch (CharacterCodingException x) {
+ throw new Error(x);
+ }
+ return safeTrim(ba, bb.position(), isTrusted);
}
- static byte[] encode(char[] ca, int off, int len) {
+ static byte[] encode(byte coder, byte[] val) {
String csn = Charset.defaultCharset().name();
try {
// use charset name encode() variant which provides caching.
- return encode(csn, ca, off, len);
+ return encode(csn, coder, val);
} catch (UnsupportedEncodingException x) {
warnUnsupportedCharset(csn);
}
try {
- return encode("ISO-8859-1", ca, off, len);
+ return encode("ISO-8859-1", coder, val);
} catch (UnsupportedEncodingException x) {
// If this code is hit during VM initialization, MessageUtils is
// the only way we will be able to get any kind of error message.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StringDecoderUTF8.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.Character.isSurrogate;
+import static java.lang.Character.highSurrogate;
+import static java.lang.Character.lowSurrogate;
+import static java.lang.Character.isSupplementaryCodePoint;
+import static java.lang.StringUTF16.putChar;
+
+class StringDecoderUTF8 extends StringCoding.StringDecoder {
+
+ StringDecoderUTF8(Charset cs, String rcn) {
+ super(cs, rcn);
+ }
+
+ private static boolean isNotContinuation(int b) {
+ return (b & 0xc0) != 0x80;
+ }
+
+ private static boolean isMalformed3(int b1, int b2, int b3) {
+ return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+ (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
+ }
+
+ private static boolean isMalformed3_2(int b1, int b2) {
+ return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+ (b2 & 0xc0) != 0x80;
+ }
+
+ private static boolean isMalformed4(int b2, int b3, int b4) {
+ return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 ||
+ (b4 & 0xc0) != 0x80;
+ }
+
+ private static boolean isMalformed4_2(int b1, int b2) {
+ return (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
+ (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
+ (b2 & 0xc0) != 0x80;
+ }
+
+ private static boolean isMalformed4_3(int b3) {
+ return (b3 & 0xc0) != 0x80;
+ }
+
+ // for nb == 3/4
+ private static int malformedN(byte[] src, int sp, int nb) {
+ if (nb == 3) {
+ int b1 = src[sp++];
+ int b2 = src[sp++]; // no need to lookup b3
+ return ((b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
+ isNotContinuation(b2)) ? 1 : 2;
+ } else if (nb == 4) { // we don't care the speed here
+ int b1 = src[sp++] & 0xff;
+ int b2 = src[sp++] & 0xff;
+ if (b1 > 0xf4 ||
+ (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
+ (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
+ isNotContinuation(b2))
+ return 1;
+ if (isNotContinuation(src[sp++]))
+ return 2;
+ return 3;
+ }
+ assert false;
+ return -1;
+ }
+
+ private static char repl = '\ufffd';
+
+ StringCoding.Result decode(byte[] src, int sp, int len) {
+ return decode(src, sp, len, result);
+ }
+
+ static StringCoding.Result decode(byte[] src, int sp, int len,
+ StringCoding.Result ret) {
+ int sl = sp + len;
+ byte[] dst = new byte[len];
+ int dp = 0;
+ if (COMPACT_STRINGS) { // Latin1 only loop
+ while (sp < sl) {
+ int b1 = src[sp];
+ if (b1 >= 0) {
+ dst[dp++] = (byte)b1;
+ sp++;
+ continue;
+ }
+ if ((b1 == (byte)0xc2 || b1 == (byte)0xc3) &&
+ sp + 1 < sl) {
+ int b2 = src[sp + 1];
+ if (!isNotContinuation(b2)) {
+ dst[dp++] = (byte)(((b1 << 6) ^ b2)^
+ (((byte) 0xC0 << 6) ^
+ ((byte) 0x80 << 0)));
+ sp += 2;
+ continue;
+ }
+ }
+ // anything not a latin1, including the repl
+ // we have to go with the utf16
+ break;
+ }
+ if (sp == sl) {
+ if (dp != dst.length) {
+ dst = Arrays.copyOf(dst, dp);
+ }
+ return ret.with(dst, LATIN1);
+ }
+ }
+ if (dp == 0) {
+ dst = new byte[len << 1];
+ } else {
+ byte[] buf = new byte[len << 1];
+ StringLatin1.inflate(dst, 0, buf, 0, dp);
+ dst = buf;
+ }
+ while (sp < sl) {
+ int b1 = src[sp++];
+ if (b1 >= 0) {
+ putChar(dst, dp++, (char) b1);
+ } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
+ if (sp < sl) {
+ int b2 = src[sp++];
+ if (isNotContinuation(b2)) {
+ putChar(dst, dp++, repl);
+ sp--;
+ } else {
+ putChar(dst, dp++, (char)(((b1 << 6) ^ b2)^
+ (((byte) 0xC0 << 6) ^
+ ((byte) 0x80 << 0))));
+ }
+ continue;
+ }
+ putChar(dst, dp++, repl);
+ break;
+ } else if ((b1 >> 4) == -2) {
+ if (sp + 1 < sl) {
+ int b2 = src[sp++];
+ int b3 = src[sp++];
+ if (isMalformed3(b1, b2, b3)) {
+ putChar(dst, dp++, repl);
+ sp -= 3;
+ sp += malformedN(src, sp, 3);
+ } else {
+ char c = (char)((b1 << 12) ^
+ (b2 << 6) ^
+ (b3 ^
+ (((byte) 0xE0 << 12) ^
+ ((byte) 0x80 << 6) ^
+ ((byte) 0x80 << 0))));
+ putChar(dst, dp++, isSurrogate(c) ? repl : c);
+ }
+ continue;
+ }
+ if (sp < sl && isMalformed3_2(b1, src[sp])) {
+ putChar(dst, dp++, repl);
+ continue;
+ }
+ putChar(dst, dp++, repl);
+ break;
+ } else if ((b1 >> 3) == -2) {
+ if (sp + 2 < sl) {
+ int b2 = src[sp++];
+ int b3 = src[sp++];
+ int b4 = src[sp++];
+ int uc = ((b1 << 18) ^
+ (b2 << 12) ^
+ (b3 << 6) ^
+ (b4 ^
+ (((byte) 0xF0 << 18) ^
+ ((byte) 0x80 << 12) ^
+ ((byte) 0x80 << 6) ^
+ ((byte) 0x80 << 0))));
+ if (isMalformed4(b2, b3, b4) ||
+ !isSupplementaryCodePoint(uc)) { // shortest form check
+ putChar(dst, dp++, repl);
+ sp -= 4;
+ sp += malformedN(src, sp, 4);
+ } else {
+ putChar(dst, dp++, highSurrogate(uc));
+ putChar(dst, dp++, lowSurrogate(uc));
+ }
+ continue;
+ }
+ b1 &= 0xff;
+ if (b1 > 0xf4 ||
+ sp < sl && isMalformed4_2(b1, src[sp] & 0xff)) {
+ putChar(dst, dp++, repl);
+ continue;
+ }
+ sp++;
+ putChar(dst, dp++, repl);
+ if (sp < sl && isMalformed4_3(src[sp])) {
+ continue;
+ }
+ break;
+ } else {
+ putChar(dst, dp++, repl);
+ }
+ }
+ if (dp != len) {
+ dst = Arrays.copyOf(dst, dp << 1);
+ }
+ return ret.with(dst, UTF16);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StringLatin1.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Spliterator;
+import java.util.function.IntConsumer;
+import java.util.stream.IntStream;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+import static java.lang.String.checkOffset;
+
+final class StringLatin1 {
+
+ public static char charAt(byte[] value, int index) {
+ if (index < 0 || index >= value.length) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ return (char)(value[index] & 0xff);
+ }
+
+ public static boolean canEncode(int cp) {
+ return cp >>> 8 == 0;
+ }
+
+ public static int length(byte[] value) {
+ return value.length;
+ }
+
+ public static int codePointAt(byte[] value, int index, int end) {
+ return value[index] & 0xff;
+ }
+
+ public static int codePointBefore(byte[] value, int index) {
+ return value[index - 1] & 0xff;
+ }
+
+ public static int codePointCount(byte[] value, int beginIndex, int endIndex) {
+ return endIndex - beginIndex;
+ }
+
+ public static char[] toChars(byte[] value) {
+ char[] dst = new char[value.length];
+ inflate(value, 0, dst, 0, value.length);
+ return dst;
+ }
+
+ public static byte[] inflate(byte[] value, int off, int len) {
+ byte[] ret = StringUTF16.newBytesFor(len);
+ inflate(value, off, ret, 0, len);
+ return ret;
+ }
+
+ public static void getChars(byte[] value, int srcBegin, int srcEnd, char dst[], int dstBegin) {
+ inflate(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+ }
+
+ public static void getBytes(byte[] value, int srcBegin, int srcEnd, byte dst[], int dstBegin) {
+ System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static boolean equals(byte[] value, byte[] other) {
+ if (value.length == other.length) {
+ for (int i = 0; i < value.length; i++) {
+ if (value[i] != other[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int compareTo(byte[] value, byte[] other) {
+ int len1 = value.length;
+ int len2 = other.length;
+ int lim = Math.min(len1, len2);
+ for (int k = 0; k < lim; k++) {
+ if (value[k] != other[k]) {
+ return getChar(value, k) - getChar(other, k);
+ }
+ }
+ return len1 - len2;
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int compareToUTF16(byte[] value, byte[] other) {
+ int len1 = length(value);
+ int len2 = StringUTF16.length(other);
+ int lim = Math.min(len1, len2);
+ for (int k = 0; k < lim; k++) {
+ char c1 = getChar(value, k);
+ char c2 = StringUTF16.getChar(other, k);
+ if (c1 != c2) {
+ return c1 - c2;
+ }
+ }
+ return len1 - len2;
+ }
+
+ public static int hashCode(byte[] value) {
+ int h = 0;
+ for (byte v : value) {
+ h = 31 * h + (v & 0xff);
+ }
+ return h;
+ }
+
+ public static int indexOf(byte[] value, int ch, int fromIndex) {
+ if (!canEncode(ch)) {
+ return -1;
+ }
+ int max = value.length;
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ } else if (fromIndex >= max) {
+ // Note: fromIndex might be near -1>>>1.
+ return -1;
+ }
+ byte c = (byte)ch;
+ for (int i = fromIndex; i < max; i++) {
+ if (value[i] == c) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int indexOf(byte[] value, byte[] str) {
+ if (str.length == 0) {
+ return 0;
+ }
+ if (value.length == 0) {
+ return -1;
+ }
+ return indexOf(value, value.length, str, str.length, 0);
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
+ byte first = str[0];
+ int max = (valueCount - strCount);
+ for (int i = fromIndex; i <= max; i++) {
+ // Look for first character.
+ if (value[i] != first) {
+ while (++i <= max && value[i] != first);
+ }
+ // Found first character, now look at the rest of value
+ if (i <= max) {
+ int j = i + 1;
+ int end = j + strCount - 1;
+ for (int k = 1; j < end && value[j] == str[k]; j++, k++);
+ if (j == end) {
+ // Found whole string.
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public static int lastIndexOf(byte[] src, int srcCount,
+ byte[] tgt, int tgtCount, int fromIndex) {
+ int min = tgtCount - 1;
+ int i = min + fromIndex;
+ int strLastIndex = tgtCount - 1;
+ char strLastChar = (char)(tgt[strLastIndex] & 0xff);
+
+ startSearchForLastChar:
+ while (true) {
+ while (i >= min && (src[i] & 0xff) != strLastChar) {
+ i--;
+ }
+ if (i < min) {
+ return -1;
+ }
+ int j = i - 1;
+ int start = j - strLastIndex;
+ int k = strLastIndex - 1;
+ while (j > start) {
+ if ((src[j--] & 0xff) != (tgt[k--] & 0xff)) {
+ i--;
+ continue startSearchForLastChar;
+ }
+ }
+ return start + 1;
+ }
+ }
+
+ public static int lastIndexOf(final byte[] value, int ch, int fromIndex) {
+ if (!canEncode(ch)) {
+ return -1;
+ }
+ int off = Math.min(fromIndex, value.length - 1);
+ for (; off >= 0; off--) {
+ if (value[off] == (byte)ch) {
+ return off;
+ }
+ }
+ return -1;
+ }
+
+ public static String replace(byte[] value, char oldChar, char newChar) {
+ if (canEncode(oldChar)) {
+ int len = value.length;
+ int i = -1;
+ while (++i < len) {
+ if (value[i] == (byte)oldChar) {
+ break;
+ }
+ }
+ if (i < len) {
+ if (canEncode(newChar)) {
+ byte buf[] = new byte[len];
+ for (int j = 0; j < i; j++) { // TBD arraycopy?
+ buf[j] = value[j];
+ }
+ while (i < len) {
+ byte c = value[i];
+ buf[i] = (c == (byte)oldChar) ? (byte)newChar : c;
+ i++;
+ }
+ return new String(buf, LATIN1);
+ } else {
+ byte[] buf = StringUTF16.newBytesFor(len);
+ // inflate from latin1 to UTF16
+ inflate(value, 0, buf, 0, i);
+ while (i < len) {
+ char c = (char)(value[i] & 0xff);
+ StringUTF16.putChar(buf, i, (c == oldChar) ? newChar : c);
+ i++;
+ }
+ return new String(buf, UTF16);
+ }
+ }
+ }
+ return null; // for string to return this;
+ }
+
+ // case insensitive
+ public static boolean regionMatchesCI(byte[] value, int toffset,
+ byte[] other, int ooffset, int len) {
+ int last = toffset + len;
+ while (toffset < last) {
+ char c1 = (char)(value[toffset++] & 0xff);
+ char c2 = (char)(other[ooffset++] & 0xff);
+ if (c1 == c2) {
+ continue;
+ }
+ char u1 = Character.toUpperCase(c1);
+ char u2 = Character.toUpperCase(c2);
+ if (u1 == u2) {
+ continue;
+ }
+ if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+ continue;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean regionMatchesCI_UTF16(byte[] value, int toffset,
+ byte[] other, int ooffset, int len) {
+ int last = toffset + len;
+ while (toffset < last) {
+ char c1 = (char)(value[toffset++] & 0xff);
+ char c2 = StringUTF16.getChar(other, ooffset++);
+ if (c1 == c2) {
+ continue;
+ }
+ char u1 = Character.toUpperCase(c1);
+ char u2 = Character.toUpperCase(c2);
+ if (u1 == u2) {
+ continue;
+ }
+ if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+ continue;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public static String toLowerCase(String str, byte[] value, Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException();
+ }
+ int first;
+ final int len = value.length;
+ // Now check if there are any characters that need to be changed, or are surrogate
+ for (first = 0 ; first < len; first++) {
+ int cp = value[first] & 0xff;
+ if (cp != Character.toLowerCase(cp)) { // no need to check Character.ERROR
+ break;
+ }
+ }
+ if (first == len)
+ return str;
+ String lang = locale.getLanguage();
+ if (lang == "tr" || lang == "az" || lang == "lt") {
+ return toLowerCaseEx(str, value, first, locale, true);
+ }
+ byte[] result = new byte[len];
+ System.arraycopy(value, 0, result, 0, first); // Just copy the first few
+ // lowerCase characters.
+ for (int i = first; i < len; i++) {
+ int cp = value[i] & 0xff;
+ cp = Character.toLowerCase(cp);
+ if (!canEncode(cp)) { // not a latin1 character
+ return toLowerCaseEx(str, value, first, locale, false);
+ }
+ result[i] = (byte)cp;
+ }
+ return new String(result, LATIN1);
+ }
+
+ private static String toLowerCaseEx(String str, byte[] value,
+ int first, Locale locale, boolean localeDependent)
+ {
+ byte[] result = StringUTF16.newBytesFor(value.length);
+ int resultOffset = 0;
+ for (int i = 0; i < first; i++) {
+ StringUTF16.putChar(result, resultOffset++, value[i] & 0xff);
+ }
+ for (int i = first; i < value.length; i++) {
+ int srcChar = value[i] & 0xff;
+ int lowerChar;
+ char[] lowerCharArray;
+ if (localeDependent) {
+ lowerChar = ConditionalSpecialCasing.toLowerCaseEx(str, i, locale);
+ } else {
+ lowerChar = Character.toLowerCase(srcChar);
+ }
+ if (Character.isBmpCodePoint(lowerChar)) { // Character.ERROR is not a bmp
+ StringUTF16.putChar(result, resultOffset++, lowerChar);
+ } else {
+ if (lowerChar == Character.ERROR) {
+ lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(str, i, locale);
+ } else {
+ lowerCharArray = Character.toChars(lowerChar);
+ }
+ /* Grow result if needed */
+ int mapLen = lowerCharArray.length;
+ if (mapLen > 1) {
+ byte[] result2 = StringUTF16.newBytesFor((result.length >> 1) + mapLen - 1);
+ System.arraycopy(result, 0, result2, 0, resultOffset << 1);
+ result = result2;
+ }
+ for (int x = 0; x < mapLen; ++x) {
+ StringUTF16.putChar(result, resultOffset++, lowerCharArray[x]);
+ }
+ }
+ }
+ return StringUTF16.newString(result, 0, resultOffset);
+ }
+
+ public static String toUpperCase(String str, byte[] value, Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException();
+ }
+ int first;
+ final int len = value.length;
+
+ // Now check if there are any characters that need to be changed, or are surrogate
+ for (first = 0 ; first < len; first++ ) {
+ int cp = value[first] & 0xff;
+ if (cp != Character.toUpperCaseEx(cp)) { // no need to check Character.ERROR
+ break;
+ }
+ }
+ if (first == len) {
+ return str;
+ }
+ String lang = locale.getLanguage();
+ if (lang == "tr" || lang == "az" || lang == "lt") {
+ return toUpperCaseEx(str, value, first, locale, true);
+ }
+ byte[] result = new byte[len];
+ System.arraycopy(value, 0, result, 0, first); // Just copy the first few
+ // upperCase characters.
+ for (int i = first; i < len; i++) {
+ int cp = value[i] & 0xff;
+ cp = Character.toUpperCaseEx(cp);
+ if (!canEncode(cp)) { // not a latin1 character
+ return toUpperCaseEx(str, value, first, locale, false);
+ }
+ result[i] = (byte)cp;
+ }
+ return new String(result, LATIN1);
+ }
+
+ private static String toUpperCaseEx(String str, byte[] value,
+ int first, Locale locale, boolean localeDependent)
+ {
+ byte[] result = StringUTF16.newBytesFor(value.length);
+ int resultOffset = 0;
+ for (int i = 0; i < first; i++) {
+ StringUTF16.putChar(result, resultOffset++, value[i] & 0xff);
+ }
+ for (int i = first; i < value.length; i++) {
+ int srcChar = value[i] & 0xff;
+ int upperChar;
+ char[] upperCharArray;
+ if (localeDependent) {
+ upperChar = ConditionalSpecialCasing.toUpperCaseEx(str, i, locale);
+ } else {
+ upperChar = Character.toUpperCaseEx(srcChar);
+ }
+ if (Character.isBmpCodePoint(upperChar)) {
+ StringUTF16.putChar(result, resultOffset++, upperChar);
+ } else {
+ if (upperChar == Character.ERROR) {
+ if (localeDependent) {
+ upperCharArray =
+ ConditionalSpecialCasing.toUpperCaseCharArray(str, i, locale);
+ } else {
+ upperCharArray = Character.toUpperCaseCharArray(srcChar);
+ }
+ } else {
+ upperCharArray = Character.toChars(upperChar);
+ }
+ /* Grow result if needed */
+ int mapLen = upperCharArray.length;
+ if (mapLen > 1) {
+ byte[] result2 = StringUTF16.newBytesFor((result.length >> 1) + mapLen - 1);
+ System.arraycopy(result, 0, result2, 0, resultOffset << 1);
+ result = result2;
+ }
+ for (int x = 0; x < mapLen; ++x) {
+ StringUTF16.putChar(result, resultOffset++, upperCharArray[x]);
+ }
+ }
+ }
+ return StringUTF16.newString(result, 0, resultOffset);
+ }
+
+ public static String trim(byte[] value) {
+ int len = value.length;
+ int st = 0;
+ while ((st < len) && ((value[st] & 0xff) <= ' ')) {
+ st++;
+ }
+ while ((st < len) && ((value[len - 1] & 0xff) <= ' ')) {
+ len--;
+ }
+ return ((st > 0) || (len < value.length)) ?
+ newString(value, st, len - st) : null;
+ }
+
+ public static void putChar(byte[] val, int index, int c) {
+ //assert (canEncode(c));
+ val[index] = (byte)(c);
+ }
+
+ public static char getChar(byte[] val, int index) {
+ return (char)(val[index] & 0xff);
+ }
+
+ public static byte[] toBytes(int[] val, int off, int len) {
+ byte[] ret = new byte[len];
+ for (int i = 0; i < len; i++) {
+ int cp = val[off++];
+ if (!canEncode(cp)) {
+ return null;
+ }
+ ret[i] = (byte)cp;
+ }
+ return ret;
+ }
+
+ public static byte[] toBytes(char c) {
+ return new byte[] { (byte)c };
+ }
+
+ public static String newString(byte[] val, int index, int len) {
+ return new String(Arrays.copyOfRange(val, index, index + len),
+ LATIN1);
+ }
+
+ public static void fillNull(byte[] val, int index, int end) {
+ Arrays.fill(val, index, end, (byte)0);
+ }
+
+ // inflatedCopy byte[] -> char[]
+ @HotSpotIntrinsicCandidate
+ private static void inflate(byte[] src, int srcOff, char[] dst, int dstOff, int len) {
+ for (int i = 0; i < len; i++) {
+ dst[dstOff++] = (char)(src[srcOff++] & 0xff);
+ }
+ }
+
+ // inflatedCopy byte[] -> byte[]
+ @HotSpotIntrinsicCandidate
+ public static void inflate(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
+ for (int i = 0; i < len; i++) {
+ StringUTF16.putChar(dst, dstOff++, src[srcOff++] & 0xff);
+ }
+ }
+
+ static class CharsSpliterator implements Spliterator.OfInt {
+ private final byte[] array;
+ private int index; // current index, modified on advance/split
+ private final int fence; // one past last index
+ private final int cs;
+
+ CharsSpliterator(byte[] array, int acs) {
+ this(array, 0, array.length, acs);
+ }
+
+ CharsSpliterator(byte[] array, int origin, int fence, int acs) {
+ this.array = array;
+ this.index = origin;
+ this.fence = fence;
+ this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
+ | Spliterator.SUBSIZED;
+ }
+
+ @Override
+ public OfInt trySplit() {
+ int lo = index, mid = (lo + fence) >>> 1;
+ return (lo >= mid)
+ ? null
+ : new CharsSpliterator(array, lo, index = mid, cs);
+ }
+
+ @Override
+ public void forEachRemaining(IntConsumer action) {
+ byte[] a; int i, hi; // hoist accesses and checks from loop
+ if (action == null)
+ throw new NullPointerException();
+ if ((a = array).length >= (hi = fence) &&
+ (i = index) >= 0 && i < (index = hi)) {
+ do { action.accept(a[i] & 0xff); } while (++i < hi);
+ }
+ }
+
+ @Override
+ public boolean tryAdvance(IntConsumer action) {
+ if (action == null)
+ throw new NullPointerException();
+ if (index >= 0 && index < fence) {
+ action.accept(array[index++] & 0xff);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public long estimateSize() { return (long)(fence - index); }
+
+ @Override
+ public int characteristics() {
+ return cs;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////
+
+ public static void getCharsSB(byte[] val, int srcBegin, int srcEnd, char dst[], int dstBegin) {
+ checkOffset(srcEnd, val.length);
+ getChars(val, srcBegin, srcEnd, dst, dstBegin);
+ }
+
+ public static void inflateSB(byte[] val, byte[] dst, int dstOff, int count) {
+ checkOffset(count, val.length);
+ checkOffset(dstOff + count, dst.length >> 1); // dst is utf16
+ inflate(val, 0, dst, dstOff, count);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StringUTF16.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,971 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Spliterator;
+import java.util.function.IntConsumer;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
+import static java.lang.String.UTF16;
+import static java.lang.String.LATIN1;
+import static java.lang.String.checkIndex;
+import static java.lang.String.checkOffset;
+
+final class StringUTF16 {
+
+ public static byte[] newBytesFor(int len) {
+ if (len < 0) {
+ throw new NegativeArraySizeException();
+ }
+ if (len > MAX_LENGTH) {
+ throw new OutOfMemoryError("UTF16 String size is " + len +
+ ", should be less than " + MAX_LENGTH);
+ }
+ return new byte[len << 1];
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static void putChar(byte[] val, int index, int c) {
+ index <<= 1;
+ val[index++] = (byte)(c >> HI_BYTE_SHIFT);
+ val[index] = (byte)(c >> LO_BYTE_SHIFT);
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static char getChar(byte[] val, int index) {
+ index <<= 1;
+ return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
+ ((val[index] & 0xff) << LO_BYTE_SHIFT));
+ }
+
+ public static char charAt(byte[] value, int index) {
+ if (index < 0 || index >= value.length >> 1) {
+ throw new StringIndexOutOfBoundsException(index);
+ }
+ return getChar(value, index);
+ }
+
+ public static int length(byte[] value) {
+ return value.length >> 1;
+ }
+
+ public static int codePointAt(byte[] value, int index, int end) {
+ char c1 = getChar(value, index);
+ if (Character.isHighSurrogate(c1) && ++index < end) {
+ char c2 = getChar(value, index);
+ if (Character.isLowSurrogate(c2)) {
+ return Character.toCodePoint(c1, c2);
+ }
+ }
+ return c1;
+ }
+
+ public static int codePointBefore(byte[] value, int index) {
+ char c2 = getChar(value, --index);
+ if (Character.isLowSurrogate(c2) && index > 0) {
+ char c1 = getChar(value, --index);
+ if (Character.isHighSurrogate(c1)) {
+ return Character.toCodePoint(c1, c2);
+ }
+ }
+ return c2;
+ }
+
+ public static int codePointCount(byte[] value, int beginIndex, int endIndex) {
+ int count = endIndex - beginIndex;
+ for (int i = beginIndex; i < endIndex; ) {
+ if (Character.isHighSurrogate(getChar(value, i++)) &&
+ i < endIndex &&
+ Character.isLowSurrogate(getChar(value, i))) {
+ count--;
+ i++;
+ }
+ }
+ return count;
+ }
+
+ public static char[] toChars(byte[] value) {
+ char[] dst = new char[value.length >> 1];
+ getChars(value, 0, dst.length, dst, 0);
+ return dst;
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static byte[] toBytes(char[] value, int off, int len) {
+ byte[] val = newBytesFor(len);
+ for (int i = 0; i < len; i++) {
+ putChar(val, i, value[off++]);
+ }
+ return val;
+ }
+
+ public static byte[] compress(char[] val, int off, int len) {
+ byte[] ret = new byte[len];
+ if (compress(val, off, ret, 0, len) == len) {
+ return ret;
+ }
+ return null;
+ }
+
+ public static byte[] compress(byte[] val, int off, int len) {
+ byte[] ret = new byte[len];
+ if (compress(val, off, ret, 0, len) == len) {
+ return ret;
+ }
+ return null;
+ }
+
+ // compressedCopy char[] -> byte[]
+ @HotSpotIntrinsicCandidate
+ private static int compress(char[] src, int srcOff, byte[] dst, int dstOff, int len) {
+ for (int i = 0; i < len; i++) {
+ int c = src[srcOff++];
+ if (c >>> 8 != 0) {
+ return 0;
+ }
+ dst[dstOff++] = (byte)c;
+ }
+ return len;
+ }
+
+ // compressedCopy byte[] -> byte[]
+ @HotSpotIntrinsicCandidate
+ public static int compress(byte[] src, int srcOff, byte[] dst, int dstOff, int len) {
+ for (int i = 0; i < len; i++) {
+ int c = getChar(src, srcOff++);
+ if (c >>> 8 != 0) {
+ return 0;
+ }
+ dst[dstOff++] = (byte)c;
+ }
+ return len;
+ }
+
+ public static byte[] toBytes(int[] val, int index, int len) {
+ final int end = index + len;
+ // Pass 1: Compute precise size of char[]
+ int n = len;
+ for (int i = index; i < end; i++) {
+ int cp = val[i];
+ if (Character.isBmpCodePoint(cp))
+ continue;
+ else if (Character.isValidCodePoint(cp))
+ n++;
+ else throw new IllegalArgumentException(Integer.toString(cp));
+ }
+ // Pass 2: Allocate and fill in <high, low> pair
+ byte[] buf = newBytesFor(n);
+ for (int i = index, j = 0; i < end; i++, j++) {
+ int cp = val[i];
+ if (Character.isBmpCodePoint(cp)) {
+ putChar(buf, j, cp);
+ } else {
+ putChar(buf, j++, Character.highSurrogate(cp));
+ putChar(buf, j, Character.lowSurrogate(cp));
+ }
+ }
+ return buf;
+ }
+
+ public static byte[] toBytes(char c) {
+ byte[] result = new byte[2];
+ putChar(result, 0, c);
+ return result;
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static void getChars(byte[] value, int srcBegin, int srcEnd, char dst[], int dstBegin) {
+ for (int i = srcBegin; i < srcEnd; i++) {
+ dst[dstBegin++] = getChar(value, i);
+ }
+ }
+
+ /* @see java.lang.String.getBytes(int, int, byte[], int) */
+ public static void getBytes(byte[] value, int srcBegin, int srcEnd, byte dst[], int dstBegin) {
+ srcBegin <<= 1;
+ srcEnd <<= 1;
+ for (int i = srcBegin + (1 >> LO_BYTE_SHIFT); i < srcEnd; i += 2) {
+ dst[dstBegin++] = value[i];
+ }
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static boolean equals(byte[] value, byte[] other) {
+ if (value.length == other.length) {
+ int len = value.length >> 1;
+ for (int i = 0; i < len; i++) {
+ if (getChar(value, i) != getChar(other, i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int compareTo(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) {
+ return c1 - c2;
+ }
+ }
+ return len1 - len2;
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int compareToLatin1(byte[] value, byte[] other) {
+ int len1 = length(value);
+ int len2 = StringLatin1.length(other);
+ int lim = Math.min(len1, len2);
+ for (int k = 0; k < lim; k++) {
+ char c1 = getChar(value, k);
+ char c2 = StringLatin1.getChar(other, k);
+ if (c1 != c2) {
+ return c1 - c2;
+ }
+ }
+ return len1 - len2;
+ }
+
+ public static int hashCode(byte[] value) {
+ int h = 0;
+ int length = value.length >> 1;
+ for (int i = 0; i < length; i++) {
+ h = 31 * h + getChar(value, i);
+ }
+ return h;
+ }
+
+ public static int indexOf(byte[] value, int ch, int fromIndex) {
+ int max = value.length >> 1;
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ } else if (fromIndex >= max) {
+ // Note: fromIndex might be near -1>>>1.
+ return -1;
+ }
+ if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ // handle most cases here (ch is a BMP code point or a
+ // negative value (invalid code point))
+ return indexOfChar(value, ch, fromIndex, max);
+ } else {
+ return indexOfSupplementary(value, ch, fromIndex, max);
+ }
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int indexOf(byte[] value, byte[] str) {
+ if (str.length == 0) {
+ return 0;
+ }
+ if (value.length == 0) {
+ return -1;
+ }
+ return indexOf(value, length(value), str, length(str), 0);
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int indexOf(byte[] value, int valueCount, byte[] str, int strCount, int fromIndex) {
+ char first = getChar(str, 0);
+ int max = (valueCount - strCount);
+ for (int i = fromIndex; i <= max; i++) {
+ // Look for first character.
+ if (getChar(value, i) != first) {
+ while (++i <= max && getChar(value, i) != first);
+ }
+ // Found first character, now look at the rest of value
+ if (i <= max) {
+ int j = i + 1;
+ int end = j + strCount - 1;
+ for (int k = 1; j < end && getChar(value, j) == getChar(str, k); j++, k++);
+ if (j == end) {
+ // Found whole string.
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Handles indexOf Latin1 substring in UTF16 string.
+ */
+ @HotSpotIntrinsicCandidate
+ public static int indexOfLatin1(byte[] value, byte[] str) {
+ if (str.length == 0) {
+ return 0;
+ }
+ if (value.length == 0) {
+ return -1;
+ }
+ return indexOfLatin1(value, length(value), str, str.length, 0);
+ }
+
+ @HotSpotIntrinsicCandidate
+ public static int indexOfLatin1(byte[] src, int srcCount, byte[] tgt, int tgtCount, int fromIndex) {
+ char first = (char)(tgt[0] & 0xff);
+ int max = (srcCount - tgtCount);
+ for (int i = fromIndex; i <= max; i++) {
+ // Look for first character.
+ if (getChar(src, i) != first) {
+ while (++i <= max && getChar(src, i) != first);
+ }
+ // Found first character, now look at the rest of v2
+ if (i <= max) {
+ int j = i + 1;
+ int end = j + tgtCount - 1;
+ for (int k = 1;
+ j < end && getChar(src, j) == (tgt[k] & 0xff);
+ j++, k++);
+ if (j == end) {
+ // Found whole string.
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ @HotSpotIntrinsicCandidate
+ private static int indexOfChar(byte[] value, int ch, int fromIndex, int max) {
+ for (int i = fromIndex; i < max; i++) {
+ if (getChar(value, i) == ch) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Handles (rare) calls of indexOf with a supplementary character.
+ */
+ private static int indexOfSupplementary(byte[] value, int ch, int fromIndex, int max) {
+ if (Character.isValidCodePoint(ch)) {
+ final char hi = Character.highSurrogate(ch);
+ final char lo = Character.lowSurrogate(ch);
+ for (int i = fromIndex; i < max - 1; i++) {
+ if (getChar(value, i) == hi && getChar(value, i + 1 ) == lo) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public static int lastIndexOf(byte[] src, int srcCount,
+ byte[] tgt, int tgtCount, int fromIndex) {
+ int min = tgtCount - 1;
+ int i = min + fromIndex;
+ int strLastIndex = tgtCount - 1;
+ char strLastChar = getChar(tgt, strLastIndex);
+
+ startSearchForLastChar:
+ while (true) {
+ while (i >= min && getChar(src, i) != strLastChar) {
+ i--;
+ }
+ if (i < min) {
+ return -1;
+ }
+ int j = i - 1;
+ int start = j - strLastIndex;
+ int k = strLastIndex - 1;
+ while (j > start) {
+ if (getChar(src, j--) != getChar(tgt, k--)) {
+ i--;
+ continue startSearchForLastChar;
+ }
+ }
+ return start + 1;
+ }
+ }
+
+ public static int lastIndexOf(byte[] value, int ch, int fromIndex) {
+ if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
+ // handle most cases here (ch is a BMP code point or a
+ // negative value (invalid code point))
+ int i = Math.min(fromIndex, (value.length >> 1) - 1);
+ for (; i >= 0; i--) {
+ if (getChar(value, i) == ch) {
+ return i;
+ }
+ }
+ return -1;
+ } else {
+ return lastIndexOfSupplementary(value, ch, fromIndex);
+ }
+ }
+
+ /**
+ * Handles (rare) calls of lastIndexOf with a supplementary character.
+ */
+ private static int lastIndexOfSupplementary(final byte[] value, int ch, int fromIndex) {
+ if (Character.isValidCodePoint(ch)) {
+ char hi = Character.highSurrogate(ch);
+ char lo = Character.lowSurrogate(ch);
+ int i = Math.min(fromIndex, (value.length >> 1) - 2);
+ for (; i >= 0; i--) {
+ if (getChar(value, i) == hi && getChar(value, i + 1) == lo) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public static String replace(byte[] value, char oldChar, char newChar) {
+ int len = value.length >> 1;
+ int i = -1;
+ while (++i < len) {
+ if (getChar(value, i) == oldChar) {
+ break;
+ }
+ }
+ if (i < len) {
+ byte buf[] = new byte[value.length];
+ for (int j = 0; j < i; j++) {
+ putChar(buf, j, getChar(value, j)); // TBD:arraycopy?
+ }
+ while (i < len) {
+ char c = getChar(value, i);
+ putChar(buf, i, c == oldChar ? newChar : c);
+ i++;
+ }
+ // Check if we should try to compress to latin1
+ if (String.COMPACT_STRINGS &&
+ !StringLatin1.canEncode(oldChar) &&
+ StringLatin1.canEncode(newChar)) {
+ byte[] val = compress(buf, 0, len);
+ if (val != null) {
+ return new String(val, LATIN1);
+ }
+ }
+ return new String(buf, UTF16);
+ }
+ return null;
+ }
+
+ public static boolean regionMatchesCI(byte[] value, int toffset,
+ byte[] other, int ooffset, int len) {
+ int last = toffset + len;
+ 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;
+ }
+
+ public static boolean regionMatchesCI_Latin1(byte[] value, int toffset,
+ byte[] other, int ooffset,
+ int len) {
+ int last = toffset + len;
+ while (toffset < last) {
+ char c1 = getChar(value, toffset++);
+ char c2 = (char)(other[ooffset++] & 0xff);
+ if (c1 == c2) {
+ continue;
+ }
+ char u1 = Character.toUpperCase(c1);
+ char u2 = Character.toUpperCase(c2);
+ if (u1 == u2) {
+ continue;
+ }
+ if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
+ continue;
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public static String toLowerCase(String str, byte[] value, Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException();
+ }
+ int first;
+ boolean hasSurr = false;
+ final int len = value.length >> 1;
+
+ // Now check if there are any characters that need to be changed, or are surrogate
+ for (first = 0 ; first < len; first++) {
+ int cp = (int)getChar(value, first);
+ if (Character.isSurrogate((char)cp)) {
+ hasSurr = true;
+ break;
+ }
+ if (cp != Character.toLowerCase(cp)) { // no need to check Character.ERROR
+ break;
+ }
+ }
+ if (first == len)
+ return str;
+ byte[] result = new byte[value.length];
+ System.arraycopy(value, 0, result, 0, first << 1); // Just copy the first few
+ // lowerCase characters.
+ String lang = locale.getLanguage();
+ if (lang == "tr" || lang == "az" || lang == "lt") {
+ return toLowerCaseEx(str, value, result, first, locale, true);
+ }
+ if (hasSurr) {
+ return toLowerCaseEx(str, value, result, first, locale, false);
+ }
+ int bits = 0;
+ for (int i = first; i < len; i++) {
+ int cp = (int)getChar(value, i);
+ if (cp == '\u03A3' || // GREEK CAPITAL LETTER SIGMA
+ Character.isSurrogate((char)cp)) {
+ return toLowerCaseEx(str, value, result, i, locale, false);
+ }
+ if (cp == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
+ return toLowerCaseEx(str, value, result, i, locale, true);
+ }
+ cp = Character.toLowerCase(cp);
+ if (!Character.isBmpCodePoint(cp)) {
+ return toLowerCaseEx(str, value, result, i, locale, false);
+ }
+ bits |= cp;
+ putChar(result, i, cp);
+ }
+ if (bits >>> 8 != 0) {
+ return new String(result, UTF16);
+ } else {
+ return newString(result, 0, len);
+ }
+ }
+
+ private static String toLowerCaseEx(String str, byte[] value,
+ byte[] result, int first, Locale locale,
+ boolean localeDependent) {
+ int resultOffset = first;
+ int length = value.length >> 1;
+ int srcCount;
+ for (int i = first; i < length; i += srcCount) {
+ int srcChar = getChar(value, i);
+ int lowerChar;
+ char[] lowerCharArray;
+ srcCount = 1;
+ if (Character.isSurrogate((char)srcChar)) {
+ srcChar = codePointAt(value, i, length);
+ srcCount = Character.charCount(srcChar);
+ }
+ if (localeDependent ||
+ srcChar == '\u03A3' || // GREEK CAPITAL LETTER SIGMA
+ srcChar == '\u0130') { // LATIN CAPITAL LETTER I WITH DOT ABOVE
+ lowerChar = ConditionalSpecialCasing.toLowerCaseEx(str, i, locale);
+ } else {
+ lowerChar = Character.toLowerCase(srcChar);
+ }
+ if (Character.isBmpCodePoint(lowerChar)) { // Character.ERROR is not a bmp
+ putChar(result, resultOffset++, lowerChar);
+ } else {
+ if (lowerChar == Character.ERROR) {
+ lowerCharArray = ConditionalSpecialCasing.toLowerCaseCharArray(str, i, locale);
+ } else {
+ lowerCharArray = Character.toChars(lowerChar);
+ }
+ /* Grow result if needed */
+ int mapLen = lowerCharArray.length;
+ if (mapLen > srcCount) {
+ byte[] result2 = newBytesFor((result.length >> 1) + mapLen - srcCount);
+ System.arraycopy(result, 0, result2, 0, resultOffset << 1);
+ result = result2;
+ }
+ for (int x = 0; x < mapLen; ++x) {
+ putChar(result, resultOffset++, lowerCharArray[x]);
+ }
+ }
+ }
+ return newString(result, 0, resultOffset);
+ }
+
+ public static String toUpperCase(String str, byte[] value, Locale locale) {
+ if (locale == null) {
+ throw new NullPointerException();
+ }
+ int first;
+ boolean hasSurr = false;
+ final int len = value.length >> 1;
+
+ // Now check if there are any characters that need to be changed, or are surrogate
+ for (first = 0 ; first < len; first++) {
+ int cp = (int)getChar(value, first);
+ if (Character.isSurrogate((char)cp)) {
+ hasSurr = true;
+ break;
+ }
+ if (cp != Character.toUpperCaseEx(cp)) { // no need to check Character.ERROR
+ break;
+ }
+ }
+ if (first == len) {
+ return str;
+ }
+ byte[] result = new byte[value.length];
+ System.arraycopy(value, 0, result, 0, first << 1); // Just copy the first few
+ // upperCase characters.
+ String lang = locale.getLanguage();
+ if (lang == "tr" || lang == "az" || lang == "lt") {
+ return toUpperCaseEx(str, value, result, first, locale, true);
+ }
+ if (hasSurr) {
+ return toUpperCaseEx(str, value, result, first, locale, false);
+ }
+ int bits = 0;
+ for (int i = first; i < len; i++) {
+ int cp = (int)getChar(value, i);
+ if (Character.isSurrogate((char)cp)) {
+ return toUpperCaseEx(str, value, result, i, locale, false);
+ }
+ cp = Character.toUpperCaseEx(cp);
+ if (!Character.isBmpCodePoint(cp)) { // Character.ERROR is not bmp
+ return toUpperCaseEx(str, value, result, i, locale, false);
+ }
+ bits |= cp;
+ putChar(result, i, cp);
+ }
+ if (bits >>> 8 != 0) {
+ return new String(result, UTF16);
+ } else {
+ return newString(result, 0, len);
+ }
+ }
+
+ private static String toUpperCaseEx(String str, byte[] value,
+ byte[] result, int first,
+ Locale locale, boolean localeDependent)
+ {
+ int resultOffset = first;
+ int length = value.length >> 1;
+ int srcCount;
+ for (int i = first; i < length; i += srcCount) {
+ int srcChar = getChar(value, i);
+ int upperChar;
+ char[] upperCharArray;
+ srcCount = 1;
+ if (Character.isSurrogate((char)srcChar)) {
+ srcChar = codePointAt(value, i, length);
+ srcCount = Character.charCount(srcChar);
+ }
+ if (localeDependent) {
+ upperChar = ConditionalSpecialCasing.toUpperCaseEx(str, i, locale);
+ } else {
+ upperChar = Character.toUpperCaseEx(srcChar);
+ }
+ if (Character.isBmpCodePoint(upperChar)) {
+ putChar(result, resultOffset++, upperChar);
+ } else {
+ if (upperChar == Character.ERROR) {
+ if (localeDependent) {
+ upperCharArray =
+ ConditionalSpecialCasing.toUpperCaseCharArray(str, i, locale);
+ } else {
+ upperCharArray = Character.toUpperCaseCharArray(srcChar);
+ }
+ } else {
+ upperCharArray = Character.toChars(upperChar);
+ }
+ /* Grow result if needed */
+ int mapLen = upperCharArray.length;
+ if (mapLen > srcCount) {
+ byte[] result2 = newBytesFor((result.length >> 1) + mapLen - srcCount);
+ System.arraycopy(result, 0, result2, 0, resultOffset << 1);
+ result = result2;
+ }
+ for (int x = 0; x < mapLen; ++x) {
+ putChar(result, resultOffset++, upperCharArray[x]);
+ }
+ }
+ }
+ return newString(result, 0, resultOffset);
+ }
+
+ public static String trim(byte[] value) {
+ int length = value.length >> 1;
+ int len = length;
+ int st = 0;
+ while (st < len && getChar(value, st) <= ' ') {
+ st++;
+ }
+ while (st < len && getChar(value, len - 1) <= ' ') {
+ len--;
+ }
+ return ((st > 0) || (len < length )) ?
+ new String(Arrays.copyOfRange(value, st << 1, len << 1), UTF16) :
+ null;
+ }
+
+ public static void putChars(byte[] val, int index, char[] str, int off, int end) {
+ while (off < end) {
+ putChar(val, index++, str[off++]);
+ }
+ }
+
+ public static String newString(byte[] val, int index, int len) {
+ if (String.COMPACT_STRINGS) {
+ byte[] buf = compress(val, index, len);
+ if (buf != null) {
+ return new String(buf, LATIN1);
+ }
+ }
+ int last = index + len;
+ return new String(Arrays.copyOfRange(val, index << 1, last << 1), UTF16);
+ }
+
+ public static void fillNull(byte[] val, int index, int end) {
+ Arrays.fill(val, index << 1, end << 1, (byte)0);
+ }
+
+ static class CharsSpliterator implements Spliterator.OfInt {
+ private final byte[] array;
+ private int index; // current index, modified on advance/split
+ private final int fence; // one past last index
+ private final int cs;
+
+ CharsSpliterator(byte[] array, int acs) {
+ this(array, 0, array.length >> 1, acs);
+ }
+
+ CharsSpliterator(byte[] array, int origin, int fence, int acs) {
+ this.array = array;
+ this.index = origin;
+ this.fence = fence;
+ this.cs = acs | Spliterator.ORDERED | Spliterator.SIZED
+ | Spliterator.SUBSIZED;
+ }
+
+ @Override
+ public OfInt trySplit() {
+ int lo = index, mid = (lo + fence) >>> 1;
+ return (lo >= mid)
+ ? null
+ : new CharsSpliterator(array, lo, index = mid, cs);
+ }
+
+ @Override
+ public void forEachRemaining(IntConsumer action) {
+ byte[] a; int i, hi; // hoist accesses and checks from loop
+ if (action == null)
+ throw new NullPointerException();
+ if (((a = array).length >> 1) >= (hi = fence) &&
+ (i = index) >= 0 && i < (index = hi)) {
+ do { action.accept(getChar(a, i)); } while (++i < hi);
+ }
+ }
+
+ @Override
+ public boolean tryAdvance(IntConsumer action) {
+ if (action == null)
+ throw new NullPointerException();
+ if (index >= 0 && index < fence) {
+ action.accept(getChar(array, index++));
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public long estimateSize() { return (long)(fence - index); }
+
+ @Override
+ public int characteristics() {
+ return cs;
+ }
+ }
+
+ static class CodePointsSpliterator implements Spliterator.OfInt {
+ private final byte[] array;
+ private int index; // current index, modified on advance/split
+ private final int fence; // one past last index
+ private final int cs;
+
+ CodePointsSpliterator(byte[] array, int acs) {
+ this(array, 0, array.length >> 1, acs);
+ }
+
+ CodePointsSpliterator(byte[] array, int origin, int fence, int acs) {
+ this.array = array;
+ this.index = origin;
+ this.fence = fence;
+ this.cs = acs | Spliterator.ORDERED;
+ }
+
+ @Override
+ public OfInt trySplit() {
+ int lo = index, mid = (lo + fence) >>> 1;
+ if (lo >= mid)
+ return null;
+
+ int midOneLess;
+ // If the mid-point intersects a surrogate pair
+ if (Character.isLowSurrogate(getChar(array, mid)) &&
+ Character.isHighSurrogate(getChar(array, midOneLess = (mid -1)))) {
+ // If there is only one pair it cannot be split
+ if (lo >= midOneLess)
+ return null;
+ // Shift the mid-point to align with the surrogate pair
+ return new CodePointsSpliterator(array, lo, index = midOneLess, cs);
+ }
+ return new CodePointsSpliterator(array, lo, index = mid, cs);
+ }
+
+ @Override
+ public void forEachRemaining(IntConsumer action) {
+ byte[] a; int i, hi; // hoist accesses and checks from loop
+ if (action == null)
+ throw new NullPointerException();
+ if (((a = array).length >> 1) >= (hi = fence) &&
+ (i = index) >= 0 && i < (index = hi)) {
+ do {
+ i = advance(a, i, hi, action);
+ } while (i < hi);
+ }
+ }
+
+ @Override
+ public boolean tryAdvance(IntConsumer action) {
+ if (action == null)
+ throw new NullPointerException();
+ if (index >= 0 && index < fence) {
+ index = advance(array, index, fence, action);
+ return true;
+ }
+ return false;
+ }
+
+ // Advance one code point from the index, i, and return the next
+ // index to advance from
+ private static int advance(byte[] a, int i, int hi, IntConsumer action) {
+ char c1 = getChar(a, i++);
+ int cp = c1;
+ if (Character.isHighSurrogate(c1) && i < hi) {
+ char c2 = getChar(a, i);
+ if (Character.isLowSurrogate(c2)) {
+ i++;
+ cp = Character.toCodePoint(c1, c2);
+ }
+ }
+ action.accept(cp);
+ return i;
+ }
+
+ @Override
+ public long estimateSize() { return (long)(fence - index); }
+
+ @Override
+ public int characteristics() {
+ return cs;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////
+
+ public static void getCharsSB(byte[] val, int srcBegin, int srcEnd, char dst[], int dstBegin) {
+ checkOffset(srcEnd, val.length >> 1);
+ getChars(val, srcBegin, srcEnd, dst, dstBegin);
+ }
+
+ public static void putCharSB(byte[] val, int index, int c) {
+ checkIndex(index, val.length >> 1);
+ putChar(val, index, c);
+ }
+
+ public static void putCharsSB(byte[] val, int index, char[] ca, int off, int end) {
+ checkOffset(index + end - off, val.length >> 1);
+ putChars(val, index, ca, off, end);
+ }
+
+ public static void putCharsSB(byte[] val, int index, CharSequence s, int off, int end) {
+ checkOffset(index + end - off, val.length >> 1);
+ for (int i = off; i < end; i++) {
+ putChar(val, index++, s.charAt(i));
+ }
+ }
+
+ public static int codePointAtSB(byte[] val, int index, int end) {
+ checkOffset(end, val.length >> 1);
+ return codePointAt(val, index, end);
+ }
+
+ public static int codePointBeforeSB(byte[] val, int index) {
+ checkOffset(index, val.length >> 1);
+ return codePointBefore(val, index);
+ }
+
+ public static int codePointCountSB(byte[] val, int beginIndex, int endIndex) {
+ checkOffset(endIndex, val.length >> 1);
+ return codePointCount(val, beginIndex, endIndex);
+ }
+
+ public static String newStringSB(byte[] val, int index, int len) {
+ checkOffset(index + len, val.length >> 1);
+ return newString(val, index, len);
+ }
+
+ ////////////////////////////////////////////////////////////////
+
+ private static native boolean isBigEndian();
+
+ static final int HI_BYTE_SHIFT;
+ static final int LO_BYTE_SHIFT;
+ static {
+ if (isBigEndian()) {
+ HI_BYTE_SHIFT = 8;
+ LO_BYTE_SHIFT = 0;
+ } else {
+ HI_BYTE_SHIFT = 0;
+ LO_BYTE_SHIFT = 8;
+ }
+ }
+
+ static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;
+}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/BoundMethodHandle.java Wed Jul 05 21:00:20 2017 +0200
@@ -34,14 +34,16 @@
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Field;
import java.util.Arrays;
-import java.util.HashMap;
+import java.util.function.Function;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ConcurrentHashMap;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
import sun.invoke.util.ValueConversions;
import sun.invoke.util.Wrapper;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
-import jdk.internal.org.objectweb.asm.Type;
/**
* The flavor of method handle which emulates an invoke instruction
@@ -217,7 +219,7 @@
/*non-public*/ int fieldCount() {
return 1;
}
- /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
+ /*non-public*/ static final SpeciesData SPECIES_DATA = new SpeciesData("L", Species_L.class);
/*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) {
return new Species_L(mt, lf, argL0);
}
@@ -335,7 +337,7 @@
static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
- private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
+ SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
this.typeChars = types;
this.typeCodes = basicTypes(types);
this.clazz = clazz;
@@ -355,26 +357,14 @@
assert(!INIT_DONE);
if (constructor() == null) {
String types = typeChars;
+ CACHE.put(types, this);
Factory.makeCtors(clazz, types, this.constructor);
Factory.makeGetters(clazz, types, this.getters);
Factory.makeNominalGetters(types, this.nominalGetters, this.getters);
}
}
- private SpeciesData(String typeChars) {
- // Placeholder only.
- this.typeChars = typeChars;
- this.typeCodes = basicTypes(typeChars);
- this.clazz = null;
- this.constructor = null;
- this.getters = null;
- this.nominalGetters = null;
- this.extensions = null;
- }
- private boolean isPlaceholder() { return clazz == null; }
-
- private static final HashMap<String, SpeciesData> CACHE = new HashMap<>();
- static { CACHE.put("", EMPTY); } // make bootstrap predictable
+ private static final ConcurrentMap<String, SpeciesData> CACHE = new ConcurrentHashMap<>();
private static final boolean INIT_DONE; // set after <clinit> finishes...
SpeciesData extendWith(byte type) {
@@ -390,62 +380,52 @@
}
private static SpeciesData get(String types) {
- // Acquire cache lock for query.
- SpeciesData d = lookupCache(types);
- if (!d.isPlaceholder())
- return d;
- synchronized (d) {
- // Use synch. on the placeholder to prevent multiple instantiation of one species.
- // Creating this class forces a recursive call to getForClass.
- if (lookupCache(types).isPlaceholder())
- Factory.generateConcreteBMHClass(types);
- }
- // Reacquire cache lock.
- d = lookupCache(types);
- // Class loading must have upgraded the cache.
- assert(d != null && !d.isPlaceholder());
- return d;
- }
- static SpeciesData getForClass(String types, Class<? extends BoundMethodHandle> clazz) {
- // clazz is a new class which is initializing its SPECIES_DATA field
- return updateCache(types, new SpeciesData(types, clazz));
- }
- private static synchronized SpeciesData lookupCache(String types) {
- SpeciesData d = CACHE.get(types);
- if (d != null) return d;
- d = new SpeciesData(types);
- assert(d.isPlaceholder());
- CACHE.put(types, d);
- return d;
- }
- private static synchronized SpeciesData updateCache(String types, SpeciesData d) {
- SpeciesData d2;
- assert((d2 = CACHE.get(types)) == null || d2.isPlaceholder());
- assert(!d.isPlaceholder());
- CACHE.put(types, d);
- return d;
+ return CACHE.computeIfAbsent(types, new Function<String, SpeciesData>() {
+ @Override
+ public SpeciesData apply(String types) {
+ Class<? extends BoundMethodHandle> bmhcl = Factory.getConcreteBMHClass(types);
+ // SpeciesData instantiation may throw VirtualMachineError because of
+ // code cache overflow...
+ SpeciesData speciesData = new SpeciesData(types, bmhcl);
+ // CHM.computeIfAbsent ensures only one SpeciesData will be set
+ // successfully on the concrete BMH class if ever
+ Factory.setSpeciesDataToConcreteBMHClass(bmhcl, speciesData);
+ // the concrete BMH class is published via SpeciesData instance
+ // returned here only after it's SPECIES_DATA field is set
+ return speciesData;
+ }
+ });
}
- static {
- // pre-fill the BMH speciesdata cache with BMH's inner classes
- final Class<BoundMethodHandle> rootCls = BoundMethodHandle.class;
+ /**
+ * This is to be called when assertions are enabled. It checks whether SpeciesData for all of the statically
+ * defined species subclasses of BoundMethodHandle has been added to the SpeciesData cache. See below in the
+ * static initializer for
+ */
+ static boolean speciesDataCachePopulated() {
+ Class<BoundMethodHandle> rootCls = BoundMethodHandle.class;
try {
for (Class<?> c : rootCls.getDeclaredClasses()) {
if (rootCls.isAssignableFrom(c)) {
final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
- SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh);
+ SpeciesData d = Factory.getSpeciesDataFromConcreteBMHClass(cbmh);
assert(d != null) : cbmh.getName();
assert(d.clazz == cbmh);
- assert(d == lookupCache(d.typeChars));
+ assert(CACHE.get(d.typeChars) == d);
}
}
} catch (Throwable e) {
throw newInternalError(e);
}
+ return true;
+ }
- for (SpeciesData d : CACHE.values()) {
- d.initForBootstrap();
- }
+ static {
+ // Pre-fill the BMH species-data cache with EMPTY and all BMH's inner subclasses.
+ EMPTY.initForBootstrap();
+ Species_L.SPECIES_DATA.initForBootstrap();
+ // check that all static SpeciesData instances have been initialized
+ assert speciesDataCachePopulated();
// Note: Do not simplify this, because INIT_DONE must not be
// a compile-time constant during bootstrapping.
INIT_DONE = Boolean.TRUE;
@@ -479,6 +459,7 @@
static final String BMH_SIG = "L"+BMH+";";
static final String SPECIES_DATA = "java/lang/invoke/BoundMethodHandle$SpeciesData";
static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
+ static final String STABLE_SIG = "Ljava/lang/invoke/Stable;";
static final String SPECIES_PREFIX_NAME = "Species_";
static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
@@ -493,6 +474,26 @@
static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
+ static final ConcurrentMap<String, Class<? extends BoundMethodHandle>> CLASS_CACHE = new ConcurrentHashMap<>();
+
+ /**
+ * Get a concrete subclass of BMH for a given combination of bound types.
+ *
+ * @param types the type signature, wherein reference types are erased to 'L'
+ * @return the concrete BMH class
+ */
+ static Class<? extends BoundMethodHandle> getConcreteBMHClass(String types) {
+ // CHM.computeIfAbsent ensures generateConcreteBMHClass is called
+ // only once per key.
+ return CLASS_CACHE.computeIfAbsent(
+ types, new Function<String, Class<? extends BoundMethodHandle>>() {
+ @Override
+ public Class<? extends BoundMethodHandle> apply(String types) {
+ return generateConcreteBMHClass(types);
+ }
+ });
+ }
+
/**
* Generate a concrete subclass of BMH for a given combination of bound types.
*
@@ -529,7 +530,7 @@
* }
* final SpeciesData speciesData() { return SPECIES_DATA; }
* final int fieldCount() { return 3; }
- * static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
+ * @Stable static SpeciesData SPECIES_DATA; // injected afterwards
* static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
* return new Species_LLI(mt, lf, argL0, argL1, argI2);
* }
@@ -568,7 +569,9 @@
cw.visitSource(sourceFile, null);
// emit static types and SPECIES_DATA fields
- cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
+ FieldVisitor fw = cw.visitField(NOT_ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null);
+ fw.visitAnnotation(STABLE_SIG, true);
+ fw.visitEnd();
// emit bound argument fields
for (int i = 0; i < types.length(); ++i) {
@@ -694,17 +697,6 @@
mv.visitEnd();
}
- // emit class initializer
- mv = cw.visitMethod(NOT_ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
- mv.visitCode();
- mv.visitLdcInsn(types);
- mv.visitLdcInsn(Type.getObjectType(className));
- mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG, false);
- mv.visitFieldInsn(PUTSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
- mv.visitInsn(RETURN);
- mv.visitMaxs(0, 0);
- mv.visitEnd();
-
cw.visitEnd();
// load class
@@ -715,7 +707,6 @@
UNSAFE.defineClass(className, classFile, 0, classFile.length,
BoundMethodHandle.class.getClassLoader(), null)
.asSubclass(BoundMethodHandle.class);
- UNSAFE.ensureClassInitialized(bmhClass);
return bmhClass;
}
@@ -785,7 +776,7 @@
// Auxiliary methods.
//
- static SpeciesData speciesDataFromConcreteBMHClass(Class<? extends BoundMethodHandle> cbmh) {
+ static SpeciesData getSpeciesDataFromConcreteBMHClass(Class<? extends BoundMethodHandle> cbmh) {
try {
Field F_SPECIES_DATA = cbmh.getDeclaredField("SPECIES_DATA");
return (SpeciesData) F_SPECIES_DATA.get(null);
@@ -794,6 +785,16 @@
}
}
+ static void setSpeciesDataToConcreteBMHClass(Class<? extends BoundMethodHandle> cbmh, SpeciesData speciesData) {
+ try {
+ Field F_SPECIES_DATA = cbmh.getDeclaredField("SPECIES_DATA");
+ assert F_SPECIES_DATA.getDeclaredAnnotation(Stable.class) != null;
+ F_SPECIES_DATA.set(null, speciesData);
+ } catch (ReflectiveOperationException ex) {
+ throw newInternalError(ex);
+ }
+ }
+
/**
* Field names in concrete BMHs adhere to this pattern:
* arg + type + index
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,7 +25,7 @@
package java.lang.invoke;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import java.lang.reflect.Method;
import java.util.Arrays;
import sun.invoke.util.VerifyAccess;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
import jdk.internal.org.objectweb.asm.*;
import sun.invoke.util.BytecodeDescriptor;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.security.action.GetPropertyAction;
import java.io.FilePermission;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Jul 05 21:00:20 2017 +0200
@@ -775,7 +775,7 @@
// Sample classes from each package we are willing to bind to statically:
java.lang.Object.class,
java.util.Arrays.class,
- sun.misc.Unsafe.class
+ jdk.internal.misc.Unsafe.class
//MethodHandle.class already covered
};
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MemberName.java Wed Jul 05 21:00:20 2017 +0200
@@ -694,8 +694,11 @@
@Override
public int hashCode() {
- return Objects.hash(clazz, getReferenceKind(), name, getType());
+ // Avoid autoboxing getReferenceKind(), since this is used early and will force
+ // early initialization of Byte$ByteCache
+ return Objects.hash(clazz, new Byte(getReferenceKind()), name, getType());
}
+
@Override
public boolean equals(Object that) {
return (that instanceof MemberName && this.equals((MemberName)that));
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Jul 05 21:00:20 2017 +0200
@@ -50,7 +50,7 @@
static native int getMembers(Class<?> defc, String matchName, String matchSig,
int matchFlags, Class<?> caller, int skip, MemberName[] results);
- /// Field layout queries parallel to sun.misc.Unsafe:
+ /// Field layout queries parallel to jdk.internal.misc.Unsafe:
static native long objectFieldOffset(MemberName self); // e.g., returns vmindex
static native long staticFieldOffset(MemberName self); // e.g., returns vmindex
static native Object staticFieldBase(MemberName self); // e.g., returns clazz
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* This class consists exclusively of static names internal to the
--- a/jdk/src/java.base/share/classes/java/math/BigDecimal.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/math/BigDecimal.java Wed Jul 05 21:00:20 2017 +0200
@@ -3726,12 +3726,12 @@
}
private static class UnsafeHolder {
- private static final sun.misc.Unsafe unsafe;
+ private static final jdk.internal.misc.Unsafe unsafe;
private static final long intCompactOffset;
private static final long intValOffset;
static {
try {
- unsafe = sun.misc.Unsafe.getUnsafe();
+ unsafe = jdk.internal.misc.Unsafe.getUnsafe();
intCompactOffset = unsafe.objectFieldOffset
(BigDecimal.class.getDeclaredField("intCompact"));
intValOffset = unsafe.objectFieldOffset
--- a/jdk/src/java.base/share/classes/java/math/BigInteger.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/math/BigInteger.java Wed Jul 05 21:00:20 2017 +0200
@@ -4526,12 +4526,12 @@
// Support for resetting final fields while deserializing
private static class UnsafeHolder {
- private static final sun.misc.Unsafe unsafe;
+ private static final jdk.internal.misc.Unsafe unsafe;
private static final long signumOffset;
private static final long magOffset;
static {
try {
- unsafe = sun.misc.Unsafe.getUnsafe();
+ unsafe = jdk.internal.misc.Unsafe.getUnsafe();
signumOffset = unsafe.objectFieldOffset
(BigInteger.class.getDeclaredField("signum"));
magOffset = unsafe.objectFieldOffset
--- a/jdk/src/java.base/share/classes/java/net/Inet6Address.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/Inet6Address.java Wed Jul 05 21:00:20 2017 +0200
@@ -576,11 +576,11 @@
};
private static final long FIELDS_OFFSET;
- private static final sun.misc.Unsafe UNSAFE;
+ private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
- sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
Inet6Address.class.getDeclaredField("holder6"));
UNSAFE = unsafe;
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,6 +29,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
+import java.util.Objects;
import java.util.ServiceLoader;
import java.security.AccessController;
import java.io.ObjectStreamException;
@@ -733,7 +734,7 @@
*/
public String toString() {
String hostName = holder().getHostName();
- return ((hostName != null) ? hostName : "")
+ return Objects.toString(hostName, "")
+ "/" + getHostAddress();
}
@@ -1493,11 +1494,11 @@
}
private static final long FIELDS_OFFSET;
- private static final sun.misc.Unsafe UNSAFE;
+ private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
- sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
InetAddress.class.getDeclaredField("holder")
);
--- a/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/InetSocketAddress.java Wed Jul 05 21:00:20 2017 +0200
@@ -303,10 +303,10 @@
}
private static final long FIELDS_OFFSET;
- private static final sun.misc.Unsafe UNSAFE;
+ private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
- sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
InetSocketAddress.class.getDeclaredField("holder"));
UNSAFE = unsafe;
--- a/jdk/src/java.base/share/classes/java/net/SocketOptions.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/SocketOptions.java Wed Jul 05 21:00:20 2017 +0200
@@ -61,21 +61,21 @@
* If the requested option is binary, it can be set using this method by
* a java.lang.Boolean:
* <BR><PRE>
- * s.setOption(TCP_NODELAY, new Boolean(true));
+ * s.setOption(TCP_NODELAY, Boolean.TRUE);
* // OK - enables TCP_NODELAY, a binary option
* </PRE>
* <BR>
- * Any option can be disabled using this method with a Boolean(false):
+ * Any option can be disabled using this method with a Boolean.FALSE:
* <BR><PRE>
- * s.setOption(TCP_NODELAY, new Boolean(false));
+ * s.setOption(TCP_NODELAY, Boolean.FALSE);
* // OK - disables TCP_NODELAY
- * s.setOption(SO_LINGER, new Boolean(false));
+ * s.setOption(SO_LINGER, Boolean.FALSE);
* // OK - disables SO_LINGER
* </PRE>
* <BR>
* For an option that has a notion of on and off, and requires
* a non-boolean parameter, setting its value to anything other than
- * <I>Boolean(false)</I> implicitly enables it.
+ * <I>Boolean.FALSE</I> implicitly enables it.
* <BR>
* Throws SocketException if the option is unrecognized,
* the socket is closed, or some low-level error occurred
@@ -91,8 +91,8 @@
/**
* Fetch the value of an option.
- * Binary options will return java.lang.Boolean(true)
- * if enabled, java.lang.Boolean(false) if disabled, e.g.:
+ * Binary options will return java.lang.Boolean.TRUE
+ * if enabled, java.lang.Boolean.FALSE if disabled, e.g.:
* <BR><PRE>
* SocketImpl s;
* ...
@@ -105,13 +105,13 @@
* <P>
* For options that take a particular type as a parameter,
* getOption(int) will return the parameter's value, else
- * it will return java.lang.Boolean(false):
+ * it will return java.lang.Boolean.FALSE:
* <PRE>
* Object o = s.getOption(SO_LINGER);
* if (o instanceof Integer) {
* System.out.print("Linger time is " + ((Integer)o).intValue());
* } else {
- * // the true type of o is java.lang.Boolean(false);
+ * // the true type of o is java.lang.Boolean.FALSE;
* }
* </PRE>
*
--- a/jdk/src/java.base/share/classes/java/net/URLConnection.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/net/URLConnection.java Wed Jul 05 21:00:20 2017 +0200
@@ -32,6 +32,7 @@
import java.util.Hashtable;
import java.util.Date;
import java.util.Iterator;
+import java.util.Objects;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.StringTokenizer;
@@ -1250,7 +1251,7 @@
if (handler != null) {
ContentHandler h = handlers.putIfAbsent(contentType, handler);
- return h != null ? h : handler;
+ return Objects.requireNonNullElse(h, handler);
}
try {
@@ -1263,7 +1264,7 @@
assert handler != null;
ContentHandler h = handlers.putIfAbsent(contentType, handler);
- return h != null ? h : handler;
+ return Objects.requireNonNullElse(h, handler);
}
/*
--- a/jdk/src/java.base/share/classes/java/nio/Bits.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/nio/Bits.java Wed Jul 05 21:00:20 2017 +0200
@@ -32,7 +32,7 @@
import jdk.internal.misc.JavaNioAccess;
import jdk.internal.misc.JavaLangRefAccess;
import jdk.internal.misc.SharedSecrets;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.misc.VM;
/**
--- a/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template Wed Jul 05 21:00:20 2017 +0200
@@ -29,7 +29,7 @@
import java.io.FileDescriptor;
import sun.misc.Cleaner;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.misc.VM;
import sun.nio.ch.DirectBuffer;
--- a/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
package java.nio;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
#if[rw]
@@ -477,7 +477,7 @@
#if[rw]
public float getFloat() {
- int x = unsafe.getIntUnaligned(hb, byteOffset(nextPutIndex(4)), bigEndian);
+ int x = unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
return Float.intBitsToFloat(x);
}
--- a/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/nio/MappedByteBuffer.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,7 +26,7 @@
package java.nio;
import java.io.FileDescriptor;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
--- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java Wed Jul 05 21:00:20 2017 +0200
@@ -37,6 +37,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Objects;
import java.util.Set;
import java.util.ServiceLoader;
import java.util.ServiceConfigurationError;
@@ -625,6 +626,7 @@
private final String name; // tickles a bug in oldjavac
private final String[] aliases; // tickles a bug in oldjavac
+ private final String[] zeroAliases = new String[0];
private Set<String> aliasSet = null;
/**
@@ -642,7 +644,7 @@
*/
protected Charset(String canonicalName, String[] aliases) {
checkName(canonicalName);
- String[] as = (aliases == null) ? new String[0] : aliases;
+ String[] as = Objects.requireNonNullElse(aliases, zeroAliases);
for (int i = 0; i < as.length; i++)
checkName(as[i]);
this.name = canonicalName;
--- a/jdk/src/java.base/share/classes/java/security/SecureRandom.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandom.java Wed Jul 05 21:00:20 2017 +0200
@@ -419,7 +419,7 @@
* @since 1.5
*/
public String getAlgorithm() {
- return (algorithm != null) ? algorithm : "unknown";
+ return Objects.toString(algorithm, "unknown");
}
/**
--- a/jdk/src/java.base/share/classes/java/time/ZoneId.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/ZoneId.java Wed Jul 05 21:00:20 2017 +0200
@@ -310,8 +310,7 @@
public static ZoneId of(String zoneId, Map<String, String> aliasMap) {
Objects.requireNonNull(zoneId, "zoneId");
Objects.requireNonNull(aliasMap, "aliasMap");
- String id = aliasMap.get(zoneId);
- id = (id != null ? id : zoneId);
+ String id = Objects.requireNonNullElse(aliasMap.get(zoneId), zoneId);
return of(id);
}
--- a/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/chrono/Chronology.java Wed Jul 05 21:00:20 2017 +0200
@@ -177,7 +177,7 @@
static Chronology from(TemporalAccessor temporal) {
Objects.requireNonNull(temporal, "temporal");
Chronology obj = temporal.query(TemporalQueries.chronology());
- return (obj != null ? obj : IsoChronology.INSTANCE);
+ return Objects.requireNonNullElse(obj, IsoChronology.INSTANCE);
}
//-----------------------------------------------------------------------
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java Wed Jul 05 21:00:20 2017 +0200
@@ -2892,7 +2892,8 @@
@Override
public String toString() {
- return "ReducedValue(" + field + "," + minWidth + "," + maxWidth + "," + (baseDate != null ? baseDate : baseValue) + ")";
+ return "ReducedValue(" + field + "," + minWidth + "," + maxWidth +
+ "," + Objects.requireNonNullElse(baseDate, baseValue) + ")";
}
}
@@ -3851,6 +3852,10 @@
return parseOffsetBased(context, text, position, position + 2, OffsetIdPrinterParser.INSTANCE_ID_ZERO);
} else if (context.charEquals(nextChar, 'G') && length >= position + 3 &&
context.charEquals(nextNextChar, 'M') && context.charEquals(text.charAt(position + 2), 'T')) {
+ if (length >= position + 4 && context.charEquals(text.charAt(position + 3), '0')) {
+ context.setParsed(ZoneId.of("GMT0"));
+ return position + 4;
+ }
return parseOffsetBased(context, text, position, position + 3, OffsetIdPrinterParser.INSTANCE_ID_ZERO);
}
}
@@ -4328,7 +4333,7 @@
private String getChronologyName(Chronology chrono, Locale locale) {
String key = "calendarname." + chrono.getCalendarType();
String name = DateTimeTextProvider.getLocalizedResource(key, locale);
- return name != null ? name : chrono.getId();
+ return Objects.requireNonNullElseGet(name, () -> chrono.getId());
}
}
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimePrintContext.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimePrintContext.java Wed Jul 05 21:00:20 2017 +0200
@@ -146,7 +146,7 @@
if (overrideZone != null) {
// if have zone and instant, calculation is simple, defaulting chrono if necessary
if (temporal.isSupported(INSTANT_SECONDS)) {
- Chronology chrono = (effectiveChrono != null ? effectiveChrono : IsoChronology.INSTANCE);
+ Chronology chrono = Objects.requireNonNullElse(effectiveChrono, IsoChronology.INSTANCE);
return chrono.zonedDateTime(Instant.from(temporal), overrideZone);
}
// block changing zone on OffsetTime, and similar problem cases
--- a/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/time/temporal/IsoFields.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -102,7 +102,7 @@
* The complete date is expressed using three fields:
* <ul>
* <li>{@link #DAY_OF_QUARTER DAY_OF_QUARTER} - the day within the quarter, from 1 to 90, 91 or 92
- * <li>{@link #QUARTER_OF_YEAR QUARTER_OF_YEAR} - the week within the week-based-year
+ * <li>{@link #QUARTER_OF_YEAR QUARTER_OF_YEAR} - the quarter within the year, from 1 to 4
* <li>{@link ChronoField#YEAR YEAR} - the standard ISO year
* </ul>
*
@@ -571,9 +571,6 @@
//-------------------------------------------------------------------------
private static final int[] QUARTER_DAYS = {0, 90, 181, 273, 0, 91, 182, 274};
- private static boolean isIso(TemporalAccessor temporal) {
- return Chronology.from(temporal).equals(IsoChronology.INSTANCE);
- }
private static void ensureIso(TemporalAccessor temporal) {
if (isIso(temporal) == false) {
@@ -681,7 +678,7 @@
@Override
public boolean isSupportedBy(Temporal temporal) {
- return temporal.isSupported(EPOCH_DAY);
+ return temporal.isSupported(EPOCH_DAY) && isIso(temporal);
}
@SuppressWarnings("unchecked")
@@ -721,4 +718,8 @@
return name;
}
}
+
+ static boolean isIso(TemporalAccessor temporal) {
+ return Chronology.from(temporal).equals(IsoChronology.INSTANCE);
+ }
}
--- a/jdk/src/java.base/share/classes/java/util/Arrays.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Arrays.java Wed Jul 05 21:00:20 2017 +0200
@@ -2882,6 +2882,7 @@
* @param a2 the other array to be tested for equality
* @return {@code true} if the two arrays are equal
*/
+ @HotSpotIntrinsicCandidate
public static boolean equals(byte[] a, byte[] a2) {
if (a==a2)
return true;
--- a/jdk/src/java.base/share/classes/java/util/Collections.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Collections.java Wed Jul 05 21:00:20 2017 +0200
@@ -2090,7 +2090,8 @@
* through the returned set.<p>
*
* It is imperative that the user manually synchronize on the returned
- * set when iterating over it:
+ * collection when traversing it via {@link Iterator}, {@link Spliterator}
+ * or {@link Stream}:
* <pre>
* Set s = Collections.synchronizedSet(new HashSet());
* ...
@@ -2149,8 +2150,9 @@
* through the returned sorted set (or its views).<p>
*
* It is imperative that the user manually synchronize on the returned
- * sorted set when iterating over it or any of its {@code subSet},
- * {@code headSet}, or {@code tailSet} views.
+ * sorted set when traversing it or any of its {@code subSet},
+ * {@code headSet}, or {@code tailSet} views via {@link Iterator},
+ * {@link Spliterator} or {@link Stream}:
* <pre>
* SortedSet s = Collections.synchronizedSortedSet(new TreeSet());
* ...
@@ -2240,8 +2242,9 @@
* accomplished through the returned navigable set (or its views).<p>
*
* It is imperative that the user manually synchronize on the returned
- * navigable set when iterating over it or any of its {@code subSet},
- * {@code headSet}, or {@code tailSet} views.
+ * navigable set when traversing it, or any of its {@code subSet},
+ * {@code headSet}, or {@code tailSet} views, via {@link Iterator},
+ * {@link Spliterator} or {@link Stream}:
* <pre>
* NavigableSet s = Collections.synchronizedNavigableSet(new TreeSet());
* ...
@@ -2355,7 +2358,8 @@
* through the returned list.<p>
*
* It is imperative that the user manually synchronize on the returned
- * list when iterating over it:
+ * list when traversing it via {@link Iterator}, {@link Spliterator}
+ * or {@link Stream}:
* <pre>
* List list = Collections.synchronizedList(new ArrayList());
* ...
@@ -2523,7 +2527,8 @@
* through the returned map.<p>
*
* It is imperative that the user manually synchronize on the returned
- * map when iterating over any of its collection views:
+ * map when traversing any of its collection views via {@link Iterator},
+ * {@link Spliterator} or {@link Stream}:
* <pre>
* Map m = Collections.synchronizedMap(new HashMap());
* ...
@@ -2700,9 +2705,10 @@
* through the returned sorted map (or its views).<p>
*
* It is imperative that the user manually synchronize on the returned
- * sorted map when iterating over any of its collection views, or the
+ * sorted map when traversing any of its collection views, or the
* collections views of any of its {@code subMap}, {@code headMap} or
- * {@code tailMap} views.
+ * {@code tailMap} views, via {@link Iterator}, {@link Spliterator} or
+ * {@link Stream}:
* <pre>
* SortedMap m = Collections.synchronizedSortedMap(new TreeMap());
* ...
@@ -2797,9 +2803,10 @@
* accomplished through the returned navigable map (or its views).<p>
*
* It is imperative that the user manually synchronize on the returned
- * navigable map when iterating over any of its collection views, or the
+ * navigable map when traversing any of its collection views, or the
* collections views of any of its {@code subMap}, {@code headMap} or
- * {@code tailMap} views.
+ * {@code tailMap} views, via {@link Iterator}, {@link Spliterator} or
+ * {@link Stream}:
* <pre>
* NavigableMap m = Collections.synchronizedNavigableMap(new TreeMap());
* ...
--- a/jdk/src/java.base/share/classes/java/util/Formatter.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Formatter.java Wed Jul 05 21:00:20 2017 +0200
@@ -49,6 +49,7 @@
import java.text.NumberFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.Objects;
import java.time.DateTimeException;
import java.time.Instant;
@@ -3860,7 +3861,7 @@
ampm = dfs.getAmPmStrings();
}
String s = ampm[t.get(Calendar.AM_PM)];
- sb.append(s.toLowerCase(l != null ? l : Locale.US));
+ sb.append(s.toLowerCase(Objects.requireNonNullElse(l, Locale.US)));
break;
}
case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?)
@@ -3893,7 +3894,7 @@
TimeZone tz = t.getTimeZone();
sb.append(tz.getDisplayName((t.get(Calendar.DST_OFFSET) != 0),
TimeZone.SHORT,
- (l == null) ? Locale.US : l));
+ Objects.requireNonNullElse(l, Locale.US)));
break;
}
@@ -3901,7 +3902,7 @@
case DateTime.NAME_OF_DAY_ABBREV: // 'a'
case DateTime.NAME_OF_DAY: { // 'A'
int i = t.get(Calendar.DAY_OF_WEEK);
- Locale lt = ((l == null) ? Locale.US : l);
+ Locale lt = Objects.requireNonNullElse(l, Locale.US);
DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
if (c == DateTime.NAME_OF_DAY)
sb.append(dfs.getWeekdays()[i]);
@@ -3913,7 +3914,7 @@
case DateTime.NAME_OF_MONTH_ABBREV_X: // 'h' -- same b
case DateTime.NAME_OF_MONTH: { // 'B'
int i = t.get(Calendar.MONTH);
- Locale lt = ((l == null) ? Locale.US : l);
+ Locale lt = Objects.requireNonNullElse(l, Locale.US);
DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
if (c == DateTime.NAME_OF_MONTH)
sb.append(dfs.getMonths()[i]);
@@ -3984,7 +3985,7 @@
StringBuilder tsb = new StringBuilder();
print(tsb, t, DateTime.AM_PM, l);
- sb.append(tsb.toString().toUpperCase(l != null ? l : Locale.US));
+ sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l, Locale.US)));
break;
}
case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999)
@@ -4092,7 +4093,7 @@
ampm = dfs.getAmPmStrings();
}
String s = ampm[t.get(ChronoField.AMPM_OF_DAY)];
- sb.append(s.toLowerCase(l != null ? l : Locale.US));
+ sb.append(s.toLowerCase(Objects.requireNonNullElse(l, Locale.US)));
break;
}
case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?)
@@ -4131,7 +4132,7 @@
sb.append(TimeZone.getTimeZone(zid.getId())
.getDisplayName(zid.getRules().isDaylightSavings(instant),
TimeZone.SHORT,
- (l == null) ? Locale.US : l));
+ Objects.requireNonNullElse(l, Locale.US)));
break;
}
sb.append(zid.getId());
@@ -4141,7 +4142,7 @@
case DateTime.NAME_OF_DAY_ABBREV: // 'a'
case DateTime.NAME_OF_DAY: { // 'A'
int i = t.get(ChronoField.DAY_OF_WEEK) % 7 + 1;
- Locale lt = ((l == null) ? Locale.US : l);
+ Locale lt = Objects.requireNonNullElse(l, Locale.US);
DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
if (c == DateTime.NAME_OF_DAY)
sb.append(dfs.getWeekdays()[i]);
@@ -4153,7 +4154,7 @@
case DateTime.NAME_OF_MONTH_ABBREV_X: // 'h' -- same b
case DateTime.NAME_OF_MONTH: { // 'B'
int i = t.get(ChronoField.MONTH_OF_YEAR) - 1;
- Locale lt = ((l == null) ? Locale.US : l);
+ Locale lt = Objects.requireNonNullElse(l, Locale.US);
DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
if (c == DateTime.NAME_OF_MONTH)
sb.append(dfs.getMonths()[i]);
@@ -4223,7 +4224,7 @@
// this may be in wrong place for some locales
StringBuilder tsb = new StringBuilder();
print(tsb, t, DateTime.AM_PM, l);
- sb.append(tsb.toString().toUpperCase(l != null ? l : Locale.US));
+ sb.append(tsb.toString().toUpperCase(Objects.requireNonNullElse(l, Locale.US)));
break;
}
case DateTime.DATE_TIME: { // 'c' (Sat Nov 04 12:02:33 EST 1999)
--- a/jdk/src/java.base/share/classes/java/util/Objects.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Objects.java Wed Jul 05 21:00:20 2017 +0200
@@ -295,7 +295,7 @@
* {@code defaultObj} is {@code null}
* @since 9
*/
- public static <T> T nonNullElse(T obj, T defaultObj) {
+ public static <T> T requireNonNullElse(T obj, T defaultObj) {
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}
@@ -314,8 +314,9 @@
* the {@code supplier.get()} value is {@code null}
* @since 9
*/
- public static <T> T nonNullElseGet(T obj, Supplier<? extends T> supplier) {
- return (obj != null) ? obj : requireNonNull(requireNonNull(supplier, "supplier").get(), "supplier.get()");
+ public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier) {
+ return (obj != null) ? obj
+ : requireNonNull(requireNonNull(supplier, "supplier").get(), "supplier.get()");
}
/**
--- a/jdk/src/java.base/share/classes/java/util/Random.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Random.java Wed Jul 05 21:00:20 2017 +0200
@@ -34,7 +34,7 @@
import java.util.stream.LongStream;
import java.util.stream.StreamSupport;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* An instance of this class is used to generate a stream of
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CompletableFuture.java Wed Jul 05 21:00:20 2017 +0200
@@ -2775,7 +2775,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long RESULT;
private static final long STACK;
private static final long NEXT;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java Wed Jul 05 21:00:20 2017 +0200
@@ -297,7 +297,7 @@
* Table accesses require volatile/atomic reads, writes, and
* CASes. Because there is no other way to arrange this without
* adding further indirections, we use intrinsics
- * (sun.misc.Unsafe) operations.
+ * (jdk.internal.misc.Unsafe) operations.
*
* We use the top (sign) bit of Node hash fields for control
* purposes -- it is available anyway because of addressing
@@ -3287,7 +3287,7 @@
return true;
}
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long LOCKSTATE;
static {
try {
@@ -6330,7 +6330,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long SIZECTL;
private static final long TRANSFERINDEX;
private static final long BASECOUNT;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedDeque.java Wed Jul 05 21:00:20 2017 +0200
@@ -326,7 +326,7 @@
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long PREV;
private static final long ITEM;
private static final long NEXT;
@@ -1608,7 +1608,7 @@
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long HEAD;
private static final long TAIL;
static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentLinkedQueue.java Wed Jul 05 21:00:20 2017 +0200
@@ -929,7 +929,7 @@
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long HEAD;
private static final long TAIL;
private static final long ITEM;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java Wed Jul 05 21:00:20 2017 +0200
@@ -534,7 +534,7 @@
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE;
private static final long NEXT;
@@ -614,7 +614,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long RIGHT;
static {
try {
@@ -3596,7 +3596,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long HEAD;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java Wed Jul 05 21:00:20 2017 +0200
@@ -510,7 +510,7 @@
U.putObjectVolatile(this, MAP, map);
}
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long MAP;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java Wed Jul 05 21:00:20 2017 +0200
@@ -1545,7 +1545,7 @@
private void resetLock() {
U.putObjectVolatile(this, LOCK, new Object());
}
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long LOCK;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/CountedCompleter.java Wed Jul 05 21:00:20 2017 +0200
@@ -754,7 +754,7 @@
protected void setRawResult(T t) { }
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long PENDING;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Exchanger.java Wed Jul 05 21:00:20 2017 +0200
@@ -625,7 +625,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long BOUND;
private static final long SLOT;
private static final long MATCH;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java Wed Jul 05 21:00:20 2017 +0200
@@ -1337,7 +1337,7 @@
}
// Unsafe mechanics. Note that some are (and must be) the same as in FJP
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long QLOCK;
private static final int ABASE;
private static final int ASHIFT;
@@ -3452,7 +3452,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long CTL;
private static final long RUNSTATE;
private static final int ABASE;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java Wed Jul 05 21:00:20 2017 +0200
@@ -1517,7 +1517,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long STATUS;
static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java Wed Jul 05 21:00:20 2017 +0200
@@ -185,7 +185,7 @@
}
// Set up to allow setting thread fields in constructor
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long THREADLOCALS;
private static final long INHERITABLETHREADLOCALS;
private static final long INHERITEDACCESSCONTROLCONTEXT;
@@ -248,7 +248,7 @@
*/
private static ThreadGroup createThreadGroup() {
try {
- sun.misc.Unsafe u = sun.misc.Unsafe.getUnsafe();
+ jdk.internal.misc.Unsafe u = jdk.internal.misc.Unsafe.getUnsafe();
long tg = u.objectFieldOffset
(Thread.class.getDeclaredField("group"));
long gp = u.objectFieldOffset
--- a/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/FutureTask.java Wed Jul 05 21:00:20 2017 +0200
@@ -484,7 +484,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long STATE;
private static final long RUNNER;
private static final long WAITERS;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/LinkedTransferQueue.java Wed Jul 05 21:00:20 2017 +0200
@@ -538,7 +538,7 @@
private static final long serialVersionUID = -3375979862319811754L;
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long ITEM;
private static final long NEXT;
private static final long WAITER;
@@ -1564,7 +1564,7 @@
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long HEAD;
private static final long TAIL;
private static final long SWEEPVOTES;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/Phaser.java Wed Jul 05 21:00:20 2017 +0200
@@ -1137,7 +1137,7 @@
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long STATE;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java Wed Jul 05 21:00:20 2017 +0200
@@ -1010,7 +1010,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long ALLOCATIONSPINLOCK;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java Wed Jul 05 21:00:20 2017 +0200
@@ -1596,7 +1596,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long CTL;
private static final long TAIL;
private static final long HEAD;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java Wed Jul 05 21:00:20 2017 +0200
@@ -283,7 +283,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long MATCH;
private static final long NEXT;
@@ -509,7 +509,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long HEAD;
static {
try {
@@ -575,7 +575,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long ITEM;
private static final long NEXT;
@@ -817,7 +817,7 @@
}
}
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long HEAD;
private static final long TAIL;
private static final long CLEANME;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java Wed Jul 05 21:00:20 2017 +0200
@@ -1050,7 +1050,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java Wed Jul 05 21:00:20 2017 +0200
@@ -49,7 +49,7 @@
public class AtomicBoolean implements java.io.Serializable {
private static final long serialVersionUID = 4654671469794556979L;
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE;
static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java Wed Jul 05 21:00:20 2017 +0200
@@ -54,7 +54,7 @@
public class AtomicInteger extends Number implements java.io.Serializable {
private static final long serialVersionUID = 6214790243416807050L;
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE;
static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java Wed Jul 05 21:00:20 2017 +0200
@@ -49,7 +49,7 @@
public class AtomicIntegerArray implements java.io.Serializable {
private static final long serialVersionUID = 2862133569453604235L;
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final int ABASE;
private static final int ASHIFT;
private final int[] array;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java Wed Jul 05 21:00:20 2017 +0200
@@ -367,7 +367,7 @@
*/
private static class AtomicIntegerFieldUpdaterImpl<T>
extends AtomicIntegerFieldUpdater<T> {
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class<?> cclass;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java Wed Jul 05 21:00:20 2017 +0200
@@ -54,7 +54,7 @@
public class AtomicLong extends Number implements java.io.Serializable {
private static final long serialVersionUID = 1927816293512124184L;
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE;
/**
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java Wed Jul 05 21:00:20 2017 +0200
@@ -48,7 +48,7 @@
public class AtomicLongArray implements java.io.Serializable {
private static final long serialVersionUID = -2308431214976778248L;
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final int ABASE;
private static final int ASHIFT;
private final long[] array;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java Wed Jul 05 21:00:20 2017 +0200
@@ -366,7 +366,7 @@
}
private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class<?> cclass;
@@ -490,7 +490,7 @@
private static class LockedUpdater<T> extends AtomicLongFieldUpdater<T> {
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class<?> cclass;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicMarkableReference.java Wed Jul 05 21:00:20 2017 +0200
@@ -190,7 +190,7 @@
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long PAIR;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java Wed Jul 05 21:00:20 2017 +0200
@@ -49,7 +49,7 @@
public class AtomicReference<V> implements java.io.Serializable {
private static final long serialVersionUID = -1848883965231344442L;
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE;
static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java Wed Jul 05 21:00:20 2017 +0200
@@ -52,7 +52,7 @@
public class AtomicReferenceArray<E> implements java.io.Serializable {
private static final long serialVersionUID = -6209656149925076980L;
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long ARRAY;
private static final int ABASE;
private static final int ASHIFT;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Wed Jul 05 21:00:20 2017 +0200
@@ -284,7 +284,7 @@
private static final class AtomicReferenceFieldUpdaterImpl<T,V>
extends AtomicReferenceFieldUpdater<T,V> {
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class<V> vclass;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/AtomicStampedReference.java Wed Jul 05 21:00:20 2017 +0200
@@ -190,7 +190,7 @@
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long PAIR;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java Wed Jul 05 21:00:20 2017 +0200
@@ -133,7 +133,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE;
static {
try {
@@ -372,7 +372,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long BASE;
private static final long CELLSBUSY;
private static final long PROBE;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java Wed Jul 05 21:00:20 2017 +0200
@@ -1821,7 +1821,7 @@
* are at it, we do the same for other CASable fields (which could
* otherwise be done with atomic field updaters).
*/
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long STATE;
private static final long HEAD;
private static final long TAIL;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java Wed Jul 05 21:00:20 2017 +0200
@@ -524,7 +524,7 @@
return U.compareAndSwapObject(this, NEXT, expect, update);
}
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long NEXT;
static final long PREV;
private static final long THREAD;
@@ -2285,7 +2285,7 @@
* are at it, we do the same for other CASable fields (which could
* otherwise be done with atomic field updaters).
*/
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long STATE;
private static final long HEAD;
private static final long TAIL;
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java Wed Jul 05 21:00:20 2017 +0200
@@ -394,7 +394,7 @@
}
// Hotspot implementation via intrinsics API
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long PARKBLOCKER;
private static final long SECONDARY;
static {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java Wed Jul 05 21:00:20 2017 +0200
@@ -1501,7 +1501,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long TID;
static {
try {
--- a/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java Wed Jul 05 21:00:20 2017 +0200
@@ -1398,7 +1398,7 @@
}
// Unsafe mechanics
- private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
+ private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long STATE;
private static final long WHEAD;
private static final long WTAIL;
--- a/jdk/src/java.base/share/classes/java/util/zip/CRC32C.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/zip/CRC32C.java Wed Jul 05 21:00:20 2017 +0200
@@ -28,7 +28,7 @@
import java.nio.ByteOrder;
import jdk.internal.HotSpotIntrinsicCandidate;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
/**
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,7 +30,7 @@
import java.io.FileDescriptor;
import java.security.ProtectionDomain;
import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/** A repository of "shared secrets", which are a mechanism for
calling implementation-private methods in another package without
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,1391 @@
+/*
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.misc;
+
+import java.lang.reflect.Field;
+import java.security.ProtectionDomain;
+
+import sun.reflect.CallerSensitive;
+import sun.reflect.Reflection;
+import sun.misc.VM;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
+
+
+/**
+ * A collection of methods for performing low-level, unsafe operations.
+ * Although the class and all methods are public, use of this class is
+ * limited because only trusted code can obtain instances of it.
+ *
+ * @author John R. Rose
+ * @see #getUnsafe
+ */
+
+public final class Unsafe {
+
+ private static native void registerNatives();
+ static {
+ registerNatives();
+ sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
+ }
+
+ private Unsafe() {}
+
+ private static final Unsafe theUnsafe = new Unsafe();
+
+ /**
+ * Provides the caller with the capability of performing unsafe
+ * operations.
+ *
+ * <p>The returned {@code Unsafe} object should be carefully guarded
+ * by the caller, since it can be used to read and write data at arbitrary
+ * memory addresses. It must never be passed to untrusted code.
+ *
+ * <p>Most methods in this class are very low-level, and correspond to a
+ * small number of hardware instructions (on typical machines). Compilers
+ * are encouraged to optimize these methods accordingly.
+ *
+ * <p>Here is a suggested idiom for using unsafe operations:
+ *
+ * <pre> {@code
+ * class MyTrustedClass {
+ * private static final Unsafe unsafe = Unsafe.getUnsafe();
+ * ...
+ * private long myCountAddress = ...;
+ * public int getCount() { return unsafe.getByte(myCountAddress); }
+ * }}</pre>
+ *
+ * (It may assist compilers to make the local variable {@code final}.)
+ *
+ * @throws SecurityException if a security manager exists and its
+ * {@code checkPropertiesAccess} method doesn't allow
+ * access to the system properties.
+ */
+ @CallerSensitive
+ public static Unsafe getUnsafe() {
+ Class<?> caller = Reflection.getCallerClass();
+ if (!VM.isSystemDomainLoader(caller.getClassLoader()))
+ throw new SecurityException("Unsafe");
+ return theUnsafe;
+ }
+
+ /// peek and poke operations
+ /// (compilers should optimize these to memory ops)
+
+ // These work on object fields in the Java heap.
+ // They will not work on elements of packed arrays.
+
+ /**
+ * Fetches a value from a given Java variable.
+ * More specifically, fetches a field or array element within the given
+ * object {@code o} at the given offset, or (if {@code o} is null)
+ * from the memory address whose numerical value is the given offset.
+ * <p>
+ * The results are undefined unless one of the following cases is true:
+ * <ul>
+ * <li>The offset was obtained from {@link #objectFieldOffset} on
+ * the {@link java.lang.reflect.Field} of some Java field and the object
+ * referred to by {@code o} is of a class compatible with that
+ * field's class.
+ *
+ * <li>The offset and object reference {@code o} (either null or
+ * non-null) were both obtained via {@link #staticFieldOffset}
+ * and {@link #staticFieldBase} (respectively) from the
+ * reflective {@link Field} representation of some Java field.
+ *
+ * <li>The object referred to by {@code o} is an array, and the offset
+ * is an integer of the form {@code B+N*S}, where {@code N} is
+ * a valid index into the array, and {@code B} and {@code S} are
+ * the values obtained by {@link #arrayBaseOffset} and {@link
+ * #arrayIndexScale} (respectively) from the array's class. The value
+ * referred to is the {@code N}<em>th</em> element of the array.
+ *
+ * </ul>
+ * <p>
+ * If one of the above cases is true, the call references a specific Java
+ * variable (field or array element). However, the results are undefined
+ * if that variable is not in fact of the type returned by this method.
+ * <p>
+ * This method refers to a variable by means of two parameters, and so
+ * it provides (in effect) a <em>double-register</em> addressing mode
+ * for Java variables. When the object reference is null, this method
+ * uses its offset as an absolute address. This is similar in operation
+ * to methods such as {@link #getInt(long)}, which provide (in effect) a
+ * <em>single-register</em> addressing mode for non-Java variables.
+ * However, because Java variables may have a different layout in memory
+ * from non-Java variables, programmers should not assume that these
+ * two addressing modes are ever equivalent. Also, programmers should
+ * remember that offsets from the double-register addressing mode cannot
+ * be portably confused with longs used in the single-register addressing
+ * mode.
+ *
+ * @param o Java heap object in which the variable resides, if any, else
+ * null
+ * @param offset indication of where the variable resides in a Java heap
+ * object, if any, else a memory address locating the variable
+ * statically
+ * @return the value fetched from the indicated Java variable
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ */
+ @HotSpotIntrinsicCandidate
+ public native int getInt(Object o, long offset);
+
+ /**
+ * Stores a value into a given Java variable.
+ * <p>
+ * The first two parameters are interpreted exactly as with
+ * {@link #getInt(Object, long)} to refer to a specific
+ * Java variable (field or array element). The given value
+ * is stored into that variable.
+ * <p>
+ * The variable must be of the same type as the method
+ * parameter {@code x}.
+ *
+ * @param o Java heap object in which the variable resides, if any, else
+ * null
+ * @param offset indication of where the variable resides in a Java heap
+ * object, if any, else a memory address locating the variable
+ * statically
+ * @param x the value to store into the indicated Java variable
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ */
+ @HotSpotIntrinsicCandidate
+ public native void putInt(Object o, long offset, int x);
+
+ /**
+ * Fetches a reference value from a given Java variable.
+ * @see #getInt(Object, long)
+ */
+ @HotSpotIntrinsicCandidate
+ public native Object getObject(Object o, long offset);
+
+ /**
+ * Stores a reference value into a given Java variable.
+ * <p>
+ * Unless the reference {@code x} being stored is either null
+ * or matches the field type, the results are undefined.
+ * If the reference {@code o} is non-null, card marks or
+ * other store barriers for that object (if the VM requires them)
+ * are updated.
+ * @see #putInt(Object, long, int)
+ */
+ @HotSpotIntrinsicCandidate
+ public native void putObject(Object o, long offset, Object x);
+
+ /** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public native boolean getBoolean(Object o, long offset);
+ /** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
+ public native void putBoolean(Object o, long offset, boolean x);
+ /** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public native byte getByte(Object o, long offset);
+ /** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
+ public native void putByte(Object o, long offset, byte x);
+ /** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public native short getShort(Object o, long offset);
+ /** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
+ public native void putShort(Object o, long offset, short x);
+ /** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public native char getChar(Object o, long offset);
+ /** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
+ public native void putChar(Object o, long offset, char x);
+ /** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public native long getLong(Object o, long offset);
+ /** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
+ public native void putLong(Object o, long offset, long x);
+ /** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public native float getFloat(Object o, long offset);
+ /** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
+ public native void putFloat(Object o, long offset, float x);
+ /** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public native double getDouble(Object o, long offset);
+ /** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
+ public native void putDouble(Object o, long offset, double x);
+
+ // These read VM internal data.
+
+ /**
+ * Fetches an uncompressed reference value from a given native variable
+ * ignoring the VM's compressed references mode.
+ *
+ * @param address a memory address locating the variable
+ * @return the value fetched from the indicated native variable
+ */
+ public native Object getUncompressedObject(long address);
+
+ /**
+ * Fetches the {@link java.lang.Class} Java mirror for the given native
+ * metaspace {@code Klass} pointer.
+ *
+ * @param metaspaceKlass a native metaspace {@code Klass} pointer
+ * @return the {@link java.lang.Class} Java mirror
+ */
+ public native Class<?> getJavaMirror(long metaspaceKlass);
+
+ /**
+ * Fetches a native metaspace {@code Klass} pointer for the given Java
+ * object.
+ *
+ * @param o Java heap object for which to fetch the class pointer
+ * @return a native metaspace {@code Klass} pointer
+ */
+ public native long getKlassPointer(Object o);
+
+ // These work on values in the C heap.
+
+ /**
+ * Fetches a value from a given memory address. If the address is zero, or
+ * does not point into a block obtained from {@link #allocateMemory}, the
+ * results are undefined.
+ *
+ * @see #allocateMemory
+ */
+ @HotSpotIntrinsicCandidate
+ public native byte getByte(long address);
+
+ /**
+ * Stores a value into a given memory address. If the address is zero, or
+ * does not point into a block obtained from {@link #allocateMemory}, the
+ * results are undefined.
+ *
+ * @see #getByte(long)
+ */
+ @HotSpotIntrinsicCandidate
+ public native void putByte(long address, byte x);
+
+ /** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
+ public native short getShort(long address);
+ /** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
+ public native void putShort(long address, short x);
+ /** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
+ public native char getChar(long address);
+ /** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
+ public native void putChar(long address, char x);
+ /** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
+ public native int getInt(long address);
+ /** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
+ public native void putInt(long address, int x);
+ /** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
+ public native long getLong(long address);
+ /** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
+ public native void putLong(long address, long x);
+ /** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
+ public native float getFloat(long address);
+ /** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
+ public native void putFloat(long address, float x);
+ /** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
+ public native double getDouble(long address);
+ /** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
+ public native void putDouble(long address, double x);
+
+ /**
+ * Fetches a native pointer from a given memory address. If the address is
+ * zero, or does not point into a block obtained from {@link
+ * #allocateMemory}, the results are undefined.
+ *
+ * <p>If the native pointer is less than 64 bits wide, it is extended as
+ * an unsigned number to a Java long. The pointer may be indexed by any
+ * given byte offset, simply by adding that offset (as a simple integer) to
+ * the long representing the pointer. The number of bytes actually read
+ * from the target address may be determined by consulting {@link
+ * #addressSize}.
+ *
+ * @see #allocateMemory
+ */
+ @HotSpotIntrinsicCandidate
+ public native long getAddress(long address);
+
+ /**
+ * Stores a native pointer into a given memory address. If the address is
+ * zero, or does not point into a block obtained from {@link
+ * #allocateMemory}, the results are undefined.
+ *
+ * <p>The number of bytes actually written at the target address may be
+ * determined by consulting {@link #addressSize}.
+ *
+ * @see #getAddress(long)
+ */
+ @HotSpotIntrinsicCandidate
+ public native void putAddress(long address, long x);
+
+ /// wrappers for malloc, realloc, free:
+
+ /**
+ * Allocates a new block of native memory, of the given size in bytes. The
+ * contents of the memory are uninitialized; they will generally be
+ * garbage. The resulting native pointer will never be zero, and will be
+ * aligned for all value types. Dispose of this memory by calling {@link
+ * #freeMemory}, or resize it with {@link #reallocateMemory}.
+ *
+ * @throws IllegalArgumentException if the size is negative or too large
+ * for the native size_t type
+ *
+ * @throws OutOfMemoryError if the allocation is refused by the system
+ *
+ * @see #getByte(long)
+ * @see #putByte(long, byte)
+ */
+ public native long allocateMemory(long bytes);
+
+ /**
+ * Resizes a new block of native memory, to the given size in bytes. The
+ * contents of the new block past the size of the old block are
+ * uninitialized; they will generally be garbage. The resulting native
+ * pointer will be zero if and only if the requested size is zero. The
+ * resulting native pointer will be aligned for all value types. Dispose
+ * of this memory by calling {@link #freeMemory}, or resize it with {@link
+ * #reallocateMemory}. The address passed to this method may be null, in
+ * which case an allocation will be performed.
+ *
+ * @throws IllegalArgumentException if the size is negative or too large
+ * for the native size_t type
+ *
+ * @throws OutOfMemoryError if the allocation is refused by the system
+ *
+ * @see #allocateMemory
+ */
+ public native long reallocateMemory(long address, long bytes);
+
+ /**
+ * Sets all bytes in a given block of memory to a fixed value
+ * (usually zero).
+ *
+ * <p>This method determines a block's base address by means of two parameters,
+ * and so it provides (in effect) a <em>double-register</em> addressing mode,
+ * as discussed in {@link #getInt(Object,long)}. When the object reference is null,
+ * the offset supplies an absolute base address.
+ *
+ * <p>The stores are in coherent (atomic) units of a size determined
+ * by the address and length parameters. If the effective address and
+ * length are all even modulo 8, the stores take place in 'long' units.
+ * If the effective address and length are (resp.) even modulo 4 or 2,
+ * the stores take place in units of 'int' or 'short'.
+ *
+ * @since 1.7
+ */
+ public native void setMemory(Object o, long offset, long bytes, byte value);
+
+ /**
+ * Sets all bytes in a given block of memory to a fixed value
+ * (usually zero). This provides a <em>single-register</em> addressing mode,
+ * as discussed in {@link #getInt(Object,long)}.
+ *
+ * <p>Equivalent to {@code setMemory(null, address, bytes, value)}.
+ */
+ public void setMemory(long address, long bytes, byte value) {
+ setMemory(null, address, bytes, value);
+ }
+
+ /**
+ * Sets all bytes in a given block of memory to a copy of another
+ * block.
+ *
+ * <p>This method determines each block's base address by means of two parameters,
+ * and so it provides (in effect) a <em>double-register</em> addressing mode,
+ * as discussed in {@link #getInt(Object,long)}. When the object reference is null,
+ * the offset supplies an absolute base address.
+ *
+ * <p>The transfers are in coherent (atomic) units of a size determined
+ * by the address and length parameters. If the effective addresses and
+ * length are all even modulo 8, the transfer takes place in 'long' units.
+ * If the effective addresses and length are (resp.) even modulo 4 or 2,
+ * the transfer takes place in units of 'int' or 'short'.
+ *
+ * @since 1.7
+ */
+ @HotSpotIntrinsicCandidate
+ public native void copyMemory(Object srcBase, long srcOffset,
+ Object destBase, long destOffset,
+ long bytes);
+ /**
+ * Sets all bytes in a given block of memory to a copy of another
+ * block. This provides a <em>single-register</em> addressing mode,
+ * as discussed in {@link #getInt(Object,long)}.
+ *
+ * Equivalent to {@code copyMemory(null, srcAddress, null, destAddress, bytes)}.
+ */
+ public void copyMemory(long srcAddress, long destAddress, long bytes) {
+ copyMemory(null, srcAddress, null, destAddress, bytes);
+ }
+
+ /**
+ * Disposes of a block of native memory, as obtained from {@link
+ * #allocateMemory} or {@link #reallocateMemory}. The address passed to
+ * this method may be null, in which case no action is taken.
+ *
+ * @see #allocateMemory
+ */
+ public native void freeMemory(long address);
+
+ /// random queries
+
+ /**
+ * This constant differs from all results that will ever be returned from
+ * {@link #staticFieldOffset}, {@link #objectFieldOffset},
+ * or {@link #arrayBaseOffset}.
+ */
+ public static final int INVALID_FIELD_OFFSET = -1;
+
+ /**
+ * Reports the location of a given field in the storage allocation of its
+ * class. Do not expect to perform any sort of arithmetic on this offset;
+ * it is just a cookie which is passed to the unsafe heap memory accessors.
+ *
+ * <p>Any given field will always have the same offset and base, and no
+ * two distinct fields of the same class will ever have the same offset
+ * and base.
+ *
+ * <p>As of 1.4.1, offsets for fields are represented as long values,
+ * although the Sun JVM does not use the most significant 32 bits.
+ * However, JVM implementations which store static fields at absolute
+ * addresses can use long offsets and null base pointers to express
+ * the field locations in a form usable by {@link #getInt(Object,long)}.
+ * Therefore, code which will be ported to such JVMs on 64-bit platforms
+ * must preserve all bits of static field offsets.
+ * @see #getInt(Object, long)
+ */
+ public native long objectFieldOffset(Field f);
+
+ /**
+ * Reports the location of a given static field, in conjunction with {@link
+ * #staticFieldBase}.
+ * <p>Do not expect to perform any sort of arithmetic on this offset;
+ * it is just a cookie which is passed to the unsafe heap memory accessors.
+ *
+ * <p>Any given field will always have the same offset, and no two distinct
+ * fields of the same class will ever have the same offset.
+ *
+ * <p>As of 1.4.1, offsets for fields are represented as long values,
+ * although the Sun JVM does not use the most significant 32 bits.
+ * It is hard to imagine a JVM technology which needs more than
+ * a few bits to encode an offset within a non-array object,
+ * However, for consistency with other methods in this class,
+ * this method reports its result as a long value.
+ * @see #getInt(Object, long)
+ */
+ public native long staticFieldOffset(Field f);
+
+ /**
+ * Reports the location of a given static field, in conjunction with {@link
+ * #staticFieldOffset}.
+ * <p>Fetch the base "Object", if any, with which static fields of the
+ * given class can be accessed via methods like {@link #getInt(Object,
+ * long)}. This value may be null. This value may refer to an object
+ * which is a "cookie", not guaranteed to be a real Object, and it should
+ * not be used in any way except as argument to the get and put routines in
+ * this class.
+ */
+ public native Object staticFieldBase(Field f);
+
+ /**
+ * Detects if the given class may need to be initialized. This is often
+ * needed in conjunction with obtaining the static field base of a
+ * class.
+ * @return false only if a call to {@code ensureClassInitialized} would have no effect
+ */
+ public native boolean shouldBeInitialized(Class<?> c);
+
+ /**
+ * Ensures the given class has been initialized. This is often
+ * needed in conjunction with obtaining the static field base of a
+ * class.
+ */
+ public native void ensureClassInitialized(Class<?> c);
+
+ /**
+ * Reports the offset of the first element in the storage allocation of a
+ * given array class. If {@link #arrayIndexScale} returns a non-zero value
+ * for the same class, you may use that scale factor, together with this
+ * base offset, to form new offsets to access elements of arrays of the
+ * given class.
+ *
+ * @see #getInt(Object, long)
+ * @see #putInt(Object, long, int)
+ */
+ public native int arrayBaseOffset(Class<?> arrayClass);
+
+ /** The value of {@code arrayBaseOffset(boolean[].class)} */
+ public static final int ARRAY_BOOLEAN_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(boolean[].class);
+
+ /** The value of {@code arrayBaseOffset(byte[].class)} */
+ public static final int ARRAY_BYTE_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(byte[].class);
+
+ /** The value of {@code arrayBaseOffset(short[].class)} */
+ public static final int ARRAY_SHORT_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(short[].class);
+
+ /** The value of {@code arrayBaseOffset(char[].class)} */
+ public static final int ARRAY_CHAR_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(char[].class);
+
+ /** The value of {@code arrayBaseOffset(int[].class)} */
+ public static final int ARRAY_INT_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(int[].class);
+
+ /** The value of {@code arrayBaseOffset(long[].class)} */
+ public static final int ARRAY_LONG_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(long[].class);
+
+ /** The value of {@code arrayBaseOffset(float[].class)} */
+ public static final int ARRAY_FLOAT_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(float[].class);
+
+ /** The value of {@code arrayBaseOffset(double[].class)} */
+ public static final int ARRAY_DOUBLE_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(double[].class);
+
+ /** The value of {@code arrayBaseOffset(Object[].class)} */
+ public static final int ARRAY_OBJECT_BASE_OFFSET
+ = theUnsafe.arrayBaseOffset(Object[].class);
+
+ /**
+ * Reports the scale factor for addressing elements in the storage
+ * allocation of a given array class. However, arrays of "narrow" types
+ * will generally not work properly with accessors like {@link
+ * #getByte(Object, long)}, so the scale factor for such classes is reported
+ * as zero.
+ *
+ * @see #arrayBaseOffset
+ * @see #getInt(Object, long)
+ * @see #putInt(Object, long, int)
+ */
+ public native int arrayIndexScale(Class<?> arrayClass);
+
+ /** The value of {@code arrayIndexScale(boolean[].class)} */
+ public static final int ARRAY_BOOLEAN_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(boolean[].class);
+
+ /** The value of {@code arrayIndexScale(byte[].class)} */
+ public static final int ARRAY_BYTE_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(byte[].class);
+
+ /** The value of {@code arrayIndexScale(short[].class)} */
+ public static final int ARRAY_SHORT_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(short[].class);
+
+ /** The value of {@code arrayIndexScale(char[].class)} */
+ public static final int ARRAY_CHAR_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(char[].class);
+
+ /** The value of {@code arrayIndexScale(int[].class)} */
+ public static final int ARRAY_INT_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(int[].class);
+
+ /** The value of {@code arrayIndexScale(long[].class)} */
+ public static final int ARRAY_LONG_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(long[].class);
+
+ /** The value of {@code arrayIndexScale(float[].class)} */
+ public static final int ARRAY_FLOAT_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(float[].class);
+
+ /** The value of {@code arrayIndexScale(double[].class)} */
+ public static final int ARRAY_DOUBLE_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(double[].class);
+
+ /** The value of {@code arrayIndexScale(Object[].class)} */
+ public static final int ARRAY_OBJECT_INDEX_SCALE
+ = theUnsafe.arrayIndexScale(Object[].class);
+
+ /**
+ * Reports the size in bytes of a native pointer, as stored via {@link
+ * #putAddress}. This value will be either 4 or 8. Note that the sizes of
+ * other primitive types (as stored in native memory blocks) is determined
+ * fully by their information content.
+ */
+ public native int addressSize();
+
+ /** The value of {@code addressSize()} */
+ public static final int ADDRESS_SIZE = theUnsafe.addressSize();
+
+ /**
+ * Reports the size in bytes of a native memory page (whatever that is).
+ * This value will always be a power of two.
+ */
+ public native int pageSize();
+
+
+ /// random trusted operations from JNI:
+
+ /**
+ * Tells the VM to define a class, without security checks. By default, the
+ * class loader and protection domain come from the caller's class.
+ */
+ public native Class<?> defineClass(String name, byte[] b, int off, int len,
+ ClassLoader loader,
+ ProtectionDomain protectionDomain);
+
+ /**
+ * Defines a class but does not make it known to the class loader or system dictionary.
+ * <p>
+ * For each CP entry, the corresponding CP patch must either be null or have
+ * the a format that matches its tag:
+ * <ul>
+ * <li>Integer, Long, Float, Double: the corresponding wrapper object type from java.lang
+ * <li>Utf8: a string (must have suitable syntax if used as signature or name)
+ * <li>Class: any java.lang.Class object
+ * <li>String: any object (not just a java.lang.String)
+ * <li>InterfaceMethodRef: (NYI) a method handle to invoke on that call site's arguments
+ * </ul>
+ * @param hostClass context for linkage, access control, protection domain, and class loader
+ * @param data bytes of a class file
+ * @param cpPatches where non-null entries exist, they replace corresponding CP entries in data
+ */
+ public native Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches);
+
+ /**
+ * Allocates an instance but does not run any constructor.
+ * Initializes the class if it has not yet been.
+ */
+ @HotSpotIntrinsicCandidate
+ public native Object allocateInstance(Class<?> cls)
+ throws InstantiationException;
+
+ /** Throws the exception without telling the verifier. */
+ public native void throwException(Throwable ee);
+
+ /**
+ * Atomically updates Java variable to {@code x} if it is currently
+ * holding {@code expected}.
+ *
+ * <p>This operation has memory semantics of a {@code volatile} read
+ * and write. Corresponds to C11 atomic_compare_exchange_strong.
+ *
+ * @return {@code true} if successful
+ */
+ @HotSpotIntrinsicCandidate
+ public final native boolean compareAndSwapObject(Object o, long offset,
+ Object expected,
+ Object x);
+
+ /**
+ * Atomically updates Java variable to {@code x} if it is currently
+ * holding {@code expected}.
+ *
+ * <p>This operation has memory semantics of a {@code volatile} read
+ * and write. Corresponds to C11 atomic_compare_exchange_strong.
+ *
+ * @return {@code true} if successful
+ */
+ @HotSpotIntrinsicCandidate
+ public final native boolean compareAndSwapInt(Object o, long offset,
+ int expected,
+ int x);
+
+ /**
+ * Atomically updates Java variable to {@code x} if it is currently
+ * holding {@code expected}.
+ *
+ * <p>This operation has memory semantics of a {@code volatile} read
+ * and write. Corresponds to C11 atomic_compare_exchange_strong.
+ *
+ * @return {@code true} if successful
+ */
+ @HotSpotIntrinsicCandidate
+ public final native boolean compareAndSwapLong(Object o, long offset,
+ long expected,
+ long x);
+
+ /**
+ * Fetches a reference value from a given Java variable, with volatile
+ * load semantics. Otherwise identical to {@link #getObject(Object, long)}
+ */
+ @HotSpotIntrinsicCandidate
+ public native Object getObjectVolatile(Object o, long offset);
+
+ /**
+ * Stores a reference value into a given Java variable, with
+ * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)}
+ */
+ @HotSpotIntrinsicCandidate
+ public native void putObjectVolatile(Object o, long offset, Object x);
+
+ /** Volatile version of {@link #getInt(Object, long)} */
+ @HotSpotIntrinsicCandidate
+ public native int getIntVolatile(Object o, long offset);
+
+ /** Volatile version of {@link #putInt(Object, long, int)} */
+ @HotSpotIntrinsicCandidate
+ public native void putIntVolatile(Object o, long offset, int x);
+
+ /** Volatile version of {@link #getBoolean(Object, long)} */
+ @HotSpotIntrinsicCandidate
+ public native boolean getBooleanVolatile(Object o, long offset);
+
+ /** Volatile version of {@link #putBoolean(Object, long, boolean)} */
+ @HotSpotIntrinsicCandidate
+ public native void putBooleanVolatile(Object o, long offset, boolean x);
+
+ /** Volatile version of {@link #getByte(Object, long)} */
+ @HotSpotIntrinsicCandidate
+ public native byte getByteVolatile(Object o, long offset);
+
+ /** Volatile version of {@link #putByte(Object, long, byte)} */
+ @HotSpotIntrinsicCandidate
+ public native void putByteVolatile(Object o, long offset, byte x);
+
+ /** Volatile version of {@link #getShort(Object, long)} */
+ @HotSpotIntrinsicCandidate
+ public native short getShortVolatile(Object o, long offset);
+
+ /** Volatile version of {@link #putShort(Object, long, short)} */
+ @HotSpotIntrinsicCandidate
+ public native void putShortVolatile(Object o, long offset, short x);
+
+ /** Volatile version of {@link #getChar(Object, long)} */
+ @HotSpotIntrinsicCandidate
+ public native char getCharVolatile(Object o, long offset);
+
+ /** Volatile version of {@link #putChar(Object, long, char)} */
+ @HotSpotIntrinsicCandidate
+ public native void putCharVolatile(Object o, long offset, char x);
+
+ /** Volatile version of {@link #getLong(Object, long)} */
+ @HotSpotIntrinsicCandidate
+ public native long getLongVolatile(Object o, long offset);
+
+ /** Volatile version of {@link #putLong(Object, long, long)} */
+ @HotSpotIntrinsicCandidate
+ public native void putLongVolatile(Object o, long offset, long x);
+
+ /** Volatile version of {@link #getFloat(Object, long)} */
+ @HotSpotIntrinsicCandidate
+ public native float getFloatVolatile(Object o, long offset);
+
+ /** Volatile version of {@link #putFloat(Object, long, float)} */
+ @HotSpotIntrinsicCandidate
+ public native void putFloatVolatile(Object o, long offset, float x);
+
+ /** Volatile version of {@link #getDouble(Object, long)} */
+ @HotSpotIntrinsicCandidate
+ public native double getDoubleVolatile(Object o, long offset);
+
+ /** Volatile version of {@link #putDouble(Object, long, double)} */
+ @HotSpotIntrinsicCandidate
+ public native void putDoubleVolatile(Object o, long offset, double x);
+
+ /**
+ * Version of {@link #putObjectVolatile(Object, long, Object)}
+ * that does not guarantee immediate visibility of the store to
+ * other threads. This method is generally only useful if the
+ * underlying field is a Java volatile (or if an array cell, one
+ * that is otherwise only accessed using volatile accesses).
+ *
+ * Corresponds to C11 atomic_store_explicit(..., memory_order_release).
+ */
+ @HotSpotIntrinsicCandidate
+ public native void putOrderedObject(Object o, long offset, Object x);
+
+ /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */
+ @HotSpotIntrinsicCandidate
+ public native void putOrderedInt(Object o, long offset, int x);
+
+ /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
+ @HotSpotIntrinsicCandidate
+ public native void putOrderedLong(Object o, long offset, long x);
+
+ /**
+ * Unblocks the given thread blocked on {@code park}, or, if it is
+ * not blocked, causes the subsequent call to {@code park} not to
+ * block. Note: this operation is "unsafe" solely because the
+ * caller must somehow ensure that the thread has not been
+ * destroyed. Nothing special is usually required to ensure this
+ * when called from Java (in which there will ordinarily be a live
+ * reference to the thread) but this is not nearly-automatically
+ * so when calling from native code.
+ *
+ * @param thread the thread to unpark.
+ */
+ @HotSpotIntrinsicCandidate
+ public native void unpark(Object thread);
+
+ /**
+ * Blocks current thread, returning when a balancing
+ * {@code unpark} occurs, or a balancing {@code unpark} has
+ * already occurred, or the thread is interrupted, or, if not
+ * absolute and time is not zero, the given time nanoseconds have
+ * elapsed, or if absolute, the given deadline in milliseconds
+ * since Epoch has passed, or spuriously (i.e., returning for no
+ * "reason"). Note: This operation is in the Unsafe class only
+ * because {@code unpark} is, so it would be strange to place it
+ * elsewhere.
+ */
+ @HotSpotIntrinsicCandidate
+ public native void park(boolean isAbsolute, long time);
+
+ /**
+ * Gets the load average in the system run queue assigned
+ * to the available processors averaged over various periods of time.
+ * This method retrieves the given {@code nelem} samples and
+ * assigns to the elements of the given {@code loadavg} array.
+ * The system imposes a maximum of 3 samples, representing
+ * averages over the last 1, 5, and 15 minutes, respectively.
+ *
+ * @param loadavg an array of double of size nelems
+ * @param nelems the number of samples to be retrieved and
+ * must be 1 to 3.
+ *
+ * @return the number of samples actually retrieved; or -1
+ * if the load average is unobtainable.
+ */
+ public native int getLoadAverage(double[] loadavg, int nelems);
+
+ // The following contain CAS-based Java implementations used on
+ // platforms not supporting native instructions
+
+ /**
+ * Atomically adds the given value to the current value of a field
+ * or array element within the given object {@code o}
+ * at the given {@code offset}.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param delta the value to add
+ * @return the previous value
+ * @since 1.8
+ */
+ @HotSpotIntrinsicCandidate
+ public final int getAndAddInt(Object o, long offset, int delta) {
+ int v;
+ do {
+ v = getIntVolatile(o, offset);
+ } while (!compareAndSwapInt(o, offset, v, v + delta));
+ return v;
+ }
+
+ /**
+ * Atomically adds the given value to the current value of a field
+ * or array element within the given object {@code o}
+ * at the given {@code offset}.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param delta the value to add
+ * @return the previous value
+ * @since 1.8
+ */
+ @HotSpotIntrinsicCandidate
+ public final long getAndAddLong(Object o, long offset, long delta) {
+ long v;
+ do {
+ v = getLongVolatile(o, offset);
+ } while (!compareAndSwapLong(o, offset, v, v + delta));
+ return v;
+ }
+
+ /**
+ * Atomically exchanges the given value with the current value of
+ * a field or array element within the given object {@code o}
+ * at the given {@code offset}.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param newValue new value
+ * @return the previous value
+ * @since 1.8
+ */
+ @HotSpotIntrinsicCandidate
+ public final int getAndSetInt(Object o, long offset, int newValue) {
+ int v;
+ do {
+ v = getIntVolatile(o, offset);
+ } while (!compareAndSwapInt(o, offset, v, newValue));
+ return v;
+ }
+
+ /**
+ * Atomically exchanges the given value with the current value of
+ * a field or array element within the given object {@code o}
+ * at the given {@code offset}.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param newValue new value
+ * @return the previous value
+ * @since 1.8
+ */
+ @HotSpotIntrinsicCandidate
+ public final long getAndSetLong(Object o, long offset, long newValue) {
+ long v;
+ do {
+ v = getLongVolatile(o, offset);
+ } while (!compareAndSwapLong(o, offset, v, newValue));
+ return v;
+ }
+
+ /**
+ * Atomically exchanges the given reference value with the current
+ * reference value of a field or array element within the given
+ * object {@code o} at the given {@code offset}.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param newValue new value
+ * @return the previous value
+ * @since 1.8
+ */
+ @HotSpotIntrinsicCandidate
+ public final Object getAndSetObject(Object o, long offset, Object newValue) {
+ Object v;
+ do {
+ v = getObjectVolatile(o, offset);
+ } while (!compareAndSwapObject(o, offset, v, newValue));
+ return v;
+ }
+
+
+ /**
+ * Ensures that loads before the fence will not be reordered with loads and
+ * stores after the fence; a "LoadLoad plus LoadStore barrier".
+ *
+ * Corresponds to C11 atomic_thread_fence(memory_order_acquire)
+ * (an "acquire fence").
+ *
+ * A pure LoadLoad fence is not provided, since the addition of LoadStore
+ * is almost always desired, and most current hardware instructions that
+ * provide a LoadLoad barrier also provide a LoadStore barrier for free.
+ * @since 1.8
+ */
+ @HotSpotIntrinsicCandidate
+ public native void loadFence();
+
+ /**
+ * Ensures that loads and stores before the fence will not be reordered with
+ * stores after the fence; a "StoreStore plus LoadStore barrier".
+ *
+ * Corresponds to C11 atomic_thread_fence(memory_order_release)
+ * (a "release fence").
+ *
+ * A pure StoreStore fence is not provided, since the addition of LoadStore
+ * is almost always desired, and most current hardware instructions that
+ * provide a StoreStore barrier also provide a LoadStore barrier for free.
+ * @since 1.8
+ */
+ @HotSpotIntrinsicCandidate
+ public native void storeFence();
+
+ /**
+ * Ensures that loads and stores before the fence will not be reordered
+ * with loads and stores after the fence. Implies the effects of both
+ * loadFence() and storeFence(), and in addition, the effect of a StoreLoad
+ * barrier.
+ *
+ * Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
+ * @since 1.8
+ */
+ @HotSpotIntrinsicCandidate
+ public native void fullFence();
+
+ /**
+ * Throws IllegalAccessError; for use by the VM for access control
+ * error support.
+ * @since 1.8
+ */
+ private static void throwIllegalAccessError() {
+ throw new IllegalAccessError();
+ }
+
+ /**
+ * @return Returns true if the native byte ordering of this
+ * platform is big-endian, false if it is little-endian.
+ */
+ public final boolean isBigEndian() { return BE; }
+
+ /**
+ * @return Returns true if this platform is capable of performing
+ * accesses at addresses which are not aligned for the type of the
+ * primitive type being accessed, false otherwise.
+ */
+ public final boolean unalignedAccess() { return unalignedAccess; }
+
+ /**
+ * Fetches a value at some byte offset into a given Java object.
+ * More specifically, fetches a value within the given object
+ * <code>o</code> at the given offset, or (if <code>o</code> is
+ * null) from the memory address whose numerical value is the
+ * given offset. <p>
+ *
+ * The specification of this method is the same as {@link
+ * #getLong(Object, long)} except that the offset does not need to
+ * have been obtained from {@link #objectFieldOffset} on the
+ * {@link java.lang.reflect.Field} of some Java field. The value
+ * in memory is raw data, and need not correspond to any Java
+ * variable. Unless <code>o</code> is null, the value accessed
+ * must be entirely within the allocated object. The endianness
+ * of the value in memory is the endianness of the native platform.
+ *
+ * <p> The read will be atomic with respect to the largest power
+ * of two that divides the GCD of the offset and the storage size.
+ * For example, getLongUnaligned will make atomic reads of 2-, 4-,
+ * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
+ * respectively. There are no other guarantees of atomicity.
+ * <p>
+ * 8-byte atomicity is only guaranteed on platforms on which
+ * support atomic accesses to longs.
+ *
+ * @param o Java heap object in which the value resides, if any, else
+ * null
+ * @param offset The offset in bytes from the start of the object
+ * @return the value fetched from the indicated object
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ * @since 1.9
+ */
+ @HotSpotIntrinsicCandidate
+ public final long getLongUnaligned(Object o, long offset) {
+ if ((offset & 7) == 0) {
+ return getLong(o, offset);
+ } else if ((offset & 3) == 0) {
+ return makeLong(getInt(o, offset),
+ getInt(o, offset + 4));
+ } else if ((offset & 1) == 0) {
+ return makeLong(getShort(o, offset),
+ getShort(o, offset + 2),
+ getShort(o, offset + 4),
+ getShort(o, offset + 6));
+ } else {
+ return makeLong(getByte(o, offset),
+ getByte(o, offset + 1),
+ getByte(o, offset + 2),
+ getByte(o, offset + 3),
+ getByte(o, offset + 4),
+ getByte(o, offset + 5),
+ getByte(o, offset + 6),
+ getByte(o, offset + 7));
+ }
+ }
+ /**
+ * As {@link #getLongUnaligned(Object, long)} but with an
+ * additional argument which specifies the endianness of the value
+ * as stored in memory.
+ *
+ * @param o Java heap object in which the variable resides
+ * @param offset The offset in bytes from the start of the object
+ * @param bigEndian The endianness of the value
+ * @return the value fetched from the indicated object
+ * @since 1.9
+ */
+ public final long getLongUnaligned(Object o, long offset, boolean bigEndian) {
+ return convEndian(bigEndian, getLongUnaligned(o, offset));
+ }
+
+ /** @see #getLongUnaligned(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public final int getIntUnaligned(Object o, long offset) {
+ if ((offset & 3) == 0) {
+ return getInt(o, offset);
+ } else if ((offset & 1) == 0) {
+ return makeInt(getShort(o, offset),
+ getShort(o, offset + 2));
+ } else {
+ return makeInt(getByte(o, offset),
+ getByte(o, offset + 1),
+ getByte(o, offset + 2),
+ getByte(o, offset + 3));
+ }
+ }
+ /** @see #getLongUnaligned(Object, long, boolean) */
+ public final int getIntUnaligned(Object o, long offset, boolean bigEndian) {
+ return convEndian(bigEndian, getIntUnaligned(o, offset));
+ }
+
+ /** @see #getLongUnaligned(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public final short getShortUnaligned(Object o, long offset) {
+ if ((offset & 1) == 0) {
+ return getShort(o, offset);
+ } else {
+ return makeShort(getByte(o, offset),
+ getByte(o, offset + 1));
+ }
+ }
+ /** @see #getLongUnaligned(Object, long, boolean) */
+ public final short getShortUnaligned(Object o, long offset, boolean bigEndian) {
+ return convEndian(bigEndian, getShortUnaligned(o, offset));
+ }
+
+ /** @see #getLongUnaligned(Object, long) */
+ @HotSpotIntrinsicCandidate
+ public final char getCharUnaligned(Object o, long offset) {
+ return (char)getShortUnaligned(o, offset);
+ }
+
+ /** @see #getLongUnaligned(Object, long, boolean) */
+ public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
+ return convEndian(bigEndian, getCharUnaligned(o, offset));
+ }
+
+ /**
+ * Stores a value at some byte offset into a given Java object.
+ * <p>
+ * The specification of this method is the same as {@link
+ * #getLong(Object, long)} except that the offset does not need to
+ * have been obtained from {@link #objectFieldOffset} on the
+ * {@link java.lang.reflect.Field} of some Java field. The value
+ * in memory is raw data, and need not correspond to any Java
+ * variable. The endianness of the value in memory is the
+ * endianness of the native platform.
+ * <p>
+ * The write will be atomic with respect to the largest power of
+ * two that divides the GCD of the offset and the storage size.
+ * For example, putLongUnaligned will make atomic writes of 2-, 4-,
+ * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
+ * respectively. There are no other guarantees of atomicity.
+ * <p>
+ * 8-byte atomicity is only guaranteed on platforms on which
+ * support atomic accesses to longs.
+ *
+ * @param o Java heap object in which the value resides, if any, else
+ * null
+ * @param offset The offset in bytes from the start of the object
+ * @param x the value to store
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ * @since 1.9
+ */
+ @HotSpotIntrinsicCandidate
+ public final void putLongUnaligned(Object o, long offset, long x) {
+ if ((offset & 7) == 0) {
+ putLong(o, offset, x);
+ } else if ((offset & 3) == 0) {
+ putLongParts(o, offset,
+ (int)(x >> 0),
+ (int)(x >>> 32));
+ } else if ((offset & 1) == 0) {
+ putLongParts(o, offset,
+ (short)(x >>> 0),
+ (short)(x >>> 16),
+ (short)(x >>> 32),
+ (short)(x >>> 48));
+ } else {
+ putLongParts(o, offset,
+ (byte)(x >>> 0),
+ (byte)(x >>> 8),
+ (byte)(x >>> 16),
+ (byte)(x >>> 24),
+ (byte)(x >>> 32),
+ (byte)(x >>> 40),
+ (byte)(x >>> 48),
+ (byte)(x >>> 56));
+ }
+ }
+
+ /**
+ * As {@link #putLongUnaligned(Object, long, long)} but with an additional
+ * argument which specifies the endianness of the value as stored in memory.
+ * @param o Java heap object in which the value resides
+ * @param offset The offset in bytes from the start of the object
+ * @param x the value to store
+ * @param bigEndian The endianness of the value
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ * @since 1.9
+ */
+ public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) {
+ putLongUnaligned(o, offset, convEndian(bigEndian, x));
+ }
+
+ /** @see #putLongUnaligned(Object, long, long) */
+ @HotSpotIntrinsicCandidate
+ public final void putIntUnaligned(Object o, long offset, int x) {
+ if ((offset & 3) == 0) {
+ putInt(o, offset, x);
+ } else if ((offset & 1) == 0) {
+ putIntParts(o, offset,
+ (short)(x >> 0),
+ (short)(x >>> 16));
+ } else {
+ putIntParts(o, offset,
+ (byte)(x >>> 0),
+ (byte)(x >>> 8),
+ (byte)(x >>> 16),
+ (byte)(x >>> 24));
+ }
+ }
+ /** @see #putLongUnaligned(Object, long, long, boolean) */
+ public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) {
+ putIntUnaligned(o, offset, convEndian(bigEndian, x));
+ }
+
+ /** @see #putLongUnaligned(Object, long, long) */
+ @HotSpotIntrinsicCandidate
+ public final void putShortUnaligned(Object o, long offset, short x) {
+ if ((offset & 1) == 0) {
+ putShort(o, offset, x);
+ } else {
+ putShortParts(o, offset,
+ (byte)(x >>> 0),
+ (byte)(x >>> 8));
+ }
+ }
+ /** @see #putLongUnaligned(Object, long, long, boolean) */
+ public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
+ putShortUnaligned(o, offset, convEndian(bigEndian, x));
+ }
+
+ /** @see #putLongUnaligned(Object, long, long) */
+ @HotSpotIntrinsicCandidate
+ public final void putCharUnaligned(Object o, long offset, char x) {
+ putShortUnaligned(o, offset, (short)x);
+ }
+ /** @see #putLongUnaligned(Object, long, long, boolean) */
+ public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
+ putCharUnaligned(o, offset, convEndian(bigEndian, x));
+ }
+
+ // JVM interface methods
+ private native boolean unalignedAccess0();
+ private native boolean isBigEndian0();
+
+ // BE is true iff the native endianness of this platform is big.
+ private static final boolean BE = theUnsafe.isBigEndian0();
+
+ // unalignedAccess is true iff this platform can perform unaligned accesses.
+ private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
+
+ private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
+
+ // These methods construct integers from bytes. The byte ordering
+ // is the native endianness of this platform.
+ private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
+ return ((toUnsignedLong(i0) << pickPos(56, 0))
+ | (toUnsignedLong(i1) << pickPos(56, 8))
+ | (toUnsignedLong(i2) << pickPos(56, 16))
+ | (toUnsignedLong(i3) << pickPos(56, 24))
+ | (toUnsignedLong(i4) << pickPos(56, 32))
+ | (toUnsignedLong(i5) << pickPos(56, 40))
+ | (toUnsignedLong(i6) << pickPos(56, 48))
+ | (toUnsignedLong(i7) << pickPos(56, 56)));
+ }
+ private static long makeLong(short i0, short i1, short i2, short i3) {
+ return ((toUnsignedLong(i0) << pickPos(48, 0))
+ | (toUnsignedLong(i1) << pickPos(48, 16))
+ | (toUnsignedLong(i2) << pickPos(48, 32))
+ | (toUnsignedLong(i3) << pickPos(48, 48)));
+ }
+ private static long makeLong(int i0, int i1) {
+ return (toUnsignedLong(i0) << pickPos(32, 0))
+ | (toUnsignedLong(i1) << pickPos(32, 32));
+ }
+ private static int makeInt(short i0, short i1) {
+ return (toUnsignedInt(i0) << pickPos(16, 0))
+ | (toUnsignedInt(i1) << pickPos(16, 16));
+ }
+ private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
+ return ((toUnsignedInt(i0) << pickPos(24, 0))
+ | (toUnsignedInt(i1) << pickPos(24, 8))
+ | (toUnsignedInt(i2) << pickPos(24, 16))
+ | (toUnsignedInt(i3) << pickPos(24, 24)));
+ }
+ private static short makeShort(byte i0, byte i1) {
+ return (short)((toUnsignedInt(i0) << pickPos(8, 0))
+ | (toUnsignedInt(i1) << pickPos(8, 8)));
+ }
+
+ private static byte pick(byte le, byte be) { return BE ? be : le; }
+ private static short pick(short le, short be) { return BE ? be : le; }
+ private static int pick(int le, int be) { return BE ? be : le; }
+
+ // These methods write integers to memory from smaller parts
+ // provided by their caller. The ordering in which these parts
+ // are written is the native endianness of this platform.
+ private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
+ putByte(o, offset + 0, pick(i0, i7));
+ putByte(o, offset + 1, pick(i1, i6));
+ putByte(o, offset + 2, pick(i2, i5));
+ putByte(o, offset + 3, pick(i3, i4));
+ putByte(o, offset + 4, pick(i4, i3));
+ putByte(o, offset + 5, pick(i5, i2));
+ putByte(o, offset + 6, pick(i6, i1));
+ putByte(o, offset + 7, pick(i7, i0));
+ }
+ private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
+ putShort(o, offset + 0, pick(i0, i3));
+ putShort(o, offset + 2, pick(i1, i2));
+ putShort(o, offset + 4, pick(i2, i1));
+ putShort(o, offset + 6, pick(i3, i0));
+ }
+ private void putLongParts(Object o, long offset, int i0, int i1) {
+ putInt(o, offset + 0, pick(i0, i1));
+ putInt(o, offset + 4, pick(i1, i0));
+ }
+ private void putIntParts(Object o, long offset, short i0, short i1) {
+ putShort(o, offset + 0, pick(i0, i1));
+ putShort(o, offset + 2, pick(i1, i0));
+ }
+ private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
+ putByte(o, offset + 0, pick(i0, i3));
+ putByte(o, offset + 1, pick(i1, i2));
+ putByte(o, offset + 2, pick(i2, i1));
+ putByte(o, offset + 3, pick(i3, i0));
+ }
+ private void putShortParts(Object o, long offset, byte i0, byte i1) {
+ putByte(o, offset + 0, pick(i0, i1));
+ putByte(o, offset + 1, pick(i1, i0));
+ }
+
+ // Zero-extend an integer
+ private static int toUnsignedInt(byte n) { return n & 0xff; }
+ private static int toUnsignedInt(short n) { return n & 0xffff; }
+ private static long toUnsignedLong(byte n) { return n & 0xffl; }
+ private static long toUnsignedLong(short n) { return n & 0xffffl; }
+ private static long toUnsignedLong(int n) { return n & 0xffffffffl; }
+
+ // Maybe byte-reverse an integer
+ private static char convEndian(boolean big, char n) { return big == BE ? n : Character.reverseBytes(n); }
+ private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n) ; }
+ private static int convEndian(boolean big, int n) { return big == BE ? n : Integer.reverseBytes(n) ; }
+ private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; }
+}
--- a/jdk/src/java.base/share/classes/sun/invoke/anon/AnonymousClassLoader.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/invoke/anon/AnonymousClassLoader.java Wed Jul 05 21:00:20 2017 +0200
@@ -78,7 +78,7 @@
this.hostClass = hostClass;
}
- public static AnonymousClassLoader make(sun.misc.Unsafe unsafe, Class<?> hostClass) {
+ public static AnonymousClassLoader make(jdk.internal.misc.Unsafe unsafe, Class<?> hostClass) {
if (unsafe == null) throw new NullPointerException();
return new AnonymousClassLoader(hostClass);
}
@@ -189,13 +189,13 @@
private static int fakeNameCounter = 99999;
// ignore two warnings on this line:
- private static sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ private static jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
// preceding line requires that this class be on the boot class path
private static final Method defineAnonymousClass;
static {
Method dac = null;
- Class<? extends sun.misc.Unsafe> unsafeClass = unsafe.getClass();
+ Class<? extends jdk.internal.misc.Unsafe> unsafeClass = unsafe.getClass();
try {
dac = unsafeClass.getMethod("defineAnonymousClass",
Class.class,
--- a/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,18 +27,19 @@
public enum Wrapper {
// wrapperType primitiveType char zero emptyArray format
- BOOLEAN( Boolean.class, boolean.class, 'Z', (Boolean)false, new boolean[0], Format.unsigned( 1)),
+ BOOLEAN( Boolean.class, boolean.class, 'Z', Boolean.FALSE, new boolean[0], Format.unsigned( 1)),
// These must be in the order defined for widening primitive conversions in JLS 5.1.2
- BYTE ( Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed( 8)),
- SHORT ( Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed( 16)),
- CHAR (Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
- INT ( Integer.class, int.class, 'I', (Integer)/*(int)*/0, new int[0], Format.signed( 32)),
- LONG ( Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed( 64)),
- FLOAT ( Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
- DOUBLE ( Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
- OBJECT ( Object.class, Object.class, 'L', null, new Object[0], Format.other( 1)),
+ // Avoid boxing integral types here to defer initialization of internal caches
+ BYTE ( Byte.class, byte.class, 'B', new Byte((byte)0), new byte[0], Format.signed( 8)),
+ SHORT ( Short.class, short.class, 'S', new Short((short)0), new short[0], Format.signed( 16)),
+ CHAR (Character.class, char.class, 'C', new Character((char)0), new char[0], Format.unsigned(16)),
+ INT ( Integer.class, int.class, 'I', new Integer(0), new int[0], Format.signed( 32)),
+ LONG ( Long.class, long.class, 'J', new Long(0), new long[0], Format.signed( 64)),
+ FLOAT ( Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
+ DOUBLE ( Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
+ OBJECT ( Object.class, Object.class, 'L', null, new Object[0], Format.other( 1)),
// VOID must be the last type, since it is "assignable" from any other type:
- VOID ( Void.class, void.class, 'V', null, null, Format.other( 0)),
+ VOID ( Void.class, void.class, 'V', null, null, Format.other( 0)),
;
private final Class<?> wrapperType;
--- a/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/misc/InnocuousThread.java Wed Jul 05 21:00:20 2017 +0200
@@ -36,7 +36,7 @@
* ThreadGroup and supports the ability to erase ThreadLocals.
*/
public final class InnocuousThread extends ManagedLocalsThread {
- private static final Unsafe UNSAFE;
+ private static final jdk.internal.misc.Unsafe UNSAFE;
private static final ThreadGroup INNOCUOUSTHREADGROUP;
private static final AccessControlContext ACC;
private static final long INHERITEDACCESSCONTROLCONTEXT;
@@ -92,7 +92,7 @@
});
// Find and use topmost ThreadGroup as parent of new group
- UNSAFE = Unsafe.getUnsafe();
+ UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
Class<?> tk = Thread.class;
Class<?> gk = ThreadGroup.class;
--- a/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/misc/ManagedLocalsThread.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,7 +30,7 @@
* locals erased on construction.
*/
public class ManagedLocalsThread extends Thread {
- private static final Unsafe UNSAFE;
+ private static final jdk.internal.misc.Unsafe UNSAFE;
private static final long THREAD_LOCALS;
private static final long INHERITABLE_THREAD_LOCALS;
@@ -77,7 +77,7 @@
}
static {
- UNSAFE = Unsafe.getUnsafe();
+ UNSAFE = jdk.internal.misc.Unsafe.getUnsafe();
Class<?> t = Thread.class;
try {
THREAD_LOCALS = UNSAFE.objectFieldOffset
--- a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Wed Jul 05 21:00:20 2017 +0200
@@ -1036,355 +1036,8 @@
throw new IllegalAccessError();
}
- /**
- * @return Returns true if the native byte ordering of this
- * platform is big-endian, false if it is little-endian.
- */
- public final boolean isBigEndian() { return BE; }
-
- /**
- * @return Returns true if this platform is capable of performing
- * accesses at addresses which are not aligned for the type of the
- * primitive type being accessed, false otherwise.
- */
- public final boolean unalignedAccess() { return unalignedAccess; }
-
- /**
- * Fetches a value at some byte offset into a given Java object.
- * More specifically, fetches a value within the given object
- * <code>o</code> at the given offset, or (if <code>o</code> is
- * null) from the memory address whose numerical value is the
- * given offset. <p>
- *
- * The specification of this method is the same as {@link
- * #getLong(Object, long)} except that the offset does not need to
- * have been obtained from {@link #objectFieldOffset} on the
- * {@link java.lang.reflect.Field} of some Java field. The value
- * in memory is raw data, and need not correspond to any Java
- * variable. Unless <code>o</code> is null, the value accessed
- * must be entirely within the allocated object. The endianness
- * of the value in memory is the endianness of the native platform.
- *
- * <p> The read will be atomic with respect to the largest power
- * of two that divides the GCD of the offset and the storage size.
- * For example, getLongUnaligned will make atomic reads of 2-, 4-,
- * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
- * respectively. There are no other guarantees of atomicity.
- * <p>
- * 8-byte atomicity is only guaranteed on platforms on which
- * support atomic accesses to longs.
- *
- * @param o Java heap object in which the value resides, if any, else
- * null
- * @param offset The offset in bytes from the start of the object
- * @return the value fetched from the indicated object
- * @throws RuntimeException No defined exceptions are thrown, not even
- * {@link NullPointerException}
- * @since 1.9
- */
- @HotSpotIntrinsicCandidate
- public final long getLongUnaligned(Object o, long offset) {
- if ((offset & 7) == 0) {
- return getLong(o, offset);
- } else if ((offset & 3) == 0) {
- return makeLong(getInt(o, offset),
- getInt(o, offset + 4));
- } else if ((offset & 1) == 0) {
- return makeLong(getShort(o, offset),
- getShort(o, offset + 2),
- getShort(o, offset + 4),
- getShort(o, offset + 6));
- } else {
- return makeLong(getByte(o, offset),
- getByte(o, offset + 1),
- getByte(o, offset + 2),
- getByte(o, offset + 3),
- getByte(o, offset + 4),
- getByte(o, offset + 5),
- getByte(o, offset + 6),
- getByte(o, offset + 7));
- }
- }
- /**
- * As {@link #getLongUnaligned(Object, long)} but with an
- * additional argument which specifies the endianness of the value
- * as stored in memory.
- *
- * @param o Java heap object in which the variable resides
- * @param offset The offset in bytes from the start of the object
- * @param bigEndian The endianness of the value
- * @return the value fetched from the indicated object
- * @since 1.9
- */
- public final long getLongUnaligned(Object o, long offset, boolean bigEndian) {
- return convEndian(bigEndian, getLongUnaligned(o, offset));
- }
-
- /** @see #getLongUnaligned(Object, long) */
- @HotSpotIntrinsicCandidate
- public final int getIntUnaligned(Object o, long offset) {
- if ((offset & 3) == 0) {
- return getInt(o, offset);
- } else if ((offset & 1) == 0) {
- return makeInt(getShort(o, offset),
- getShort(o, offset + 2));
- } else {
- return makeInt(getByte(o, offset),
- getByte(o, offset + 1),
- getByte(o, offset + 2),
- getByte(o, offset + 3));
- }
- }
- /** @see #getLongUnaligned(Object, long, boolean) */
- public final int getIntUnaligned(Object o, long offset, boolean bigEndian) {
- return convEndian(bigEndian, getIntUnaligned(o, offset));
- }
-
- /** @see #getLongUnaligned(Object, long) */
- @HotSpotIntrinsicCandidate
- public final short getShortUnaligned(Object o, long offset) {
- if ((offset & 1) == 0) {
- return getShort(o, offset);
- } else {
- return makeShort(getByte(o, offset),
- getByte(o, offset + 1));
- }
- }
- /** @see #getLongUnaligned(Object, long, boolean) */
- public final short getShortUnaligned(Object o, long offset, boolean bigEndian) {
- return convEndian(bigEndian, getShortUnaligned(o, offset));
- }
-
- /** @see #getLongUnaligned(Object, long) */
- @HotSpotIntrinsicCandidate
- public final char getCharUnaligned(Object o, long offset) {
- return (char)getShortUnaligned(o, offset);
- }
-
- /** @see #getLongUnaligned(Object, long, boolean) */
- public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
- return convEndian(bigEndian, getCharUnaligned(o, offset));
- }
-
- /**
- * Stores a value at some byte offset into a given Java object.
- * <p>
- * The specification of this method is the same as {@link
- * #getLong(Object, long)} except that the offset does not need to
- * have been obtained from {@link #objectFieldOffset} on the
- * {@link java.lang.reflect.Field} of some Java field. The value
- * in memory is raw data, and need not correspond to any Java
- * variable. The endianness of the value in memory is the
- * endianness of the native platform.
- * <p>
- * The write will be atomic with respect to the largest power of
- * two that divides the GCD of the offset and the storage size.
- * For example, putLongUnaligned will make atomic writes of 2-, 4-,
- * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
- * respectively. There are no other guarantees of atomicity.
- * <p>
- * 8-byte atomicity is only guaranteed on platforms on which
- * support atomic accesses to longs.
- *
- * @param o Java heap object in which the value resides, if any, else
- * null
- * @param offset The offset in bytes from the start of the object
- * @param x the value to store
- * @throws RuntimeException No defined exceptions are thrown, not even
- * {@link NullPointerException}
- * @since 1.9
- */
- @HotSpotIntrinsicCandidate
- public final void putLongUnaligned(Object o, long offset, long x) {
- if ((offset & 7) == 0) {
- putLong(o, offset, x);
- } else if ((offset & 3) == 0) {
- putLongParts(o, offset,
- (int)(x >> 0),
- (int)(x >>> 32));
- } else if ((offset & 1) == 0) {
- putLongParts(o, offset,
- (short)(x >>> 0),
- (short)(x >>> 16),
- (short)(x >>> 32),
- (short)(x >>> 48));
- } else {
- putLongParts(o, offset,
- (byte)(x >>> 0),
- (byte)(x >>> 8),
- (byte)(x >>> 16),
- (byte)(x >>> 24),
- (byte)(x >>> 32),
- (byte)(x >>> 40),
- (byte)(x >>> 48),
- (byte)(x >>> 56));
- }
- }
-
- /**
- * As {@link #putLongUnaligned(Object, long, long)} but with an additional
- * argument which specifies the endianness of the value as stored in memory.
- * @param o Java heap object in which the value resides
- * @param offset The offset in bytes from the start of the object
- * @param x the value to store
- * @param bigEndian The endianness of the value
- * @throws RuntimeException No defined exceptions are thrown, not even
- * {@link NullPointerException}
- * @since 1.9
- */
- public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) {
- putLongUnaligned(o, offset, convEndian(bigEndian, x));
- }
-
- /** @see #putLongUnaligned(Object, long, long) */
- @HotSpotIntrinsicCandidate
- public final void putIntUnaligned(Object o, long offset, int x) {
- if ((offset & 3) == 0) {
- putInt(o, offset, x);
- } else if ((offset & 1) == 0) {
- putIntParts(o, offset,
- (short)(x >> 0),
- (short)(x >>> 16));
- } else {
- putIntParts(o, offset,
- (byte)(x >>> 0),
- (byte)(x >>> 8),
- (byte)(x >>> 16),
- (byte)(x >>> 24));
- }
- }
- /** @see #putLongUnaligned(Object, long, long, boolean) */
- public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) {
- putIntUnaligned(o, offset, convEndian(bigEndian, x));
- }
-
- /** @see #putLongUnaligned(Object, long, long) */
- @HotSpotIntrinsicCandidate
- public final void putShortUnaligned(Object o, long offset, short x) {
- if ((offset & 1) == 0) {
- putShort(o, offset, x);
- } else {
- putShortParts(o, offset,
- (byte)(x >>> 0),
- (byte)(x >>> 8));
- }
- }
- /** @see #putLongUnaligned(Object, long, long, boolean) */
- public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
- putShortUnaligned(o, offset, convEndian(bigEndian, x));
- }
-
- /** @see #putLongUnaligned(Object, long, long) */
- @HotSpotIntrinsicCandidate
- public final void putCharUnaligned(Object o, long offset, char x) {
- putShortUnaligned(o, offset, (short)x);
- }
- /** @see #putLongUnaligned(Object, long, long, boolean) */
- public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
- putCharUnaligned(o, offset, convEndian(bigEndian, x));
- }
-
// JVM interface methods
private native boolean unalignedAccess0();
private native boolean isBigEndian0();
- // BE is true iff the native endianness of this platform is big.
- private static final boolean BE = theUnsafe.isBigEndian0();
-
- // unalignedAccess is true iff this platform can perform unaligned accesses.
- private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
-
- private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
-
- // These methods construct integers from bytes. The byte ordering
- // is the native endianness of this platform.
- private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
- return ((toUnsignedLong(i0) << pickPos(56, 0))
- | (toUnsignedLong(i1) << pickPos(56, 8))
- | (toUnsignedLong(i2) << pickPos(56, 16))
- | (toUnsignedLong(i3) << pickPos(56, 24))
- | (toUnsignedLong(i4) << pickPos(56, 32))
- | (toUnsignedLong(i5) << pickPos(56, 40))
- | (toUnsignedLong(i6) << pickPos(56, 48))
- | (toUnsignedLong(i7) << pickPos(56, 56)));
- }
- private static long makeLong(short i0, short i1, short i2, short i3) {
- return ((toUnsignedLong(i0) << pickPos(48, 0))
- | (toUnsignedLong(i1) << pickPos(48, 16))
- | (toUnsignedLong(i2) << pickPos(48, 32))
- | (toUnsignedLong(i3) << pickPos(48, 48)));
- }
- private static long makeLong(int i0, int i1) {
- return (toUnsignedLong(i0) << pickPos(32, 0))
- | (toUnsignedLong(i1) << pickPos(32, 32));
- }
- private static int makeInt(short i0, short i1) {
- return (toUnsignedInt(i0) << pickPos(16, 0))
- | (toUnsignedInt(i1) << pickPos(16, 16));
- }
- private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
- return ((toUnsignedInt(i0) << pickPos(24, 0))
- | (toUnsignedInt(i1) << pickPos(24, 8))
- | (toUnsignedInt(i2) << pickPos(24, 16))
- | (toUnsignedInt(i3) << pickPos(24, 24)));
- }
- private static short makeShort(byte i0, byte i1) {
- return (short)((toUnsignedInt(i0) << pickPos(8, 0))
- | (toUnsignedInt(i1) << pickPos(8, 8)));
- }
-
- private static byte pick(byte le, byte be) { return BE ? be : le; }
- private static short pick(short le, short be) { return BE ? be : le; }
- private static int pick(int le, int be) { return BE ? be : le; }
-
- // These methods write integers to memory from smaller parts
- // provided by their caller. The ordering in which these parts
- // are written is the native endianness of this platform.
- private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
- putByte(o, offset + 0, pick(i0, i7));
- putByte(o, offset + 1, pick(i1, i6));
- putByte(o, offset + 2, pick(i2, i5));
- putByte(o, offset + 3, pick(i3, i4));
- putByte(o, offset + 4, pick(i4, i3));
- putByte(o, offset + 5, pick(i5, i2));
- putByte(o, offset + 6, pick(i6, i1));
- putByte(o, offset + 7, pick(i7, i0));
- }
- private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
- putShort(o, offset + 0, pick(i0, i3));
- putShort(o, offset + 2, pick(i1, i2));
- putShort(o, offset + 4, pick(i2, i1));
- putShort(o, offset + 6, pick(i3, i0));
- }
- private void putLongParts(Object o, long offset, int i0, int i1) {
- putInt(o, offset + 0, pick(i0, i1));
- putInt(o, offset + 4, pick(i1, i0));
- }
- private void putIntParts(Object o, long offset, short i0, short i1) {
- putShort(o, offset + 0, pick(i0, i1));
- putShort(o, offset + 2, pick(i1, i0));
- }
- private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
- putByte(o, offset + 0, pick(i0, i3));
- putByte(o, offset + 1, pick(i1, i2));
- putByte(o, offset + 2, pick(i2, i1));
- putByte(o, offset + 3, pick(i3, i0));
- }
- private void putShortParts(Object o, long offset, byte i0, byte i1) {
- putByte(o, offset + 0, pick(i0, i1));
- putByte(o, offset + 1, pick(i1, i0));
- }
-
- // Zero-extend an integer
- private static int toUnsignedInt(byte n) { return n & 0xff; }
- private static int toUnsignedInt(short n) { return n & 0xffff; }
- private static long toUnsignedLong(byte n) { return n & 0xffl; }
- private static long toUnsignedLong(short n) { return n & 0xffffl; }
- private static long toUnsignedLong(int n) { return n & 0xffffffffl; }
-
- // Maybe byte-reverse an integer
- private static char convEndian(boolean big, char n) { return big == BE ? n : Character.reverseBytes(n); }
- private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n) ; }
- private static int convEndian(boolean big, int n) { return big == BE ? n : Integer.reverseBytes(n) ; }
- private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; }
}
--- a/jdk/src/java.base/share/classes/sun/nio/ch/NativeObject.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/NativeObject.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,7 +29,7 @@
package sun.nio.ch; // Formerly in sun.misc
import java.nio.ByteOrder;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
// ## In the fullness of time, this class will be eliminated
--- a/jdk/src/java.base/share/classes/sun/nio/ch/Util.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/ch/Util.java Wed Jul 05 21:00:20 2017 +0200
@@ -35,7 +35,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.misc.Cleaner;
import sun.security.action.GetPropertyAction;
--- a/jdk/src/java.base/share/classes/sun/nio/cs/ArrayDecoder.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/ArrayDecoder.java Wed Jul 05 21:00:20 2017 +0200
@@ -32,4 +32,8 @@
public interface ArrayDecoder {
int decode(byte[] src, int off, int len, char[] dst);
+
+ default boolean isASCIICompatible() {
+ return false;
+ }
}
--- a/jdk/src/java.base/share/classes/sun/nio/cs/ArrayEncoder.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/ArrayEncoder.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,10 +26,24 @@
package sun.nio.cs;
/*
- * FastPath char[]->byte[] encoder, REPLACE on malformed input or
+ * FastPath char[]/byte[] -> byte[] encoder, REPLACE on malformed input or
* unmappable input.
*/
public interface ArrayEncoder {
+
+ // is only used by j.u.zip.ZipCoder for utf8
int encode(char[] src, int off, int len, byte[] dst);
+
+ default int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
+ return -1;
+ }
+
+ default int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+ return -1;
+ }
+
+ default boolean isASCIICompatible() {
+ return false;
+ }
}
--- a/jdk/src/java.base/share/classes/sun/nio/cs/DoubleByte.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/DoubleByte.java Wed Jul 05 21:00:20 2017 +0200
@@ -115,6 +115,7 @@
final char[] b2cSB;
final int b2Min;
final int b2Max;
+ final boolean isASCIICompatible;
// for SimpleEUC override
protected CoderResult crMalformedOrUnderFlow(int b) {
@@ -132,16 +133,23 @@
public Decoder(Charset cs, float avgcpb, float maxcpb,
char[][] b2c, char[] b2cSB,
- int b2Min, int b2Max) {
+ int b2Min, int b2Max,
+ boolean isASCIICompatible) {
super(cs, avgcpb, maxcpb);
this.b2c = b2c;
this.b2cSB = b2cSB;
this.b2Min = b2Min;
this.b2Max = b2Max;
+ this.isASCIICompatible = isASCIICompatible;
+ }
+
+ public Decoder(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
+ boolean isASCIICompatible) {
+ this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max, isASCIICompatible);
}
public Decoder(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
- this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max);
+ this(cs, 0.5f, 1.0f, b2c, b2cSB, b2Min, b2Max, false);
}
protected CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) {
@@ -215,6 +223,7 @@
return decodeBufferLoop(src, dst);
}
+ @Override
public int decode(byte[] src, int sp, int len, char[] dst) {
int dp = 0;
int sl = sp + len;
@@ -230,12 +239,12 @@
if (b2c[b1] == B2C_UNMAPPABLE || // isNotLeadingByte
b2c[b2] != B2C_UNMAPPABLE || // isLeadingByte
decodeSingle(b2) != UNMAPPABLE_DECODING) {
- sp--;
+ sp--;
}
}
}
if (c == UNMAPPABLE_DECODING) {
- c = repl;
+ c = repl;
}
}
dst[dp++] = c;
@@ -243,6 +252,11 @@
return dp;
}
+ @Override
+ public boolean isASCIICompatible() {
+ return isASCIICompatible;
+ }
+
public void implReset() {
super.implReset();
}
@@ -274,8 +288,14 @@
private int currentState;
public Decoder_EBCDIC(Charset cs,
- char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
- super(cs, b2c, b2cSB, b2Min, b2Max);
+ char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
+ boolean isASCIICompatible) {
+ super(cs, b2c, b2cSB, b2Min, b2Max, isASCIICompatible);
+ }
+
+ public Decoder_EBCDIC(Charset cs,
+ char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
+ super(cs, b2c, b2cSB, b2Min, b2Max, false);
}
public void implReset() {
@@ -403,6 +423,7 @@
}
}
+ @Override
public int decode(byte[] src, int sp, int len, char[] dst) {
int dp = 0;
int sl = sp + len;
@@ -451,8 +472,13 @@
b2cSB_UNMAPPABLE = new char[0x100];
Arrays.fill(b2cSB_UNMAPPABLE, UNMAPPABLE_DECODING);
}
+ public Decoder_DBCSONLY(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
+ boolean isASCIICompatible) {
+ super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, isASCIICompatible);
+ }
+
public Decoder_DBCSONLY(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
- super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max);
+ super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, false);
}
}
@@ -464,8 +490,9 @@
private final int SS3 = 0x8F;
public Decoder_EUC_SIM(Charset cs,
- char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
- super(cs, b2c, b2cSB, b2Min, b2Max);
+ char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
+ boolean isASCIICompatible) {
+ super(cs, b2c, b2cSB, b2Min, b2Max, isASCIICompatible);
}
// No support provided for G2/G3 for SimpleEUC
@@ -481,6 +508,7 @@
return CoderResult.unmappableForLength(2);
}
+ @Override
public int decode(byte[] src, int sp, int len, char[] dst) {
int dp = 0;
int sl = sp + len;
@@ -515,17 +543,25 @@
private final char[] c2b;
private final char[] c2bIndex;
protected Surrogate.Parser sgp;
+ final boolean isASCIICompatible;
public Encoder(Charset cs, char[] c2b, char[] c2bIndex) {
+ this(cs, c2b, c2bIndex, false);
+ }
+
+ public Encoder(Charset cs, char[] c2b, char[] c2bIndex, boolean isASCIICompatible) {
super(cs, 2.0f, 2.0f);
this.c2b = c2b;
this.c2bIndex = c2bIndex;
+ this.isASCIICompatible = isASCIICompatible;
}
- public Encoder(Charset cs, float avg, float max, byte[] repl, char[] c2b, char[] c2bIndex) {
+ public Encoder(Charset cs, float avg, float max, byte[] repl, char[] c2b, char[] c2bIndex,
+ boolean isASCIICompatible) {
super(cs, avg, max, repl);
this.c2b = c2b;
this.c2bIndex = c2bIndex;
+ this.isASCIICompatible = isASCIICompatible;
}
public boolean canEncode(char c) {
@@ -624,6 +660,7 @@
repl = newReplacement;
}
+ @Override
public int encode(char[] src, int sp, int len, byte[] dst) {
int dp = 0;
int sl = sp + len;
@@ -647,11 +684,69 @@
} else { // SingleByte
dst[dp++] = (byte)bb;
}
+ }
+ return dp;
+ }
+
+ @Override
+ public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
+ int dp = 0;
+ int sl = sp + len;
+ while (sp < sl) {
+ char c = (char)(src[sp++] & 0xff);
+ int bb = encodeChar(c);
+ if (bb == UNMAPPABLE_ENCODING) {
+ // no surrogate pair in latin1 string
+ dst[dp++] = repl[0];
+ if (repl.length > 1) {
+ dst[dp++] = repl[1];
+ }
+ continue;
+ } //else
+ if (bb > MAX_SINGLEBYTE) { // DoubleByte
+ dst[dp++] = (byte)(bb >> 8);
+ dst[dp++] = (byte)bb;
+ } else { // SingleByte
+ dst[dp++] = (byte)bb;
+ }
}
return dp;
}
+ @Override
+ public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+ int dp = 0;
+ int sl = sp + len;
+ while (sp < sl) {
+ char c = StringUTF16.getChar(src, sp++);
+ int bb = encodeChar(c);
+ if (bb == UNMAPPABLE_ENCODING) {
+ if (Character.isHighSurrogate(c) && sp < sl &&
+ Character.isLowSurrogate(StringUTF16.getChar(src, sp))) {
+ sp++;
+ }
+ dst[dp++] = repl[0];
+ if (repl.length > 1) {
+ dst[dp++] = repl[1];
+ }
+ continue;
+ } //else
+ if (bb > MAX_SINGLEBYTE) { // DoubleByte
+ dst[dp++] = (byte)(bb >> 8);
+ dst[dp++] = (byte)bb;
+ } else { // SingleByte
+ dst[dp++] = (byte)bb;
+ }
+ }
+ return dp;
+ }
+
+ @Override
+ public boolean isASCIICompatible() {
+ return isASCIICompatible;
+ }
+
public int encodeChar(char ch) {
return c2b[c2bIndex[ch >> 8] + (ch & 0xff)];
}
@@ -741,9 +836,11 @@
}
public static class Encoder_DBCSONLY extends Encoder {
+
public Encoder_DBCSONLY(Charset cs, byte[] repl,
- char[] c2b, char[] c2bIndex) {
- super(cs, 2.0f, 2.0f, repl, c2b, c2bIndex);
+ char[] c2b, char[] c2bIndex,
+ boolean isASCIICompatible) {
+ super(cs, 2.0f, 2.0f, repl, c2b, c2bIndex, isASCIICompatible);
}
public int encodeChar(char ch) {
@@ -754,8 +851,6 @@
}
}
-
-
public static class Encoder_EBCDIC extends Encoder {
static final int SBCS = 0;
static final int DBCS = 1;
@@ -764,8 +859,9 @@
protected int currentState = SBCS;
- public Encoder_EBCDIC(Charset cs, char[] c2b, char[] c2bIndex) {
- super(cs, 4.0f, 5.0f, new byte[] {(byte)0x6f}, c2b, c2bIndex);
+ public Encoder_EBCDIC(Charset cs, char[] c2b, char[] c2bIndex,
+ boolean isASCIICompatible) {
+ super(cs, 4.0f, 5.0f, new byte[] {(byte)0x6f}, c2b, c2bIndex, isASCIICompatible);
}
protected void implReset() {
@@ -878,6 +974,7 @@
}
}
+ @Override
public int encode(char[] src, int sp, int len, byte[] dst) {
int dp = 0;
int sl = sp + len;
@@ -917,12 +1014,88 @@
}
return dp;
}
+
+ @Override
+ public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
+ int dp = 0;
+ int sl = sp + len;
+ while (sp < sl) {
+ char c = (char)(src[sp++] & 0xff);
+ int bb = encodeChar(c);
+ if (bb == UNMAPPABLE_ENCODING) {
+ // no surrogate pair in latin1 string
+ dst[dp++] = repl[0];
+ if (repl.length > 1)
+ dst[dp++] = repl[1];
+ continue;
+ } //else
+ if (bb > MAX_SINGLEBYTE) { // DoubleByte
+ if (currentState == SBCS) {
+ currentState = DBCS;
+ dst[dp++] = SO;
+ }
+ dst[dp++] = (byte)(bb >> 8);
+ dst[dp++] = (byte)bb;
+ } else { // SingleByte
+ if (currentState == DBCS) {
+ currentState = SBCS;
+ dst[dp++] = SI;
+ }
+ dst[dp++] = (byte)bb;
+ }
+ }
+ if (currentState == DBCS) {
+ currentState = SBCS;
+ dst[dp++] = SI;
+ }
+ return dp;
+ }
+
+ @Override
+ public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+ int dp = 0;
+ int sl = sp + len;
+ while (sp < sl) {
+ char c = StringUTF16.getChar(src, sp++);
+ int bb = encodeChar(c);
+ if (bb == UNMAPPABLE_ENCODING) {
+ if (Character.isHighSurrogate(c) && sp < sl &&
+ Character.isLowSurrogate(StringUTF16.getChar(src, sp))) {
+ sp++;
+ }
+ dst[dp++] = repl[0];
+ if (repl.length > 1)
+ dst[dp++] = repl[1];
+ continue;
+ } //else
+ if (bb > MAX_SINGLEBYTE) { // DoubleByte
+ if (currentState == SBCS) {
+ currentState = DBCS;
+ dst[dp++] = SO;
+ }
+ dst[dp++] = (byte)(bb >> 8);
+ dst[dp++] = (byte)bb;
+ } else { // SingleByte
+ if (currentState == DBCS) {
+ currentState = SBCS;
+ dst[dp++] = SI;
+ }
+ dst[dp++] = (byte)bb;
+ }
+ }
+ if (currentState == DBCS) {
+ currentState = SBCS;
+ dst[dp++] = SI;
+ }
+ return dp;
+ }
}
// EUC_SIMPLE
public static class Encoder_EUC_SIM extends Encoder {
- public Encoder_EUC_SIM(Charset cs, char[] c2b, char[] c2bIndex) {
- super(cs, c2b, c2bIndex);
+ public Encoder_EUC_SIM(Charset cs, char[] c2b, char[] c2bIndex,
+ boolean isASCIICompatible) {
+ super(cs, c2b, c2bIndex, isASCIICompatible);
}
}
--- a/jdk/src/java.base/share/classes/sun/nio/cs/HKSCS.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/HKSCS.java Wed Jul 05 21:00:20 2017 +0200
@@ -53,7 +53,7 @@
// super(cs, 0.5f, 1.0f);
// need to extends DoubleByte.Decoder so the
// sun.io can use it. this implementation
- super(cs, 0.5f, 1.0f, null, null, 0, 0);
+ super(cs, 0.5f, 1.0f, null, null, 0, 0, true);
this.big5Dec = big5Dec;
this.b2cBmp = b2cBmp;
this.b2cSupp = b2cSupp;
@@ -239,7 +239,7 @@
char[][] c2bBmp,
char[][] c2bSupp)
{
- super(cs, null, null);
+ super(cs, null, null, true);
this.big5Enc = big5Enc;
this.c2bBmp = c2bBmp;
this.c2bSupp = c2bSupp;
@@ -389,6 +389,33 @@
return dp;
}
+ public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+ int dp = 0;
+ int sl = sp + len;
+ int dl = dst.length;
+ while (sp < sl) {
+ char c = StringUTF16.getChar(src, sp++);
+ int bb = encodeChar(c);
+ if (bb == UNMAPPABLE_ENCODING) {
+ if (!Character.isHighSurrogate(c) || sp == sl ||
+ !Character.isLowSurrogate(StringUTF16.getChar(src,sp)) ||
+ (bb = encodeSupp(Character.toCodePoint(c, StringUTF16.getChar(src, sp++))))
+ == UNMAPPABLE_ENCODING) {
+ dst[dp++] = repl[0];
+ if (repl.length > 1)
+ dst[dp++] = repl[1];
+ continue;
+ }
+ }
+ if (bb > MAX_SINGLEBYTE) { // DoubleByte
+ dst[dp++] = (byte)(bb >> 8);
+ dst[dp++] = (byte)bb;
+ } else { // SingleByte
+ dst[dp++] = (byte)bb;
+ }
+ }
+ return dp;
+ }
static char[] C2B_UNMAPPABLE = new char[0x100];
static {
--- a/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java Wed Jul 05 21:00:20 2017 +0200
@@ -132,6 +132,10 @@
dst[dp++] = (char)(src[sp++] & 0xff);
return dp;
}
+
+ public boolean isASCIICompatible() {
+ return true;
+ }
}
private static class Encoder extends CharsetEncoder
@@ -297,5 +301,9 @@
}
return dp;
}
+
+ public boolean isASCIICompatible() {
+ return true;
+ }
}
}
--- a/jdk/src/java.base/share/classes/sun/nio/cs/SingleByte.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/SingleByte.java Wed Jul 05 21:00:20 2017 +0200
@@ -49,10 +49,18 @@
public static final class Decoder extends CharsetDecoder
implements ArrayDecoder {
private final char[] b2c;
+ private final boolean isASCIICompatible;
public Decoder(Charset cs, char[] b2c) {
super(cs, 1.0f, 1.0f);
this.b2c = b2c;
+ this.isASCIICompatible = false;
+ }
+
+ public Decoder(Charset cs, char[] b2c, boolean isASCIICompatible) {
+ super(cs, 1.0f, 1.0f);
+ this.b2c = b2c;
+ this.isASCIICompatible = isASCIICompatible;
}
private CoderResult decodeArrayLoop(ByteBuffer src, CharBuffer dst) {
@@ -116,6 +124,7 @@
repl = newReplacement.charAt(0);
}
+ @Override
public int decode(byte[] src, int sp, int len, char[] dst) {
if (len > dst.length)
len = dst.length;
@@ -129,6 +138,11 @@
}
return dp;
}
+
+ @Override
+ public boolean isASCIICompatible() {
+ return isASCIICompatible;
+ }
}
public static final class Encoder extends CharsetEncoder
@@ -136,11 +150,13 @@
private Surrogate.Parser sgp;
private final char[] c2b;
private final char[] c2bIndex;
+ private final boolean isASCIICompatible;
- public Encoder(Charset cs, char[] c2b, char[] c2bIndex) {
+ public Encoder(Charset cs, char[] c2b, char[] c2bIndex, boolean isASCIICompatible) {
super(cs, 1.0f, 1.0f);
this.c2b = c2b;
this.c2bIndex = c2bIndex;
+ this.isASCIICompatible = isASCIICompatible;
}
public boolean canEncode(char c) {
@@ -252,6 +268,51 @@
}
return dp;
}
+
+ @Override
+ public int encodeFromLatin1(byte[] src, int sp, int len, byte[] dst) {
+ int dp = 0;
+ int sl = sp + Math.min(len, dst.length);
+ while (sp < sl) {
+ char c = (char)(src[sp++] & 0xff);
+ int b = encode(c);
+ if (b == UNMAPPABLE_ENCODING) {
+ dst[dp++] = repl;
+ } else {
+ dst[dp++] = (byte)b;
+ }
+ }
+ return dp;
+ }
+
+ @Override
+ public int encodeFromUTF16(byte[] src, int sp, int len, byte[] dst) {
+ int dp = 0;
+ int sl = sp + Math.min(len, dst.length);
+ while (sp < sl) {
+ char c = StringUTF16.getChar(src, sp++);
+ int b = encode(c);
+ if (b != UNMAPPABLE_ENCODING) {
+ dst[dp++] = (byte)b;
+ continue;
+ }
+ if (Character.isHighSurrogate(c) && sp < sl &&
+ Character.isLowSurrogate(StringUTF16.getChar(src, sp))) {
+ if (len > dst.length) {
+ sl++;
+ len--;
+ }
+ sp++;
+ }
+ dst[dp++] = repl;
+ }
+ return dp;
+ }
+
+ @Override
+ public boolean isASCIICompatible() {
+ return isASCIICompatible;
+ }
}
// init the c2b and c2bIndex tables from b2c.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/StringUTF16.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.cs;
+
+import static sun.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET;
+import static sun.misc.Unsafe.ARRAY_BYTE_INDEX_SCALE;
+
+class StringUTF16 {
+
+ public static char getChar(byte[] val, int index) {
+ return unsafe.getChar(val,
+ ARRAY_BYTE_BASE_OFFSET + ARRAY_BYTE_INDEX_SCALE * index * 2L);
+ }
+
+ private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+}
--- a/jdk/src/java.base/share/classes/sun/nio/cs/US_ASCII.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/US_ASCII.java Wed Jul 05 21:00:20 2017 +0200
@@ -146,6 +146,10 @@
}
return dp;
}
+
+ public boolean isASCIICompatible() {
+ return true;
+ }
}
private static class Encoder extends CharsetEncoder
@@ -259,6 +263,10 @@
}
return dp;
}
+
+ public boolean isASCIICompatible() {
+ return true;
+ }
}
}
--- a/jdk/src/java.base/share/classes/sun/nio/cs/UTF_8.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/UTF_8.java Wed Jul 05 21:00:20 2017 +0200
@@ -549,6 +549,10 @@
}
return dp;
}
+
+ public boolean isASCIICompatible() {
+ return true;
+ }
}
private static final class Encoder extends CharsetEncoder
@@ -742,5 +746,9 @@
}
return dp;
}
+
+ public boolean isASCIICompatible() {
+ return true;
+ }
}
}
--- a/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/Cancellable.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,7 +26,7 @@
package sun.nio.fs;
import sun.misc.ManagedLocalsThread;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import java.util.concurrent.ExecutionException;
/**
--- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffer.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,7 +25,7 @@
package sun.nio.fs;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.misc.Cleaner;
/**
--- a/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/nio/fs/NativeBuffers.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,7 +25,7 @@
package sun.nio.fs;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Factory for native buffers.
--- a/jdk/src/java.base/share/classes/sun/reflect/AccessorGenerator.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/AccessorGenerator.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,7 +26,7 @@
package sun.reflect;
import java.lang.reflect.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/** Shared functionality for all accessor generators */
--- a/jdk/src/java.base/share/classes/sun/reflect/ClassDefiner.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/ClassDefiner.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/** Utility class which assists in calling Unsafe.defineClass() by
creating a new class loader which delegates to the one needed in
--- a/jdk/src/java.base/share/classes/sun/reflect/FieldInfo.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/FieldInfo.java Wed Jul 05 21:00:20 2017 +0200
@@ -38,7 +38,7 @@
private String signature;
private int modifiers;
// This is compatible with the old reflection implementation's
- // "slot" value to allow sun.misc.Unsafe to work
+ // "slot" value to allow jdk.internal.misc.Unsafe to work
private int slot;
// Not really necessary to provide a constructor since the VM
--- a/jdk/src/java.base/share/classes/sun/reflect/MagicAccessorImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/MagicAccessorImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -32,7 +32,7 @@
fields and methods of other classes. It is used to hold the code
for dynamically-generated FieldAccessorImpl and MethodAccessorImpl
subclasses. (Use of the word "unsafe" was avoided in this class's
- name to avoid confusion with {@link sun.misc.Unsafe}.) </P>
+ name to avoid confusion with {@link jdk.internal.misc.Unsafe}.) </P>
<P> The bug fix for 4486457 also necessitated disabling
verification for this class and all subclasses, as opposed to just
--- a/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/ReflectionFactory.java Wed Jul 05 21:00:20 2017 +0200
@@ -44,7 +44,7 @@
subversion of both the language and the verifier. For this reason,
they are all instance methods, and access to the constructor of
this factory is guarded by a security check, in similar style to
- {@link sun.misc.Unsafe}. </P>
+ {@link jdk.internal.misc.Unsafe}. </P>
*/
public class ReflectionFactory {
--- a/jdk/src/java.base/share/classes/sun/reflect/UnsafeFieldAccessorImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/UnsafeFieldAccessorImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,9 +27,9 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
-/** Base class for sun.misc.Unsafe-based FieldAccessors. The
+/** Base class for jdk.internal.misc.Unsafe-based FieldAccessors. The
observation is that there are only nine types of fields from the
standpoint of reflection code: the eight primitive types and
Object. Using class Unsafe instead of generated bytecodes saves
--- a/jdk/src/java.base/share/classes/sun/reflect/UnsafeQualifiedFieldAccessorImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/UnsafeQualifiedFieldAccessorImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,10 +27,10 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
- * Base class for sun.misc.Unsafe-based FieldAccessors for fields with
+ * Base class for jdk.internal.misc.Unsafe-based FieldAccessors for fields with
* final or volatile qualifiers. These differ from unqualified
* versions in that (1) they check for read-only status (2) they use
* the volatile forms of Unsafe get/put methods. (When accessed via
--- a/jdk/src/java.base/share/classes/sun/reflect/UnsafeQualifiedStaticFieldAccessorImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/UnsafeQualifiedStaticFieldAccessorImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -28,9 +28,9 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
-/** Base class for sun.misc.Unsafe-based FieldAccessors for final or
+/** Base class for jdk.internal.misc.Unsafe-based FieldAccessors for final or
static volatile fields. */
abstract class UnsafeQualifiedStaticFieldAccessorImpl
--- a/jdk/src/java.base/share/classes/sun/reflect/UnsafeStaticFieldAccessorImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/UnsafeStaticFieldAccessorImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -28,9 +28,9 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
-/** Base class for sun.misc.Unsafe-based FieldAccessors for static
+/** Base class for jdk.internal.misc.Unsafe-based FieldAccessors for static
fields. The observation is that there are only nine types of
fields from the standpoint of reflection code: the eight primitive
types and Object. Using class Unsafe instead of generated
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Wed Jul 05 21:00:20 2017 +0200
@@ -337,7 +337,7 @@
/**
* Checks if {@code Class cls} is a VM-anonymous class
- * as defined by {@link sun.misc.Unsafe#defineAnonymousClass}
+ * as defined by {@link jdk.internal.misc.Unsafe#defineAnonymousClass}
* (not to be confused with a Java Language anonymous inner class).
*/
public static boolean isVMAnonymousClass(Class<?> cls) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,7 +30,7 @@
import java.nio.ByteOrder;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Optimized methods for converting between byte[] and int[]/long[], both for
--- a/jdk/src/java.base/share/native/libjava/String.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libjava/String.c Wed Jul 05 21:00:20 2017 +0200
@@ -31,3 +31,14 @@
{
return JVM_InternString(env, this);
}
+
+JNIEXPORT jboolean JNICALL
+Java_java_lang_StringUTF16_isBigEndian(JNIEnv *env, jclass cls)
+{
+ unsigned int endianTest = 0xff000000;
+ if (((char*)(&endianTest))[0] != 0) {
+ return JNI_TRUE;
+ } else {
+ return JNI_FALSE;
+ }
+}
--- a/jdk/src/java.base/share/native/libjava/check_version.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libjava/check_version.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,10 +24,11 @@
*/
#include "jni.h"
+#include "jni_util.h"
#include "jvm.h"
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
jint vm_version = JVM_GetInterfaceVersion();
if (vm_version != JVM_INTERFACE_VERSION) {
--- a/jdk/src/java.base/share/native/libjava/jio.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libjava/jio.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "jni.h"
+#ifndef STATIC_BUILD
/* This is a temporary solution until we figure out how to let native
* libraries use jio_* without linking with the VM.
@@ -63,3 +64,6 @@
return len;
}
+
+#endif
+
--- a/jdk/src/java.base/share/native/libjava/jni_util.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libjava/jni_util.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -389,6 +389,117 @@
extern size_t getLastErrorString(char *buf, size_t len);
extern int getErrorString(int err, char *buf, size_t len);
+
+#ifdef STATIC_BUILD
+/* Macros for handling declaration of static/dynamic
+ * JNI library Load/Unload functions
+ *
+ * Use DEF_JNI_On{Un}Load when you want a static and non-static entry points.
+ * Use DEF_STATIC_JNI_On{Un}Load when you only want a static one.
+ *
+ * LIBRARY_NAME must be set to the name of the library
+ */
+
+/* These three macros are needed to get proper concatenation of
+ * the LIBRARY_NAME
+ *
+ * NOTE: LIBRARY_NAME must be set for static builds.
+ */
+#define ADD_LIB_NAME3(name, lib) name ## lib
+#define ADD_LIB_NAME2(name, lib) ADD_LIB_NAME3(name, lib)
+#define ADD_LIB_NAME(entry) ADD_LIB_NAME2(entry, LIBRARY_NAME)
+
+#define DEF_JNI_OnLoad \
+ADD_LIB_NAME(JNI_OnLoad_)(JavaVM *vm, void *reserved) \
+{ \
+ jint JNICALL ADD_LIB_NAME(JNI_OnLoad_dynamic_)(JavaVM *vm, void *reserved); \
+ ADD_LIB_NAME(JNI_OnLoad_dynamic_)(vm, reserved); \
+ return JNI_VERSION_1_8; \
+} \
+jint JNICALL ADD_LIB_NAME(JNI_OnLoad_dynamic_)
+
+#define DEF_STATIC_JNI_OnLoad \
+JNIEXPORT jint JNICALL ADD_LIB_NAME(JNI_OnLoad_)(JavaVM *vm, void *reserved) { \
+ return JNI_VERSION_1_8; \
+}
+
+#define DEF_JNI_OnUnload \
+ADD_LIB_NAME(JNI_OnUnload_)(JavaVM *vm, void *reserved) \
+{ \
+ void JNICALL ADD_LIB_NAME(JNI_OnUnload_dynamic_)(JavaVM *vm, void *reserved); \
+ ADD_LIB_NAME(JNI_OnUnload_dynamic_)(vm, reserved); \
+} \
+void JNICALL ADD_LIB_NAME(JNI_OnUnload_dynamic_)
+
+#define DEF_STATIC_JNI_OnUnload \
+ADD_LIB_NAME(JNI_OnUnload_)
+
+#else
+
+#define DEF_JNI_OnLoad JNI_OnLoad
+#define DEF_STATIC_JNI_OnLoad
+#define DEF_JNI_OnUnload JNI_OnUnload
+#define DEF_STATIC_JNI_OnUnload
+#endif
+
+#ifdef STATIC_BUILD
+/* Macros for handling declaration of static/dynamic
+ * Agent library Load/Attach/Unload functions
+ *
+ * Use DEF_Agent_OnLoad, DEF_Agent_OnAttach or DEF_Agent_OnUnload
+ * when you want both static and non-static entry points.
+ * Use DEF_STATIC_Agent_OnLoad, DEF_STATIC_Agent_OnAttach or
+ * DEF_STATIC_Agent_OnUnload when you only want a static one.
+ *
+ * LIBRARY_NAME must be set to the name of the library for static builds.
+ */
+
+#define DEF_Agent_OnLoad \
+ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) \
+{ \
+ jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)(JavaVM *vm, char *options, void *reserved); \
+ return ADD_LIB_NAME(Agent_OnLoad_dynamic_)(vm, options, reserved); \
+} \
+jint JNICALL ADD_LIB_NAME(Agent_OnLoad_dynamic_)
+
+#define DEF_STATIC_Agent_OnLoad \
+JNIEXPORT jint JNICALL ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) { \
+ return JNI_FALSE; \
+}
+
+#define DEF_Agent_OnAttach \
+ADD_LIB_NAME(Agent_OnAttach_)(JavaVM *vm, char *options, void *reserved) \
+{ \
+ jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)(JavaVM *vm, char *options, void *reserved); \
+ return ADD_LIB_NAME(Agent_OnAttach_dynamic_)(vm, options, reserved); \
+} \
+jint JNICALL ADD_LIB_NAME(Agent_OnAttach_dynamic_)
+
+#define DEF_STATIC_Agent_OnAttach \
+JNIEXPORT jint JNICALL ADD_LIB_NAME(Agent_OnLoad_)(JavaVM *vm, char *options, void *reserved) { \
+ return JNI_FALSE; \
+}
+
+#define DEF_Agent_OnUnload \
+ADD_LIB_NAME(Agent_OnUnload_)(JavaVM *vm) \
+{ \
+ void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)(JavaVM *vm); \
+ ADD_LIB_NAME(Agent_OnUnload_dynamic_)(vm); \
+} \
+void JNICALL ADD_LIB_NAME(Agent_OnUnload_dynamic_)
+
+#define DEF_STATIC_Agent_OnUnload \
+ADD_LIB_NAME(Agent_OnUnload_)
+
+#else
+#define DEF_Agent_OnLoad Agent_OnLoad
+#define DEF_Agent_OnAttach Agent_OnAttach
+#define DEF_Agent_OnUnload Agent_OnUnload
+#define DEF_STATIC_Agent_OnLoad
+#define DEF_STATIC_Agent_OnAttach
+#define DEF_STATIC_Agent_OnUnload
+#endif
+
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
--- a/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -26,6 +26,7 @@
#include <string.h>
#include "jni.h"
+#include "jni_util.h"
#include "endian.hpp"
#include "imageDecompressor.hpp"
@@ -246,7 +247,7 @@
}
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved) {
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_2) != JNI_OK) {
@@ -646,6 +647,6 @@
return module;
}
-JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
+JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *vm, void *reserved) {
ImageDecompressor::image_decompressor_close();
}
--- a/jdk/src/java.base/share/native/libjimage/imageFile.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libjimage/imageFile.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -118,7 +118,7 @@
// Deflate the attribute stream into an array of attributes.
u1 byte;
// Repeat until end header is found.
- while ((byte = *data)) {
+ while ((data != NULL) && (byte = *data)) {
// Extract kind from header byte.
u1 kind = attribute_kind(byte);
assert(kind < ATTRIBUTE_COUNT && "invalid image location attribute");
@@ -191,7 +191,7 @@
// Release module data resource.
ImageModuleData::~ImageModuleData() {
if (_data) {
- delete _data;
+ delete[] _data;
}
}
@@ -274,7 +274,7 @@
}
ImageFileReaderTable::~ImageFileReaderTable() {
- delete _table;
+ delete[] _table;
}
// Add a new image entry to the table.
@@ -414,7 +414,7 @@
close();
// Free up name.
if (_name) {
- delete _name;
+ delete[] _name;
_name = NULL;
}
}
@@ -668,7 +668,7 @@
&strings);
// If not memory mapped then release temporary buffer.
if (!MemoryMapImage) {
- delete compressed_data;
+ delete[] compressed_data;
}
} else {
// Read bytes from offset beyond the image index.
--- a/jdk/src/java.base/share/native/libnet/net_util.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libnet/net_util.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,7 @@
}
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env;
jclass iCls;
--- a/jdk/src/java.base/share/native/libnio/nio_util.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libnio/nio_util.c Wed Jul 05 21:00:20 2017 +0200
@@ -28,7 +28,7 @@
#include "jni_util.h"
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
JNIEnv *env;
--- a/jdk/src/java.base/share/native/libverify/check_code.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libverify/check_code.c Wed Jul 05 21:00:20 2017 +0200
@@ -86,6 +86,7 @@
#include <stdlib.h>
#include "jni.h"
+#include "jni_util.h"
#include "jvm.h"
#include "classfile_constants.h"
#include "opcodes.in_out"
@@ -481,6 +482,11 @@
static void print_formatted_methodname(context_type *context, int index);
#endif
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
void initialize_class_hash(context_type *context)
{
hash_table_type *class_hash = &(context->class_hash);
--- a/jdk/src/java.base/share/native/libzip/ZipFile.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/share/native/libzip/ZipFile.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,12 @@
static int OPEN_READ = java_util_zip_ZipFile_OPEN_READ;
static int OPEN_DELETE = java_util_zip_ZipFile_OPEN_DELETE;
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
JNIEXPORT void JNICALL
Java_java_util_zip_ZipFile_initIDs(JNIEnv *env, jclass cls)
{
--- a/jdk/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/solaris/classes/sun/nio/ch/EventPortWrapper.java Wed Jul 05 21:00:20 2017 +0200
@@ -31,7 +31,7 @@
import java.util.HashMap;
import java.util.Map;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.security.action.GetIntegerAction;
import static sun.nio.ch.SolarisEventPort.*;
--- a/jdk/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java Wed Jul 05 21:00:20 2017 +0200
@@ -28,7 +28,7 @@
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.util.concurrent.RejectedExecutionException;
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Provides an AsynchronousChannelGroup implementation based on the Solaris 10
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,7 +29,7 @@
import java.nio.file.attribute.*;
import java.util.*;
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixConstants.*;
import static sun.nio.fs.SolarisConstants.*;
--- a/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisWatchService.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/solaris/classes/sun/nio/fs/SolarisWatchService.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,7 +30,7 @@
import java.security.PrivilegedAction;
import java.util.*;
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.UnixConstants.*;
--- a/jdk/src/java.base/unix/native/libjava/jlong_md.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/unix/native/libjava/jlong_md.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,11 +65,19 @@
#define jlong_zero_init ((jlong) 0L)
#ifdef _LP64
-#define jlong_to_ptr(a) ((void*)(a))
-#define ptr_to_jlong(a) ((jlong)(a))
+ #ifndef jlong_to_ptr
+ #define jlong_to_ptr(a) ((void*)(a))
+ #endif
+ #ifndef ptr_to_jlong
+ #define ptr_to_jlong(a) ((jlong)(a))
+ #endif
#else
-#define jlong_to_ptr(a) ((void*)(int)(a))
-#define ptr_to_jlong(a) ((jlong)(int)(a))
+ #ifndef jlong_to_ptr
+ #define jlong_to_ptr(a) ((void*)(int)(a))
+ #endif
+ #ifndef ptr_to_jlong
+ #define ptr_to_jlong(a) ((jlong)(int)(a))
+ #endif
#endif
#define jint_to_jlong(a) ((jlong)(a))
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/Iocp.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/Iocp.java Wed Jul 05 21:00:20 2017 +0200
@@ -36,7 +36,7 @@
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Windows implementation of AsynchronousChannelGroup encapsulating an I/O
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/PendingIoCache.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/PendingIoCache.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
import java.nio.channels.*;
import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Maintains a mapping of pending I/O requests (identified by the address of
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -33,7 +33,7 @@
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Windows implementation of AsynchronousServerSocketChannel using overlapped I/O.
--- a/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -34,7 +34,7 @@
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Windows implementation of AsynchronousSocketChannel using overlapped I/O.
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java Wed Jul 05 21:00:20 2017 +0200
@@ -28,7 +28,7 @@
import java.nio.file.attribute.*;
import java.util.concurrent.TimeUnit;
import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.security.action.GetPropertyAction;
import static sun.nio.fs.WindowsNativeDispatcher.*;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -33,7 +33,7 @@
import java.io.*;
import java.util.*;
import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.nio.ch.ThreadPool;
import sun.security.util.SecurityConstants;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsLinkSupport.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsLinkSupport.java Wed Jul 05 21:00:20 2017 +0200
@@ -30,7 +30,7 @@
import java.io.IOError;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.WindowsNativeDispatcher.*;
import static sun.nio.fs.WindowsConstants.*;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsNativeDispatcher.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Win32 and library calls.
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsSecurityDescriptor.java Wed Jul 05 21:00:20 2017 +0200
@@ -29,7 +29,7 @@
import java.nio.file.attribute.*;
import java.util.*;
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.WindowsNativeDispatcher.*;
import static sun.nio.fs.WindowsConstants.*;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java Wed Jul 05 21:00:20 2017 +0200
@@ -31,7 +31,7 @@
import java.nio.channels.FileChannel;
import java.io.IOException;
import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.WindowsNativeDispatcher.*;
import static sun.nio.fs.WindowsConstants.*;
--- a/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.base/windows/classes/sun/nio/fs/WindowsWatchService.java Wed Jul 05 21:00:20 2017 +0200
@@ -36,7 +36,7 @@
import java.util.Set;
import com.sun.nio.file.ExtendedWatchEventModifier;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import static sun.nio.fs.WindowsNativeDispatcher.*;
import static sun.nio.fs.WindowsConstants.*;
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/LWCToolkit.m Wed Jul 05 21:00:20 2017 +0200
@@ -740,7 +740,7 @@
JNF_COCOA_EXIT(env)
}
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
OSXAPP_SetJavaVM(vm);
// We need to let Foundation know that this is a multithreaded application, if it isn't already.
--- a/jdk/src/java.desktop/macosx/native/libjawt/jawt.m Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libjawt/jawt.m Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,12 +24,18 @@
*/
#import <jawt.h>
+#import "jni_util.h"
#import <jawt_md.h>
#import "awt_DrawingSurface.h"
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Get the AWT native structure.
* This function returns JNI_FALSE if an error occurs.
*/
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.h Wed Jul 05 21:00:20 2017 +0200
@@ -23,6 +23,12 @@
* questions.
*/
+/*
+ * Must include this before JavaNativeFoundation.h to get jni.h from build
+ */
+#include "jni.h"
+#include "jni_util.h"
+
#import <Cocoa/Cocoa.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
--- a/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libosxapp/NSApplicationAWT.m Wed Jul 05 21:00:20 2017 +0200
@@ -33,6 +33,10 @@
#import "QueuingApplicationDelegate.h"
#import "AWTIconData.h"
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
static BOOL sUsingDefaultNIB = YES;
static NSString *SHARED_FRAMEWORK_BUNDLE = @"/System/Library/Frameworks/JavaVM.framework";
@@ -432,10 +436,10 @@
@end
-void OSXAPP_SetApplicationDelegate(id <NSApplicationDelegate> delegate)
+void OSXAPP_SetApplicationDelegate(id <NSApplicationDelegate> newdelegate)
{
AWT_ASSERT_APPKIT_THREAD;
- applicationDelegate = delegate;
+ applicationDelegate = newdelegate;
if (NSApp != nil) {
[NSApp setDelegate: applicationDelegate];
--- a/jdk/src/java.desktop/macosx/native/libosxui/AquaLookAndFeel.m Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libosxui/AquaLookAndFeel.m Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,10 @@
* questions.
*/
+// Must include this before JavaNativeFoundation.h to get jni.h from build
+#include "jni.h"
+#include "jni_util.h"
+
#import <JavaNativeFoundation/JavaNativeFoundation.h>
/*
@@ -30,6 +34,7 @@
* <rdar://4984599> AWT's JNI_OnLoad called multiple times
* Please remove when <rdar://5121166> has been resolved.
*/
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
+{
return JNI_VERSION_1_4;
}
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,7 +25,7 @@
package sun.awt;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import javax.accessibility.AccessibleContext;
import java.awt.*;
--- a/jdk/src/java.desktop/share/classes/sun/font/StrikeCache.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/font/StrikeCache.java Wed Jul 05 21:00:20 2017 +0200
@@ -37,7 +37,7 @@
import sun.java2d.pipe.BufferedContext;
import sun.java2d.pipe.RenderQueue;
import sun.java2d.pipe.hw.AccelGraphicsConfig;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/RenderBuffer.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/RenderBuffer.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,7 +25,7 @@
package sun.java2d.pipe;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
--- a/jdk/src/java.desktop/share/classes/sun/swing/SwingAccessor.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/sun/swing/SwingAccessor.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,7 +25,7 @@
package sun.swing;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import java.awt.*;
import javax.swing.*;
--- a/jdk/src/java.desktop/share/native/libfontmanager/sunFont.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/native/libfontmanager/sunFont.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,10 @@
static void *theNullScalerContext = NULL;
extern void AccelGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph);
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
JNIEXPORT jlong JNICALL
Java_sun_font_NullFontScaler_getNullScalerContext
--- a/jdk/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,7 @@
JavaVM *jvm;
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
jvm = vm;
return JNI_VERSION_1_2;
--- a/jdk/src/java.desktop/share/native/libjsound/Platform.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/native/libjsound/Platform.c Wed Jul 05 21:00:20 2017 +0200
@@ -28,6 +28,10 @@
// Platform.java includes
#include "com_sun_media_sound_Platform.h"
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
/*
* Class: com_sun_media_sound_Platform
--- a/jdk/src/java.desktop/share/native/libjsound/Utilities.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/native/libjsound/Utilities.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
*/
#include <jni.h>
+#include "jni_util.h"
#include "SoundDefs.h"
#include "Configure.h" // put flags for debug msgs etc. here
--- a/jdk/src/java.desktop/share/native/liblcms/LCMS.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/native/liblcms/LCMS.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -134,7 +134,7 @@
JNU_ThrowByName(env, "java/awt/color/CMMException", errMsg);
}
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *jvm, void *reserved) {
javaVM = jvm;
cmsSetLogErrorHandler(errorHandler);
--- a/jdk/src/java.desktop/share/native/libmlib_image/mlib_ImageUtils.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/native/libmlib_image/mlib_ImageUtils.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,14 @@
#include "mlib_image.h"
+#include <jni.h>
+#include "jni_util.h"
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
/***************************************************************/
typedef union {
mlib_d64 db;
--- a/jdk/src/java.desktop/share/native/libsplashscreen/java_awt_SplashScreen.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/share/native/libsplashscreen/java_awt_SplashScreen.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
#include <sizecalc.h>
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM * vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM * vm, void *reserved)
{
return JNI_VERSION_1_2;
}
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDConstants.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDConstants.java Wed Jul 05 21:00:20 2017 +0200
@@ -31,7 +31,7 @@
import java.util.Arrays;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Motif DnD protocol global constants and convenience routines.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDDragSourceProtocol.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDDragSourceProtocol.java Wed Jul 05 21:00:20 2017 +0200
@@ -33,7 +33,7 @@
import java.util.Map;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* XDragSourceProtocol implementation for Motif DnD protocol.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/MotifDnDDropTargetProtocol.java Wed Jul 05 21:00:20 2017 +0200
@@ -33,7 +33,7 @@
import java.io.IOException;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* XDropTargetProtocol implementation for Motif DnD protocol.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/Native.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/Native.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,7 +25,7 @@
package sun.awt.X11;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import java.util.Vector;
import java.security.AccessController;
import java.security.PrivilegedAction;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/UnsafeXDisposerRecord.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/UnsafeXDisposerRecord.java Wed Jul 05 21:00:20 2017 +0200
@@ -24,7 +24,7 @@
*/
package sun.awt.X11;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.util.logging.PlatformLogger;
class UnsafeXDisposerRecord implements sun.java2d.DisposerRecord {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/WindowPropertyGetter.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/WindowPropertyGetter.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,7 +26,7 @@
package sun.awt.X11;
import java.util.*;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
public class WindowPropertyGetter {
private static Unsafe unsafe = XlibWrapper.unsafe;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XAtom.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XAtom.java Wed Jul 05 21:00:20 2017 +0200
@@ -55,7 +55,7 @@
* @since 1.5
*/
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import java.util.HashMap;
public final class XAtom {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDnDDragSourceProtocol.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDnDDragSourceProtocol.java Wed Jul 05 21:00:20 2017 +0200
@@ -35,7 +35,7 @@
import sun.util.logging.PlatformLogger;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* XDragSourceProtocol implementation for XDnD protocol.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDnDDropTargetProtocol.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDnDDropTargetProtocol.java Wed Jul 05 21:00:20 2017 +0200
@@ -35,7 +35,7 @@
import sun.util.logging.PlatformLogger;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* XDropTargetProtocol implementation for XDnD protocol.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDropTargetContextPeer.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XDropTargetContextPeer.java Wed Jul 05 21:00:20 2017 +0200
@@ -41,7 +41,7 @@
import sun.awt.dnd.SunDropTargetContextPeer;
import sun.awt.dnd.SunDropTargetEvent;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* The XDropTargetContextPeer is the class responsible for handling
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedHelper.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedHelper.java Wed Jul 05 21:00:20 2017 +0200
@@ -25,7 +25,7 @@
package sun.awt.X11;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.util.logging.PlatformLogger;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XKeysym.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XKeysym.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
package sun.awt.X11;
import java.util.Hashtable;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.util.logging.PlatformLogger;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XQueryTree.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XQueryTree.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
package sun.awt.X11;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
public class XQueryTree {
private static Unsafe unsafe = XlibWrapper.unsafe;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTranslateCoordinates.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTranslateCoordinates.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
package sun.awt.X11;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
public class XTranslateCoordinates {
private static Unsafe unsafe = XlibWrapper.unsafe;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWM.java Wed Jul 05 21:00:20 2017 +0200
@@ -31,7 +31,7 @@
package sun.awt.X11;
import sun.awt.IconInfo;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import java.awt.Insets;
import java.awt.Frame;
import java.awt.Rectangle;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XlibWrapper.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XlibWrapper.java Wed Jul 05 21:00:20 2017 +0200
@@ -27,7 +27,7 @@
import java.security.AccessController;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
import sun.security.action.GetPropertyAction;
final class XlibWrapper {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/keysym2ucs.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/keysym2ucs.h Wed Jul 05 21:00:20 2017 +0200
@@ -65,7 +65,7 @@
tojava
tojava package sun.awt.X11;
tojava import java.util.Hashtable;
-tojava import sun.misc.Unsafe;
+tojava import jdk.internal.misc.Unsafe;
tojava
tojava import sun.util.logging.PlatformLogger;
tojava
--- a/jdk/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -178,7 +178,7 @@
}
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
return AWT_OnLoad(vm, reserved);
}
--- a/jdk/src/java.desktop/unix/native/libawt_headless/awt/HeadlessToolkit.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_headless/awt/HeadlessToolkit.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,14 +31,17 @@
extern JavaVM *jvm;
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
jvm = vm;
return JNI_VERSION_1_2;
}
+#ifndef STATIC_BUILD
+// The same function exists in libawt.a::awt_LoadLibrary.c
JNIEXPORT jboolean JNICALL AWTIsHeadless() {
return JNI_TRUE;
}
+#endif
#endif
--- a/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c Wed Jul 05 21:00:20 2017 +0200
@@ -151,7 +151,7 @@
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
jvm = vm;
return JNI_VERSION_1_2;
--- a/jdk/src/java.desktop/unix/native/libjawt/jawt.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libjawt/jawt.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,10 +24,16 @@
*/
#include <jawt.h>
+#include "jni_util.h"
#include "awt_DrawingSurface.h"
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Get the AWT native structure. This function returns JNI_FALSE if
* an error occurs.
*/
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_CommonUtils.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,11 @@
static int alsa_enumerate_pcm_subdevices = FALSE; // default: no
static int alsa_enumerate_midi_subdevices = FALSE; // default: no
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
void initAlsaSupport() {
char* enumerate;
if (!alsa_inited) {
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@
JavaVM *jvm = NULL;
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *vm, void *reserved)
+DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
{
TRY;
--- a/jdk/src/java.desktop/windows/native/libjawt/jawt.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.desktop/windows/native/libjawt/jawt.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,17 @@
#define _JNI_IMPLEMENTATION_
#include <jawt.h>
+#include "jni_util.h"
#include "awt.h"
#include "awt_DrawingSurface.h"
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Get the AWT native structure. This function returns JNI_FALSE if
* an error occurs.
*/
--- a/jdk/src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,11 @@
*/
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Class: sun_instrument_InstrumentationImpl
* Method: isModifiableClass0
* Signature: (Ljava/lang/Class;)Z
--- a/jdk/src/java.instrument/share/native/libinstrument/InvocationAdapter.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.instrument/share/native/libinstrument/InvocationAdapter.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -141,7 +141,7 @@
* to create boot class path segments to append to the boot class path.
*/
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *tail, void * reserved) {
+DEF_Agent_OnLoad(JavaVM *vm, char *tail, void * reserved) {
JPLISInitializationError initerror = JPLIS_INIT_ERROR_NONE;
jint result = JNI_OK;
JPLISAgent * agent = NULL;
@@ -290,7 +290,7 @@
* the JPLIS library.
*/
JNIEXPORT jint JNICALL
-Agent_OnAttach(JavaVM* vm, char *args, void * reserved) {
+DEF_Agent_OnAttach(JavaVM* vm, char *args, void * reserved) {
JPLISInitializationError initerror = JPLIS_INIT_ERROR_NONE;
jint result = JNI_OK;
JPLISAgent * agent = NULL;
@@ -435,7 +435,7 @@
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm) {
+DEF_Agent_OnUnload(JavaVM *vm) {
}
--- a/jdk/src/java.instrument/share/native/libinstrument/JarFacade.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.instrument/share/native/libinstrument/JarFacade.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,10 @@
* questions.
*/
+#ifdef STATIC_BUILD
+#define getAttribute JarGetAttribute
+#endif
+
typedef struct _jarAttribute {
char* name;
char* value;
--- a/jdk/src/java.instrument/share/native/libinstrument/Utilities.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.instrument/share/native/libinstrument/Utilities.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,13 @@
#include <jni.h>
#include <jvmti.h>
+#include "jni_util.h"
+
+#ifdef STATIC_BUILD
+#define allocate instAllocate
+#define deallocate instDeallocate
+#endif
+
#ifdef __cplusplus
extern "C" {
--- a/jdk/src/java.management/share/classes/sun/management/BaseOperatingSystemImpl.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.management/share/classes/sun/management/BaseOperatingSystemImpl.java Wed Jul 05 21:00:20 2017 +0200
@@ -28,7 +28,7 @@
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.ManagementFactory;
import javax.management.ObjectName;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
/**
* Implementation class for the operating system.
--- a/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java Wed Jul 05 21:00:20 2017 +0200
@@ -51,7 +51,7 @@
static {
// make sure that the management lib is loaded within
// java.lang.management.ManagementFactory
- sun.misc.Unsafe.getUnsafe().ensureClassInitialized(ManagementFactory.class);
+ jdk.internal.misc.Unsafe.getUnsafe().ensureClassInitialized(ManagementFactory.class);
}
private static final VMManagement jvm = new VMManagementImpl();
--- a/jdk/src/java.management/share/native/libmanagement/management.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.management/share/native/libmanagement/management.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <jni.h>
+#include "jni_util.h"
#include "jvm.h"
#include "management.h"
@@ -35,7 +36,7 @@
jint jmm_version = 0;
JNIEXPORT jint JNICALL
- JNI_OnLoad(JavaVM *vm, void *reserved) {
+ DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv* env;
jvm = vm;
--- a/jdk/src/java.prefs/macosx/native/libprefs/MacOSXPreferencesFile.m Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.prefs/macosx/native/libprefs/MacOSXPreferencesFile.m Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,6 +64,11 @@
#include "jlong.h"
#include "jvm.h"
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
// Throw an OutOfMemoryError with the given message.
static void throwOutOfMemoryError(JNIEnv *env, const char *msg)
--- a/jdk/src/java.prefs/unix/native/libprefs/FileSystemPreferences.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.prefs/unix/native/libprefs/FileSystemPreferences.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,11 @@
#include <utime.h>
#include "jni_util.h"
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
JNIEXPORT jint JNICALL
Java_java_util_prefs_FileSystemPreferences_chmod(JNIEnv *env,
jclass thisclass, jstring java_fname, jint permission) {
--- a/jdk/src/java.prefs/windows/native/libprefs/WindowsPreferences.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.prefs/windows/native/libprefs/WindowsPreferences.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,12 @@
#ifdef __cplusplus
extern "C" {
#endif
+
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
JNIEXPORT jintArray JNICALL Java_java_util_prefs_WindowsPreferences_WindowsRegOpenKey
(JNIEnv* env, jclass this_class, jint hKey, jbyteArray lpSubKey, jint securityMask) {
HKEY handle;
--- a/jdk/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
#import <string.h>
#import <time.h>
+#include "jni_util.h"
+
/*
* Based largely on klist.c,
*
@@ -92,7 +94,7 @@
* Class: sun_security_krb5_KrbCreds
* Method: JNI_OnLoad
*/
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
@@ -191,7 +193,7 @@
* Class: sun_security_jgss_KrbCreds
* Method: JNI_OnUnload
*/
-JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved)
+JNIEXPORT void JNICALL DEF_JNI_OnUnload(JavaVM *jvm, void *reserved)
{
JNIEnv *env;
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KerberosSecrets.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KerberosSecrets.java Wed Jul 05 21:00:20 2017 +0200
@@ -26,7 +26,7 @@
package sun.security.krb5;
import javax.security.auth.kerberos.KeyTab;
-import sun.misc.Unsafe;
+import jdk.internal.misc.Unsafe;
public class KerberosSecrets {
private static final Unsafe unsafe = Unsafe.getUnsafe();
--- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/PrincipalName.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/PrincipalName.java Wed Jul 05 21:00:20 2017 +0200
@@ -187,10 +187,10 @@
}
private static final long NAME_STRINGS_OFFSET;
- private static final sun.misc.Unsafe UNSAFE;
+ private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
- sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+ jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
NAME_STRINGS_OFFSET = unsafe.objectFieldOffset(
PrincipalName.class.getDeclaredField("nameStrings"));
UNSAFE = unsafe;
--- a/jdk/src/java.security.jgss/share/native/libj2gss/NativeUtil.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/native/libj2gss/NativeUtil.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
#include "NativeFunc.h"
#include "jlong.h"
#include <jni.h>
+#include "jni_util.h"
const int JAVA_DUPLICATE_TOKEN_CODE = 19; /* DUPLICATE_TOKEN */
const int JAVA_OLD_TOKEN_CODE = 20; /* OLD_TOKEN */
@@ -94,7 +95,7 @@
int JGSS_DEBUG;
JNIEXPORT jint JNICALL
-JNI_OnLoad(JavaVM *jvm, void *reserved) {
+DEF_JNI_OnLoad(JavaVM *jvm, void *reserved) {
JNIEnv *env;
jclass cls;
@@ -363,7 +364,7 @@
}
JNIEXPORT void JNICALL
-JNI_OnUnload(JavaVM *jvm, void *reserved) {
+DEF_JNI_OnUnload(JavaVM *jvm, void *reserved) {
JNIEnv *env;
if ((*jvm)->GetEnv(jvm, (void **)&env, JNI_VERSION_1_2)) {
--- a/jdk/src/java.security.jgss/share/native/libj2gss/NativeUtil.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.security.jgss/share/native/libj2gss/NativeUtil.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,9 +54,6 @@
extern jstring getMinorMessage(JNIEnv *, jobject, OM_uint32);
extern int sameMech(gss_OID, gss_OID);
- JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *, void *);
- JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *, void *);
-
extern int JGSS_DEBUG;
extern jclass CLS_Object;
--- a/jdk/src/java.security.jgss/windows/native/libw2k_lsa_auth/NativeCreds.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.security.jgss/windows/native/libw2k_lsa_auth/NativeCreds.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
#include <lmcons.h>
#include <lmapibuf.h>
#include <jni.h>
+#include "jni_util.h"
#include <winsock.h>
#undef LSA_SUCCESS
@@ -107,7 +108,7 @@
* Method: JNI_OnLoad
*/
-JNIEXPORT jint JNICALL JNI_OnLoad(
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(
JavaVM *jvm,
void *reserved) {
@@ -329,7 +330,7 @@
* Method: JNI_OnUnload
*/
-JNIEXPORT void JNICALL JNI_OnUnload(
+JNIEXPORT void JNICALL DEF_JNI_OnUnload(
JavaVM *jvm,
void *reserved) {
--- a/jdk/src/java.smartcardio/share/native/libj2pcsc/pcsc.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/java.smartcardio/share/native/libj2pcsc/pcsc.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,6 +55,8 @@
#include "pcsc_md.h"
+#include "jni_util.h"
+
#define MAX_STACK_BUFFER_SIZE 8192
// make the buffers larger than what should be necessary, just in case
@@ -101,7 +103,7 @@
}
}
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_4;
}
--- a/jdk/src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.attach/linux/native/libattach/VirtualMachineImpl.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,11 @@
} while(0)
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Defines a callback that is invoked for each process
*/
typedef void (*ProcessCallback)(const pid_t pid, void* user_data);
--- a/jdk/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,6 +51,11 @@
} while(0)
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Class: sun_tools_attach_VirtualMachineImpl
* Method: socket
* Signature: ()I
--- a/jdk/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,11 @@
} while(0)
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Class: sun_tools_attach_VirtualMachineImpl
* Method: open
* Signature: (Ljava/lang/String;)I
--- a/jdk/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.attach/windows/native/libattach/VirtualMachineImpl.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -87,6 +87,10 @@
#define ERR_OPEN_JVM_FAIL 200
#define ERR_GET_ENQUEUE_FUNC_FAIL 201
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
/*
* Code copied to target process
--- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/Big5_Solaris.java.template Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/Big5_Solaris.java.template Wed Jul 05 21:00:20 2017 +0200
@@ -51,12 +51,12 @@
public CharsetDecoder newDecoder() {
initb2c();
- return new DoubleByte.Decoder(this, b2c, b2cSB, 0x40, 0xfe);
+ return new DoubleByte.Decoder(this, b2c, b2cSB, 0x40, 0xfe, true);
}
public CharsetEncoder newEncoder() {
initc2b();
- return new DoubleByte.Encoder(this, c2b, c2bIndex);
+ return new DoubleByte.Encoder(this, c2b, c2bIndex, true);
}
static char[][] b2c;
--- a/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM834.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM834.java Wed Jul 05 21:00:20 2017 +0200
@@ -62,7 +62,7 @@
protected static class Encoder extends DoubleByte.Encoder_DBCSONLY {
public Encoder(Charset cs) {
super(cs, new byte[] {(byte)0xfe, (byte)0xfe},
- IBM933.c2b, IBM933.c2bIndex);
+ IBM933.c2b, IBM933.c2bIndex, false);
}
public int encodeChar(char ch) {
--- a/jdk/src/jdk.crypto.ec/share/native/libsunec/ECC_JNI.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.crypto.ec/share/native/libsunec/ECC_JNI.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
*/
#include <jni.h>
+#include "jni_util.h"
#include "impl/ecc_impl.h"
#define ILLEGAL_STATE_EXCEPTION "java/lang/IllegalStateException"
@@ -36,6 +37,11 @@
extern "C" {
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Throws an arbitrary Java exception.
*/
void ThrowException(JNIEnv *env, const char *exceptionName)
--- a/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
//
#include <jni.h>
+#include "jni_util.h"
#include <stdlib.h>
#include <string.h>
#include <windows.h>
@@ -51,6 +52,11 @@
extern "C" {
/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
+/*
* Throws an arbitrary Java exception.
* The exception message is a Windows system error message.
*/
--- a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_general.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_general.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
*/
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
@@ -73,7 +73,7 @@
JavaVM* jvm = NULL;
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
jvm = vm;
return JNI_VERSION_1_4;
}
--- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c Wed Jul 05 21:00:20 2017 +0200
@@ -27,6 +27,7 @@
#include <string.h>
#include <strings.h>
#include <jni.h>
+#include "jni_util.h"
#include <libsoftcrypto.h>
#include "nativeCrypto.h"
#include "nativeFunc.h"
@@ -59,7 +60,7 @@
(*env)->DeleteLocalRef(env, jExClass);
}
-JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_4;
}
--- a/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptEngine.m Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.deploy.osx/macosx/native/libapplescriptengine/AppleScriptEngine.m Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,10 @@
#import "apple_applescript_AppleScriptEngine.h"
#import "apple_applescript_AppleScriptEngineFactory.h"
+// Must include this before JavaNativeFoundation.h to get jni.h from build
+#include "jni.h"
+#include "jni_util.h"
+
#import <JavaNativeFoundation/JavaNativeFoundation.h>
#import "NS_Java_ConversionUtils.h"
@@ -33,6 +37,10 @@
//#define DEBUG 1
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
/*
* Class: apple_applescript_AppleScriptEngineFactory
--- a/jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.deploy.osx/macosx/native/libosx/Dispatch.m Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,21 @@
* questions.
*/
+/*
+ * Must include this before JavaNativeFoundation.h to get jni.h from build
+ */
+#include "jni.h"
+#include "jni_util.h"
+
#import "com_apple_concurrent_LibDispatchNative.h"
#import <dispatch/dispatch.h>
#import <JavaNativeFoundation/JavaNativeFoundation.h>
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
/*
* Class: com_apple_concurrent_LibDispatchNative
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -194,7 +194,7 @@
* Returning JNI_ERR will cause the java_g VM to core dump, be careful.
*/
JNIEXPORT jint JNICALL
-Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+DEF_Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
jvmtiError error;
jvmtiCapabilities needed_capabilities;
@@ -380,7 +380,7 @@
}
JNIEXPORT void JNICALL
-Agent_OnUnload(JavaVM *vm)
+DEF_Agent_OnUnload(JavaVM *vm)
{
gdata->isLoaded = JNI_FALSE;
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,4 @@
void debugInit_exit(jvmtiError, const char *);
void forceExit(int);
-JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *, char *, void *);
-JNIEXPORT void JNICALL Agent_OnUnload(JavaVM *);
-
#endif
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/transport.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/transport.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -101,9 +101,10 @@
static void *
loadTransportLibrary(const char *libdir, const char *name)
{
+ char buf[MAXPATHLEN*2+100];
+#ifndef STATIC_BUILD
void *handle;
char libname[MAXPATHLEN+2];
- char buf[MAXPATHLEN*2+100];
const char *plibdir;
/* Convert libdir from UTF-8 to platform encoding */
@@ -125,6 +126,9 @@
/* dlopen (unix) / LoadLibrary (windows) the transport library */
handle = dbgsysLoadLibrary(libname, buf, sizeof(buf));
return handle;
+#else
+ return (dbgsysLoadLibrary(NULL, buf, sizeof(buf)));
+#endif
}
/*
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/util.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -278,18 +278,6 @@
#define MOD_SYNTHETIC 0xf0000000 /* not in source code */
/*
- * jlong conversion macros
- */
-#define jlong_zero ((jlong) 0)
-#define jlong_one ((jlong) 1)
-
-#define jlong_to_ptr(a) ((void*)(intptr_t)(a))
-#define ptr_to_jlong(a) ((jlong)(intptr_t)(a))
-#define jint_to_jlong(a) ((jlong)(a))
-#define jlong_to_jint(a) ((jint)(a))
-
-
-/*
* util funcs
*/
void util_initialize(JNIEnv *env);
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/vm_interface.h Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/vm_interface.h Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
#include <jni.h>
#include <jvm.h>
#include <jvmti.h>
+#include "jni_util.h"
#include "log_messages.h"
--- a/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.c Wed Jul 05 21:00:20 2017 +0200
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <jni.h>
+#include "jni_util.h"
#include "jvm.h"
#include "management_ext.h"
@@ -35,7 +36,7 @@
jint jmm_version = 0;
JNIEXPORT jint JNICALL
- JNI_OnLoad(JavaVM *vm, void *reserved) {
+ DEF_JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv* env;
jvm = vm;
--- a/jdk/src/jdk.pack200/share/native/common-unpack/utils.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.pack200/share/native/common-unpack/utils.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -77,6 +77,8 @@
#ifndef PRODUCT
+#ifndef STATIC_BUILD
+// use the definition in libjvm when building statically
void breakpoint() { } // hook for debugger
int assert_failed(const char* p) {
char message[1<<12];
@@ -87,6 +89,7 @@
return 0;
}
#endif
+#endif
void unpack_abort(const char* msg, unpacker* u) {
if (msg == null) msg = "corrupt pack file or internal error";
--- a/jdk/src/jdk.pack200/share/native/libunpack/jni.cpp Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.pack200/share/native/libunpack/jni.cpp Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -95,6 +95,11 @@
} while (JNI_FALSE)
#endif
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
static jlong read_input_via_jni(unpacker* self,
void* buf, jlong minlen, jlong maxlen);
--- a/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.sctp/unix/native/libsctp/SctpNet.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
static const char* nativeSctpLib = "libsctp.so.1";
static jboolean funcsLoaded = JNI_FALSE;
-JNIEXPORT jint JNICALL JNI_OnLoad
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad
(JavaVM *vm, void *reserved) {
return JNI_VERSION_1_2;
}
--- a/jdk/src/jdk.security.auth/unix/native/libjaas/Unix.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.security.auth/unix/native/libjaas/Unix.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
#endif
#include <jni.h>
+#include "jni_util.h"
#include "com_sun_security_auth_module_UnixSystem.h"
#include <stdio.h>
#include <pwd.h>
@@ -36,6 +37,11 @@
#include <stdlib.h>
#include <string.h>
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
JNIEXPORT void JNICALL
Java_com_sun_security_auth_module_UnixSystem_getUnixInfo
(JNIEnv *env, jobject obj) {
--- a/jdk/src/jdk.security.auth/windows/native/libjaas/nt.c Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/src/jdk.security.auth/windows/native/libjaas/nt.c Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
*/
#include <jni.h>
+#include "jni_util.h"
#include "com_sun_security_auth_module_NTSystem.h"
#include <windows.h>
@@ -49,6 +50,11 @@
(*env)->ThrowNew(env, clazz, msg);
}
+/*
+ * Declare library specific JNI_Onload entry if static build
+ */
+DEF_STATIC_JNI_OnLoad
+
JNIEXPORT jlong JNICALL
Java_com_sun_security_auth_module_NTSystem_getImpersonationToken0
(JNIEnv *env, jobject obj) {
--- a/jdk/test/ProblemList.txt Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/ProblemList.txt Wed Jul 05 21:00:20 2017 +0200
@@ -363,6 +363,18 @@
# 8062512
java/util/spi/ResourceBundleControlProvider/UserDefaultControlTest.java generic-all
+# 8076458
+java/util/stream/test/org/openjdk/tests/java/util/stream/FlatMapOpTest.java generic-all
+
+# 8130337
+java/util/stream/test/org/openjdk/tests/java/util/stream/IntPrimitiveOpsTests.java generic-all
+
+# 8080165, 8085982
+java/util/Arrays/ParallelPrefix.java generic-all
+
+# 8079538
+java/util/BitSet/BitSetStreamTest.java generic-all
+
############################################################################
# jdk_instrument
--- a/jdk/test/TEST.groups Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/TEST.groups Wed Jul 05 21:00:20 2017 +0200
@@ -28,7 +28,9 @@
tier1 = \
:jdk_lang \
-java/lang/ProcessHandle/TreeTest.java \
+ -java/util/zip/TestLocalTime.java \
:jdk_util \
+ -java/util/concurrent/Phaser/Basic.java \
sun/nio/cs/ISO8859x.java \
java/nio/Buffer \
com/sun/crypto/provider/Cipher \
@@ -36,6 +38,8 @@
tier2 = \
java/lang/ProcessHandle/TreeTest.java \
+ java/util/zip/TestLocalTime.java \
+ java/util/concurrent/Phaser/Basic.java \
:jdk_io \
:jdk_nio \
-sun/nio/cs/ISO8859x.java \
--- a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -47,6 +47,7 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.TimeUnit;
+import javax.net.ssl.SSLHandshakeException;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
@@ -234,6 +235,12 @@
if (e.getCause() instanceof SocketTimeoutException) {
// SSL connect will timeout via readReply using
// SocketTimeoutException
+ e.printStackTrace();
+ pass();
+ } else if (e.getCause() instanceof SSLHandshakeException
+ && e.getCause().getCause() instanceof EOFException) {
+ // test seems to be failing intermittently on some
+ // platforms.
pass();
} else {
fail(e);
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java Wed Jul 05 21:00:20 2017 +0200
@@ -1248,7 +1248,7 @@
() -> p.toHandle(),
() -> p.supportsNormalTermination(),
() -> p.children(),
- () -> p.allChildren());
+ () -> p.descendants());
}
--- a/jdk/test/java/lang/ProcessHandle/OnExitTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/ProcessHandle/OnExitTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -129,7 +129,7 @@
printf(" You can try to increase the timeout or%n");
printf(" you can try to use a faster VM (i.e. not a debug version).%n");
}
- children = getAllChildren(procHandle);
+ children = getDescendants(procHandle);
ConcurrentHashMap<ProcessHandle, CompletableFuture<ProcessHandle>> completions =
new ConcurrentHashMap<>();
--- a/jdk/test/java/lang/ProcessHandle/PermissionTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/ProcessHandle/PermissionTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -62,9 +62,9 @@
}
@Test
- public void allChildrenWithPermission() {
+ public void descendantsWithPermission() {
Policy.setPolicy(new TestPolicy(new RuntimePermission("manageProcess")));
- currentHndl.allChildren();
+ currentHndl.descendants();
}
@Test
@@ -122,7 +122,7 @@
@Test(groups = { "NoManageProcessPermission" }, expectedExceptions = SecurityException.class)
public void noPermissionAllChildren() {
- currentHndl.allChildren();
+ currentHndl.descendants();
}
@Test(groups = { "NoManageProcessPermission" }, expectedExceptions = SecurityException.class)
--- a/jdk/test/java/lang/ProcessHandle/ProcessUtil.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/ProcessHandle/ProcessUtil.java Wed Jul 05 21:00:20 2017 +0200
@@ -63,8 +63,8 @@
* @param ph the Process to get children of
* @return a list of child ProcessHandles
*/
- public static List<ProcessHandle> getAllChildren(ProcessHandle ph) {
- return ph.allChildren()
+ public static List<ProcessHandle> getDescendants(ProcessHandle ph) {
+ return ph.descendants()
.filter(ProcessUtil::isNotWindowsConsole)
.collect(Collectors.toList());
}
@@ -117,7 +117,7 @@
// ignore
}
}
- subprocesses = getAllChildren(ph);
+ subprocesses = getDescendants(ph);
count = subprocesses.size();
System.out.printf(" waiting for subprocesses of %s to start," +
" expected: %d, current: %d%n", ph, nchildren, count);
@@ -133,7 +133,7 @@
* @return the ProcessHandle
*/
public static ProcessHandle destroyProcessTree(ProcessHandle p) {
- Stream<ProcessHandle> children = p.allChildren().filter(ProcessUtil::isNotWindowsConsole);
+ Stream<ProcessHandle> children = p.descendants().filter(ProcessUtil::isNotWindowsConsole);
children.forEach(ph -> {
System.out.printf("destroyProcessTree destroyForcibly%n");
printProcess(ph);
--- a/jdk/test/java/lang/ProcessHandle/TreeTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/ProcessHandle/TreeTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -193,21 +193,21 @@
}
// show the complete list of children (for debug)
- List<ProcessHandle> allChildren = getAllChildren(p1Handle);
- printf(" allChildren: %s%n",
- allChildren.stream().map(p -> p.getPid())
- .collect(Collectors.toList()));
+ List<ProcessHandle> descendants = getDescendants(p1Handle);
+ printf(" descendants: %s%n",
+ descendants.stream().map(p -> p.getPid())
+ .collect(Collectors.toList()));
- // Verify that all spawned children show up in the allChildren List
+ // Verify that all spawned children show up in the descendants List
processes.forEach((p, parent) -> {
Assert.assertEquals(p.isAlive(), true, "Child should be alive: " + p);
- Assert.assertTrue(allChildren.contains(p), "Spawned child should be listed in allChildren: " + p);
+ Assert.assertTrue(descendants.contains(p), "Spawned child should be listed in descendants: " + p);
});
// Closing JavaChild's InputStream will cause all children to exit
p1.getOutputStream().close();
- for (ProcessHandle p : allChildren) {
+ for (ProcessHandle p : descendants) {
try {
p.onExit().get(); // wait for the child to exit
} catch (ExecutionException e) {
@@ -228,9 +228,9 @@
/**
* Test destroy of processes.
* A JavaChild is started and it starts three children.
- * Each one is then checked to be alive and listed by allChildren
+ * Each one is then checked to be alive and listed by descendants
* and forcibly destroyed.
- * After they exit they should no longer be listed by allChildren.
+ * After they exit they should no longer be listed by descendants.
*/
@Test
public static void test3() {
@@ -263,24 +263,24 @@
Assert.assertTrue(spawnCount.await(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
"Timeout waiting for processes to start");
- // Debugging; list allChildren that are not expected in processes
- List<ProcessHandle> allChildren = ProcessUtil.getAllChildren(p1Handle);
- long count = allChildren.stream()
+ // Debugging; list descendants that are not expected in processes
+ List<ProcessHandle> descendants = ProcessUtil.getDescendants(p1Handle);
+ long count = descendants.stream()
.filter(ph -> !processes.containsKey(ph))
.count();
if (count > 0) {
- allChildren.stream()
+ descendants.stream()
.filter(ph -> !processes.containsKey(ph))
.forEach(ph1 -> ProcessUtil.printProcess(ph1, "Extra process: "));
ProcessUtil.logTaskList();
- Assert.assertEquals(0, count, "Extra processes in allChildren");
+ Assert.assertEquals(0, count, "Extra processes in descendants");
}
- // Verify that all spawned children are alive, show up in the allChildren list
+ // Verify that all spawned children are alive, show up in the descendants list
// then destroy them
processes.forEach((p, parent) -> {
Assert.assertEquals(p.isAlive(), true, "Child should be alive: " + p);
- Assert.assertTrue(allChildren.contains(p), "Spawned child should be listed in allChildren: " + p);
+ Assert.assertTrue(descendants.contains(p), "Spawned child should be listed in descendants: " + p);
p.destroyForcibly();
});
Assert.assertEquals(processes.size(), newChildren, "Wrong number of children");
@@ -305,8 +305,8 @@
p1.destroyForcibly();
p1.waitFor();
- // Verify that none of the spawned children are still listed by allChildren
- List<ProcessHandle> remaining = getAllChildren(self);
+ // Verify that none of the spawned children are still listed by descendants
+ List<ProcessHandle> remaining = getDescendants(self);
Assert.assertFalse(remaining.remove(p1Handle), "Child p1 should have exited");
remaining = remaining.stream().filter(processes::containsKey).collect(Collectors.toList());
Assert.assertEquals(remaining.size(), 0, "Subprocess(es) should have exited: " + remaining);
@@ -415,28 +415,28 @@
Assert.assertTrue(spawnCount.await(Utils.adjustTimeout(30L), TimeUnit.SECONDS),
"Timeout waiting for processes to start");
- // Debugging; list allChildren that are not expected in processes
- List<ProcessHandle> allChildren = ProcessUtil.getAllChildren(p1Handle);
- long count = allChildren.stream()
+ // Debugging; list descendants that are not expected in processes
+ List<ProcessHandle> descendants = ProcessUtil.getDescendants(p1Handle);
+ long count = descendants.stream()
.filter(ph -> !processes.containsKey(ph))
.count();
if (count > 0) {
- allChildren.stream()
+ descendants.stream()
.filter(ph -> !processes.containsKey(ph))
.forEach(ph1 -> ProcessUtil.printProcess(ph1, "Extra process: "));
ProcessUtil.logTaskList();
- Assert.assertEquals(0, count, "Extra processes in allChildren");
+ Assert.assertEquals(0, count, "Extra processes in descendants");
}
Assert.assertEquals(getChildren(p1Handle).size(),
factor, "expected direct children");
- count = getAllChildren(p1Handle).size();
+ count = getDescendants(p1Handle).size();
long totalChildren = factor * factor * factor + factor * factor + factor;
Assert.assertTrue(count >= totalChildren,
"expected at least " + totalChildren + ", actual: " + count);
- List<ProcessHandle> subprocesses = getAllChildren(p1Handle);
- printf(" allChildren: %s%n",
+ List<ProcessHandle> subprocesses = getDescendants(p1Handle);
+ printf(" descendants: %s%n",
subprocesses.stream().map(p -> p.getPid())
.collect(Collectors.toList()));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/Chars.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/*
+ @test
+ @bug 8054307
+ @summary test chars() and codePoints()
+*/
+
+import java.util.Arrays;
+import java.util.Random;
+
+public class Chars {
+
+ public static void main(String[] args) {
+ Random r = new Random();
+ for (int i = 0; i < 10; i++) {
+ int n = 100 + r.nextInt(100);
+ char[] cc = new char[n];
+ int[] ccExp = new int[n];
+ int[] cpExp = new int[n];
+ // latin1
+ for (int j = 0; j < n; j++) {
+ cc[j] = (char)(ccExp[j] = cpExp[j] = r.nextInt(0x80));
+ }
+ testChars(cc, ccExp);
+ testCPs(cc, cpExp);
+
+ // bmp without surrogates
+ for (int j = 0; j < n; j++) {
+ cc[j] = (char)(ccExp[j] = cpExp[j] = r.nextInt(0x8000));
+ }
+ testChars(cc, ccExp);
+ testCPs(cc, cpExp);
+
+ // bmp with surrogates
+ int k = 0;
+ for (int j = 0; j < n; j++) {
+ if (j % 9 == 5 && j + 1 < n) {
+ int cp = 0x10000 + r.nextInt(2000);
+ cpExp[k++] = cp;
+ Character.toChars(cp, cc, j);
+ ccExp[j] = cc[j];
+ ccExp[j + 1] = cc[j + 1];
+ j++;
+ } else {
+ cc[j] = (char)(ccExp[j] = cpExp[k++] = r.nextInt(0x8000));
+ }
+ }
+ cpExp = Arrays.copyOf(cpExp, k);
+ testChars(cc, ccExp);
+ testCPs(cc, cpExp);
+ }
+ }
+
+ static void testChars(char[] cc, int[] expected) {
+ String str = new String(cc);
+ if (!Arrays.equals(expected, str.chars().toArray())) {
+ throw new RuntimeException("chars/codePoints() failed!");
+ }
+ }
+
+ static void testCPs(char[] cc, int[] expected) {
+ String str = new String(cc);
+ if (!Arrays.equals(expected, str.codePoints().toArray())) {
+ throw new RuntimeException("chars/codePoints() failed!");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CharAt.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.charAt.
+ * @run testng/othervm -XX:+CompactStrings CharAt
+ * @run testng/othervm -XX:-CompactStrings CharAt
+ */
+
+public class CharAt extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ new Object[] { STRING_L1, new char[] { 'A' } },
+ new Object[] { STRING_L2, new char[] { 'A', 'B' } },
+ new Object[] { STRING_L4, new char[] { 'A', 'B', 'C', 'D' } },
+ new Object[] { STRING_LLONG,
+ new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
+ new Object[] { STRING_U1, new char[] { '\uFF21' } },
+ new Object[] { STRING_U2, new char[] { '\uFF21', '\uFF22' } },
+ new Object[] { STRING_M12, new char[] { '\uFF21', 'A' } },
+ new Object[] { STRING_M11, new char[] { 'A', '\uFF21' } }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testCharAt(String str, char[] expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ IntStream
+ .range(0, str.length())
+ .forEach(
+ i -> assertEquals(
+ str.charAt(i),
+ expected[i],
+ String.format(
+ "testing String(%s).charAt(%d), source : %s, ",
+ escapeNonASCIIs(data),
+ i, source)));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CodePointAt.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.codePointAt.
+ * @run testng/othervm -XX:+CompactStrings CodePointAt
+ * @run testng/othervm -XX:-CompactStrings CodePointAt
+ */
+
+public class CodePointAt extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_L1, new int[] { 'A' } },
+ new Object[] { STRING_L2, new int[] { 'A', 'B' } },
+ new Object[] { STRING_L4, new int[] { 'A', 'B', 'C', 'D' } },
+ new Object[] { STRING_LLONG,
+ new int[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
+ new Object[] { STRING_U1, new int[] { '\uFF21' } },
+ new Object[] { STRING_U2, new int[] { '\uFF21', '\uFF22' } },
+ new Object[] { STRING_M12, new int[] { '\uFF21', 'A' } },
+ new Object[] { STRING_M11, new int[] { 'A', '\uFF21' } },
+ new Object[] {
+ STRING_SUPPLEMENTARY,
+ new int[] { Character.toCodePoint('\uD801', '\uDC00'),
+ '\uDC00',
+ Character.toCodePoint('\uD801', '\uDC01'),
+ '\uDC01', '\uFF21', 'A' }, } };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testCodePointAt(String str, int[] expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ IntStream
+ .range(0, str.length())
+ .forEach(
+ i -> assertEquals(
+ str.codePointAt(i),
+ expected[i],
+ String.format(
+ "testing String(%s).codePointAt(%d), source : %s, ",
+ escapeNonASCIIs(data),
+ i, source)));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CodePointBefore.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.codePointBefore.
+ * @run testng/othervm -XX:+CompactStrings CodePointBefore
+ * @run testng/othervm -XX:-CompactStrings CodePointBefore
+ */
+
+public class CodePointBefore extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_L1, new int[] { 'A' } },
+ new Object[] { STRING_L2, new int[] { 'A', 'B' } },
+ new Object[] { STRING_L4, new int[] { 'A', 'B', 'C', 'D' } },
+ new Object[] { STRING_LLONG,
+ new int[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
+ new Object[] { STRING_U1, new int[] { '\uFF21' } },
+ new Object[] { STRING_U2, new int[] { '\uFF21', '\uFF22' } },
+ new Object[] { STRING_M12, new int[] { '\uFF21', 'A' } },
+ new Object[] { STRING_M11, new int[] { 'A', '\uFF21' } },
+ new Object[] {
+ STRING_SUPPLEMENTARY,
+ new int[] { '\uD801', Character.toCodePoint('\uD801', '\uDC00'),
+ '\uD801', Character.toCodePoint('\uD801', '\uDC01'),
+ '\uFF21', 'A' }, } };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testCodePointBefore(String str, int[] expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ IntStream
+ .range(0, str.length())
+ .forEach(
+ i -> assertEquals(
+ str.codePointBefore(i + 1),
+ expected[i],
+ String.format(
+ "testing String(%s).codePointBefore(%d), source : %s, ",
+ escapeNonASCIIs(data),
+ i + 1, source)));
+ });
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CodePointCount.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.codePointCount.
+ * @run testng/othervm -XX:+CompactStrings CodePointCount
+ * @run testng/othervm -XX:-CompactStrings CodePointCount
+ */
+
+public class CodePointCount extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] { new Object[] { STRING_EMPTY, 0, 0, 0 },
+ new Object[] { STRING_L1, 0, 1, 1 },
+ new Object[] { STRING_L1, 1, 1, 0 },
+ new Object[] { STRING_L2, 0, 2, 2 },
+ new Object[] { STRING_L2, 0, 1, 1 },
+ new Object[] { STRING_L2, 1, 2, 1 },
+ new Object[] { STRING_L4, 0, 4, 4 },
+ new Object[] { STRING_L4, 0, 1, 1 },
+ new Object[] { STRING_L4, 2, 4, 2 },
+ new Object[] { STRING_LLONG, 0, 8, 8 },
+ new Object[] { STRING_LLONG, 0, 5, 5 },
+ new Object[] { STRING_LLONG, 4, 8, 4 },
+ new Object[] { STRING_LLONG, 0, 7, 7 },
+ new Object[] { STRING_U1, 0, 1, 1 },
+ new Object[] { STRING_U2, 0, 2, 2 },
+ new Object[] { STRING_U2, 0, 1, 1 },
+ new Object[] { STRING_U2, 1, 2, 1 },
+ new Object[] { STRING_M12, 0, 2, 2 },
+ new Object[] { STRING_M12, 0, 1, 1 },
+ new Object[] { STRING_M12, 1, 2, 1 },
+ new Object[] { STRING_M11, 0, 2, 2 },
+ new Object[] { STRING_M11, 0, 1, 1 },
+ new Object[] { STRING_M11, 1, 2, 1 },
+ new Object[] { STRING_SUPPLEMENTARY, 0, 1, 1 },
+ new Object[] { STRING_SUPPLEMENTARY, 0, 2, 1 },
+ new Object[] { STRING_SUPPLEMENTARY, 0, 3, 2 },
+ new Object[] { STRING_SUPPLEMENTARY, 0, 5, 3 },
+ new Object[] { STRING_SUPPLEMENTARY, 0, 6, 4 },
+ new Object[] { STRING_SUPPLEMENTARY, 1, 4, 2 },
+ new Object[] { STRING_SUPPLEMENTARY, 1, 6, 4 },
+ new Object[] { STRING_SUPPLEMENTARY, 2, 4, 1 },};
+ }
+
+ @Test(dataProvider = "provider")
+ public void testCodePointCount(String str, int beginIndex, int endIndex,
+ int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.codePointCount(beginIndex, endIndex),
+ expected,
+ String.format(
+ "testing String(%s).codePointCount(%d, %d), source : %s, ",
+ escapeNonASCIIs(data), beginIndex,
+ endIndex, source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CompactString.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.annotations.BeforeClass;
+
+/*
+ * Base class of tests for Compact String.
+ *
+ */
+public class CompactString {
+
+ final Map<String, Map<String, String>> map = new HashMap<>();
+
+ enum StringSources {
+ EMPTY(STRING_EMPTY, BYTE_ARRAY_EMTPY, CHAR_ARRAY_EMPTY,
+ POINT_ARRAY_EMTPY), LDUPLICATE(STRING_LDUPLICATE,
+ BYTE_ARRAY_LDUPLICATE, CHAR_ARRAY_LDUPLICATE,
+ POINT_ARRAY_LDUPLICATE), LLONG(STRING_LLONG, BYTE_ARRAY_LLONG,
+ CHAR_ARRAY_LLONG, POINT_ARRAY_LLONG), L1(STRING_L1,
+ BYTE_ARRAY_L1, CHAR_ARRAY_L1, POINT_ARRAY_L1), L2(STRING_L2,
+ BYTE_ARRAY_L2, CHAR_ARRAY_L2, POINT_ARRAY_L2), L4(STRING_L4,
+ BYTE_ARRAY_L4, CHAR_ARRAY_L4, POINT_ARRAY_L4), UDUPLICATE(
+ STRING_UDUPLICATE, BYTE_ARRAY_UDUPLICATE,
+ CHAR_ARRAY_UDUPLICATE, POINT_ARRAY_UDUPLICATE), U1(STRING_U1,
+ BYTE_ARRAY_U1, CHAR_ARRAY_U1, POINT_ARRAY_U1), U2(STRING_U2,
+ BYTE_ARRAY_U2, CHAR_ARRAY_U2, POINT_ARRAY_U2), MDUPLICATE1(
+ STRING_MDUPLICATE1, BYTE_ARRAY_MDUPLICATE1,
+ CHAR_ARRAY_MDUPLICATE1, POINT_ARRAY_MDUPLICATE1), MDUPLICATE2(
+ STRING_MDUPLICATE2, BYTE_ARRAY_MDUPLICATE2,
+ CHAR_ARRAY_MDUPLICATE2, POINT_ARRAY_MDUPLICATE2), MLONG1(
+ STRING_MLONG1, BYTE_ARRAY_MLONG1, CHAR_ARRAY_MLONG1,
+ POINT_ARRAY_MLONG1), MLONG2(STRING_MLONG2, BYTE_ARRAY_MLONG2,
+ CHAR_ARRAY_MLONG2, POINT_ARRAY_MLONG2), M11(STRING_M11,
+ BYTE_ARRAY_M11, CHAR_ARRAY_M11, POINT_ARRAY_M11), M12(
+ STRING_M12, BYTE_ARRAY_M12, CHAR_ARRAY_M12, POINT_ARRAY_M12), SUPPLEMENTARY(
+ STRING_SUPPLEMENTARY, BYTE_ARRAY_SUPPLEMENTARY,
+ CHAR_ARRAY_SUPPLEMENTARY, POINT_ARRAY_SUPPLEMENTARY), SUPPLEMENTARY_LOWERCASE(
+ STRING_SUPPLEMENTARY_LOWERCASE,
+ BYTE_ARRAY_SUPPLEMENTARY_LOWERCASE,
+ CHAR_ARRAY_SUPPLEMENTARY_LOWERCASE,
+ POINT_ARRAY_SUPPLEMENTARY_LOWERCASE);
+
+ private StringSources(String s, byte[] b, char[] c, int[] i) {
+ str = s;
+ ba = b;
+ ca = c;
+ ia = i;
+ }
+
+ String getString() {
+ return str;
+ }
+
+ byte[] getByteArray() {
+ return ba;
+ }
+
+ char[] getCharArray() {
+ return ca;
+ }
+
+ int[] getIntArray() {
+ return ia;
+ }
+
+ private final String str;
+ private final byte[] ba;
+ private final char[] ca;
+ private final int[] ia;
+ }
+
+ protected static final String DEFAULT_CHARSET_NAME = "UTF-8";
+ protected static final Charset DEFAULT_CHARSET = Charset
+ .forName(DEFAULT_CHARSET_NAME);
+
+ protected static final String STRING_EMPTY = "";
+ protected static final byte[] BYTE_ARRAY_EMTPY = new byte[0];
+ protected static final char[] CHAR_ARRAY_EMPTY = new char[0];
+ protected static final int[] POINT_ARRAY_EMTPY = new int[0];
+
+ protected static final String STRING_LDUPLICATE = "ABABABABAB";
+ protected static final byte[] BYTE_ARRAY_LDUPLICATE = new byte[] { 'A', 'B',
+ 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
+ protected static final char[] CHAR_ARRAY_LDUPLICATE = new char[] { 'A', 'B',
+ 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
+ protected static final int[] POINT_ARRAY_LDUPLICATE = new int[] { 'A', 'B',
+ 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B' };
+
+ protected static final String STRING_LLONG = "ABCDEFGH";
+ protected static final byte[] BYTE_ARRAY_LLONG = new byte[] { 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G', 'H' };
+ protected static final char[] CHAR_ARRAY_LLONG = new char[] { 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G', 'H' };
+ protected static final int[] POINT_ARRAY_LLONG = new int[] { 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G', 'H' };
+
+ protected static final String STRING_L1 = "A";
+ protected static final byte[] BYTE_ARRAY_L1 = new byte[] { 'A' };
+ protected static final char[] CHAR_ARRAY_L1 = new char[] { 'A' };
+ protected static final int[] POINT_ARRAY_L1 = new int[] { 'A' };
+
+ protected static final String STRING_L2 = "AB";
+ protected static final byte[] BYTE_ARRAY_L2 = new byte[] { 'A', 'B' };
+ protected static final char[] CHAR_ARRAY_L2 = new char[] { 'A', 'B' };
+ protected static final int[] POINT_ARRAY_L2 = new int[] { 'A', 'B' };
+
+ protected static final String STRING_L4 = "ABCD";
+ protected static final byte[] BYTE_ARRAY_L4 = new byte[] { 'A', 'B', 'C', 'D' };
+ protected static final char[] CHAR_ARRAY_L4 = new char[] { 'A', 'B', 'C', 'D' };
+ protected static final int[] POINT_ARRAY_L4 = new int[] { 'A', 'B', 'C', 'D' };
+
+ /*
+ * Because right now ASCII is the default encoding parameter for source code
+ * in JDK build environment, so we escape them. same as below.
+ */
+ protected static final String STRING_UDUPLICATE = "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22";
+ protected static final byte[] BYTE_ARRAY_UDUPLICATE = getBytes(STRING_UDUPLICATE);
+ protected static final char[] CHAR_ARRAY_UDUPLICATE = new char[] { '\uFF21',
+ '\uFF22', '\uFF21', '\uFF22', '\uFF21', '\uFF22', '\uFF21',
+ '\uFF22', '\uFF21', '\uFF22' };
+ protected static final int[] POINT_ARRAY_UDUPLICATE = new int[] { '\uFF21',
+ '\uFF22', '\uFF21', '\uFF22', '\uFF21', '\uFF22', '\uFF21',
+ '\uFF22', '\uFF21', '\uFF22' };
+
+ protected static final String STRING_U1 = "\uFF21";
+ protected static final byte[] BYTE_ARRAY_U1 = getBytes(STRING_U1);
+ protected static final char[] CHAR_ARRAY_U1 = new char[] { '\uFF21' };
+ protected static final int[] POINT_ARRAY_U1 = new int[] { '\uFF21' };
+
+ protected static final String STRING_U2 = "\uFF21\uFF22";
+ protected static final byte[] BYTE_ARRAY_U2 = getBytes(STRING_U2);
+ protected static final char[] CHAR_ARRAY_U2 = new char[] { '\uFF21', '\uFF22' };
+ protected static final int[] POINT_ARRAY_U2 = new int[] { '\uFF21', '\uFF22' };
+
+ protected static final String STRING_MDUPLICATE1 = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
+ protected static final byte[] BYTE_ARRAY_MDUPLICATE1 = getBytes(STRING_MDUPLICATE1);
+ protected static final char[] CHAR_ARRAY_MDUPLICATE1 = new char[] { '\uFF21',
+ 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A' };
+ protected static final int[] POINT_ARRAY_MDUPLICATE1 = new int[] { '\uFF21',
+ 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A' };
+
+ protected static final String STRING_MDUPLICATE2 = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
+ protected static final byte[] BYTE_ARRAY_MDUPLICATE2 = getBytes(STRING_MDUPLICATE2);
+ protected static final char[] CHAR_ARRAY_MDUPLICATE2 = new char[] { 'A',
+ '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A',
+ '\uFF21' };
+ protected static final int[] POINT_ARRAY_MDUPLICATE2 = new int[] { 'A',
+ '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A', '\uFF21', 'A',
+ '\uFF21' };
+
+ protected static final String STRING_MLONG1 = "A\uFF21B\uFF22C\uFF23D\uFF24E\uFF25F\uFF26G\uFF27H\uFF28";
+ protected static final byte[] BYTE_ARRAY_MLONG1 = getBytes(STRING_MLONG1);
+ protected static final char[] CHAR_ARRAY_MLONG1 = new char[] { 'A', '\uFF21',
+ 'B', '\uFF22', 'C', '\uFF23', 'D', '\uFF24', 'E', '\uFF25', 'F',
+ '\uFF26', 'G', '\uFF27', 'H', '\uFF28' };
+ protected static final int[] POINT_ARRAY_MLONG1 = new int[] { 'A', '\uFF21',
+ 'B', '\uFF22', 'C', '\uFF23', 'D', '\uFF24', 'E', '\uFF25', 'F',
+ '\uFF26', 'G', '\uFF27', 'H', '\uFF28' };
+
+ protected static final String STRING_MLONG2 = "\uFF21A\uFF22B\uFF23C\uFF24D\uFF25E\uFF26F\uFF27G\uFF28H";
+ protected static final byte[] BYTE_ARRAY_MLONG2 = getBytes(STRING_MLONG2);
+ protected static final char[] CHAR_ARRAY_MLONG2 = new char[] { '\uFF21', 'A',
+ '\uFF22', 'B', '\uFF23', 'C', '\uFF24', 'D', '\uFF25', 'E',
+ '\uFF26', 'F', '\uFF27', 'G', '\uFF28', 'H' };
+ protected static final int[] POINT_ARRAY_MLONG2 = new int[] { '\uFF21', 'A',
+ '\uFF22', 'B', '\uFF23', 'C', '\uFF24', 'D', '\uFF25', 'E',
+ '\uFF26', 'F', '\uFF27', 'G', '\uFF28', 'H' };
+
+ protected static final String STRING_M11 = "A\uFF21";
+ protected static final byte[] BYTE_ARRAY_M11 = getBytes(STRING_M11);
+ protected static final char[] CHAR_ARRAY_M11 = new char[] { 'A', '\uFF21' };
+ protected static final int[] POINT_ARRAY_M11 = new int[] { 'A', '\uFF21' };
+
+ protected static final String STRING_M12 = "\uFF21A";
+ protected static final byte[] BYTE_ARRAY_M12 = getBytes(STRING_M12);
+ protected static final char[] CHAR_ARRAY_M12 = new char[] { '\uFF21', 'A' };
+ protected static final int[] POINT_ARRAY_M12 = new int[] { '\uFF21', 'A' };
+
+ protected static final String STRING_SUPPLEMENTARY = "\uD801\uDC00\uD801\uDC01\uFF21A";
+ protected static final byte[] BYTE_ARRAY_SUPPLEMENTARY = getBytes(STRING_SUPPLEMENTARY);
+ protected static final char[] CHAR_ARRAY_SUPPLEMENTARY = new char[] {
+ '\uD801', '\uDC00', '\uD801', '\uDC01', '\uFF21', 'A' };
+ protected static final int[] POINT_ARRAY_SUPPLEMENTARY = new int[] {
+ '\uD801', '\uDC00', '\uD801', '\uDC01', '\uFF21', 'A' };
+
+ protected static final String STRING_SUPPLEMENTARY_LOWERCASE = "\uD801\uDC28\uD801\uDC29\uFF41a";
+ protected static final byte[] BYTE_ARRAY_SUPPLEMENTARY_LOWERCASE = getBytes(STRING_SUPPLEMENTARY_LOWERCASE);
+ protected static final char[] CHAR_ARRAY_SUPPLEMENTARY_LOWERCASE = new char[] {
+ '\uD801', '\uDC28', '\uD801', '\uDC29', '\uFF41', 'a' };
+ protected static final int[] POINT_ARRAY_SUPPLEMENTARY_LOWERCASE = new int[] {
+ '\uD801', '\uDC28', '\uD801', '\uDC29', '\uFF41', 'a' };
+
+ protected static final String SRC_BYTE_ARRAY_WITH_CHARSETNAME = "source from byte array with charset name";
+ protected static final String SRC_BYTE_ARRAY_WITH_CHARSET = "source from byte array with charset";
+ protected static final String SRC_CHAR_ARRAY = "source from char array";
+ protected static final String SRC_POINT_ARRAY = "source from code point array";
+ protected static final String SRC_STRING = "source from String";
+ protected static final String SRC_STRINGBUFFER = "source from StringBuffer";
+ protected static final String SRC_STRINGBUILDER = "source from StringBuilder";
+ protected static final String SRC_COPYVALUEOF = "source from copyValueOf from char array";
+ protected static final String SRC_VALUEOF = "source from valueOf from char array";
+
+ static {
+ System.out
+ .println(String
+ .format("====== The platform's default charset is \"%s\", we're using \"%s\" for testing.",
+ Charset.defaultCharset().name(),
+ DEFAULT_CHARSET_NAME));
+ }
+
+ private static byte[] getBytes(String str) {
+ byte[] res = null;
+ try {
+ res = str.getBytes(DEFAULT_CHARSET_NAME);
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ throw new RuntimeException("caught UnsupportedEncodingException!!!", e);
+ }
+ return res;
+ }
+
+ private void setUpOneString(String content, byte[] ba, char[] ca, int[] cpa)
+ throws UnsupportedEncodingException {
+ final Map<String, String> m = new HashMap<>();
+ m.put(SRC_BYTE_ARRAY_WITH_CHARSETNAME, new String(ba,
+ DEFAULT_CHARSET_NAME));
+ m.put(SRC_BYTE_ARRAY_WITH_CHARSET, new String(ba, DEFAULT_CHARSET));
+ m.put(SRC_CHAR_ARRAY, new String(ca));
+ m.put(SRC_POINT_ARRAY, new String(cpa, 0, cpa.length));
+ m.put(SRC_STRING, new String(content));
+ m.put(SRC_STRINGBUFFER, new String(new StringBuffer(content)));
+ m.put(SRC_STRINGBUILDER, new String(new StringBuilder(content)));
+ m.put(SRC_COPYVALUEOF, String.copyValueOf(ca));
+ m.put(SRC_VALUEOF, String.valueOf(ca));
+ map.put(content, m);
+ }
+
+ /*
+ * Set up the test data, use 9 ways to construct one String.
+ *
+ * @throws UnsupportedEncodingException
+ * If the named charset is not supported in setUpOneString(xxx).
+ */
+ @BeforeClass
+ public void setUp() throws UnsupportedEncodingException {
+ for (StringSources src : StringSources.values()) {
+ setUpOneString(src.getString(), src.getByteArray(),
+ src.getCharArray(), src.getIntArray());
+ }
+ }
+
+ /*
+ * Because right now system default charset in JPRT environment is only
+ * guaranteed to support ASCII characters in log, so we escape them.
+ */
+ protected String escapeNonASCIIs(String str) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c > 0x7F) {
+ sb.append("\\u").append(Integer.toHexString((int) c));
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /*
+ * Because right now system default charset in JPRT environment is only
+ * guaranteed to support ASCII characters in log, so we escape them.
+ */
+ protected String escapeNonASCII(char c) {
+ StringBuilder sb = new StringBuilder();
+ if (c > 0x7F) {
+ sb.append("\\u").append(Integer.toHexString((int) c));
+ } else {
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CompareTo.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.compareTo.
+ * @run testng/othervm -XX:+CompactStrings CompareTo
+ * @run testng/othervm -XX:-CompactStrings CompareTo
+ */
+
+public class CompareTo extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "A", -1 },
+ new Object[] { STRING_EMPTY, "\uFF21", -1 },
+ new Object[] { STRING_L1, "AB", -1 },
+ new Object[] { STRING_L1, "A", 0 },
+ new Object[] { STRING_L1, "a", -32 },
+ new Object[] { STRING_L1, "\uFF21", -65248 },
+ new Object[] { STRING_L2, "AB", 0 },
+ new Object[] { STRING_L2, "Ab", -32 },
+ new Object[] { STRING_L2, "AA", 1 },
+ new Object[] { STRING_L2, "\uFF21", -65248 },
+ new Object[] { STRING_L2, "A\uFF21", -65247 },
+ new Object[] { STRING_L4, "ABC", 1 },
+ new Object[] { STRING_L4, "AB", 2 },
+ new Object[] { STRING_L4, "ABcD", -32 },
+ new Object[] { STRING_L4, "ABCD\uFF21\uFF21", -2 },
+ new Object[] { STRING_L4, "ABCD\uFF21", -1 },
+ new Object[] { STRING_LLONG, "ABCDEFG\uFF21", -65241 },
+ new Object[] { STRING_LLONG, "AB", 6 },
+ new Object[] { STRING_LLONG, "ABCD", 4 },
+ new Object[] { STRING_LLONG, "ABCDEFGH\uFF21\uFF21", -2 },
+ new Object[] { STRING_U1, "\uFF21", 0 },
+ new Object[] { STRING_U1, "\uFF22", -1 },
+ new Object[] { STRING_U1, "\uFF21\uFF22", -1 },
+ new Object[] { STRING_U1, "A", 65248 },
+ new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
+ new Object[] { STRING_U2, "\uFF22", -1 },
+ new Object[] { STRING_U2, "\uFF21\uFF21", 1 },
+ new Object[] { STRING_U2, "A", 65248 },
+ new Object[] { STRING_M12, "\uFF21A", 0 },
+ new Object[] { STRING_M12, "A\uFF21", 65248 },
+ new Object[] { STRING_M12, "\uFF21\uFF21", -65248 },
+ new Object[] { STRING_M11, "A\uFF21", 0 },
+ new Object[] { STRING_M11, "\uFF21A", -65248 },
+ new Object[] { STRING_M11, "AA", 65248 }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testCompareTo(String str, String anotherString, int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.compareTo(anotherString),
+ expected,
+ String.format(
+ "testing String(%s).compareTo(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/CompareToIgnoreCase.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.compareToIgnoreCase.
+ * @run testng/othervm -XX:+CompactStrings CompareToIgnoreCase
+ * @run testng/othervm -XX:-CompactStrings CompareToIgnoreCase
+ */
+
+public class CompareToIgnoreCase extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "A", -1 },
+ new Object[] { STRING_L1, "a", 0 },
+ new Object[] { STRING_L1, "A", 0 },
+ new Object[] { STRING_L1, "\uFF21", -65248 },
+ new Object[] { STRING_L1, "B", -1 },
+ new Object[] { STRING_L2, "AB", 0 },
+ new Object[] { STRING_L2, "aB", 0 },
+ new Object[] { STRING_L2, "\uFF21", -65248 },
+ new Object[] { STRING_L2, "A\uFF21", -65247 },
+ new Object[] { STRING_L4, "ABCD", 0 },
+ new Object[] { STRING_L4, "abcd", 0 },
+ new Object[] { STRING_L4, "ABc\uFF21", -65245 },
+ new Object[] { STRING_LLONG, "ABCDEFGH", 0 },
+ new Object[] { STRING_LLONG, "abcdefgh", 0 },
+ new Object[] { STRING_LLONG, "ABCDEFG\uFF21", -65241 },
+ new Object[] { STRING_LLONG, "abcdefg\uFF21", -65241 },
+ new Object[] { STRING_U1, "\uFF41", 0 },
+ new Object[] { STRING_U1,
+ "\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48", -7 },
+ new Object[] { STRING_U1, "A", 65248 },
+ new Object[] { STRING_U2, "\uFF41", 1 },
+ new Object[] { STRING_U2, "\uFF41\uFF42", 0 },
+ new Object[] { STRING_U2,
+ "\uFF41\uFF42\uFF43\uFF44\uFF45\uFF46\uFF47\uFF48", -6 },
+ new Object[] { STRING_M12, "\uFF41a", 0 },
+ new Object[] { STRING_M12, "\uFF41\uFF42", -65249 },
+ new Object[] { STRING_M11, "a\uFF41", 0 },
+ new Object[] { STRING_M11, "a\uFF42", -1 }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testCompareToIgnoreCase(String str, String anotherString,
+ int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.compareToIgnoreCase(anotherString),
+ expected,
+ String.format(
+ "testing String(%s).compareToIgnoreCase(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Concat.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.concat.
+ * @run testng/othervm -XX:+CompactStrings Concat
+ * @run testng/othervm -XX:-CompactStrings Concat
+ */
+
+public class Concat extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ new Object[] { STRING_EMPTY, "ABC", "ABC" },
+ new Object[] { STRING_EMPTY,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "ABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_EMPTY,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+ new Object[] { STRING_L1,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "AABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_L1,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "A\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+ new Object[] { STRING_L2,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "ABABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_L2,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "AB\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+ new Object[] { STRING_L4,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "ABCDABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_L4,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "ABCD\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+ new Object[] { STRING_LLONG,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "ABCDEFGHABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_LLONG,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "ABCDEFGH\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+ new Object[] { STRING_U1,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "\uFF21ABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_U1,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "\uFF21\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+ new Object[] { STRING_U2,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "\uFF21\uFF22ABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_U2,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "\uFF21\uFF22\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+ new Object[] { STRING_M12,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "\uFF21AABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_M12,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "\uFF21A\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" },
+ new Object[] { STRING_M11,
+ "ABC".concat("\uFF21\uFF22\uFF23").concat("DEF"),
+ "A\uFF21ABC\uFF21\uFF22\uFF23DEF" },
+ new Object[] {
+ STRING_M11,
+ "\uFF21\uFF22\uFF23".concat("ABC").concat(
+ "\uFF24\uFF25\uFF26"),
+ "A\uFF21\uFF21\uFF22\uFF23ABC\uFF24\uFF25\uFF26" }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testConcat(String str, String anotherString, String expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.concat(anotherString),
+ expected,
+ String.format(
+ "testing String(%s).concat(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Contains.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.contains.
+ * @run testng/othervm -XX:+CompactStrings Contains
+ * @run testng/othervm -XX:-CompactStrings Contains
+ */
+
+public class Contains extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "", true },
+ new Object[] { STRING_EMPTY, "A", false },
+ new Object[] { STRING_EMPTY, "\uFF21", false },
+ new Object[] { STRING_L1, "", true },
+ new Object[] { STRING_L1, "A", true },
+ new Object[] { STRING_L1, "\uFF21", false },
+ new Object[] { STRING_L2, "", true },
+ new Object[] { STRING_L2, "A", true },
+ new Object[] { STRING_L2, "AB", true },
+ new Object[] { STRING_L2, "B", true },
+ new Object[] { STRING_L2, "ABC", false },
+ new Object[] { STRING_L2, "ab", false },
+ new Object[] { STRING_L4, "ABCD", true },
+ new Object[] { STRING_L4, "BC", true },
+ new Object[] { STRING_LLONG, "ABCDEFGH", true },
+ new Object[] { STRING_LLONG, "BCDEFGH", true },
+ new Object[] { STRING_LLONG, "EF", true },
+ new Object[] { STRING_U1, "", true },
+ new Object[] { STRING_U1, "\uFF21", true },
+ new Object[] { STRING_U1, "a", false },
+ new Object[] { STRING_U1, "\uFF21B", false },
+ new Object[] { STRING_U2, "", true },
+ new Object[] { STRING_U2, "\uFF21\uFF22", true },
+ new Object[] { STRING_U2, "a", false },
+ new Object[] { STRING_U2, "\uFF21B", false },
+ new Object[] { STRING_M12, "\uFF21A", true },
+ new Object[] { STRING_M12, "\uFF21", true },
+ new Object[] { STRING_M12, "A", true },
+ new Object[] { STRING_M12, "A\uFF21", false },
+ new Object[] { STRING_M11, "A\uFF21", true },
+ new Object[] { STRING_M11, "Ab", false }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testContains(String str, String anotherString, boolean expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.contains(anotherString),
+ expected,
+ String.format(
+ "testing String(%s).contains(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/EndsWith.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.endsWith.
+ * @run testng/othervm -XX:+CompactStrings EndsWith
+ * @run testng/othervm -XX:-CompactStrings EndsWith
+ */
+
+public class EndsWith extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] { new Object[] { STRING_EMPTY, "", true },
+ new Object[] { STRING_EMPTY, "A", false },
+ new Object[] { STRING_L1, "A", true },
+ new Object[] { STRING_L1, "", true },
+ new Object[] { STRING_L1, " ", false },
+ new Object[] { STRING_L2, "AB", true },
+ new Object[] { STRING_L2, "B", true },
+ new Object[] { STRING_L2, "", true },
+ new Object[] { STRING_L2, "A", false },
+ new Object[] { STRING_L4, "ABCD", true },
+ new Object[] { STRING_L4, "CD", true },
+ new Object[] { STRING_L4, "D", true },
+ new Object[] { STRING_L4, "", true },
+ new Object[] { STRING_L4, "BC", false },
+ new Object[] { STRING_LLONG, "ABCDEFGH", true },
+ new Object[] { STRING_LLONG, "EFGH", true },
+ new Object[] { STRING_LLONG, "", true },
+ new Object[] { STRING_LLONG, "CDEF", false },
+ new Object[] { STRING_LLONG, "\uFF28", false },
+ new Object[] { STRING_U1, "\uFF21", true },
+ new Object[] { STRING_U1, "", true },
+ new Object[] { STRING_U1, "\uFF22", false },
+ new Object[] { STRING_U1, "B", false },
+ new Object[] { STRING_U2, "\uFF21\uFF22", true },
+ new Object[] { STRING_U2, "\uFF22", true },
+ new Object[] { STRING_U2, "", true },
+ new Object[] { STRING_U2, "\uFF21", false },
+ new Object[] { STRING_M12, "\uFF21A", true },
+ new Object[] { STRING_M12, "A", true },
+ new Object[] { STRING_M12, "", true },
+ new Object[] { STRING_M12, "AA", false },
+ new Object[] { STRING_M11, "A\uFF21", true },
+ new Object[] { STRING_M11, "\uFF21", true },
+ new Object[] { STRING_M11, "", true },
+ new Object[] { STRING_M11, "\uFF21\uFF21", false }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testEndsWith(String str, String suffix, boolean expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.endsWith(suffix),
+ expected,
+ String.format(
+ "testing String(%s).endsWith(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(suffix), source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Equals.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.equals.
+ * @run testng/othervm -XX:+CompactStrings Equals
+ * @run testng/othervm -XX:-CompactStrings Equals
+ */
+
+public class Equals extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ new Object[] { STRING_EMPTY, "", true },
+ new Object[] { STRING_EMPTY, "A", false },
+ new Object[] { STRING_EMPTY, new StringBuffer(""), false },
+ new Object[] { STRING_L1, "A", true },
+ new Object[] { STRING_L1, "", false },
+ new Object[] { STRING_L1, new StringBuffer("A"), false },
+ new Object[] { STRING_L2, "AB", true },
+ new Object[] { STRING_L2, "", false },
+ new Object[] { STRING_L2, new StringBuilder("AB"), false },
+ new Object[] { STRING_L4, "ABCD", true },
+ new Object[] { STRING_L4, "abc", false },
+ new Object[] { STRING_L4, "", false },
+ new Object[] { STRING_LLONG, "ABCDEFGH", true },
+ new Object[] { STRING_LLONG, "ABCDEFG", false },
+ new Object[] { STRING_LLONG, new StringBuilder("ABCDEFGH"),
+ false },
+ new Object[] { STRING_U1, "\uFF21", true },
+ new Object[] { STRING_U1, "", false },
+ new Object[] { STRING_U2, "\uFF21\uFF22", true },
+ new Object[] { STRING_U2, "\uFF21", false },
+ new Object[] { STRING_U2, "", false },
+ new Object[] { STRING_U2, new StringBuilder("\uFF21\uFF22"),
+ false },
+ new Object[] { STRING_M12, "\uFF21A", true },
+ new Object[] { STRING_M12, "A\uFF21", false },
+ new Object[] { STRING_M11, "A\uFF21", true },
+ new Object[] { STRING_M11, new StringBuilder("\uFF21A"), false }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testEquals(String str, Object obj, boolean expected) {
+ map.get(str).forEach(
+ (source, data) -> {
+ assertEquals(data.equals(obj), expected, String.format(
+ "testing String(%s).equals(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(obj.toString()), source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/EqualsIgnoreCase.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.equalsIgnoreCase.
+ * @run testng/othervm -XX:+CompactStrings EqualsIgnoreCase
+ * @run testng/othervm -XX:-CompactStrings EqualsIgnoreCase
+ */
+
+public class EqualsIgnoreCase extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "", true },
+ new Object[] { STRING_L1, "a", true },
+ new Object[] { STRING_L2, "aB", true },
+ new Object[] { STRING_L4, "AbCd", true },
+ new Object[] { STRING_LLONG, "aBcDeFgH", true },
+ new Object[] { STRING_U1, "\uFF41", true },
+ new Object[] { STRING_U1, "\uFF21", true },
+ new Object[] { STRING_U2, "\uFF41\uFF42", true },
+ new Object[] { STRING_U2, "\uFF41\uFF22", true },
+ new Object[] { STRING_U2, "\uFF21\uFF42", true },
+ new Object[] { STRING_M12, "\uFF41a", true },
+ new Object[] { STRING_M12, "\uFF21A", true },
+ new Object[] { STRING_M11, "a\uFF41", true },
+ new Object[] { STRING_M11, "A\uFF21", true },
+
+ };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testEqualsIgnoreCase(String str, String anotherString,
+ boolean expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.equalsIgnoreCase(anotherString),
+ expected,
+ String.format(
+ "testing String(%s).equalsIgnoreCase(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/GetChars.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.getChars.
+ * @run testng/othervm -XX:+CompactStrings GetChars
+ * @run testng/othervm -XX:-CompactStrings GetChars
+ */
+
+public class GetChars extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, 0, STRING_EMPTY.length(),
+ new char[STRING_EMPTY.length()], 0, CHAR_ARRAY_EMPTY },
+ new Object[] { STRING_L1, 0, STRING_L1.length(),
+ new char[STRING_L1.length()], 0, CHAR_ARRAY_L1 },
+ new Object[] { STRING_L2, 0, STRING_L2.length(),
+ new char[STRING_L2.length()], 0, CHAR_ARRAY_L2 },
+ new Object[] { STRING_L4, 0, STRING_L4.length(),
+ new char[STRING_L4.length()], 0, CHAR_ARRAY_L4 },
+ new Object[] { STRING_LLONG, 0, STRING_LLONG.length(),
+ new char[STRING_LLONG.length()], 0, CHAR_ARRAY_LLONG },
+ new Object[] { STRING_U1, 0, STRING_U1.length(),
+ new char[STRING_U1.length()], 0, CHAR_ARRAY_U1 },
+ new Object[] { STRING_U2, 0, STRING_U2.length(),
+ new char[STRING_U2.length()], 0, CHAR_ARRAY_U2 },
+ new Object[] { STRING_M12, 0, STRING_M12.length(),
+ new char[STRING_M12.length()], 0, CHAR_ARRAY_M12 },
+ new Object[] { STRING_M11, 0, STRING_M11.length(),
+ new char[STRING_M11.length()], 0, CHAR_ARRAY_M11 },
+ new Object[] { STRING_UDUPLICATE, 0,
+ STRING_UDUPLICATE.length(),
+ new char[STRING_UDUPLICATE.length()], 0,
+ CHAR_ARRAY_UDUPLICATE },
+ new Object[] { STRING_MDUPLICATE1, 0,
+ STRING_MDUPLICATE1.length(),
+ new char[STRING_MDUPLICATE1.length()], 0,
+ CHAR_ARRAY_MDUPLICATE1 }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testGetChars(String str, int srcBegin, int srcEnd, char[] dst,
+ int dstBegin, char[] expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ data.getChars(srcBegin, srcEnd, dst, dstBegin);
+ assertTrue(
+ Arrays.equals(dst, expected),
+ String.format(
+ "testing String(%s).getChars(%d, %d, %s, %d), source : %s, ",
+ escapeNonASCIIs(data), srcBegin,
+ srcEnd, escapeNonASCIIs(Arrays
+ .toString(dst)), dstBegin,
+ source));
+ });
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/IndexOf.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.indexOf.
+ * @run testng/othervm -XX:+CompactStrings IndexOf
+ * @run testng/othervm -XX:-CompactStrings IndexOf
+ */
+
+public class IndexOf extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, (int) 'A', -1 },
+ new Object[] { STRING_L1, (int) 'A', 0 },
+ new Object[] { STRING_L2, (int) 'A', 0 },
+ new Object[] { STRING_L2, (int) 'B', 1 },
+ new Object[] { STRING_L4, (int) 'A', 0 },
+ new Object[] { STRING_L4, (int) 'D', 3 },
+ new Object[] { STRING_L4, (int) 'E', -1 },
+ new Object[] { STRING_LLONG, (int) 'A', 0 },
+ new Object[] { STRING_LLONG, (int) 'H', 7 },
+ new Object[] { STRING_U1, (int) '\uFF21', 0 },
+ new Object[] { STRING_U1, (int) 'A', -1 },
+ new Object[] { STRING_U2, (int) '\uFF21', 0 },
+ new Object[] { STRING_U2, (int) '\uFF22', 1 },
+ new Object[] { STRING_M12, (int) '\uFF21', 0 },
+ new Object[] { STRING_M12, (int) 'A', 1 },
+ new Object[] { STRING_M11, (int) 'A', 0 },
+ new Object[] { STRING_M11, (int) '\uFF21', 1 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 0 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 1 },
+ new Object[] { STRING_SUPPLEMENTARY, 'A', 5 },
+ new Object[] { STRING_SUPPLEMENTARY, '\uFF21', 4 },
+ new Object[] { STRING_SUPPLEMENTARY,
+ Character.toCodePoint('\uD801', '\uDC00'), 0 },
+ new Object[] { STRING_SUPPLEMENTARY,
+ Character.toCodePoint('\uD801', '\uDC01'), 2 }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testIndexOf(String str, int ch, int expected) {
+ map.get(str).forEach(
+ (source, data) -> {
+ assertEquals(data.indexOf(ch), expected, String.format(
+ "testing String(%s).indexOf(%d), source : %s, ",
+ escapeNonASCIIs(data), ch, source));
+ });
+ }
+
+ @DataProvider
+ public Object[][] provider2() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, (int) 'A', 0, -1 },
+ new Object[] { STRING_L1, (int) 'A', 0, 0 },
+ new Object[] { STRING_L1, (int) 'A', 1, -1 },
+ new Object[] { STRING_L1, (int) 'B', 0, -1 },
+ new Object[] { STRING_L2, (int) 'A', 0, 0 },
+ new Object[] { STRING_L2, (int) 'A', 1, -1 },
+ new Object[] { STRING_L2, (int) 'B', 0, 1 },
+ new Object[] { STRING_L2, (int) 'B', 1, 1 },
+ new Object[] { STRING_L4, (int) 'A', 0, 0 },
+ new Object[] { STRING_L4, (int) 'D', 2, 3 },
+ new Object[] { STRING_L4, (int) 'B', 2, -1 },
+ new Object[] { STRING_LLONG, (int) 'A', 0, 0 },
+ new Object[] { STRING_LLONG, (int) 'H', 5, 7 },
+ new Object[] { STRING_U1, (int) '\uFF21', 0, 0 },
+ new Object[] { STRING_U1, (int) 'A', 0, -1 },
+ new Object[] { STRING_U2, (int) '\uFF21', 0, 0 },
+ new Object[] { STRING_U2, (int) '\uFF22', 0, 1 },
+ new Object[] { STRING_M12, (int) '\uFF21', 0, 0 },
+ new Object[] { STRING_M12, (int) 'A', 1, 1 },
+ new Object[] { STRING_M11, (int) 'A', 0, 0 },
+ new Object[] { STRING_M11, (int) '\uFF21', 1, 1 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 1, 2 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 1, 1 }, };
+ }
+
+ @Test(dataProvider = "provider2")
+ public void testIndexOf(String str, int ch, int fromIndex, int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.indexOf(ch, fromIndex),
+ expected,
+ String.format(
+ "testing String(%s).indexOf(%d, %d), source : %s, ",
+ escapeNonASCIIs(data), ch,
+ fromIndex, source));
+ });
+ }
+
+ @DataProvider
+ public Object[][] provider3() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "A", -1 },
+ new Object[] { STRING_L1, "A", 0 },
+ new Object[] { STRING_L1, "AB", -1 },
+ new Object[] { STRING_L2, "A", 0 },
+ new Object[] { STRING_L2, "B", 1 },
+ new Object[] { STRING_L2, "AB", 0 },
+ new Object[] { STRING_L2, "AC", -1 },
+ new Object[] { STRING_L2, "ABC", -1 },
+ new Object[] { STRING_L4, "ABCD", 0 },
+ new Object[] { STRING_L4, "D", 3 },
+ new Object[] { STRING_LLONG, "ABCDEFGH", 0 },
+ new Object[] { STRING_LLONG, "EFGH", 4 },
+ new Object[] { STRING_LLONG, "EFGHI", -1 },
+ new Object[] { STRING_U1, "\uFF21", 0 },
+ new Object[] { STRING_U1, "\uFF21A", -1 },
+ new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
+ new Object[] { STRING_U2, "\uFF22", 1 },
+ new Object[] { STRING_U2, "A\uFF22", -1 },
+ new Object[] { STRING_M12, "\uFF21A", 0 },
+ new Object[] { STRING_M12, "A", 1 },
+ new Object[] { STRING_M12, "\uFF21\uFF21", -1 },
+ new Object[] { STRING_M11, "A\uFF21", 0 },
+ new Object[] { STRING_M11, "\uFF21", 1 },
+ new Object[] { STRING_M11, "A", 0 },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+ 0 },
+ new Object[] { STRING_UDUPLICATE,
+ "\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21", 1 },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21",
+ -1 }, };
+ }
+
+ @Test(dataProvider = "provider3")
+ public void testIndexOf(String str, String anotherString, int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.indexOf(anotherString),
+ expected,
+ String.format(
+ "testing String(%s).indexOf(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ source));
+ });
+ }
+
+ @DataProvider
+ public Object[][] provider4() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "A", 0, -1 },
+ new Object[] { STRING_L1, "A", 0, 0 },
+ new Object[] { STRING_L1, "A", 1, -1 },
+ new Object[] { STRING_L1, "AB", 0, -1 },
+ new Object[] { STRING_L2, "A", 0, 0 },
+ new Object[] { STRING_L2, "B", 0, 1 },
+ new Object[] { STRING_L2, "AB", 0, 0 },
+ new Object[] { STRING_L2, "AB", 1, -1 },
+ new Object[] { STRING_L4, "ABCD", 0, 0 },
+ new Object[] { STRING_L4, "BC", 0, 1 },
+ new Object[] { STRING_L4, "A", 0, 0 },
+ new Object[] { STRING_L4, "CD", 0, 2 },
+ new Object[] { STRING_L4, "A", 2, -1 },
+ new Object[] { STRING_L4, "ABCDE", 0, -1 },
+ new Object[] { STRING_LLONG, "ABCDEFGH", 0, 0 },
+ new Object[] { STRING_LLONG, "DEFGH", 0, 3 },
+ new Object[] { STRING_LLONG, "A", 0, 0 },
+ new Object[] { STRING_LLONG, "GHI", 0, -1 },
+ new Object[] { STRING_U1, "\uFF21", 0, 0 },
+ new Object[] { STRING_U1, "\uFF21A", 0, -1 },
+ new Object[] { STRING_U2, "\uFF21\uFF22", 0, 0 },
+ new Object[] { STRING_U2, "\uFF22", 0, 1 },
+ new Object[] { STRING_U2, "\uFF21", 1, -1 },
+ new Object[] { STRING_M12, "\uFF21A", 0, 0 },
+ new Object[] { STRING_M12, "A", 1, 1 },
+ new Object[] { STRING_M12, "\uFF21A", 1, -1 },
+ new Object[] { STRING_M12, "\uFF21", 0, 0 },
+ new Object[] { STRING_M11, "A\uFF21", 0, 0 },
+ new Object[] { STRING_M11, "\uFF21", 1, 1 },
+ new Object[] { STRING_M11, "A\uFF21", 1, -1 },
+ new Object[] { STRING_M11, "A\uFF21A", 0, -1 },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+ 0, 0 },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+ 1, -1 },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+ 1, 1 },
+ new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
+ 4, 4 },
+ new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22",
+ 7, -1 }, };
+ }
+
+ @Test(dataProvider = "provider4")
+ public void testIndexOf(String str, String anotherString, int fromIndex,
+ int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.indexOf(anotherString, fromIndex),
+ expected,
+ String.format(
+ "testing String(%s).indexOf(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ fromIndex, source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Intern.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.intern.
+ * @run testng/othervm -XX:+CompactStrings Intern
+ * @run testng/othervm -XX:-CompactStrings Intern
+ */
+
+public class Intern extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "" },
+ new Object[] { STRING_L1, "A" },
+ new Object[] { STRING_LLONG, "ABCDEFGH" },
+ new Object[] { STRING_U1, "\uFF21" },
+ new Object[] { STRING_U2, "\uFF21\uFF22" },
+ new Object[] { STRING_M12, "\uFF21A" },
+ new Object[] { STRING_M11, "A\uFF21" },
+ new Object[] { STRING_MDUPLICATE1,
+ "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A" }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testIntern(String str, String expected) {
+ map.get(str).forEach(
+ (source, data) -> {
+ assertTrue(data.intern() == expected, String.format(
+ "testing String(%s).intern(), source : %s, ",
+ escapeNonASCIIs(data), source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/LastIndexOf.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.lastIndexOf.
+ * @run testng/othervm -XX:+CompactStrings LastIndexOf
+ * @run testng/othervm -XX:-CompactStrings LastIndexOf
+ */
+
+public class LastIndexOf extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, (int) 'A', -1 },
+ new Object[] { STRING_L1, (int) 'A', 0 },
+ new Object[] { STRING_L2, (int) 'A', 0 },
+ new Object[] { STRING_L2, (int) 'B', 1 },
+ new Object[] { STRING_L4, (int) 'A', 0 },
+ new Object[] { STRING_L4, (int) 'D', 3 },
+ new Object[] { STRING_LLONG, (int) 'A', 0 },
+ new Object[] { STRING_LLONG, (int) 'H', 7 },
+ new Object[] { STRING_U1, (int) '\uFF21', 0 },
+ new Object[] { STRING_U1, (int) 'B', -1 },
+ new Object[] { STRING_U2, (int) '\uFF21', 0 },
+ new Object[] { STRING_U2, (int) '\uFF22', 1 },
+ new Object[] { STRING_M12, (int) '\uFF21', 0 },
+ new Object[] { STRING_M12, (int) 'A', 1 },
+ new Object[] { STRING_M11, (int) 'A', 0 },
+ new Object[] { STRING_M11, (int) '\uFF21', 1 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 9 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 8 },
+ new Object[] { STRING_SUPPLEMENTARY,
+ Character.toCodePoint('\uD801', '\uDC01'), 2 }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testLastIndexOf(String str, int ch, int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.lastIndexOf(ch),
+ expected,
+ String.format(
+ "testing String(%s).lastIndexOf(%d), source : %s, ",
+ escapeNonASCIIs(data), ch, source));
+ });
+ }
+
+ @DataProvider
+ public Object[][] provider2() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, (int) 'A', 0, -1 },
+ new Object[] { STRING_L1, (int) 'A', 0, 0 },
+ new Object[] { STRING_L1, (int) 'A', 1, 0 },
+ new Object[] { STRING_L2, (int) 'A', 0, 0 },
+ new Object[] { STRING_L2, (int) 'B', 1, 1 },
+ new Object[] { STRING_L2, (int) 'B', 2, 1 },
+ new Object[] { STRING_L4, (int) 'A', 0, 0 },
+ new Object[] { STRING_L4, (int) 'C', 2, 2 },
+ new Object[] { STRING_L4, (int) 'C', 1, -1 },
+ new Object[] { STRING_LLONG, (int) 'A', 0, 0 },
+ new Object[] { STRING_LLONG, (int) 'H', 7, 7 },
+ new Object[] { STRING_LLONG, (int) 'H', 6, -1 },
+ new Object[] { STRING_U1, (int) '\uFF21', 0, 0 },
+ new Object[] { STRING_U1, (int) '\uFF21', 7, 0 },
+ new Object[] { STRING_U2, (int) '\uFF21', 0, 0 },
+ new Object[] { STRING_U2, (int) '\uFF22', 0, -1 },
+ new Object[] { STRING_M12, (int) '\uFF21', 0, 0 },
+ new Object[] { STRING_M12, (int) 'A', 1, 1 },
+ new Object[] { STRING_M12, (int) 'A', 0, -1 },
+ new Object[] { STRING_M11, (int) 'A', 0, 0 },
+ new Object[] { STRING_M11, (int) '\uFF21', 1, 1 },
+ new Object[] { STRING_M11, (int) '\uFF21', 0, -1 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 5, 4 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF21', 6, 6 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 5, 5 },
+ new Object[] { STRING_UDUPLICATE, (int) '\uFF22', 6, 5 }, };
+ }
+
+ @Test(dataProvider = "provider2")
+ public void testLastIndexOf(String str, int ch, int fromIndex, int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.lastIndexOf(ch, fromIndex),
+ expected,
+ String.format(
+ "testing String(%s).lastIndexOf(%d, %d), source : %s, ",
+ escapeNonASCIIs(data), ch,
+ fromIndex, source));
+ });
+ }
+
+ @DataProvider
+ public Object[][] provider3() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "A", -1 },
+ new Object[] { STRING_L1, "A", 0 },
+ new Object[] { STRING_L1, "AB", -1 },
+
+ new Object[] { STRING_L2, "AB", 0 },
+ new Object[] { STRING_L2, "B", 1 },
+ new Object[] { STRING_L4, "ABCD", 0 },
+ new Object[] { STRING_L4, "B", 1 },
+ new Object[] { STRING_LLONG, "ABCD", 0 },
+ new Object[] { STRING_LLONG, "GH", 6 },
+ new Object[] { STRING_U1, "\uFF21", 0 },
+ new Object[] { STRING_U1, "\uFF22", -1 },
+ new Object[] { STRING_U2, "\uFF21\uFF22", 0 },
+ new Object[] { STRING_U2, "\uFF22", 1 },
+ new Object[] { STRING_M12, "\uFF21A", 0 },
+ new Object[] { STRING_M12, "A", 1 },
+ new Object[] { STRING_M11, "A\uFF21", 0 },
+ new Object[] { STRING_M11, "\uFF21", 1 },
+ new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21\uFF22", 6 },
+ new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", 8 }, };
+ }
+
+ @Test(dataProvider = "provider3")
+ public void testLastIndexOf(String str, String anotherString, int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.lastIndexOf(anotherString),
+ expected,
+ String.format(
+ "testing String(%s).lastIndexOf(%s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ source));
+ });
+ }
+
+ @DataProvider
+ public Object[][] provider4() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "A", 0, -1 },
+ new Object[] { STRING_L2, "AB", 0, 0 },
+
+ new Object[] { STRING_L1, "AB", -1, -1 },
+
+ new Object[] { STRING_L2, "B", 1, 1 },
+ new Object[] { STRING_L2, "B", 0, -1 },
+ new Object[] { STRING_L4, "ABC", 3, 0 },
+ new Object[] { STRING_L4, "ABC", 0, 0 },
+ new Object[] { STRING_L4, "ABC", 1, 0 },
+ new Object[] { STRING_L4, "BC", 1, 1 },
+ new Object[] { STRING_L4, "BC", 0, -1 },
+ new Object[] { STRING_LLONG, "ABCDEFGH", 0, 0 },
+ new Object[] { STRING_LLONG, "EFGH", 7, 4 },
+ new Object[] { STRING_LLONG, "EFGH", 3, -1 },
+ new Object[] { STRING_U1, "\uFF21", 0, 0 },
+ new Object[] { STRING_U1, "\uFF21", 7, 0 },
+ new Object[] { STRING_U2, "\uFF21\uFF22", 0, 0 },
+ new Object[] { STRING_U2, "\uFF21\uFF22", 1, 0 },
+ new Object[] { STRING_M12, "\uFF21A", 0, 0 },
+ new Object[] { STRING_M12, "A", 1, 1 },
+ new Object[] { STRING_M12, "A", 0, -1 },
+ new Object[] { STRING_M11, "A\uFF21", 0, 0 },
+ new Object[] { STRING_M11, "A\uFF21", 1, 0 },
+ new Object[] { STRING_M11, "\uFF21", 0, -1 },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+ 9, 0 },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+ 0, 0 },
+ new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", 6, 6 },
+ new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22\uFF21", 6, 6 }, };
+ }
+
+ @Test(dataProvider = "provider4")
+ public void testLastIndexOf(String str, String anotherString,
+ int fromIndex, int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.lastIndexOf(anotherString, fromIndex),
+ expected,
+ String.format(
+ "testing String(%s).lastIndexOf(%s, %d), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(anotherString),
+ fromIndex, source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Length.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.length.
+ * @run testng/othervm -XX:+CompactStrings Length
+ * @run testng/othervm -XX:-CompactStrings Length
+ */
+
+public class Length extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, 0 }, new Object[] { STRING_L1, 1 },
+ new Object[] { STRING_L2, 2 },
+ new Object[] { STRING_LLONG, 8 },
+ new Object[] { STRING_U1, 1 }, new Object[] { STRING_U2, 2 },
+ new Object[] { STRING_M12, 2 }, new Object[] { STRING_M11, 2 },
+ new Object[] { STRING_UDUPLICATE, 10 },
+ new Object[] { STRING_SUPPLEMENTARY, 6 }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testLength(String str, int expected) {
+ map.get(str).forEach(
+ (source, data) -> {
+ assertEquals(data.length(), expected, String.format(
+ "testing String(%s).length(), source : %s, ",
+ escapeNonASCIIs(data), source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Numbers.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is testing
+ * Integer/Long's methods related to String.
+ * @run testng/othervm -XX:+CompactStrings Numbers
+ * @run testng/othervm -XX:-CompactStrings Numbers
+ */
+
+public class Numbers {
+
+ /*
+ * Data provider for testIntegerLong
+ *
+ * @return input parameter for testIntegerLong
+ */
+ @DataProvider
+ public Object[][] numbers() {
+ return new Object[][] {
+ { Integer.toBinaryString(Integer.MAX_VALUE),
+ "1111111111111111111111111111111" },
+ { Integer.toBinaryString(Integer.MIN_VALUE),
+ "10000000000000000000000000000000" },
+ { Integer.toBinaryString(7), "111" },
+ { Integer.toBinaryString(0), "0" },
+ { Integer.toOctalString(Integer.MAX_VALUE), "17777777777" },
+ { Integer.toOctalString(Integer.MIN_VALUE), "20000000000" },
+ { Integer.toOctalString(9), "11" },
+ { Integer.toOctalString(0), "0" },
+ { Integer.toHexString(Integer.MAX_VALUE), "7fffffff" },
+ { Integer.toHexString(Integer.MIN_VALUE), "80000000" },
+ { Integer.toHexString(17), "11" },
+ { Integer.toHexString(0), "0" },
+ { Integer.toString(Integer.MAX_VALUE, 2),
+ "1111111111111111111111111111111" },
+ { Integer.toString(Integer.MIN_VALUE, 2),
+ "-10000000000000000000000000000000" },
+ { Integer.toString(7, 2), "111" },
+ { Integer.toString(0, 2), "0" },
+ { Integer.toString(Integer.MAX_VALUE, 8), "17777777777" },
+ { Integer.toString(Integer.MIN_VALUE, 8), "-20000000000" },
+ { Integer.toString(9, 8), "11" },
+ { Integer.toString(Integer.MAX_VALUE, 16), "7fffffff" },
+ { Integer.toString(Integer.MIN_VALUE, 16), "-80000000" },
+ { Integer.toString(17, 16), "11" },
+ { Long.toBinaryString(Long.MAX_VALUE),
+ "111111111111111111111111111111111111111111111111111111111111111" },
+ { Long.toBinaryString(Long.MIN_VALUE),
+ "1000000000000000000000000000000000000000000000000000000000000000" },
+ { Long.toOctalString(Long.MAX_VALUE), "777777777777777777777" },
+ { Long.toOctalString(Long.MIN_VALUE), "1000000000000000000000" },
+ { Long.toHexString(Long.MAX_VALUE), "7fffffffffffffff" },
+ { Long.toHexString(Long.MIN_VALUE), "8000000000000000" },
+ { Long.toString(Long.MAX_VALUE, 2),
+ "111111111111111111111111111111111111111111111111111111111111111" },
+ { Long.toString(Long.MIN_VALUE, 2),
+ "-1000000000000000000000000000000000000000000000000000000000000000" },
+ { Long.toString(Long.MAX_VALUE, 8), "777777777777777777777" },
+ { Long.toString(Long.MIN_VALUE, 8), "-1000000000000000000000" },
+ { Long.toString(Long.MAX_VALUE, 16), "7fffffffffffffff" },
+ { Long.toString(Long.MIN_VALUE, 16), "-8000000000000000" } };
+ }
+
+ /*
+ * test Integer/Long's methods related to String.
+ *
+ * @param res
+ * real result
+ * @param expected
+ * expected result
+ */
+ @Test(dataProvider = "numbers")
+ public void testIntegerLong(String res, String expected) {
+ assertEquals(res, expected);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/OffsetByCodePoints.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.offsetByCodePoints.
+ * @run testng/othervm -XX:+CompactStrings OffsetByCodePoints
+ * @run testng/othervm -XX:-CompactStrings OffsetByCodePoints
+ */
+
+public class OffsetByCodePoints extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_SUPPLEMENTARY, 0, 1, 2 },
+ new Object[] { STRING_SUPPLEMENTARY, 0, 3, 5 },
+ new Object[] { STRING_SUPPLEMENTARY, 1, 1, 2 },
+ new Object[] { STRING_SUPPLEMENTARY, 1, 3, 5 },
+ new Object[] { STRING_SUPPLEMENTARY, 2, 1, 4 },
+ new Object[] { STRING_SUPPLEMENTARY, 2, 2, 5 },
+ new Object[] { STRING_SUPPLEMENTARY, 2, 3, 6 },
+ new Object[] { STRING_SUPPLEMENTARY, 3, 1, 4 },
+ new Object[] { STRING_SUPPLEMENTARY, 3, 2, 5 },
+ new Object[] { STRING_SUPPLEMENTARY, 3, 3, 6 }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testOffsetByCodePoints(String str, int index,
+ int codePointOffset, int expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.offsetByCodePoints(index,
+ codePointOffset),
+ expected,
+ String.format(
+ "testing String(%s).offsetByCodePoints(%d, %d), source : %s, ",
+ escapeNonASCIIs(data), index,
+ codePointOffset, source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/RegionMatches.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.regionMatches.
+ * @run testng/othervm -XX:+CompactStrings RegionMatches
+ * @run testng/othervm -XX:-CompactStrings RegionMatches
+ */
+
+public class RegionMatches extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, true, 0, "", 0, 0, true },
+ new Object[] { STRING_EMPTY, true, 0, "", 0, 1, false },
+ new Object[] { STRING_EMPTY, true, 0, "A", 0, 0, true },
+ new Object[] { STRING_EMPTY, true, 0, "", 0, 0, true },
+ new Object[] { STRING_EMPTY, true, 0, "", 0, 1, false },
+ new Object[] { STRING_L1, false, 0, "a", 0, 1, false },
+ new Object[] { STRING_L1, false, 0, "BA", 1, 1, true },
+ new Object[] { STRING_L1, false, 0, "Ba", 1, 1, false },
+ new Object[] { STRING_L1, true, 0, "a", 0, 1, true },
+ new Object[] { STRING_L1, true, 0, "BA", 1, 1, true },
+ new Object[] { STRING_L1, true, 0, "Ba", 1, 1, true },
+ new Object[] { STRING_L2, true, 1, "b", 0, 1, true },
+ new Object[] { STRING_L2, true, 1, "B", 0, 1, true },
+ new Object[] { STRING_L2, true, 0, "xaBc", 1, 2, true },
+ new Object[] { STRING_L2, false, 0, "AB", 0, 2, true },
+ new Object[] { STRING_L2, false, 0, "Ab", 0, 2, false },
+ new Object[] { STRING_L2, false, 1, "BAB", 2, 1, true },
+ new Object[] { STRING_LLONG, true, 1, "bCdEF", 0, 5, true },
+ new Object[] { STRING_LLONG, false, 2, "CDEFG", 0, 5, true },
+ new Object[] { STRING_LLONG, true, 2, "CDEFg", 0, 5, true },
+ new Object[] { STRING_U1, true, 0, "\uFF41", 0, 1, true },
+ new Object[] { STRING_U1, false, 0, "\uFF41", 0, 1, false },
+ new Object[] { STRING_MDUPLICATE1, true, 0, "\uFF41a\uFF41", 0,
+ 3, true },
+ new Object[] { STRING_MDUPLICATE1, false, 0, "\uFF21a\uFF21",
+ 0, 3, false },
+ new Object[] { STRING_SUPPLEMENTARY, true, 1, "\uDC00\uD801",
+ 0, 2, true },
+ new Object[] { STRING_SUPPLEMENTARY, true, 4, "\uFF21", 0, 1,
+ true },
+ new Object[] { STRING_SUPPLEMENTARY, true, 5, "A", 0, 1, true },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 0,
+ "\uD801\uDC28\uD801\uDC29", 0, 4, true },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 1,
+ "\uDC28\uD801", 0, 2, true },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 1,
+ "\uDC00\uD801", 0, 2, false },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, true, 4,
+ "\uFF21", 0, 1, true },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 4,
+ "\uFF21", 0, 1, false },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, false, 4,
+ "\uFF41", 0, 1, true }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testRegionMatches(String str, boolean ignoreCase, int toffset,
+ String other, int ooffset, int len, boolean expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.regionMatches(ignoreCase, toffset,
+ other, ooffset, len),
+ expected,
+ String.format(
+ "testing String(%s).regionMatches(%b, %d, %s, %d, %d), source : %s, ",
+ escapeNonASCIIs(data), ignoreCase,
+ toffset, escapeNonASCIIs(other),
+ ooffset, len, source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Replace.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.replace.
+ * @run testng/othervm -XX:+CompactStrings Replace
+ * @run testng/othervm -XX:-CompactStrings Replace
+ */
+
+public class Replace extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_L1, 'A', 'B', "B" },
+ new Object[] { STRING_L1, 'A', 'A', "A" },
+ new Object[] { STRING_L1, 'A', '\uFF21', "\uFF21" },
+ new Object[] { STRING_L2, 'A', 'B', "BB" },
+ new Object[] { STRING_L2, 'B', 'A', "AA" },
+ new Object[] { STRING_L2, 'C', 'A', "AB" },
+ new Object[] { STRING_L2, 'B', '\uFF21', "A\uFF21" },
+ new Object[] { STRING_U1, '\uFF21', 'A', "A" },
+ new Object[] { STRING_U1, '\uFF22', 'A', "\uFF21" },
+ new Object[] { STRING_U2, '\uFF22', 'A', "\uFF21A" },
+ new Object[] { STRING_M12, 'A', '\uFF21', "\uFF21\uFF21" },
+ new Object[] { STRING_M11, '\uFF21', 'A', "AA" },
+ new Object[] { STRING_UDUPLICATE, '\uFF21', 'A',
+ "A\uFF22A\uFF22A\uFF22A\uFF22A\uFF22" },
+ new Object[] { STRING_MDUPLICATE1, '\uFF21', 'A', "AAAAAAAAAA" },
+ new Object[] { STRING_MDUPLICATE1, 'A', '\uFF21',
+ "\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21" }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testReplace(String str, char oldChar, char newChar,
+ String expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.replace(oldChar, newChar),
+ expected,
+ String.format(
+ "testing String(%s).replace(%s, %s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCII(oldChar),
+ escapeNonASCII(newChar), source));
+ });
+ }
+
+ @DataProvider
+ public Object[][] provider2() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "", "ABC", "ABC" },
+ new Object[] { STRING_EMPTY, "", "", "" },
+ new Object[] { STRING_L1, "A", "B", "B" },
+ new Object[] { STRING_L1, "A", "A", "A" },
+ new Object[] { STRING_L2, "B", "\uFF21", "A\uFF21" },
+ new Object[] { STRING_LLONG, "BCD", "\uFF21", "A\uFF21EFGH" },
+ new Object[] { STRING_U1, "\uFF21", "A", "A" },
+ new Object[] { STRING_U1, "\uFF21", "A\uFF21", "A\uFF21" },
+ new Object[] { STRING_U2, "\uFF21", "A", "A\uFF22" },
+ new Object[] { STRING_U2, "\uFF22", "A", "\uFF21A" },
+ new Object[] { STRING_UDUPLICATE, "\uFF21\uFF22", "AB",
+ "ABABABABAB" },
+ new Object[] { STRING_MDUPLICATE1, "\uFF21", "A", "AAAAAAAAAA" },
+ new Object[] { STRING_MDUPLICATE1, "A", "\uFF21",
+ "\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21\uFF21" }, };
+ }
+
+ @Test(dataProvider = "provider2")
+ public void testReplace(String str, CharSequence target,
+ CharSequence replacement, String expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.replace(target, replacement),
+ expected,
+ String.format(
+ "testing String(%s).replace(%s, %s), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(target.toString()),
+ escapeNonASCIIs(replacement
+ .toString()), source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/SerializationTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static jdk.testlibrary.SerializationUtils.*;
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.SerializationUtils
+ * @summary Tests Compact String. This one is testing String serialization
+ * among -XX:+CompactStrings/-XX:-CompactStrings/LegacyString
+ * @run testng/othervm -XX:+CompactStrings SerializationTest
+ * @run testng/othervm -XX:-CompactStrings SerializationTest
+ */
+
+public class SerializationTest {
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ // every byte array is serialized from corresponding String object
+ // by previous JDK(build 1.8.0_45-b14).
+ new Object[] { "", new byte[] { -84, -19, 0, 5, 116, 0, 0 } },
+ new Object[] { "A", new byte[] { -84, -19, 0, 5, 116, 0, 1, 65 } },
+ new Object[] { "AB", new byte[] { -84, -19, 0, 5, 116, 0, 2, 65, 66 } },
+ new Object[] { "abcdefghijk",
+ new byte[] {-84, -19, 0, 5, 116, 0, 11, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107 } },
+ new Object[] { "\uff21", new byte[] { -84, -19, 0, 5, 116, 0, 3, -17, -68, -95 } },
+ new Object[] { "\uff21\uff22", new byte[] { -84, -19, 0, 5, 116, 0, 6, -17, -68,
+ -95, -17, -68, -94 } },
+ new Object[] { "\uff21A\uff21A\uff21A\uff21A\uff21A",
+ new byte[] { -84, -19, 0, 5, 116, 0, 20, -17, -68, -95, 65, -17, -68,
+ -95, 65, -17, -68, -95, 65, -17, -68, -95, 65, -17, -68, -95, 65 } },
+ new Object[] { "A\uff21B\uff22C\uff23D\uff24E\uff25F\uff26G\uff27H\uff28",
+ new byte[] { -84, -19, 0, 5, 116, 0, 32, 65, -17, -68, -95, 66, -17, -68,
+ -94, 67, -17, -68, -93, 68, -17, -68, -92, 69, -17, -68, -91, 70, -17,
+ -68, -90, 71, -17, -68, -89, 72, -17, -68, -88 } },
+ new Object[] { "\uff21A\uff22B\uff23C\uff24D\uff25E\uff26F\uff27G\uff28H",
+ new byte[] { -84, -19, 0, 5, 116, 0, 32, -17, -68, -95, 65, -17, -68,
+ -94, 66, -17, -68, -93, 67, -17, -68, -92, 68, -17, -68, -91, 69, -17,
+ -68, -90, 70, -17, -68, -89, 71, -17, -68, -88, 72 } },
+ new Object[] { "\ud801\udc00\ud801\udc01\uff21A",
+ new byte[] { -84, -19, 0, 5, 116, 0, 16, -19, -96, -127, -19, -80, -128,
+ -19, -96, -127, -19, -80, -127, -17, -68, -95, 65 } },
+ new Object[] { "\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22",
+ new byte[] { -84, -19, 0, 5, 116, 0, 30, -17, -68, -95, -17, -68, -94, -17,
+ -68, -95, -17, -68, -94, -17, -68, -95, -17, -68, -94, -17, -68, -95, -17,
+ -68, -94, -17, -68, -95, -17, -68, -94 } } };
+ }
+
+ /*
+ * Verify serialization works between Compact String/Legacy String
+ */
+ @Test(dataProvider = "provider")
+ public void test(String strContent, byte[] baInJDK8) throws Exception {
+ // Serialize a String object into byte array.
+ byte[] ba = serialize(strContent);
+ assertEquals(ba, baInJDK8);
+ // Deserialize a String object from byte array which is generated by previous JDK(build 1.8.0_45-b14).
+ Object obj = deserialize(ba);
+ assertEquals(obj.getClass(), String.class);
+ assertEquals((String)obj, strContent);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Split.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.split.
+ * @run testng/othervm -XX:+CompactStrings Split
+ * @run testng/othervm -XX:-CompactStrings Split
+ */
+
+public class Split extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ new Object[] { STRING_L1, "", 0, new String[] { "A" } },
+ new Object[] { STRING_L1, "", 1, new String[] { "A" } },
+ new Object[] { STRING_L1, "", 2, new String[] { "A", "" } },
+ new Object[] { STRING_L1, "A", 0, new String[] {} },
+ new Object[] { STRING_L2, "A", 0, new String[] { "", "B" } },
+ new Object[] { STRING_L2, "B", 0, new String[] { "A" } },
+ new Object[] { STRING_LLONG, "D", 0,
+ new String[] { "ABC", "EFGH" } },
+ new Object[] { STRING_LLONG, "[D]", 0,
+ new String[] { "ABC", "EFGH" } },
+ new Object[] { STRING_LLONG, "CD", 0,
+ new String[] { "AB", "EFGH" } },
+ new Object[] { STRING_LLONG, "DC", 0,
+ new String[] { "ABCDEFGH" } },
+ new Object[] { STRING_LLONG, "[CF]", 0,
+ new String[] { "AB", "DE", "GH" } },
+ new Object[] { STRING_LLONG, "[CF]", 1,
+ new String[] { "ABCDEFGH" } },
+ new Object[] { STRING_LLONG, "[CF]", 2,
+ new String[] { "AB", "DEFGH" } },
+ new Object[] { STRING_LLONG, "[FC]", 0,
+ new String[] { "AB", "DE", "GH" } },
+ new Object[] { STRING_LLONG, "[FC]", 1,
+ new String[] { "ABCDEFGH" } },
+ new Object[] { STRING_LLONG, "[FC]", 2,
+ new String[] { "AB", "DEFGH" } },
+ new Object[] { STRING_U1, "", 0, new String[] { "\uFF21" } },
+ new Object[] { STRING_U1, "", 1, new String[] { "\uFF21" } },
+ new Object[] { STRING_U1, "", 2, new String[] { "\uFF21", "" } },
+ new Object[] { STRING_U1, "\uFF21", 0, new String[] {} },
+ new Object[] { STRING_M12, "\uFF21", 0,
+ new String[] { "", "A" } },
+ new Object[] { STRING_M12, "A", 0, new String[] { "\uFF21" } },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21",
+ 0,
+ new String[] { "", "\uFF22", "\uFF22", "\uFF22",
+ "\uFF22", "\uFF22" } },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21",
+ 2,
+ new String[] { "",
+ "\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22" } },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF21",
+ 4,
+ new String[] { "", "\uFF22", "\uFF22",
+ "\uFF22\uFF21\uFF22\uFF21\uFF22" } },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF22",
+ 0,
+ new String[] { "\uFF21", "\uFF21", "\uFF21", "\uFF21",
+ "\uFF21" } },
+ new Object[] {
+ STRING_UDUPLICATE,
+ "\uFF22",
+ 3,
+ new String[] { "\uFF21", "\uFF21",
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22" } },
+
+ new Object[] { STRING_MDUPLICATE1, "\uFF21", 0,
+ new String[] { "", "A", "A", "A", "A", "A" } },
+ new Object[] { STRING_MDUPLICATE1, "\uFF21", 3,
+ new String[] { "", "A", "A\uFF21A\uFF21A\uFF21A" } },
+ new Object[] {
+ STRING_MDUPLICATE1,
+ "A",
+ 0,
+ new String[] { "\uFF21", "\uFF21", "\uFF21", "\uFF21",
+ "\uFF21" } },
+ new Object[] {
+ STRING_MDUPLICATE1,
+ "A",
+ 4,
+ new String[] { "\uFF21", "\uFF21", "\uFF21",
+ "\uFF21A\uFF21A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "\uD801\uDC01", 0,
+ new String[] { "\uD801\uDC00", "\uFF21A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "\uDC01", 0,
+ new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "\uD801\uDC01", 0,
+ new String[] { "\uD801\uDC00", "\uFF21A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 0,
+ new String[] { "\uD801\uDC00", "", "A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 1,
+ new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "[\uD801\uDC01\uFF21]", 2,
+ new String[] { "\uD801\uDC00", "\uFF21A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 0,
+ new String[] { "\uD801\uDC00", "", "A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 1,
+ new String[] { "\uD801\uDC00\uD801\uDC01\uFF21A" } },
+ new Object[] { STRING_SUPPLEMENTARY, "[\uFF21\uD801\uDC01]", 2,
+ new String[] { "\uD801\uDC00", "\uFF21A" } },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, "\uDC01", 0,
+ new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE, "\uD801\uDC29",
+ 0, new String[] { "\uD801\uDC28", "\uFF41a" } },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ "[\uD801\uDC29\uFF41]", 0,
+ new String[] { "\uD801\uDC28", "", "a" } },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ "[\uD801\uDC29\uFF41]", 1,
+ new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ "[\uD801\uDC29\uFF41]", 2,
+ new String[] { "\uD801\uDC28", "\uFF41a" } },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ "[\uFF41\uD801\uDC29]", 0,
+ new String[] { "\uD801\uDC28", "", "a" } },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ "[\uFF41\uD801\uDC29]", 1,
+ new String[] { "\uD801\uDC28\uD801\uDC29\uFF41a" } },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ "[\uFF41\uD801\uDC29]", 2,
+ new String[] { "\uD801\uDC28", "\uFF41a" } }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testSplit(String str, String regex, int limit, String[] expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertTrue(
+ Arrays.equals(data.split(regex, limit),
+ expected),
+ String.format(
+ "testing String(%s).split(%s, %d), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(regex), limit,
+ source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/StartsWith.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.startsWith.
+ * @run testng/othervm -XX:+CompactStrings StartsWith
+ * @run testng/othervm -XX:-CompactStrings StartsWith
+ */
+
+public class StartsWith extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ new Object[] {STRING_EMPTY, "", 0, true},
+ new Object[] {STRING_EMPTY, "A", 0, false},
+ new Object[] {STRING_EMPTY, "", 0, true},
+ new Object[] {STRING_EMPTY, "", -1, false},
+ new Object[] {STRING_L1, "A", 0, true},
+ new Object[] {STRING_L1, "A", -1, false},
+ new Object[] {STRING_L1, "A", 1, false},
+ new Object[] {STRING_L2, "B", 1, true},
+ new Object[] {STRING_L2, "B", 0, false},
+ new Object[] {STRING_L2, "A", 0, true},
+ new Object[] {STRING_L2, "AB", 1, false},
+ new Object[] {STRING_L4, "ABC", 0, true},
+ new Object[] {STRING_LLONG, "ABCDEFGH", 0, true},
+ new Object[] {STRING_LLONG, "ABCDE", 0, true},
+ new Object[] {STRING_LLONG, "CDE", 0, false},
+ new Object[] {STRING_LLONG, "FG", 5, true},
+ new Object[] {STRING_U1, "\uFF21", 0, true},
+ new Object[] {STRING_U1, "", 1, true},
+ new Object[] {STRING_U1, "\uFF21", 0, true},
+ new Object[] {STRING_U1, "A", 0, false},
+ new Object[] {STRING_U2, "\uFF21\uFF22", 0, true},
+ new Object[] {STRING_U2, "\uFF21", 0, true},
+ new Object[] {STRING_U2, "\uFF22", 0, false},
+ new Object[] {STRING_U2, "", 0, true},
+ new Object[] {STRING_M12, "\uFF21", 0, true},
+ new Object[] {STRING_M12, "\uFF21A", 0, true},
+ new Object[] {STRING_M12, "A", 0, false},
+ new Object[] {STRING_M12, "\uFF21A", 0, true},
+ new Object[] {STRING_M12, "A", 1, true},
+ new Object[] {STRING_M11, "A", 0, true},
+ new Object[] {STRING_M11, "A\uFF21", 0, true},
+ new Object[] {STRING_M11, "A\uFF21", 0, true},
+ new Object[] {STRING_M11, "\uFF21", 1, true},
+ new Object[] {STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22",
+ 0, true},
+ new Object[] {STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 0, true},
+ new Object[] {STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 2, true},
+ new Object[] {STRING_UDUPLICATE,
+ "\uFF21\uFF22\uFF21\uFF22\uFF21\uFF22", 5, false},
+ new Object[] {STRING_MDUPLICATE1,
+ "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A", 0, true},
+ new Object[] {STRING_MDUPLICATE1,
+ "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21", 0, true},
+ new Object[] {STRING_MDUPLICATE1, "A\uFF21A\uFF21A\uFF21A", 1, true},
+ new Object[] {STRING_SUPPLEMENTARY, "\uDC01\uFF21", 3, true},
+ };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testStartsWith(String str, String prefix, int toffset,
+ boolean expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.startsWith(prefix, toffset),
+ expected,
+ String.format(
+ "testing String(%s).startsWith(%s, %d), source : %s, ",
+ escapeNonASCIIs(data),
+ escapeNonASCIIs(prefix), toffset,
+ source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/SubString.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.subString.
+ * @run testng/othervm -XX:+CompactStrings SubString
+ * @run testng/othervm -XX:-CompactStrings SubString
+ */
+
+public class SubString extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, 0, 0, "" },
+ new Object[] { STRING_L1, 0, 1, "A" },
+ new Object[] { STRING_L1, 1, 1, "" },
+ new Object[] { STRING_L2, 0, 2, "AB" },
+ new Object[] { STRING_L2, 1, 2, "B" },
+ new Object[] { STRING_LLONG, 0, 8, "ABCDEFGH" },
+ new Object[] { STRING_LLONG, 7, 8, "H" },
+ new Object[] { STRING_LLONG, 8, 8, "" },
+ new Object[] { STRING_LLONG, 3, 7, "DEFG" },
+ new Object[] { STRING_U1, 0, 1, "\uFF21" },
+ new Object[] { STRING_U1, 1, 1, "" },
+ new Object[] { STRING_U1, 0, 0, "" },
+ new Object[] { STRING_U2, 0, 2, "\uFF21\uFF22" },
+ new Object[] { STRING_U2, 1, 2, "\uFF22" },
+ new Object[] { STRING_U2, 2, 2, "" },
+ new Object[] { STRING_U2, 0, 2, "\uFF21\uFF22" },
+ new Object[] { STRING_U2, 1, 2, "\uFF22" },
+ new Object[] { STRING_M12, 1, 2, "A" },
+ new Object[] { STRING_M11, 0, 1, "A" },
+ new Object[] { STRING_M11, 1, 2, "\uFF21" },
+ new Object[] { STRING_UDUPLICATE, 1, 5,
+ "\uFF22\uFF21\uFF22\uFF21" },
+ new Object[] { STRING_MDUPLICATE1, 9, 10, "A" },
+ new Object[] { STRING_MDUPLICATE1, 7, 8, "A" }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testSubstring(String str, int beginIndex, int endIndex,
+ String expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertEquals(
+ data.substring(beginIndex, endIndex),
+ expected,
+ String.format(
+ "testing String(%s).substring(%d, %d), source : %s, ",
+ escapeNonASCIIs(data), beginIndex,
+ endIndex, source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/ToCharArray.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.toCharArray.
+ * @run testng/othervm -XX:+CompactStrings ToCharArray
+ * @run testng/othervm -XX:-CompactStrings ToCharArray
+ */
+
+public class ToCharArray extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ new Object[] { STRING_EMPTY, new char[] {} },
+ new Object[] { STRING_L1, new char[] { 'A' } },
+ new Object[] { STRING_L2, new char[] { 'A', 'B' } },
+ new Object[] { STRING_LLONG,
+ new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' } },
+ new Object[] { STRING_U1, new char[] { '\uFF21' } },
+ new Object[] { STRING_U2, new char[] { '\uFF21', '\uFF22' } },
+ new Object[] { STRING_M12, new char[] { '\uFF21', 'A' } },
+ new Object[] { STRING_M11, new char[] { 'A', '\uFF21' } }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testToCharArray(String str, char[] expected) {
+ map.get(str)
+ .forEach(
+ (source, data) -> {
+ assertTrue(
+ Arrays.equals(data.toCharArray(), expected),
+ String.format(
+ "testing String(%s).toCharArray(), source : %s, ",
+ escapeNonASCIIs(data), source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/ToLowerCase.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.toLowerCase.
+ * @run testng/othervm -XX:+CompactStrings ToLowerCase
+ * @run testng/othervm -XX:-CompactStrings ToLowerCase
+ */
+
+public class ToLowerCase extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ new Object[] { STRING_EMPTY, "" },
+ new Object[] { STRING_L1, "a" },
+ new Object[] { STRING_L2, "ab" },
+ new Object[] { STRING_U1, "\uFF41" },
+ new Object[] { STRING_MDUPLICATE1,
+ "\uFF41a\uFF41a\uFF41a\uFF41a\uFF41a" },
+ new Object[] { STRING_SUPPLEMENTARY,
+ "\uD801\uDC28\uD801\uDC29\uFF41a" },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ "\uD801\uDC28\uD801\uDC29\uFF41a" },
+ new Object[] { STRING_SUPPLEMENTARY,
+ STRING_SUPPLEMENTARY_LOWERCASE } };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testToLowerCase(String str, String expected) {
+ map.get(str).forEach(
+ (source, data) -> {
+ assertEquals(data.toLowerCase(), expected, String.format(
+ "testing String(%s).toLowerCase(), source : %s, ",
+ escapeNonASCIIs(data), source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/ToUpperCase.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.toUpperCase.
+ * @run testng/othervm -XX:+CompactStrings ToUpperCase
+ * @run testng/othervm -XX:-CompactStrings ToUpperCase
+ */
+
+public class ToUpperCase extends CompactString {
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+
+ new Object[] { STRING_EMPTY, "" },
+ new Object[] { STRING_L1, "A" },
+ new Object[] { STRING_L2, "AB" },
+ new Object[] { STRING_U1, "\uFF21" },
+ new Object[] { STRING_MDUPLICATE1,
+ "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A" },
+ new Object[] { STRING_SUPPLEMENTARY,
+ "\uD801\uDC00\uD801\uDC01\uFF21A" },
+
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ "\uD801\uDC00\uD801\uDC01\uFF21A" },
+ new Object[] { STRING_SUPPLEMENTARY_LOWERCASE,
+ STRING_SUPPLEMENTARY }, };
+ }
+
+ @Test(dataProvider = "provider")
+ public void testToUpperCase(String str, String expected) {
+ map.get(str).forEach(
+ (source, data) -> {
+ assertEquals(data.toUpperCase(), expected, String.format(
+ "testing String(%s).toUpperCase(), source : %s, ",
+ escapeNonASCIIs(data), source));
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/Trim.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.trim.
+ * @run testng/othervm -XX:+CompactStrings Trim
+ * @run testng/othervm -XX:-CompactStrings Trim
+ */
+
+public class Trim {
+
+ /*
+ * Data provider for testTrim
+ *
+ * @return input parameter for testTrim
+ */
+ @DataProvider
+ public Object[][] trims() {
+ return new Object[][] {
+ { " \t \t".trim(), "" },
+ { "\t \t ".trim(), "" },
+ { "\t A B C\t ".trim(), "A B C" },
+ { " \t A B C \t".trim(), "A B C" },
+ { "\t \uFF21 \uFF22 \uFF23\t ".trim(), "\uFF21 \uFF22 \uFF23" },
+ { " \t \uFF21 \uFF22 \uFF23 \t".trim(), "\uFF21 \uFF22 \uFF23" },
+ { " \t \uFF41 \uFF42 \uFF43 \t".trim(), "\uFF41 \uFF42 \uFF43" },
+ { " \t A\uFF21 B\uFF22 C\uFF23 \t".trim(),
+ "A\uFF21 B\uFF22 C\uFF23" } };
+ }
+
+ /*
+ * test trim().
+ *
+ * @param res
+ * real result
+ * @param expected
+ * expected result
+ */
+ @Test(dataProvider = "trims")
+ public void testTrim(String res, String expected) {
+ assertEquals(res, expected);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/VMOptionsTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.*;
+import java.lang.reflect.Field;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is testing
+ * if Compact String enable/disable VM Options is indeed working in String class,
+ * it's verified by testing if the VM option affect coder and
+ * COMPACT_STRINGS field in String class.
+ * @run testng/othervm -XX:+CompactStrings -DCompactStringEnabled=true VMOptionsTest
+ * @run testng/othervm -XX:-CompactStrings -DCompactStringEnabled=false VMOptionsTest
+ */
+
+public class VMOptionsTest {
+ boolean compactStringEnabled;
+ // corresponding "COMPACT_STRINGS" field in String class.
+ Field COMPACT_STRINGS;
+ // corresponding "coder" field in String class.
+ Field coder;
+
+ // corresponding coder type in String class.
+ final byte LATIN1 = 0;
+ final byte UTF16 = 1;
+
+ @BeforeClass
+ public void setUp() throws Exception {
+ compactStringEnabled = Boolean.valueOf(System.getProperty("CompactStringEnabled", null));
+ COMPACT_STRINGS = String.class.getDeclaredField("COMPACT_STRINGS");
+ COMPACT_STRINGS.setAccessible(true);
+ coder = String.class.getDeclaredField("coder");
+ coder.setAccessible(true);
+ }
+
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ new Object[] {"", LATIN1},
+ new Object[] {"abc", LATIN1},
+ new Object[] {"A\uff21", UTF16},
+ new Object[] {"\uff21\uff22", UTF16}
+ };
+ }
+
+ /*
+ * verify the coder field in String objects.
+ */
+ @Test(dataProvider = "provider")
+ public void testCoder(String str, byte expected) throws Exception {
+ byte c = (byte) coder.get(str);
+ expected = compactStringEnabled ? expected : UTF16;
+ assertEquals(c, expected);
+ }
+
+ /*
+ * verify the COMPACT_STRINGS flag in String objects.
+ */
+ @Test(dataProvider = "provider")
+ public void testCompactStringFlag(String str, byte ignore) throws Exception {
+ assertTrue(COMPACT_STRINGS.get(str).equals(compactStringEnabled));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/String/CompactString/ValueOf.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This one is for String.valueOf.
+ * valueOf(char[] data) is not tested here.
+ * @run testng/othervm -XX:+CompactStrings ValueOf
+ * @run testng/othervm -XX:-CompactStrings ValueOf
+ */
+
+public class ValueOf {
+
+ /*
+ * Data provider for testValueOf
+ *
+ * @return input parameter for testValueOf
+ */
+ @DataProvider
+ public Object[][] valueOfs() {
+ return new Object[][] { { String.valueOf(true), "true" },
+ { String.valueOf(false), "false" },
+ { String.valueOf(1.0f), "1.0" },
+ { String.valueOf(0.0f), "0.0" },
+ { String.valueOf(Float.MAX_VALUE), "3.4028235E38" },
+ { String.valueOf(Float.MIN_VALUE), "1.4E-45" },
+ { String.valueOf(1.0d), "1.0" },
+ { String.valueOf(0.0d), "0.0" },
+ { String.valueOf(Double.MAX_VALUE), "1.7976931348623157E308" },
+ { String.valueOf(Double.MIN_VALUE), "4.9E-324" },
+ { String.valueOf(1), "1" }, { String.valueOf(0), "0" },
+ { String.valueOf(Integer.MAX_VALUE), "2147483647" },
+ { String.valueOf(Integer.MIN_VALUE), "-2147483648" },
+ { String.valueOf(1L), "1" }, { String.valueOf(0L), "0" },
+ { String.valueOf(Long.MAX_VALUE), "9223372036854775807" },
+ { String.valueOf(Long.MIN_VALUE), "-9223372036854775808" } };
+ }
+
+ /*
+ * test String.valueOf(xxx).
+ *
+ * @param res
+ * real result
+ * @param expected
+ * expected result
+ */
+ @Test(dataProvider = "valueOfs")
+ public void testValueOf(String res, String expected) {
+ assertEquals(res, expected);
+ }
+
+}
--- a/jdk/test/java/lang/String/LiteralReplace.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/String/LiteralReplace.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 8058779
+ * @bug 8058779 8054307
* @library /lib/testlibrary/
* @build jdk.testlibrary.RandomFactory
* @run testng LiteralReplace
@@ -104,6 +104,109 @@
{"abcdefgh", "[a-h]", "X", "abcdefgh"},
{"aa+", "a+", "", "a"},
{"^abc$", "abc", "x", "^x$"},
+
+ // more with non-latin1 characters
+ {"\u4e00\u4e00\u4e00",
+ "\u4e00\u4e00",
+ "\u4e01",
+ "\u4e01\u4e00"},
+
+ {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08",
+ "\u4e03\u4e04\u4e05",
+ "\u4e10\u4e11\u4e12",
+ "\u4e00\u4e01\u4e02\u4e10\u4e11\u4e12\u4e06\u4e07\u4e08"},
+
+ {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08",
+ "ABC",
+ "\u4e10\u4e11\u4e12",
+ "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08"},
+
+ {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e02\u4e03\u4e07\u4e08",
+ "\u4e02\u4e03",
+ "\u4e12\u4e13",
+ "\u4e00\u4e01\u4e12\u4e13\u4e04\u4e12\u4e13\u4e07\u4e08"},
+
+ {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e02\u4e03\u4e07\u4e08",
+ "\u4e02\u4e03",
+ "ab",
+ "\u4e00\u4e01ab\u4e04ab\u4e07\u4e08"},
+
+ {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07",
+ "",
+ "_",
+ "_\u4e00_\u4e01_\u4e02_\u4e03_\u4e04_\u4e05_\u4e06_\u4e07_"},
+ {"^\u4e00\u4e01\u4e02$",
+ "\u4e00\u4e01\u4e02",
+ "\u4e03",
+ "^\u4e03$"},
+
+ {"", "\u4e00", "\u4e01", ""},
+ {"", "", "\u4e00\u4e01\u4e02", "\u4e00\u4e01\u4e02"},
+
+ {"^\u4e00\u4e01\u4e02$",
+ "\u4e00\u4e01\u4e02",
+ "X",
+ "^X$"},
+
+ {"abcdefgh",
+ "def",
+ "\u4e01",
+ "abc\u4e01gh"},
+
+ {"abcdefgh",
+ "def",
+ "\u4e01\u4e02",
+ "abc\u4e01\u4e02gh"},
+
+ {"abcdefabcgh",
+ "abc",
+ "\u4e01\u4e02",
+ "\u4e01\u4e02def\u4e01\u4e02gh"},
+
+ {"abcdefabcghabc",
+ "abc",
+ "\u4e01\u4e02",
+ "\u4e01\u4e02def\u4e01\u4e02gh\u4e01\u4e02"},
+
+ {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
+ "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
+ "abcd",
+ "abcd"},
+
+ {"\u4e00\u4e01",
+ "\u4e00\u4e01",
+ "abcdefg",
+ "abcdefg"},
+
+ {"\u4e00\u4e01xyz",
+ "\u4e00\u4e01",
+ "abcdefg",
+ "abcdefgxyz"},
+
+ {"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
+ "\u4e00\u4e00",
+ "\u4e00\u4e00\u4e00",
+ "\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00"},
+
+ {"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
+ "\u4e00\u4e00\u4e00",
+ "\u4e00\u4e00",
+ "\u4e00\u4e00\u4e00\u4e00"},
+
+ {"\u4e00.\u4e01.\u4e02.\u4e03.\u4e04.",
+ ".",
+ "-",
+ "\u4e00-\u4e01-\u4e02-\u4e03-\u4e04-"},
+
+ {"\u4e00\u4e00\u4e00\u4e00\u4e00\u4e00",
+ "\u4e00",
+ "",
+ ""},
+
+ {"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
+ "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
+ "",
+ ""},
};
}
--- a/jdk/test/java/lang/String/ToLowerCase.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/String/ToLowerCase.java Wed Jul 05 21:00:20 2017 +0200
@@ -23,7 +23,7 @@
/*
@test
- @bug 4217441 4533872 4900935 8020037 8032012 8041791 8042589
+ @bug 4217441 4533872 4900935 8020037 8032012 8041791 8042589 8054307
@summary toLowerCase should lower-case Greek Sigma correctly depending
on the context (final/non-final). Also it should handle
Locale specific (lt, tr, and az) lowercasings and supplementary
@@ -134,14 +134,60 @@
}
test(src.toString(), Locale.US, exp.toString());
+ // test latin1
+ src = new StringBuilder(0x100);
+ exp = new StringBuilder(0x100);
+ for (int cp = 0; cp < 0x100; cp++) {
+ int lowerCase = Character.toLowerCase(cp);
+ if (lowerCase == -1) { //Character.ERROR
+ continue;
+ }
+ src.appendCodePoint(cp);
+ exp.appendCodePoint(lowerCase);
+ }
+ test(src.toString(), Locale.US, exp.toString());
+
+ // test non-latin1 -> latin1
+ src = new StringBuilder(0x100).append("abc");
+ exp = new StringBuilder(0x100).append("abc");
+ for (int cp = 0x100; cp < 0x10000; cp++) {
+ int lowerCase = Character.toLowerCase(cp);
+ if (lowerCase < 0x100 && cp != '\u0130') {
+ src.appendCodePoint(cp);
+ exp.appendCodePoint(lowerCase);
+ }
+ }
+ test(src.toString(), Locale.US, exp.toString());
}
static void test(String in, Locale locale, String expected) {
+ test0(in, locale,expected);
+ for (String[] ss : new String[][] {
+ new String[] {"abc", "abc"},
+ new String[] {"aBc", "abc"},
+ new String[] {"ABC", "abc"},
+ new String[] {"ab\u4e00", "ab\u4e00"},
+ new String[] {"aB\u4e00", "ab\u4e00"},
+ new String[] {"AB\u4e00", "ab\u4e00"},
+ new String[] {"ab\uD800\uDC00", "ab\uD800\uDC00"},
+ new String[] {"aB\uD800\uDC00", "ab\uD800\uDC00"},
+ new String[] {"AB\uD800\uDC00", "ab\uD800\uDC00"},
+ new String[] {"ab\uD801\uDC1C", "ab\uD801\uDC44"},
+ new String[] {"aB\uD801\uDC1C", "ab\uD801\uDC44"},
+ new String[] {"AB\uD801\uDC1C", "ab\uD801\uDC44"},
+
+ }) {
+ test0(ss[0] + " " + in, locale, ss[1] + " " + expected);
+ test0(in + " " + ss[0], locale, expected + " " + ss[1]);
+ }
+ }
+
+ static void test0(String in, Locale locale, String expected) {
String result = in.toLowerCase(locale);
if (!result.equals(expected)) {
System.err.println("input: " + in + ", locale: " + locale +
", expected: " + expected + ", actual: " + result);
throw new RuntimeException();
}
- }
+ }
}
--- a/jdk/test/java/lang/String/ToUpperCase.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/String/ToUpperCase.java Wed Jul 05 21:00:20 2017 +0200
@@ -23,7 +23,7 @@
/*
@test
- @bug 4219630 4304573 4533872 4900935 8042589
+ @bug 4219630 4304573 4533872 4900935 8042589 8054307
@summary toUpperCase should upper-case German sharp s correctly even if
it's the only character in the string. should also uppercase
all of the 1:M char mappings correctly. Also it should handle
@@ -97,14 +97,66 @@
test("A\uD801\uDC44", Locale.ROOT, "A\uD801\uDC1c");
test("a\uD801\uDC28\uD801\uDC29\uD801\uDC2A", Locale.US, "A\uD801\uDC00\uD801\uDC01\uD801\uDC02");
test("A\uD801\uDC28a\uD801\uDC29b\uD801\uDC2Ac", Locale.US, "A\uD801\uDC00A\uD801\uDC01B\uD801\uDC02C");
+
+ // test latin1 only case
+ StringBuilder src = new StringBuilder(0x100);
+ StringBuilder exp = new StringBuilder(0x100);
+ for (int cp = 0; cp < 0x100; cp++) {
+ int upperCase = Character.toUpperCase(cp);
+ if (upperCase == -1) { //Character.ERROR
+ continue;
+ }
+ src.appendCodePoint(cp);
+ if (cp == '\u00df') {
+ exp.append("SS"); // need Character.toUpperCaseEx()
+ } else {
+ exp.appendCodePoint(upperCase);
+ }
+ }
+ test(src.toString(), Locale.US, exp.toString());
+
+ // test non-latin1 -> latin1
+ src = new StringBuilder(0x100).append("ABC");
+ exp = new StringBuilder(0x100).append("ABC");
+ for (int cp = 0x100; cp < 0x10000; cp++) {
+ int upperCase = Character.toUpperCase(cp);
+ if (upperCase < 0x100) {
+ src.appendCodePoint(cp);
+ exp.appendCodePoint(upperCase);
+ }
+ }
+ test(src.toString(), Locale.US, exp.toString());
+
}
static void test(String in, Locale locale, String expected) {
+ test0(in, locale,expected);
+ // trigger different code paths
+ for (String[] ss : new String[][] {
+ new String[] {"abc", "ABC"},
+ new String[] {"AbC", "ABC"},
+ new String[] {"ABC", "ABC"},
+ new String[] {"AB\u4e00", "AB\u4e00"},
+ new String[] {"ab\u4e00", "AB\u4e00"},
+ new String[] {"aB\u4e00", "AB\u4e00"},
+ new String[] {"AB\uD800\uDC00", "AB\uD800\uDC00"},
+ new String[] {"Ab\uD800\uDC00", "AB\uD800\uDC00"},
+ new String[] {"ab\uD800\uDC00", "AB\uD800\uDC00"},
+ new String[] {"AB\uD801\uDC44", "AB\uD801\uDC1C"},
+ new String[] {"Ab\uD801\uDC44", "AB\uD801\uDC1C"},
+ new String[] {"ab\uD801\uDC44", "AB\uD801\uDC1C"},
+ }) {
+ test0(ss[0] + " " + in, locale, ss[1] + " " + expected);
+ test0(in + " " + ss[0], locale, expected + " " + ss[1]);
+ }
+ }
+
+ static void test0(String in, Locale locale, String expected) {
String result = in.toUpperCase(locale);
if (!result.equals(expected)) {
System.err.println("input: " + in + ", locale: " + locale +
", expected: " + expected + ", actual: " + result);
throw new RuntimeException();
}
- }
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuffer/CompactStringBuffer.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8077559
+ * @summary Tests Compact String. This test is testing StringBuffer
+ * behavior related to Compact String.
+ * @run testng/othervm -XX:+CompactStrings CompactStringBuffer
+ * @run testng/othervm -XX:-CompactStrings CompactStringBuffer
+ */
+
+public class CompactStringBuffer {
+
+ /*
+ * Tests for "A"
+ */
+ @Test
+ public void testCompactStringBufferForLatinA() {
+ final String ORIGIN = "A";
+ /*
+ * Because right now ASCII is the default encoding parameter for source
+ * code in JDK build environment, so we escape them. same as below.
+ */
+ check(new StringBuffer(ORIGIN).append(new char[] { '\uFF21' }),
+ "A\uFF21");
+ check(new StringBuffer(ORIGIN).append(new StringBuffer("\uFF21")),
+ "A\uFF21");
+ check(new StringBuffer(ORIGIN).append("\uFF21"), "A\uFF21");
+ check(new StringBuffer(ORIGIN).append(new StringBuffer("\uFF21")),
+ "A\uFF21");
+ check(new StringBuffer(ORIGIN).delete(0, 1), "");
+ check(new StringBuffer(ORIGIN).delete(0, 0), "A");
+ check(new StringBuffer(ORIGIN).deleteCharAt(0), "");
+ assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), 0);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), -1);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
+ assertEquals(new StringBuffer(ORIGIN).insert(1, "\uD801\uDC00")
+ .indexOf("A", 0), 0);
+ assertEquals(new StringBuffer(ORIGIN).insert(0, "\uD801\uDC00")
+ .indexOf("A", 0), 2);
+ check(new StringBuffer(ORIGIN).insert(0, new char[] {}), "A");
+ check(new StringBuffer(ORIGIN).insert(1, new char[] { '\uFF21' }),
+ "A\uFF21");
+ check(new StringBuffer(ORIGIN).insert(0, new char[] { '\uFF21' }),
+ "\uFF21A");
+ check(new StringBuffer(ORIGIN).insert(0, new StringBuffer("\uFF21")),
+ "\uFF21A");
+ check(new StringBuffer(ORIGIN).insert(1, new StringBuffer("\uFF21")),
+ "A\uFF21");
+ check(new StringBuffer(ORIGIN).insert(0, ""), "A");
+ check(new StringBuffer(ORIGIN).insert(0, "\uFF21"), "\uFF21A");
+ check(new StringBuffer(ORIGIN).insert(1, "\uFF21"), "A\uFF21");
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 0);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), -1);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 1);
+ check(new StringBuffer(ORIGIN).replace(0, 0, "\uFF21"), "\uFF21A");
+ check(new StringBuffer(ORIGIN).replace(0, 1, "\uFF21"), "\uFF21");
+ checkSetCharAt(new StringBuffer(ORIGIN), 0, '\uFF21', "\uFF21");
+ checkSetLength(new StringBuffer(ORIGIN), 0, "");
+ checkSetLength(new StringBuffer(ORIGIN), 1, "A");
+ check(new StringBuffer(ORIGIN).substring(0), "A");
+ check(new StringBuffer(ORIGIN).substring(1), "");
+ }
+
+ /*
+ * Tests for "\uFF21"
+ */
+ @Test
+ public void testCompactStringBufferForNonLatinA() {
+ final String ORIGIN = "\uFF21";
+ check(new StringBuffer(ORIGIN).append(new char[] { 'A' }), "\uFF21A");
+ check(new StringBuffer(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
+ check(new StringBuffer(ORIGIN).append("A"), "\uFF21A");
+ check(new StringBuffer(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
+ check(new StringBuffer(ORIGIN).delete(0, 1), "");
+ check(new StringBuffer(ORIGIN).delete(0, 0), "\uFF21");
+ check(new StringBuffer(ORIGIN).deleteCharAt(0), "");
+ assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), -1);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), 0);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
+ check(new StringBuffer(ORIGIN).insert(0, new char[] {}), "\uFF21");
+ check(new StringBuffer(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21A");
+ check(new StringBuffer(ORIGIN).insert(0, new char[] { 'A' }), "A\uFF21");
+ check(new StringBuffer(ORIGIN).insert(0, new StringBuffer("A")),
+ "A\uFF21");
+ check(new StringBuffer(ORIGIN).insert(1, new StringBuffer("A")),
+ "\uFF21A");
+ check(new StringBuffer(ORIGIN).insert(0, ""), "\uFF21");
+ check(new StringBuffer(ORIGIN).insert(0, "A"), "A\uFF21");
+ check(new StringBuffer(ORIGIN).insert(1, "A"), "\uFF21A");
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), -1);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 0);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 1);
+ check(new StringBuffer(ORIGIN).replace(0, 0, "A"), "A\uFF21");
+ check(new StringBuffer(ORIGIN).replace(0, 1, "A"), "A");
+ checkSetCharAt(new StringBuffer(ORIGIN), 0, 'A', "A");
+ checkSetLength(new StringBuffer(ORIGIN), 0, "");
+ checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
+ check(new StringBuffer(ORIGIN).substring(0), "\uFF21");
+ check(new StringBuffer(ORIGIN).substring(1), "");
+ }
+
+ /*
+ * Tests for "\uFF21A"
+ */
+ @Test
+ public void testCompactStringBufferForMixedA1() {
+ final String ORIGIN = "\uFF21A";
+ check(new StringBuffer(ORIGIN).delete(0, 1), "A");
+ check(new StringBuffer(ORIGIN).delete(1, 2), "\uFF21");
+ check(new StringBuffer(ORIGIN).deleteCharAt(1), "\uFF21");
+ check(new StringBuffer(ORIGIN).deleteCharAt(0), "A");
+ assertEquals(new StringBuffer(ORIGIN).indexOf("A", 0), 1);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 0), 0);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("", 0), 0);
+ check(new StringBuffer(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21AA");
+ check(new StringBuffer(ORIGIN).insert(0, new char[] { '\uFF21' }),
+ "\uFF21\uFF21A");
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 1);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 0);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 2);
+ check(new StringBuffer(ORIGIN).replace(0, 0, "A"), "A\uFF21A");
+ check(new StringBuffer(ORIGIN).replace(0, 1, "A"), "AA");
+ checkSetCharAt(new StringBuffer(ORIGIN), 0, 'A', "AA");
+ checkSetLength(new StringBuffer(ORIGIN), 0, "");
+ checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
+ check(new StringBuffer(ORIGIN).substring(0), "\uFF21A");
+ check(new StringBuffer(ORIGIN).substring(1), "A");
+ }
+
+ /*
+ * Tests for "A\uFF21"
+ */
+ @Test
+ public void testCompactStringBufferForMixedA2() {
+ final String ORIGIN = "A\uFF21";
+ check(new StringBuffer(ORIGIN).replace(1, 2, "A"), "AA");
+ checkSetLength(new StringBuffer(ORIGIN), 1, "A");
+ check(new StringBuffer(ORIGIN).substring(0), "A\uFF21");
+ check(new StringBuffer(ORIGIN).substring(1), "\uFF21");
+ check(new StringBuffer(ORIGIN).substring(0, 1), "A");
+ }
+
+ /*
+ * Tests for "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A"
+ */
+ @Test
+ public void testCompactStringBufferForDuplicatedMixedA1() {
+ final String ORIGIN = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
+ checkSetLength(new StringBuffer(ORIGIN), 1, "\uFF21");
+ assertEquals(new StringBuffer(ORIGIN).indexOf("A", 5), 5);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 5), 6);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 9);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 8);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf(""), 10);
+ check(new StringBuffer(ORIGIN).substring(9), "A");
+ check(new StringBuffer(ORIGIN).substring(8), "\uFF21A");
+ }
+
+ /*
+ * Tests for "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21"
+ */
+ @Test
+ public void testCompactStringBufferForDuplicatedMixedA2() {
+ final String ORIGIN = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
+ checkSetLength(new StringBuffer(ORIGIN), 1, "A");
+ assertEquals(new StringBuffer(ORIGIN).indexOf("A", 5), 6);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21", 5), 5);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 8);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 9);
+ check(new StringBuffer(ORIGIN).substring(9), "\uFF21");
+ check(new StringBuffer(ORIGIN).substring(8), "A\uFF21");
+ }
+
+ /*
+ * Tests for "\uD801\uDC00\uD801\uDC01"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePoint() {
+ final String ORIGIN = "\uD801\uDC00\uD801\uDC01";
+ check(new StringBuffer(ORIGIN).append("A"), "\uD801\uDC00\uD801\uDC01A");
+ check(new StringBuffer(ORIGIN).append("\uFF21"),
+ "\uD801\uDC00\uD801\uDC01\uFF21");
+ check(new StringBuffer(ORIGIN).appendCodePoint('A'),
+ "\uD801\uDC00\uD801\uDC01A");
+ check(new StringBuffer(ORIGIN).appendCodePoint('\uFF21'),
+ "\uD801\uDC00\uD801\uDC01\uFF21");
+ assertEquals(new StringBuffer(ORIGIN).charAt(0), '\uD801');
+ assertEquals(new StringBuffer(ORIGIN).codePointAt(0),
+ Character.codePointAt(ORIGIN, 0));
+ assertEquals(new StringBuffer(ORIGIN).codePointAt(1),
+ Character.codePointAt(ORIGIN, 1));
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(2),
+ Character.codePointAt(ORIGIN, 0));
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
+ check(new StringBuffer(ORIGIN).delete(0, 2), "\uD801\uDC01");
+ check(new StringBuffer(ORIGIN).delete(0, 3), "\uDC01");
+ check(new StringBuffer(ORIGIN).deleteCharAt(1), "\uD801\uD801\uDC01");
+ checkGetChars(new StringBuffer(ORIGIN), 0, 3, new char[] { '\uD801',
+ '\uDC00', '\uD801' });
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uD801\uDC01"), 2);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uDC01"), 3);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21"), -1);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("A"), -1);
+ check(new StringBuffer(ORIGIN).insert(0, "\uFF21"),
+ "\uFF21\uD801\uDC00\uD801\uDC01");
+ check(new StringBuffer(ORIGIN).insert(1, "\uFF21"),
+ "\uD801\uFF21\uDC00\uD801\uDC01");
+ check(new StringBuffer(ORIGIN).insert(1, "A"),
+ "\uD801A\uDC00\uD801\uDC01");
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uDC00\uD801"), 1);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uD801"), 2);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), -1);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), -1);
+ assertEquals(new StringBuffer(ORIGIN).length(), 4);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 2);
+ check(new StringBuffer(ORIGIN).replace(0, 2, "A"), "A\uD801\uDC01");
+ check(new StringBuffer(ORIGIN).replace(0, 3, "A"), "A\uDC01");
+ check(new StringBuffer(ORIGIN).replace(0, 2, "\uFF21"),
+ "\uFF21\uD801\uDC01");
+ check(new StringBuffer(ORIGIN).replace(0, 3, "\uFF21"), "\uFF21\uDC01");
+ check(new StringBuffer(ORIGIN).reverse(), "\uD801\uDC01\uD801\uDC00");
+ checkSetCharAt(new StringBuffer(ORIGIN), 1, '\uDC01',
+ "\uD801\uDC01\uD801\uDC01");
+ checkSetCharAt(new StringBuffer(ORIGIN), 1, 'A', "\uD801A\uD801\uDC01");
+ checkSetLength(new StringBuffer(ORIGIN), 2, "\uD801\uDC00");
+ checkSetLength(new StringBuffer(ORIGIN), 3, "\uD801\uDC00\uD801");
+ check(new StringBuffer(ORIGIN).substring(1, 3), "\uDC00\uD801");
+ }
+
+ /*
+ * Tests for "A\uD801\uDC00\uFF21"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePointMixed1() {
+ final String ORIGIN = "A\uD801\uDC00\uFF21";
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(3),
+ Character.codePointAt(ORIGIN, 1));
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), '\uD801');
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), 'A');
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 2);
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 4), 3);
+ check(new StringBuffer(ORIGIN).delete(0, 1), "\uD801\uDC00\uFF21");
+ check(new StringBuffer(ORIGIN).delete(0, 1).delete(2, 3), "\uD801\uDC00");
+ check(new StringBuffer(ORIGIN).deleteCharAt(3).deleteCharAt(0),
+ "\uD801\uDC00");
+ assertEquals(new StringBuffer(ORIGIN).indexOf("\uFF21"), 3);
+ assertEquals(new StringBuffer(ORIGIN).indexOf("A"), 0);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("\uFF21"), 3);
+ assertEquals(new StringBuffer(ORIGIN).lastIndexOf("A"), 0);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 3);
+ check(new StringBuffer(ORIGIN).replace(1, 3, "A"), "AA\uFF21");
+ check(new StringBuffer(ORIGIN).replace(1, 4, "A"), "AA");
+ check(new StringBuffer(ORIGIN).replace(1, 4, ""), "A");
+ check(new StringBuffer(ORIGIN).reverse(), "\uFF21\uD801\uDC00A");
+ checkSetLength(new StringBuffer(ORIGIN), 1, "A");
+ check(new StringBuffer(ORIGIN).substring(0, 1), "A");
+ }
+
+ /*
+ * Tests for "\uD801\uDC00\uFF21A"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePointMixed2() {
+ final String ORIGIN = "\uD801\uDC00\uFF21A";
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(3),
+ Character.codePointAt(ORIGIN, 2));
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(2),
+ Character.codePointAt(ORIGIN, 0));
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), '\uD801');
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 2);
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 4), 3);
+ check(new StringBuffer(ORIGIN).delete(0, 2), "\uFF21A");
+ check(new StringBuffer(ORIGIN).delete(0, 3), "A");
+ check(new StringBuffer(ORIGIN).deleteCharAt(0).deleteCharAt(0)
+ .deleteCharAt(0), "A");
+ assertEquals(new StringBuffer(ORIGIN).indexOf("A"), 3);
+ assertEquals(new StringBuffer(ORIGIN).delete(0, 3).indexOf("A"), 0);
+ assertEquals(new StringBuffer(ORIGIN).replace(0, 3, "B").indexOf("A"),
+ 1);
+ assertEquals(new StringBuffer(ORIGIN).substring(3, 4).indexOf("A"), 0);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 2);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
+ check(new StringBuffer(ORIGIN).replace(0, 3, "B"), "BA");
+ check(new StringBuffer(ORIGIN).reverse(), "A\uFF21\uD801\uDC00");
+ }
+
+ /*
+ * Tests for "\uD801A\uDC00\uFF21"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePointMixed3() {
+ final String ORIGIN = "\uD801A\uDC00\uFF21";
+ assertEquals(new StringBuffer(ORIGIN).codePointAt(1), 'A');
+ assertEquals(new StringBuffer(ORIGIN).codePointAt(3), '\uFF21');
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), '\uD801');
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), 'A');
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(3), '\uDC00');
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 3);
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
+ assertEquals(new StringBuffer(ORIGIN).delete(0, 1).delete(1, 3)
+ .indexOf("A"), 0);
+ assertEquals(
+ new StringBuffer(ORIGIN).replace(0, 1, "B").replace(2, 4, "C")
+ .indexOf("A"), 1);
+ assertEquals(new StringBuffer(ORIGIN).substring(1, 4).substring(0, 1)
+ .indexOf("A"), 0);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
+ check(new StringBuffer(ORIGIN).reverse(), "\uFF21\uDC00A\uD801");
+ }
+
+ /*
+ * Tests for "A\uDC01\uFF21\uD801"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePointMixed4() {
+ final String ORIGIN = "A\uDC01\uFF21\uD801";
+ assertEquals(new StringBuffer(ORIGIN).codePointAt(1), '\uDC01');
+ assertEquals(new StringBuffer(ORIGIN).codePointAt(3), '\uD801');
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(1), 'A');
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(2), '\uDC01');
+ assertEquals(new StringBuffer(ORIGIN).codePointBefore(3), '\uFF21');
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(0, 3), 3);
+ assertEquals(new StringBuffer(ORIGIN).codePointCount(1, 3), 2);
+ assertEquals(new StringBuffer(ORIGIN).delete(1, 4).indexOf("A"), 0);
+ assertEquals(new StringBuffer(ORIGIN).replace(1, 4, "B").indexOf("A"),
+ 0);
+ assertEquals(new StringBuffer(ORIGIN).substring(0, 1).indexOf("A"), 0);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(0, 1), 1);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(1, 1), 2);
+ assertEquals(new StringBuffer(ORIGIN).offsetByCodePoints(2, 1), 3);
+ check(new StringBuffer(ORIGIN).reverse(), "\uD801\uFF21\uDC01A");
+ }
+
+ @Test
+ public void testCompactStringMisc() {
+ String ascii = "abcdefgh";
+ String asciiMixed = "abc" + "\u4e00\u4e01\u4e02" + "fgh";
+ String bmp = "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08";
+ String bmpMixed = "\u4e00\u4e01\u4e02" + "ABC" + "\u4e06\u4e07\u4e08";
+
+ check(new StringBuffer().append(ascii).delete(0, 20).toString(),
+ "");
+ check(new StringBuffer().append(ascii).delete(3, 20).toString(),
+ "abc");
+ check(new StringBuffer().append(ascii).delete(3, 6).toString(),
+ "abcgh");
+ check(new StringBuffer().append(ascii).deleteCharAt(0).toString(),
+ "bcdefgh");
+ check(new StringBuffer().append(ascii).deleteCharAt(3).toString(),
+ "abcefgh");
+ check(new StringBuffer().append(asciiMixed).delete(3, 6).toString(),
+ "abcfgh");
+ check(new StringBuffer().append(asciiMixed).deleteCharAt(3).toString(),
+ "abc\u4e01\u4e02fgh");
+ check(new StringBuffer().append(asciiMixed).deleteCharAt(3)
+ .deleteCharAt(3)
+ .deleteCharAt(3).toString(),
+ "abcfgh");
+ check(new StringBuffer().append(bmp).delete(0, 20).toString(),
+ "");
+ check(new StringBuffer().append(bmp).delete(3, 20).toString(),
+ "\u4e00\u4e01\u4e02");
+ check(new StringBuffer().append(bmp).delete(3, 6).toString(),
+ "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
+ check(new StringBuffer().append(bmp).deleteCharAt(0).toString(),
+ "\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08");
+ check(new StringBuffer().append(bmp).deleteCharAt(3).toString(),
+ "\u4e00\u4e01\u4e02\u4e04\u4e05\u4e06\u4e07\u4e08");
+ check(new StringBuffer().append(bmpMixed).delete(3, 6).toString(),
+ "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
+
+ ////////////////////////////////////////////////////////////////////
+ check(new StringBuffer().append(ascii).replace(3, 6, "AB").toString(),
+ "abcABgh");
+ check(new StringBuffer().append(asciiMixed).replace(3, 6, "AB").toString(),
+ "abcABfgh");
+ check(new StringBuffer().append(bmp).replace(3, 6, "AB").toString(),
+ "\u4e00\u4e01\u4e02AB\u4e06\u4e07\u4e08");
+
+ check(new StringBuffer().append(bmpMixed).replace(3, 6, "").toString(),
+ "\u4e00\u4e01\u4e02\u4e06\u4e07\u4e08");
+
+ check(new StringBuffer().append(ascii).replace(3, 6, "\u4e01\u4e02").toString(),
+ "abc\u4e01\u4e02gh");
+
+ ////////////////////////////////////////////////////////////////////
+ check(new StringBuffer().append(ascii).insert(3, "").toString(),
+ "abcdefgh");
+ check(new StringBuffer().append(ascii).insert(3, "AB").toString(),
+ "abcABdefgh");
+ check(new StringBuffer().append(ascii).insert(3, "\u4e01\u4e02").toString(),
+ "abc\u4e01\u4e02defgh");
+
+ check(new StringBuffer().append(asciiMixed).insert(0, 'A').toString(),
+ "Aabc\u4e00\u4e01\u4e02fgh");
+ check(new StringBuffer().append(asciiMixed).insert(3, "A").toString(),
+ "abcA\u4e00\u4e01\u4e02fgh");
+
+ check(new StringBuffer().append(ascii).insert(3, 1234567).toString(),
+ "abc1234567defgh");
+ check(new StringBuffer().append(bmp).insert(3, 1234567).toString(),
+ "\u4e00\u4e01\u4e021234567\u4e03\u4e04\u4e05\u4e06\u4e07\u4e08");
+
+ ////////////////////////////////////////////////////////////////////
+ check(new StringBuffer().append(ascii).append(1.23456).toString(),
+ "abcdefgh1.23456");
+ check(new StringBuffer().append(bmp).append(1.23456).toString(),
+ "\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e081.23456");
+ }
+
+ private void checkGetChars(StringBuffer sb, int srcBegin, int srcEnd,
+ char expected[]) {
+ char[] dst = new char[srcEnd - srcBegin];
+ sb.getChars(srcBegin, srcEnd, dst, 0);
+ assertTrue(Arrays.equals(dst, expected));
+ }
+
+ private void checkSetCharAt(StringBuffer sb, int index, char ch,
+ String expected) {
+ sb.setCharAt(index, ch);
+ check(sb, expected);
+ }
+
+ private void checkSetLength(StringBuffer sb, int newLength, String expected) {
+ sb.setLength(newLength);
+ check(sb, expected);
+ }
+
+ private void check(StringBuffer sb, String expected) {
+ check(sb.toString(), expected);
+ }
+
+ private void check(String str, String expected) {
+ assertTrue(str.equals(expected), String.format(
+ "Get (%s) but expect (%s), ", escapeNonASCIIs(str),
+ escapeNonASCIIs(expected)));
+ }
+
+ /*
+ * Because right now system default charset in JPRT environment is only
+ * guaranteed to support ASCII characters in log, so we escape them.
+ */
+ private String escapeNonASCIIs(String str) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c > 0x7F) {
+ sb.append("\\u").append(Integer.toHexString((int) c));
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuffer/CompactStringBufferSerialization.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static jdk.testlibrary.SerializationUtils.*;
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @bug 8077559
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.SerializationUtils
+ * @summary Tests Compact String. This one is testing StringBuffer serialization
+ * among -XX:+CompactStrings/-XX:-CompactStrings/LegacyStringBuffer
+ * @run testng/othervm -XX:+CompactStrings CompactStringBufferSerialization
+ * @run testng/othervm -XX:-CompactStrings CompactStringBufferSerialization
+ */
+
+public class CompactStringBufferSerialization {
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ // every byte array is serialized from corresponding StringBuilder object
+ // by previous JDK(build 1.8.0_45-b14).
+ new Object[] {
+ new StringBuffer(""),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 0, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("A"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 1, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("AB"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 2, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, 0, 65, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("abcdefghijk"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 11, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 27, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 105, 0,
+ 106, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("\uff21"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 1, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, -1, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("\uff21\uff22"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 2, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, -1, 33, -1, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("\uff21A\uff21A\uff21A\uff21A\uff21A"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 10, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("A\uff21B\uff22C\uff23D\uff24E\uff25F\uff26G\uff27H\uff28"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 16, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, 0, 65, -1, 33, 0, 66, -1, 34, 0, 67, -1, 35, 0, 68, -1, 36, 0, 69, -1, 37,
+ 0, 70, -1, 38, 0, 71, -1, 39, 0, 72, -1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("\uff21A\uff22B\uff23C\uff24D\uff25E\uff26F\uff27G\uff28H"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 16, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, -1, 33, 0, 65, -1, 34, 0, 66, -1, 35, 0, 67, -1, 36, 0, 68, -1, 37, 0, 69,
+ -1, 38, 0, 70, -1, 39, 0, 71, -1, 40, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("\ud801\udc00\ud801\udc01\uff21A"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 6, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 22, -40, 1, -36, 0, -40, 1, -36, 1, -1, 33, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuffer("\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 22, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 102,
+ 102, 101, 114, 47, 7, 7, -39, -22, -56, -22, -45, 3, 0, 3, 73, 0, 5, 99, 111, 117, 110, 116, 90, 0, 6, 115, 104, 97, 114, 101,
+ 100, 91, 0, 5, 118, 97, 108, 117, 101, 116, 0, 2, 91, 67, 120, 112, 0, 0, 0, 10, 0, 117, 114, 0, 2, 91, 67, -80, 38, 102, -80,
+ -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1,
+ 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } } };
+ }
+
+ /*
+ * Verify serialization works between Compact StringBuffer/Legacy StringBuffer
+ */
+ @Test(dataProvider = "provider")
+ public void test(StringBuffer sbContent, byte[] baInJDK8) throws Exception {
+ // Serialize a StringBuffer object into byte array.
+ byte[] ba = serialize(sbContent);
+ assertEquals(ba, baInJDK8);
+ // Deserialize a StringBuffer object from byte array which is generated by previous JDK(build 1.8.0_45-b14).
+ Object obj = deserialize(ba);
+ assertEquals(obj.getClass(), StringBuffer.class);
+ assertTrue(equals((StringBuffer)obj, sbContent));
+ }
+
+ boolean equals(StringBuffer sb, StringBuffer expected) {
+ if(sb.length() == expected.length()
+ && sb.capacity() == expected.capacity()
+ && sb.toString().equals(expected.toString())) {
+ return true;
+ }
+ return false;
+ }
+}
--- a/jdk/test/java/lang/StringBuffer/Exceptions.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/StringBuffer/Exceptions.java Wed Jul 05 21:00:20 2017 +0200
@@ -94,7 +94,7 @@
System.out.println("StringBuffer.replace(int start, int end, String str)");
tryCatch(" -1, 2, \" \"",
- new StringIndexOutOfBoundsException(-1),
+ new StringIndexOutOfBoundsException("start -1, end 2, length 7"),
new Runnable() {
public void run() {
StringBuffer sb = new StringBuffer("hilbert");
@@ -102,14 +102,14 @@
}});
tryCatch(" 7, 8, \" \"",
- new StringIndexOutOfBoundsException("start > length()"),
+ new StringIndexOutOfBoundsException("start 7, end 6, length 6"),
new Runnable() {
public void run() {
StringBuffer sb = new StringBuffer("banach");
sb.replace(7, 8, " ");
}});
tryCatch(" 2, 1, \" \"",
- new StringIndexOutOfBoundsException("start > end"),
+ new StringIndexOutOfBoundsException("start 2, end 1, length 7"),
new Runnable() {
public void run() {
StringBuffer sb = new StringBuffer("riemann");
--- a/jdk/test/java/lang/StringBuilder/BuilderForwarding.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/StringBuilder/BuilderForwarding.java Wed Jul 05 21:00:20 2017 +0200
@@ -264,4 +264,3 @@
}
}
}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuilder/CompactStringBuilder.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+/*
+ * @test
+ * @bug 8054307 8077559
+ * @summary Tests Compact String. This test is testing StringBuilder
+ * behavior related to Compact String.
+ * @run testng/othervm -XX:+CompactStrings CompactStringBuilder
+ * @run testng/othervm -XX:-CompactStrings CompactStringBuilder
+ */
+
+public class CompactStringBuilder {
+
+ /*
+ * Tests for "A"
+ */
+ @Test
+ public void testCompactStringBuilderForLatinA() {
+ final String ORIGIN = "A";
+ /*
+ * Because right now ASCII is the default encoding parameter for source
+ * code in JDK build environment, so we escape them. same as below.
+ */
+ check(new StringBuilder(ORIGIN).append(new char[] { '\uFF21' }),
+ "A\uFF21");
+ check(new StringBuilder(ORIGIN).append(new StringBuffer("\uFF21")),
+ "A\uFF21");
+ check(new StringBuilder(ORIGIN).append("\uFF21"), "A\uFF21");
+ check(new StringBuilder(ORIGIN).append(new StringBuffer("\uFF21")),
+ "A\uFF21");
+ check(new StringBuilder(ORIGIN).delete(0, 1), "");
+ check(new StringBuilder(ORIGIN).delete(0, 0), "A");
+ check(new StringBuilder(ORIGIN).deleteCharAt(0), "");
+ assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), 0);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), -1);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
+ assertEquals(new StringBuilder(ORIGIN).insert(1, "\uD801\uDC00")
+ .indexOf("A", 0), 0);
+ assertEquals(new StringBuilder(ORIGIN).insert(0, "\uD801\uDC00")
+ .indexOf("A", 0), 2);
+ check(new StringBuilder(ORIGIN).insert(0, new char[] {}), "A");
+ check(new StringBuilder(ORIGIN).insert(1, new char[] { '\uFF21' }),
+ "A\uFF21");
+ check(new StringBuilder(ORIGIN).insert(0, new char[] { '\uFF21' }),
+ "\uFF21A");
+ check(new StringBuilder(ORIGIN).insert(0, new StringBuffer("\uFF21")),
+ "\uFF21A");
+ check(new StringBuilder(ORIGIN).insert(1, new StringBuffer("\uFF21")),
+ "A\uFF21");
+ check(new StringBuilder(ORIGIN).insert(0, ""), "A");
+ check(new StringBuilder(ORIGIN).insert(0, "\uFF21"), "\uFF21A");
+ check(new StringBuilder(ORIGIN).insert(1, "\uFF21"), "A\uFF21");
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 0);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), -1);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 1);
+ check(new StringBuilder(ORIGIN).replace(0, 0, "\uFF21"), "\uFF21A");
+ check(new StringBuilder(ORIGIN).replace(0, 1, "\uFF21"), "\uFF21");
+ checkSetCharAt(new StringBuilder(ORIGIN), 0, '\uFF21', "\uFF21");
+ checkSetLength(new StringBuilder(ORIGIN), 0, "");
+ checkSetLength(new StringBuilder(ORIGIN), 1, "A");
+ check(new StringBuilder(ORIGIN).substring(0), "A");
+ check(new StringBuilder(ORIGIN).substring(1), "");
+ }
+
+ /*
+ * Tests for "\uFF21"
+ */
+ @Test
+ public void testCompactStringBuilderForNonLatinA() {
+ final String ORIGIN = "\uFF21";
+ check(new StringBuilder(ORIGIN).append(new char[] { 'A' }), "\uFF21A");
+ check(new StringBuilder(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
+ check(new StringBuilder(ORIGIN).append("A"), "\uFF21A");
+ check(new StringBuilder(ORIGIN).append(new StringBuffer("A")), "\uFF21A");
+ check(new StringBuilder(ORIGIN).delete(0, 1), "");
+ check(new StringBuilder(ORIGIN).delete(0, 0), "\uFF21");
+ check(new StringBuilder(ORIGIN).deleteCharAt(0), "");
+ assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), -1);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), 0);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
+ check(new StringBuilder(ORIGIN).insert(0, new char[] {}), "\uFF21");
+ check(new StringBuilder(ORIGIN).insert(1, new char[] { 'A' }), "\uFF21A");
+ check(new StringBuilder(ORIGIN).insert(0, new char[] { 'A' }), "A\uFF21");
+ check(new StringBuilder(ORIGIN).insert(0, new StringBuffer("A")),
+ "A\uFF21");
+ check(new StringBuilder(ORIGIN).insert(1, new StringBuffer("A")),
+ "\uFF21A");
+ check(new StringBuilder(ORIGIN).insert(0, ""), "\uFF21");
+ check(new StringBuilder(ORIGIN).insert(0, "A"), "A\uFF21");
+ check(new StringBuilder(ORIGIN).insert(1, "A"), "\uFF21A");
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), -1);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 0);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 1);
+ check(new StringBuilder(ORIGIN).replace(0, 0, "A"), "A\uFF21");
+ check(new StringBuilder(ORIGIN).replace(0, 1, "A"), "A");
+ checkSetCharAt(new StringBuilder(ORIGIN), 0, 'A', "A");
+ checkSetLength(new StringBuilder(ORIGIN), 0, "");
+ checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
+ check(new StringBuilder(ORIGIN).substring(0), "\uFF21");
+ check(new StringBuilder(ORIGIN).substring(1), "");
+ }
+
+ /*
+ * Tests for "\uFF21A"
+ */
+ @Test
+ public void testCompactStringBuilderForMixedA1() {
+ final String ORIGIN = "\uFF21A";
+ check(new StringBuilder(ORIGIN).delete(0, 1), "A");
+ check(new StringBuilder(ORIGIN).delete(1, 2), "\uFF21");
+ check(new StringBuilder(ORIGIN).deleteCharAt(1), "\uFF21");
+ check(new StringBuilder(ORIGIN).deleteCharAt(0), "A");
+ assertEquals(new StringBuilder(ORIGIN).indexOf("A", 0), 1);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 0), 0);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("", 0), 0);
+ check(new StringBuilder(ORIGIN).insert(1, new char[] { 'A' }),
+ "\uFF21AA");
+ check(new StringBuilder(ORIGIN).insert(0, new char[] { '\uFF21' }),
+ "\uFF21\uFF21A");
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 1);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 0);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 2);
+ check(new StringBuilder(ORIGIN).replace(0, 0, "A"), "A\uFF21A");
+ check(new StringBuilder(ORIGIN).replace(0, 1, "A"), "AA");
+ checkSetCharAt(new StringBuilder(ORIGIN), 0, 'A', "AA");
+ checkSetLength(new StringBuilder(ORIGIN), 0, "");
+ checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
+ check(new StringBuilder(ORIGIN).substring(0), "\uFF21A");
+ check(new StringBuilder(ORIGIN).substring(1), "A");
+ }
+
+ /*
+ * Tests for "A\uFF21"
+ */
+ @Test
+ public void testCompactStringBuilderForMixedA2() {
+ final String ORIGIN = "A\uFF21";
+ check(new StringBuilder(ORIGIN).replace(1, 2, "A"), "AA");
+ checkSetLength(new StringBuilder(ORIGIN), 1, "A");
+ check(new StringBuilder(ORIGIN).substring(0), "A\uFF21");
+ check(new StringBuilder(ORIGIN).substring(1), "\uFF21");
+ check(new StringBuilder(ORIGIN).substring(0, 1), "A");
+ }
+
+ /*
+ * Tests for "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A"
+ */
+ @Test
+ public void testCompactStringBuilderForDuplicatedMixedA1() {
+ final String ORIGIN = "\uFF21A\uFF21A\uFF21A\uFF21A\uFF21A";
+ checkSetLength(new StringBuilder(ORIGIN), 1, "\uFF21");
+ assertEquals(new StringBuilder(ORIGIN).indexOf("A", 5), 5);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 5), 6);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 9);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 8);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf(""), 10);
+ check(new StringBuilder(ORIGIN).substring(9), "A");
+ check(new StringBuilder(ORIGIN).substring(8), "\uFF21A");
+ }
+
+ /*
+ * Tests for "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21"
+ */
+ @Test
+ public void testCompactStringBuilderForDuplicatedMixedA2() {
+ final String ORIGIN = "A\uFF21A\uFF21A\uFF21A\uFF21A\uFF21";
+ checkSetLength(new StringBuilder(ORIGIN), 1, "A");
+ assertEquals(new StringBuilder(ORIGIN).indexOf("A", 5), 6);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21", 5), 5);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 8);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 9);
+ check(new StringBuilder(ORIGIN).substring(9), "\uFF21");
+ check(new StringBuilder(ORIGIN).substring(8), "A\uFF21");
+ }
+
+ /*
+ * Tests for "\uD801\uDC00\uD801\uDC01"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePoint() {
+ final String ORIGIN = "\uD801\uDC00\uD801\uDC01";
+ check(new StringBuilder(ORIGIN).append("A"), "\uD801\uDC00\uD801\uDC01A");
+ check(new StringBuilder(ORIGIN).append("\uFF21"),
+ "\uD801\uDC00\uD801\uDC01\uFF21");
+ check(new StringBuilder(ORIGIN).appendCodePoint('A'),
+ "\uD801\uDC00\uD801\uDC01A");
+ check(new StringBuilder(ORIGIN).appendCodePoint('\uFF21'),
+ "\uD801\uDC00\uD801\uDC01\uFF21");
+ assertEquals(new StringBuilder(ORIGIN).charAt(0), '\uD801');
+ assertEquals(new StringBuilder(ORIGIN).codePointAt(0),
+ Character.codePointAt(ORIGIN, 0));
+ assertEquals(new StringBuilder(ORIGIN).codePointAt(1),
+ Character.codePointAt(ORIGIN, 1));
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(2),
+ Character.codePointAt(ORIGIN, 0));
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
+ check(new StringBuilder(ORIGIN).delete(0, 2), "\uD801\uDC01");
+ check(new StringBuilder(ORIGIN).delete(0, 3), "\uDC01");
+ check(new StringBuilder(ORIGIN).deleteCharAt(1), "\uD801\uD801\uDC01");
+ checkGetChars(new StringBuilder(ORIGIN), 0, 3, new char[] { '\uD801',
+ '\uDC00', '\uD801' });
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uD801\uDC01"), 2);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uDC01"), 3);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21"), -1);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("A"), -1);
+ check(new StringBuilder(ORIGIN).insert(0, "\uFF21"),
+ "\uFF21\uD801\uDC00\uD801\uDC01");
+ check(new StringBuilder(ORIGIN).insert(1, "\uFF21"),
+ "\uD801\uFF21\uDC00\uD801\uDC01");
+ check(new StringBuilder(ORIGIN).insert(1, "A"),
+ "\uD801A\uDC00\uD801\uDC01");
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uDC00\uD801"), 1);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uD801"), 2);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), -1);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), -1);
+ assertEquals(new StringBuilder(ORIGIN).length(), 4);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 2);
+ check(new StringBuilder(ORIGIN).replace(0, 2, "A"), "A\uD801\uDC01");
+ check(new StringBuilder(ORIGIN).replace(0, 3, "A"), "A\uDC01");
+ check(new StringBuilder(ORIGIN).replace(0, 2, "\uFF21"),
+ "\uFF21\uD801\uDC01");
+ check(new StringBuilder(ORIGIN).replace(0, 3, "\uFF21"), "\uFF21\uDC01");
+ check(new StringBuilder(ORIGIN).reverse(), "\uD801\uDC01\uD801\uDC00");
+ checkSetCharAt(new StringBuilder(ORIGIN), 1, '\uDC01',
+ "\uD801\uDC01\uD801\uDC01");
+ checkSetCharAt(new StringBuilder(ORIGIN), 1, 'A', "\uD801A\uD801\uDC01");
+ checkSetLength(new StringBuilder(ORIGIN), 2, "\uD801\uDC00");
+ checkSetLength(new StringBuilder(ORIGIN), 3, "\uD801\uDC00\uD801");
+ check(new StringBuilder(ORIGIN).substring(1, 3), "\uDC00\uD801");
+ }
+
+ /*
+ * Tests for "A\uD801\uDC00\uFF21"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePointMixed1() {
+ final String ORIGIN = "A\uD801\uDC00\uFF21";
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(3),
+ Character.codePointAt(ORIGIN, 1));
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), '\uD801');
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), 'A');
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 2);
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 4), 3);
+ check(new StringBuilder(ORIGIN).delete(0, 1), "\uD801\uDC00\uFF21");
+ check(new StringBuilder(ORIGIN).delete(0, 1).delete(2, 3),
+ "\uD801\uDC00");
+ check(new StringBuilder(ORIGIN).deleteCharAt(3).deleteCharAt(0),
+ "\uD801\uDC00");
+ assertEquals(new StringBuilder(ORIGIN).indexOf("\uFF21"), 3);
+ assertEquals(new StringBuilder(ORIGIN).indexOf("A"), 0);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("\uFF21"), 3);
+ assertEquals(new StringBuilder(ORIGIN).lastIndexOf("A"), 0);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 3);
+ check(new StringBuilder(ORIGIN).replace(1, 3, "A"), "AA\uFF21");
+ check(new StringBuilder(ORIGIN).replace(1, 4, "A"), "AA");
+ check(new StringBuilder(ORIGIN).replace(1, 4, ""), "A");
+ check(new StringBuilder(ORIGIN).reverse(), "\uFF21\uD801\uDC00A");
+ checkSetLength(new StringBuilder(ORIGIN), 1, "A");
+ check(new StringBuilder(ORIGIN).substring(0, 1), "A");
+ }
+
+ /*
+ * Tests for "\uD801\uDC00\uFF21A"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePointMixed2() {
+ final String ORIGIN = "\uD801\uDC00\uFF21A";
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(3),
+ Character.codePointAt(ORIGIN, 2));
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(2),
+ Character.codePointAt(ORIGIN, 0));
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), '\uD801');
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 2);
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 4), 3);
+ check(new StringBuilder(ORIGIN).delete(0, 2), "\uFF21A");
+ check(new StringBuilder(ORIGIN).delete(0, 3), "A");
+ check(new StringBuilder(ORIGIN).deleteCharAt(0).deleteCharAt(0)
+ .deleteCharAt(0), "A");
+ assertEquals(new StringBuilder(ORIGIN).indexOf("A"), 3);
+ assertEquals(new StringBuilder(ORIGIN).delete(0, 3).indexOf("A"), 0);
+ assertEquals(new StringBuilder(ORIGIN).replace(0, 3, "B").indexOf("A"),
+ 1);
+ assertEquals(new StringBuilder(ORIGIN).substring(3, 4).indexOf("A"), 0);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 2);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
+ check(new StringBuilder(ORIGIN).replace(0, 3, "B"), "BA");
+ check(new StringBuilder(ORIGIN).reverse(), "A\uFF21\uD801\uDC00");
+ }
+
+ /*
+ * Tests for "\uD801A\uDC00\uFF21"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePointMixed3() {
+ final String ORIGIN = "\uD801A\uDC00\uFF21";
+ assertEquals(new StringBuilder(ORIGIN).codePointAt(1), 'A');
+ assertEquals(new StringBuilder(ORIGIN).codePointAt(3), '\uFF21');
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), '\uD801');
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), 'A');
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(3), '\uDC00');
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 3);
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
+ assertEquals(new StringBuilder(ORIGIN).delete(0, 1).delete(1, 3)
+ .indexOf("A"), 0);
+ assertEquals(
+ new StringBuilder(ORIGIN).replace(0, 1, "B").replace(2, 4, "C")
+ .indexOf("A"), 1);
+ assertEquals(new StringBuilder(ORIGIN).substring(1, 4).substring(0, 1)
+ .indexOf("A"), 0);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
+ check(new StringBuilder(ORIGIN).reverse(), "\uFF21\uDC00A\uD801");
+ }
+
+ /*
+ * Tests for "A\uDC01\uFF21\uD801"
+ */
+ @Test
+ public void testCompactStringForSupplementaryCodePointMixed4() {
+ final String ORIGIN = "A\uDC01\uFF21\uD801";
+ assertEquals(new StringBuilder(ORIGIN).codePointAt(1), '\uDC01');
+ assertEquals(new StringBuilder(ORIGIN).codePointAt(3), '\uD801');
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(1), 'A');
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(2), '\uDC01');
+ assertEquals(new StringBuilder(ORIGIN).codePointBefore(3), '\uFF21');
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(0, 3), 3);
+ assertEquals(new StringBuilder(ORIGIN).codePointCount(1, 3), 2);
+ assertEquals(new StringBuilder(ORIGIN).delete(1, 4).indexOf("A"), 0);
+ assertEquals(new StringBuilder(ORIGIN).replace(1, 4, "B").indexOf("A"),
+ 0);
+ assertEquals(new StringBuilder(ORIGIN).substring(0, 1).indexOf("A"), 0);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(0, 1), 1);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(1, 1), 2);
+ assertEquals(new StringBuilder(ORIGIN).offsetByCodePoints(2, 1), 3);
+ check(new StringBuilder(ORIGIN).reverse(), "\uD801\uFF21\uDC01A");
+ }
+
+ private void checkGetChars(StringBuilder sb, int srcBegin, int srcEnd,
+ char expected[]) {
+ char[] dst = new char[srcEnd - srcBegin];
+ sb.getChars(srcBegin, srcEnd, dst, 0);
+ assertTrue(Arrays.equals(dst, expected));
+ }
+
+ private void checkSetCharAt(StringBuilder sb, int index, char ch,
+ String expected) {
+ sb.setCharAt(index, ch);
+ check(sb, expected);
+ }
+
+ private void checkSetLength(StringBuilder sb, int newLength, String expected) {
+ sb.setLength(newLength);
+ check(sb, expected);
+ }
+
+ private void check(StringBuilder sb, String expected) {
+ check(sb.toString(), expected);
+ }
+
+ private void check(String str, String expected) {
+ assertTrue(str.equals(expected), String.format(
+ "Get (%s) but expect (%s), ", escapeNonASCIIs(str),
+ escapeNonASCIIs(expected)));
+ }
+
+ /*
+ * Because right now system default charset in JPRT environment is only
+ * guaranteed to support ASCII characters in log, so we escape them.
+ */
+ private String escapeNonASCIIs(String str) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < str.length(); i++) {
+ char c = str.charAt(i);
+ if (c > 0x7F) {
+ sb.append("\\u").append(Integer.toHexString((int) c));
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuilder/CompactStringBuilderSerialization.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import java.io.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static jdk.testlibrary.SerializationUtils.*;
+import static org.testng.Assert.*;
+
+/*
+ * @test
+ * @bug 8077559
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.SerializationUtils
+ * @summary Tests Compact String. This one is testing StringBuilder serialization
+ * among -XX:+CompactStrings/-XX:-CompactStrings/LegacyStringBuilder
+ * @run testng/othervm -XX:+CompactStrings CompactStringBuilderSerialization
+ * @run testng/othervm -XX:-CompactStrings CompactStringBuilderSerialization
+ */
+
+public class CompactStringBuilderSerialization {
+ @DataProvider
+ public Object[][] provider() {
+ return new Object[][] {
+ // every byte array is serialized from corresponding StringBuffer object
+ // by previous JDK(build 1.8.0_45-b14).
+ new Object[] {
+ new StringBuilder(""),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 0, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("A"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 1, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("AB"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 2, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, 0, 65, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("abcdefghijk"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 11, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 27, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0,
+ 105, 0, 106, 0, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("\uff21"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 1, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 17, -1, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("\uff21\uff22"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 2, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 18, -1, 33, -1, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("\uff21A\uff21A\uff21A\uff21A\uff21A"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 10, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1, 33, 0, 65, -1,
+ 33, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("A\uff21B\uff22C\uff23D\uff24E\uff25F\uff26G\uff27H\uff28"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 16, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, 0, 65, -1, 33, 0, 66, -1, 34, 0, 67, -1, 35, 0, 68, -1, 36, 0,
+ 69, -1, 37, 0, 70, -1, 38, 0, 71, -1, 39, 0, 72, -1, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("\uff21A\uff22B\uff23C\uff24D\uff25E\uff26F\uff27G\uff28H"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 16, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 32, -1, 33, 0, 65, -1, 34, 0, 66, -1, 35, 0, 67, -1, 36, 0, 68, -1,
+ 37, 0, 69, -1, 38, 0, 70, -1, 39, 0, 71, -1, 40, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("\ud801\udc00\ud801\udc01\uff21A"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 6, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 22, -40, 1, -36, 0, -40, 1, -36, 1, -1, 33, 0, 65, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } },
+ new Object[] {
+ new StringBuilder("\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22\uff21\uff22"),
+ new byte[] { -84, -19, 0, 5, 115, 114, 0, 23, 106, 97, 118, 97, 46, 108, 97, 110, 103, 46, 83, 116, 114, 105, 110, 103, 66, 117, 105,
+ 108, 100, 101, 114, 60, -43, -5, 20, 90, 76, 106, -53, 3, 0, 0, 120, 112, 119, 4, 0, 0, 0, 10, 117, 114, 0, 2, 91, 67, -80, 38,
+ 102, -80, -30, 93, -124, -84, 2, 0, 0, 120, 112, 0, 0, 0, 26, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34, -1, 33, -1, 34,
+ -1, 33, -1, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 } } };
+ }
+
+ /*
+ * Verify serialization works between Compact StringBuilder/Legacy StringBuilder
+ */
+ @Test(dataProvider = "provider")
+ public void test(StringBuilder sbContent, byte[] baInJDK8) throws Exception {
+ // Serialize a StringBuilder object into byte array.
+ byte[] ba = serialize(sbContent);
+ assertEquals(ba, baInJDK8);
+ // Deserialize a StringBuilder object from byte array which is generated by previous JDK(build 1.8.0_45-b14).
+ Object obj = deserialize(ba);
+ assertEquals(obj.getClass(), StringBuilder.class);
+ assertTrue(equals((StringBuilder)obj, sbContent));
+ }
+
+ boolean equals(StringBuilder sb, StringBuilder expected) {
+ if(sb.length() == expected.length()
+ && sb.capacity() == expected.capacity()
+ && sb.toString().equals(expected.toString())) {
+ return true;
+ }
+ return false;
+ }
+}
--- a/jdk/test/java/lang/StringBuilder/Exceptions.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/lang/StringBuilder/Exceptions.java Wed Jul 05 21:00:20 2017 +0200
@@ -94,21 +94,21 @@
System.out.println("StringBuilder.replace(int start, int end, String str)");
tryCatch(" -1, 2, \" \"",
- new StringIndexOutOfBoundsException(-1),
+ new StringIndexOutOfBoundsException("start -1, end 2, length 7"),
new Runnable() {
public void run() {
StringBuilder sb = new StringBuilder("hilbert");
sb.replace(-1, 2, " ");
}});
tryCatch(" 7, 8, \" \"",
- new StringIndexOutOfBoundsException("start > length()"),
+ new StringIndexOutOfBoundsException("start 7, end 6, length 6"),
new Runnable() {
public void run() {
StringBuilder sb = new StringBuilder("banach");
sb.replace(7, 8, " ");
}});
tryCatch(" 2, 1, \" \"",
- new StringIndexOutOfBoundsException("start > end"),
+ new StringIndexOutOfBoundsException("start 2, end 1, length 7"),
new Runnable() {
public void run() {
StringBuilder sb = new StringBuilder("riemann");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/security/SecureRandom/DefaultProvider.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+import static java.lang.System.out;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+/**
+ * @test
+ * @bug 8048356
+ * @summary Assert default provider used on all OS for SecureRandom
+ */
+public class DefaultProvider {
+
+ private static final String OS_NAME = System.getProperty("os.name");
+ private static final String SUNOS = "SunOS";
+ private static final String WINDOWS = "Windows";
+
+ public static void main(String[] args) throws NoSuchAlgorithmException {
+ out.println("Operating System: " + OS_NAME);
+
+ /* Test default provider used with constructor */
+ out.println("TEST: Default provider with constructor");
+ SecureRandom secureRandom = new SecureRandom();
+ String provider = secureRandom.getProvider().getName();
+ if (OS_NAME.startsWith(SUNOS)) {
+ if (!provider.startsWith("SunPKCS11-")) {
+ throw new RuntimeException("Unexpected provider name: "
+ + provider);
+ }
+ } else if (!provider.equals("SUN")) {
+ throw new RuntimeException("Unexpected provider name: "
+ + provider);
+ }
+ out.println("Passed, default provider with constructor: " + provider);
+
+ /* Test default provider with getInstance(String algorithm) */
+ out.println("TEST: SHA1PRNG supported on all platforms by SUN provider");
+ String algorithm = "SHA1PRNG";
+ provider = "SUN";
+
+ SecureRandom instance = SecureRandom.getInstance(algorithm);
+ assertInstance(instance, algorithm, provider);
+ out.println("Passed.");
+
+ if (!OS_NAME.startsWith(WINDOWS)) {
+ out.println("TEST: NativePRNG supported on all platforms"
+ + "(except Windows), by SUN provider");
+ algorithm = "NativePRNG";
+ provider = "SUN";
+ } else {
+ out.println(
+ "TEST: Windows-PRNG supported on windows by SunMSCAPI provider");
+ algorithm = "Windows-PRNG";
+ provider = "SunMSCAPI";
+ }
+ instance = SecureRandom.getInstance(algorithm);
+ assertInstance(instance, algorithm, provider);
+ out.println("Passed.");
+
+ if (OS_NAME.startsWith(SUNOS)) {
+ out.println(
+ "TEST: PKCS11 is supported on Solaris by SunPKCS11 provider");
+ algorithm = "PKCS11";
+ provider = "SunPKCS11-Solaris";
+ instance = SecureRandom.getInstance(algorithm);
+ assertInstance(instance, algorithm, provider);
+ out.println("Passed.");
+ }
+ }
+
+ private static void assertInstance(SecureRandom instance,
+ String expectedAlgorithm,
+ String expectedProvider) {
+ if (instance != null) {
+ if (!expectedAlgorithm.equalsIgnoreCase(instance.getAlgorithm())) {
+ throw new RuntimeException("Expected algorithm:"
+ + expectedAlgorithm + " actual: " + instance.getAlgorithm());
+ }
+
+ if (!expectedProvider.equalsIgnoreCase(instance.getProvider().getName())) {
+ throw new RuntimeException("Expected provider: "
+ + expectedProvider + " actual: "
+ + instance.getProvider().getName());
+ }
+ } else {
+ throw new RuntimeException("Secure instance is not created");
+ }
+ }
+}
--- a/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/time/tck/java/time/format/TCKZoneIdPrinterParser.java Wed Jul 05 21:00:20 2017 +0200
@@ -156,6 +156,7 @@
{"UTC", 3, -1, ZoneId.of("UTC"), false},
{"UT", 2, -1, ZoneId.of("UT"), false},
{"GMT", 3, -1, ZoneId.of("GMT"), false},
+ {"GMT0", 4, -1, ZoneId.of("GMT0"), false},
{"+00:00", 6, -1, ZoneOffset.UTC, true},
{"UTC+00:00", 9, -1, ZoneId.of("UTC"), false},
--- a/jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/time/test/java/time/temporal/TestIsoWeekFields.java Wed Jul 05 21:00:20 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014,2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -121,6 +121,14 @@
assertEquals(IsoFields.WEEK_BASED_YEAR.isSupportedBy(ThaiBuddhistDate.now()), false);
}
+ @Test
+ public void test_Unit_isSupportedBy_ISO() {
+ assertEquals(IsoFields.WEEK_BASED_YEARS.isSupportedBy(LocalDate.now()),true);
+ assertEquals(IsoFields.WEEK_BASED_YEARS.isSupportedBy(ThaiBuddhistDate.now()),false);
+ assertEquals(IsoFields.QUARTER_YEARS.isSupportedBy(LocalDate.now()),true);
+ assertEquals(IsoFields.QUARTER_YEARS.isSupportedBy(ThaiBuddhistDate.now()),false);
+ }
+
@Test(dataProvider = "fields")
public void test_WBY_range(TemporalField weekField, TemporalField yearField) {
assertEquals(yearField.range(), ValueRange.of(Year.MIN_VALUE, Year.MAX_VALUE));
--- a/jdk/test/java/util/Objects/BasicObjectsTest.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/util/Objects/BasicObjectsTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -241,12 +241,12 @@
String nonNullString = "non-null";
// Confirm the compile time return type matches
- String result = Objects.nonNullElse(nullString, defString);
+ String result = Objects.requireNonNullElse(nullString, defString);
errors += (result == defString) ? 0 : 1;
- errors += (Objects.nonNullElse(nonNullString, defString) == nonNullString) ? 0 : 1;
- errors += (Objects.nonNullElse(nonNullString, null) == nonNullString) ? 0 : 1;
+ errors += (Objects.requireNonNullElse(nonNullString, defString) == nonNullString) ? 0 : 1;
+ errors += (Objects.requireNonNullElse(nonNullString, null) == nonNullString) ? 0 : 1;
try {
- Objects.nonNullElse(null, null);
+ Objects.requireNonNullElse(null, null);
errors += 1;
} catch (NullPointerException npe) {
// expected
@@ -254,20 +254,20 @@
}
- // Test nonNullElseGet with a supplier
- errors += (Objects.nonNullElseGet(nullString, () -> defString) == defString) ? 0 : 1;
- errors += (Objects.nonNullElseGet(nonNullString, () -> defString) == nonNullString) ? 0 : 1;
- errors += (Objects.nonNullElseGet(nonNullString, () -> null) == nonNullString) ? 0 : 1;
+ // Test requireNonNullElseGet with a supplier
+ errors += (Objects.requireNonNullElseGet(nullString, () -> defString) == defString) ? 0 : 1;
+ errors += (Objects.requireNonNullElseGet(nonNullString, () -> defString) == nonNullString) ? 0 : 1;
+ errors += (Objects.requireNonNullElseGet(nonNullString, () -> null) == nonNullString) ? 0 : 1;
try {
- Objects.nonNullElseGet(null, () -> null);
+ Objects.requireNonNullElseGet(null, () -> null);
errors += 1;
} catch (NullPointerException npe) {
// expected
errors += npe.getMessage().equals("supplier.get()") ? 0 : 1;
}
try { // supplier is null
- Objects.nonNullElseGet(null, null);
+ Objects.requireNonNullElseGet(null, null);
errors += 1;
} catch (NullPointerException npe) {
// expected
--- a/jdk/test/java/util/concurrent/Phaser/Basic.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/util/concurrent/Phaser/Basic.java Wed Jul 05 21:00:20 2017 +0200
@@ -34,6 +34,7 @@
/*
* @test
* @bug 6445158
+ * @key intermittent
* @summary Basic tests for Phaser
* @author Chris Hegarty
*/
--- a/jdk/test/java/util/zip/TestLocalTime.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/java/util/zip/TestLocalTime.java Wed Jul 05 21:00:20 2017 +0200
@@ -21,9 +21,10 @@
* questions.
*/
-/**
+/*
* @test
* @bug 8075526
+ * @key intermittent
* @summary Test timestamp via ZipEntry.get/setTimeLocal()
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/SerializationUtils.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.testlibrary;
+
+import java.io.*;
+
+/**
+ * Common library for various test serialization utility functions.
+ */
+public final class SerializationUtils {
+ /*
+ * Serialize an object into byte array.
+ */
+ public static byte[] serialize(Object obj) throws Exception {
+ try (ByteArrayOutputStream bs = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bs);) {
+ out.writeObject(obj);
+ return bs.toByteArray();
+ }
+ }
+
+ /*
+ * Deserialize an object from byte array.
+ */
+ public static Object deserialize(byte[] ba) throws Exception {
+ try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(ba));) {
+ return in.readObject();
+ }
+ }
+}
--- a/jdk/test/sun/nio/cs/TestStringCoding.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/sun/nio/cs/TestStringCoding.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 6636323 6636319 7040220 7096080 7183053 8080248
+ * @bug 6636323 6636319 7040220 7096080 7183053 8080248 8054307
* @summary Test if StringCoding and NIO result have the same de/encoding result
* @modules java.base/sun.nio.cs
* @run main/othervm/timeout=2000 TestStringCoding
@@ -36,41 +36,61 @@
public class TestStringCoding {
public static void main(String[] args) throws Throwable {
+ // full bmp first
+ char[] bmp = new char[0x10000];
+ for (int i = 0; i < 0x10000; i++) {
+ bmp[i] = (char)i;
+ }
+ char[] latin = Arrays.copyOf(bmp, 0x100);
+ char[] ascii = Arrays.copyOf(bmp, 0x80);
+
+ byte[] latinBA = new byte[0x100];
+ for (int i = 0; i < 0x100; i++) {
+ latinBA[i] = (byte)i;
+ }
+ byte[] asciiBA = Arrays.copyOf(latinBA, 0x80);
+
for (Boolean hasSM: new boolean[] { false, true }) {
- if (hasSM)
+ if (hasSM) {
System.setSecurityManager(new PermissiveSecurityManger());
+ }
for (Charset cs: Charset.availableCharsets().values()) {
if ("ISO-2022-CN".equals(cs.name()) ||
"x-COMPOUND_TEXT".equals(cs.name()) ||
"x-JISAutoDetect".equals(cs.name()))
continue;
System.out.printf("Testing(sm=%b) " + cs.name() + "....", hasSM);
- // full bmp first
- char[] bmpCA = new char[0x10000];
- for (int i = 0; i < 0x10000; i++) {
- bmpCA[i] = (char)i;
- }
- byte[] sbBA = new byte[0x100];
- for (int i = 0; i < 0x100; i++) {
- sbBA[i] = (byte)i;
- }
- test(cs, bmpCA, sbBA);
+
+ testNewString(cs, testGetBytes(cs, new String(bmp)));
+ testNewString(cs, testGetBytes(cs, new String(latin)));
+ testNewString(cs, testGetBytes(cs, new String(ascii)));
+ testGetBytes(cs, testNewString(cs, latinBA));
+ testGetBytes(cs, testNewString(cs, asciiBA));
+
// "randomed" sizes
Random rnd = new Random();
for (int i = 0; i < 10; i++) {
- int clen = rnd.nextInt(0x10000);
- int blen = rnd.nextInt(0x100);
//System.out.printf(" blen=%d, clen=%d%n", blen, clen);
- test(cs, Arrays.copyOf(bmpCA, clen), Arrays.copyOf(sbBA, blen));
+ char[] bmp0 = Arrays.copyOf(bmp, rnd.nextInt(0x10000));
+ testNewString(cs, testGetBytes(cs, new String(bmp0)));
//add a pair of surrogates
- int pos = clen / 2;
- if ((pos + 1) < blen) {
- bmpCA[pos] = '\uD800';
- bmpCA[pos+1] = '\uDC00';
+ int pos = bmp0.length / 2;
+ if ((pos + 1) < bmp0.length) {
+ bmp0[pos] = '\uD800';
+ bmp0[pos+1] = '\uDC00';
}
- test(cs, Arrays.copyOf(bmpCA, clen), Arrays.copyOf(sbBA, blen));
+ testNewString(cs, testGetBytes(cs, new String(bmp0)));
+
+ char[] latin0 = Arrays.copyOf(latin, rnd.nextInt(0x100));
+ char[] ascii0 = Arrays.copyOf(ascii, rnd.nextInt(0x80));
+ byte[] latinBA0 = Arrays.copyOf(latinBA, rnd.nextInt(0x100));
+ byte[] asciiBA0 = Arrays.copyOf(asciiBA, rnd.nextInt(0x80));
+ testNewString(cs, testGetBytes(cs, new String(latin0)));
+ testNewString(cs, testGetBytes(cs, new String(ascii0)));
+ testGetBytes(cs, testNewString(cs, latinBA0));
+ testGetBytes(cs, testNewString(cs, asciiBA0));
}
-
+ testSurrogates(cs);
testMixed(cs);
System.out.println("done!");
}
@@ -109,8 +129,9 @@
//getBytes(cs);
bmpBA = bmpStr.getBytes(cs);
- if (!Arrays.equals(bmpBA, baNIO))
+ if (!Arrays.equals(bmpBA, baNIO)) {
throw new RuntimeException("getBytes(cs) failed -> " + cs.name());
+ }
//new String(csn);
String strSC = new String(bmpBA, cs.name());
@@ -118,49 +139,61 @@
if(!strNIO.equals(strSC)) {
throw new RuntimeException("new String(csn) failed -> " + cs.name());
}
-
//new String(cs);
strSC = new String(bmpBA, cs);
- if (!strNIO.equals(strSC))
+ if (!strNIO.equals(strSC)) {
throw new RuntimeException("new String(cs) failed -> " + cs.name());
-
+ }
}
- static void test(Charset cs, char[] bmpCA, byte[] sbBA) throws Throwable {
- String bmpStr = new String(bmpCA);
- CharsetDecoder dec = cs.newDecoder()
- .onMalformedInput(CodingErrorAction.REPLACE)
- .onUnmappableCharacter(CodingErrorAction.REPLACE);
+ static byte[] getBytes(CharsetEncoder enc, String str) throws Throwable {
+ ByteBuffer bf = enc.reset().encode(CharBuffer.wrap(str.toCharArray()));
+ byte[] ba = new byte[bf.limit()];
+ bf.get(ba, 0, ba.length);
+ return ba;
+ }
+
+ static byte[] testGetBytes(Charset cs, String str) throws Throwable {
CharsetEncoder enc = cs.newEncoder()
.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE);
-
//getBytes(csn);
- byte[] baSC = bmpStr.getBytes(cs.name());
- ByteBuffer bf = enc.reset().encode(CharBuffer.wrap(bmpCA));
- byte[] baNIO = new byte[bf.limit()];
- bf.get(baNIO, 0, baNIO.length);
- if (!Arrays.equals(baSC, baNIO))
+ byte[] baSC = str.getBytes(cs.name());
+ byte[] baNIO = getBytes(enc, str);
+ if (!Arrays.equals(baSC, baNIO)) {
throw new RuntimeException("getBytes(csn) failed -> " + cs.name());
-
+ }
//getBytes(cs);
- baSC = bmpStr.getBytes(cs);
- if (!Arrays.equals(baSC, baNIO))
+ baSC = str.getBytes(cs);
+ if (!Arrays.equals(baSC, baNIO)) {
throw new RuntimeException("getBytes(cs) failed -> " + cs.name());
+ }
+ return baSC;
+ }
+ static String testNewString(Charset cs, byte[] ba) throws Throwable {
+ CharsetDecoder dec = cs.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE);
//new String(csn);
- String strSC = new String(sbBA, cs.name());
- String strNIO = dec.reset().decode(ByteBuffer.wrap(sbBA)).toString();
-
- if(!strNIO.equals(strSC))
+ String strSC = new String(ba, cs.name());
+ String strNIO = dec.reset().decode(ByteBuffer.wrap(ba)).toString();
+ if(!strNIO.equals(strSC)) {
throw new RuntimeException("new String(csn) failed -> " + cs.name());
+ }
+ //new String(cs);
+ strSC = new String(ba, cs);
+ if (!strNIO.equals(strSC)) {
+ throw new RuntimeException("new String(cs)/bmp failed -> " + cs.name());
+ }
+ return strSC;
+ }
- //new String(cs);
- strSC = new String(sbBA, cs);
- if (!strNIO.equals(strSC))
- throw new RuntimeException("new String(cs) failed -> " + cs.name());
-
+ static void testSurrogates(Charset cs) throws Throwable {
//encode unmappable surrogates
+ CharsetEncoder enc = cs.newEncoder()
+ .onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE);
if (enc instanceof sun.nio.cs.ArrayEncoder &&
cs.contains(Charset.forName("ASCII"))) {
if (cs.name().equals("UTF-8") || // utf8 handles surrogates
--- a/jdk/test/sun/nio/cs/TestStringCodingUTF8.java Thu Nov 12 18:27:55 2015 -0800
+++ b/jdk/test/sun/nio/cs/TestStringCodingUTF8.java Wed Jul 05 21:00:20 2017 +0200
@@ -22,7 +22,7 @@
*/
/* @test
- @bug 7040220
+ @bug 7040220 8054307
@summary Test if StringCoding and NIO result have the same de/encoding result for UTF-8
* @run main/othervm/timeout=2000 TestStringCodingUTF8
* @key randomness
@@ -50,6 +50,18 @@
}
test(cs, bmp, 0, bmp.length);
+ char[] ascii = new char[0x80];
+ for (int i = 0; i < 0x80; i++) {
+ ascii[i] = (char)i;
+ }
+ test(cs, ascii, 0, ascii.length);
+
+ char[] latin1 = new char[0x100];
+ for (int i = 0; i < 0x100; i++) {
+ latin1[i] = (char)i;
+ }
+ test(cs, latin1, 0, latin1.length);
+
ArrayList<Integer> list = new ArrayList<>(0x20000);
for (int i = 0; i < 0x20000; i++) {
list.add(i, i);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/jca/PreferredProviderNegativeTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8076359 8133151
+ * @summary Test for jdk.security.provider.preferred security property
+ * @requires os.name == "SunOS"
+ * @run main/othervm PreferredProviderNegativeTest preJCESet AES:OracleUcrypto false
+ * @run main/othervm PreferredProviderNegativeTest preJCESet AES:SunNegative true
+ * @run main/othervm PreferredProviderNegativeTest afterJCESet AES:SunJGSS
+ * @run main/othervm PreferredProviderNegativeTest afterJCESet AES:SunECNegative
+ * @run main/othervm PreferredProviderNegativeTest invalidAlg AESNegative:SunJCE
+ */
+
+import java.security.Security;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+public class PreferredProviderNegativeTest {
+
+ /*
+ * Test security property could be set by valid and invalid provider
+ * before JCE was loaded
+ */
+ public static void preJCESet(String value, boolean negativeProvider)
+ throws NoSuchAlgorithmException, NoSuchPaddingException {
+ Security.setProperty("jdk.security.provider.preferred", value);
+
+ if (!Security.getProperty("jdk.security.provider.preferred")
+ .equals(value)) {
+ throw new RuntimeException(
+ "Test Failed:The property wasn't set");
+ }
+
+ String[] arrays = value.split(":");
+ Cipher cipher = Cipher.getInstance(arrays[0]);
+
+ if (negativeProvider) {
+ if (cipher.getProvider().getName().equals(arrays[1])) {
+ throw new RuntimeException(
+ "Test Failed:The provider shouldn't be set");
+ }
+ } else {
+ if (!cipher.getProvider().getName().equals(arrays[1])) {
+ throw new RuntimeException(
+ "Test Faild:The provider could be set "
+ + "by valid provider ");
+ }
+ }
+ System.out.println("Test Pass");
+ }
+
+ /*
+ * Test that the setting of the security property after Cipher.getInstance()
+ * does not influence previously loaded instances
+ */
+ public static void afterJCESet(String value)
+ throws NoSuchAlgorithmException, NoSuchPaddingException {
+ String[] arrays = value.split(":");
+ Cipher cipher = Cipher.getInstance(arrays[0]);
+
+ Security.setProperty("jdk.security.provider.preferred", value);
+ if (!cipher.getProvider().getName().equals("SunJCE")) {
+ throw new RuntimeException(
+ "Test Failed:The security property can't be updated after JCE load.");
+ }
+ System.out.println("Test Pass");
+ }
+
+ /* Test the security property with negative algorithm */
+ public static void invalidAlg(String value) throws NoSuchPaddingException {
+ String[] arrays = value.split(":");
+
+ try {
+ Security.setProperty("jdk.security.provider.preferred", value);
+ Cipher.getInstance(arrays[0]);
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println("Test Pass:Got NoSuchAlgorithmException as expired");
+ return;
+ }
+ throw new RuntimeException(
+ "Test Failed:Expected NoSuchAlgorithmException was not thrown");
+ }
+
+ public static void main(String[] args)
+ throws NoSuchAlgorithmException, NoSuchPaddingException {
+ boolean negativeProvider;
+
+ if (args.length >= 2) {
+ switch (args[0]) {
+ case "preJCESet":
+ negativeProvider = Boolean.valueOf(args[2]);
+ PreferredProviderNegativeTest.preJCESet(args[1], negativeProvider);
+ break;
+ case "afterJCESet":
+ PreferredProviderNegativeTest.afterJCESet(args[1]);
+ break;
+ case "invalidAlg":
+ PreferredProviderNegativeTest.invalidAlg(args[1]);
+ break;
+ }
+ } else {
+ throw new RuntimeException(
+ "Test Failed:Please pass the correct args");
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/jca/PreferredProviderTest.java Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8076359 8133151
+ * @summary Test the value for new jdk.security.provider.preferred security property
+ * @requires os.name == "SunOS"
+ */
+
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.List;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+
+public class PreferredProviderTest {
+
+ private static final List<DataTuple> SPARC_DATA = Arrays.asList(
+ new DataTuple("SHA-256", "SUN"), new DataTuple("SHA-384", "SUN"),
+ new DataTuple("SHA-512", "SUN"));
+ private static final List<DataTuple> X86_DATA = Arrays
+ .asList(new DataTuple("RSA", "SunRsaSign"));
+
+ public void RunTest(String type)
+ throws NoSuchAlgorithmException, NoSuchPaddingException {
+ String preferredProvider = Security
+ .getProperty("jdk.security.provider.preferred");
+ String actualProvider = null;
+ if (type.equals("sparcv9")) {
+ if (!preferredProvider.equals(
+ "AES:SunJCE, SHA-256:SUN, SHA-384:SUN, SHA-512:SUN")) {
+ throw new RuntimeException(
+ "Test Failed: wrong jdk.security.provider.preferred "
+ + "value on solaris-sparcv9");
+ }
+ for (DataTuple dataTuple : SPARC_DATA) {
+ MessageDigest md = MessageDigest
+ .getInstance(dataTuple.algorithm);
+ actualProvider = md.getProvider().getName();
+ if (!actualProvider.equals(dataTuple.provider)) {
+ throw new RuntimeException(String.format(
+ "Test Failed:Got wrong "
+ + "provider from Solaris-sparcv9 platform,"
+ + "Expected Provider: %s, Returned Provider: %s",
+ dataTuple.provider, actualProvider));
+ }
+ }
+ } else if (type.equals("amd64")) {
+ if (!preferredProvider.equals("AES:SunJCE, RSA:SunRsaSign")) {
+ throw new RuntimeException(
+ "Test Failed: wrong jdk.security.provider.preferred "
+ + "value on solaris-x86");
+ }
+ for (DataTuple dataTuple : X86_DATA) {
+ KeyFactory keyFactory = KeyFactory
+ .getInstance(dataTuple.algorithm);
+ actualProvider = keyFactory.getProvider().getName();
+ if (!actualProvider.equals(dataTuple.provider)) {
+ throw new RuntimeException(String.format(
+ "Test Failed:Got wrong "
+ + "provider from Solaris-x86 platform,"
+ + "Expected Provider: %s, Returned Provider: %s",
+ dataTuple.provider, actualProvider));
+ }
+ }
+ } else {
+ throw new RuntimeException("Test Failed: wrong platform value");
+ }
+
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+ actualProvider = cipher.getProvider().getName();
+ if (!actualProvider.equals("SunJCE")) {
+ throw new RuntimeException(String.format(
+ "Test Failed:Got wrong provider from Solaris-%s platform, "
+ + "Expected Provider: SunJCE, Returned Provider: %s",
+ type, actualProvider));
+ }
+
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ actualProvider = md.getProvider().getName();
+ if (!actualProvider.equals("OracleUcrypto")) {
+ throw new RuntimeException(String.format(
+ "Test Failed:Got wrong provider from Solaris-%s platform,"
+ + "Expected Provider: OracleUcrypto, Returned Provider: %s",
+ type, actualProvider));
+ }
+ }
+
+ private static class DataTuple {
+ private final String provider;
+ private final String algorithm;
+
+ private DataTuple(String algorithm, String provider) {
+ this.algorithm = algorithm;
+ this.provider = provider;
+ }
+ }
+
+ public static void main(String[] args)
+ throws NoSuchAlgorithmException, NoSuchPaddingException {
+
+ String arch = System.getProperty("os.arch");
+ PreferredProviderTest pp = new PreferredProviderTest();
+ pp.RunTest(arch);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/make/BuildStatic.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+default: all
+
+include $(SPEC)
+include MakeBase.gmk
+
+################################################################################
+#
+# Concatenate exported.symbols files for modules into a single global file.
+#
+
+GLOBAL_SYMBOLS_FILE := $(SUPPORT_OUTPUTDIR)/build-static/exported.symbols
+
+EXPORTED_SYMBOLS_MODULES := java.base jdk.jdwp.agent
+
+MODULES_SYMBOLS_FILES := $(foreach module, $(EXPORTED_SYMBOLS_MODULES), \
+ $(SUPPORT_OUTPUTDIR)/modules_libs/$(module)/$(module).symbols)
+
+$(GLOBAL_SYMBOLS_FILE): $(MODULES_SYMBOLS_FILES)
+ $(ECHO) $(LOG_INFO) "Generating global exported.symbols file"
+ $(MKDIR) -p $(@D)
+ $(CAT) $^ > $@
+
+TARGETS += $(GLOBAL_SYMBOLS_FILE)
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: default all
--- a/make/Init.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/make/Init.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -305,49 +305,20 @@
endif
on-failure:
- ifneq ($(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*), )
- $(PRINTF) "=== Output from failing command(s) repeated here ===\n"
- $(foreach logfile, $(sort $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*)), \
- $(PRINTF) "* For target $(notdir $(basename $(logfile))):\n" $(NEWLINE) \
- $(CAT) $(logfile) | $(GREP) -v -e "^Note: including file:" $(NEWLINE) \
- )
- $(PRINTF) "=== End of repeated output ===\n"
+ $(call PrintFailureReports)
+ $(call PrintBuildLogFailures)
+ $(PRINTF) "Hint: If caused by a warning, try configure --disable-warnings-as-errors.\n\n"
+ ifneq ($(COMPARE_BUILD), )
+ $(call CleanupCompareBuild)
endif
- if $(GREP) -q "recipe for target .* failed" $(BUILD_LOG) 2> /dev/null; then \
- $(PRINTF) "=== Make failure sequence repeated here ===\n" ; \
- $(GREP) "recipe for target .* failed" $(BUILD_LOG) ; \
- $(PRINTF) "=== End of repeated output ===\n" ; \
- $(PRINTF) "Hint: Try searching the build log for the name of the first failed target.\n" ; \
- else \
- $(PRINTF) "No indication of failed target found.\n" ; \
- $(PRINTF) "Hint: Try searching the build log for '] Error'.\n" ; \
- fi
- $(PRINTF) "Hint: If caused by a warning, try configure --disable-warnings-as-errors.\n\n"
# Support targets for COMPARE_BUILD, used for makefile development
pre-compare-build:
- $(ECHO) "Preparing for comparison rebuild"
- # Apply patch, if any
- ifneq ($(COMPARE_BUILD_PATCH), )
- $(PATCH) -p1 < $(COMPARE_BUILD_PATCH)
- endif
- # Move the first build away and re-create the output directory
- ( cd $(TOPDIR) && \
- $(MV) $(OUTPUT_ROOT) $(OUTPUT_ROOT).OLD && \
- $(MKDIR) -p $(OUTPUT_ROOT) )
- # Re-run configure with the same arguments (and possibly some additional),
- # must be done after patching.
- ( cd $(OUTPUT_ROOT) && PATH="$(ORIGINAL_PATH)" \
- $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
+ $(call PrepareCompareBuild)
post-compare-build:
- # Compare first and second build. Ignore any error code from compare.sh.
- $(ECHO) "Comparing between comparison rebuild (this/new) and baseline (other/old)"
- ifneq ($(COMPARE_BUILD_COMP_DIR), )
- +(cd $(OUTPUT_ROOT) && ./compare.sh $(COMPARE_BUILD_COMP_OPTS) -2dirs $(OUTPUT_ROOT)/$(COMPARE_BUILD_COMP_DIR) $(OUTPUT_ROOT).OLD/$(COMPARE_BUILD_COMP_DIR) || true)
- else
- +(cd $(OUTPUT_ROOT) && ./compare.sh $(COMPARE_BUILD_COMP_OPTS) -o $(OUTPUT_ROOT).OLD || true)
- endif
+ $(call CleanupCompareBuild)
+ $(call CompareBuildDoComparison)
.PHONY: print-targets print-modules reconfigure main on-failure
endif
--- a/make/InitSupport.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/make/InitSupport.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -321,6 +321,8 @@
# If any value contains "+", it will be replaced by space.
define ParseCompareBuild
ifneq ($$(COMPARE_BUILD), )
+ COMPARE_BUILD_OUTPUT_ROOT := $(TOPDIR)/build/compare-build/$(CONF_NAME)
+
ifneq ($$(findstring :, $$(COMPARE_BUILD)), )
$$(foreach part, $$(subst :, , $$(COMPARE_BUILD)), \
$$(if $$(filter PATCH=%, $$(part)), \
@@ -364,6 +366,73 @@
endif
endef
+ # Prepare for a comparison rebuild
+ define PrepareCompareBuild
+ $(ECHO) "Preparing for comparison rebuild"
+ # Apply patch, if any
+ $(if $(COMPARE_BUILD_PATCH), $(PATCH) -p1 < $(COMPARE_BUILD_PATCH))
+ # Move the first build away temporarily
+ $(RM) -r $(TOPDIR)/build/.compare-build-temp
+ $(MKDIR) -p $(TOPDIR)/build/.compare-build-temp
+ $(MV) $(OUTPUT_ROOT) $(TOPDIR)/build/.compare-build-temp
+ # Restore an old compare-build, or create a new compare-build directory.
+ if test -d $(COMPARE_BUILD_OUTPUT_ROOT); then \
+ $(MV) $(COMPARE_BUILD_OUTPUT_ROOT) $(OUTPUT_ROOT); \
+ else \
+ $(MKDIR) -p $(OUTPUT_ROOT); \
+ fi
+ # Re-run configure with the same arguments (and possibly some additional),
+ # must be done after patching.
+ ( cd $(OUTPUT_ROOT) && PATH="$(ORIGINAL_PATH)" \
+ $(BASH) $(TOPDIR)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
+ endef
+
+ # Cleanup after a compare build
+ define CleanupCompareBuild
+ # If running with a COMPARE_BUILD patch, reverse-apply it
+ $(if $(COMPARE_BUILD_PATCH), $(PATCH) -R -p1 < $(COMPARE_BUILD_PATCH))
+ # Move this build away and restore the original build
+ $(MKDIR) -p $(TOPDIR)/build/compare-build
+ $(MV) $(OUTPUT_ROOT) $(COMPARE_BUILD_OUTPUT_ROOT)
+ $(MV) $(TOPDIR)/build/.compare-build-temp/$(CONF_NAME) $(OUTPUT_ROOT)
+ $(RM) -r $(TOPDIR)/build/.compare-build-temp
+ endef
+
+ # Do the actual comparison of two builds
+ define CompareBuildDoComparison
+ # Compare first and second build. Ignore any error code from compare.sh.
+ $(ECHO) "Comparing between comparison rebuild (this/new) and baseline (other/old)"
+ $(if $(COMPARE_BUILD_COMP_DIR), \
+ +(cd $(COMPARE_BUILD_OUTPUT_ROOT) && ./compare.sh $(COMPARE_BUILD_COMP_OPTS) \
+ -2dirs $(COMPARE_BUILD_OUTPUT_ROOT)/$(COMPARE_BUILD_COMP_DIR) $(OUTPUT_ROOT)/$(COMPARE_BUILD_COMP_DIR) || true), \
+ +(cd $(COMPARE_BUILD_OUTPUT_ROOT) && ./compare.sh $(COMPARE_BUILD_COMP_OPTS) \
+ -o $(OUTPUT_ROOT) || true) \
+ )
+ endef
+
+ define PrintFailureReports
+ $(if $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*), \
+ $(PRINTF) "=== Output from failing command(s) repeated here ===\n" $(NEWLINE) \
+ $(foreach logfile, $(sort $(wildcard $(MAKESUPPORT_OUTPUTDIR)/failure-logs/*)), \
+ $(PRINTF) "* For target $(notdir $(basename $(logfile))):\n" $(NEWLINE) \
+ $(CAT) $(logfile) | $(GREP) -v -e "^Note: including file:" $(NEWLINE) \
+ ) \
+ $(PRINTF) "=== End of repeated output ===\n" \
+ )
+ endef
+
+ define PrintBuildLogFailures
+ if $(GREP) -q "recipe for target .* failed" $(BUILD_LOG) 2> /dev/null; then \
+ $(PRINTF) "=== Make failure sequence repeated here ===\n" ; \
+ $(GREP) "recipe for target .* failed" $(BUILD_LOG) ; \
+ $(PRINTF) "=== End of repeated output ===\n" ; \
+ $(PRINTF) "Hint: Try searching the build log for the name of the first failed target.\n" ; \
+ else \
+ $(PRINTF) "No indication of failed target found.\n" ; \
+ $(PRINTF) "Hint: Try searching the build log for '] Error'.\n" ; \
+ fi
+ endef
+
define RotateLogFiles
$(RM) $(BUILD_LOG).old 2> /dev/null
$(MV) $(BUILD_LOG) $(BUILD_LOG).old 2> /dev/null || true
--- a/make/Main.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/make/Main.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -93,7 +93,10 @@
unpack-sec:
+($(CD) $(JDK_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f UnpackSecurity.gmk)
-ALL_TARGETS += import-hotspot unpack-sec
+generate-exported-symbols:
+ +($(CD) $(TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f BuildStatic.gmk)
+
+ALL_TARGETS += import-hotspot unpack-sec generate-exported-symbols
################################################################################
# Gensrc targets, generating source before java compilation can be done
@@ -298,16 +301,23 @@
test:
$(call RunTests, $(TEST))
+test-hotspot-jtreg:
+ $(call RunTests, "hotspot_all")
+
test-hotspot-jtreg-native:
$(call RunTests, "hotspot_native_sanity")
+test-hotspot-internal:
+ $(call RunTests, "hotspot_internal")
+
test-jdk-jtreg-native:
$(call RunTests, "jdk_native_sanity")
test-make:
($(CD) $(SRC_ROOT)/test/make && $(MAKE) $(MAKE_ARGS) -f TestMake.gmk $(TEST_TARGET))
-ALL_TARGETS += test test-hotspot-jtreg-native test-jdk-jtreg-native test-make
+ALL_TARGETS += test test-hotspot-jtreg test-hotspot-jtreg-native \
+ test-hotspot-internal test-jdk-jtreg-native test-make
################################################################################
# Verification targets
@@ -368,10 +378,16 @@
import-hotspot: hotspot
+ generate-exported-symbols: java.base-libs jdk.jdwp.agent-libs
+
$(LIBS_TARGETS): import-hotspot
$(LAUNCHER_TARGETS): java.base-libs
+ ifeq ($(STATIC_BUILD), true)
+ $(LAUNCHER_TARGETS): generate-exported-symbols
+ endif
+
# The demos are currently linking to libjvm and libjava, just like all other
# jdk libs, even though they don't need to. To avoid warnings, make sure they
# aren't built until after libjava and libjvm are available to link to.
@@ -462,6 +478,10 @@
test-image-jdk-jtreg-native: build-test-jdk-jtreg-native
+ test-hotspot-internal: exploded-image
+
+ test-hotspot-jtreg: jimages test-image
+
endif
################################################################################
--- a/make/common/NativeCompilation.gmk Thu Nov 12 18:27:55 2015 -0800
+++ b/make/common/NativeCompilation.gmk Wed Jul 05 21:00:20 2017 +0200
@@ -35,6 +35,31 @@
endif
################################################################################
+# Create exported symbols file for static libraries
+################################################################################
+
+# get the exported symbols from mapfiles and if there
+# is no mapfile, get them from the archive
+define GetSymbols
+ $(RM) $$(@D)/$$(basename $$(@F)).symbols; \
+ if [ ! -z $$($1_MAPFILE) -a -e $$($1_MAPFILE) ]; then \
+ $(ECHO) "Getting symbols from mapfile $$($1_MAPFILE)"; \
+ $(AWK) '/global:/','/local:/' $$($1_MAPFILE) | \
+ $(SED) -e 's/#.*//;s/global://;s/local://;s/\;//;s/^[ ]*/_/;/^_$$$$/d' | \
+ $(EGREP) -v "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" > \
+ $$(@D)/$$(basename $$(@F)).symbols || true; \
+ $(NM) $$($1_TARGET) | $(GREP) " T " | \
+ $(EGREP) "JNI_OnLoad|JNI_OnUnload|Agent_OnLoad|Agent_OnUnload|Agent_OnAttach" | \
+ $(CUT) -d ' ' -f 3 >> $$(@D)/$$(basename $$(@F)).symbols || true;\
+ else \
+ $(ECHO) "Getting symbols from nm"; \
+ $(NM) -m $$($1_TARGET) | $(GREP) "__TEXT" | \
+ $(EGREP) -v "non-external|private extern|__TEXT,__eh_frame" | \
+ $(SED) -e 's/.* //' > $$(@D)/$$(basename $$(@F)).symbols; \
+ fi
+endef
+
+################################################################################
# Define a native toolchain configuration that can be used by
# SetupNativeCompilation calls
#
@@ -274,6 +299,15 @@
SetupNativeCompilation = $(NamedParamsMacroTemplate)
define SetupNativeCompilationBody
+ # If we're doing a static build and producing a library
+ # force it to be a static library and remove the -l libraries
+ ifeq ($(STATIC_BUILD), true)
+ ifneq ($$($1_LIBRARY),)
+ $1_STATIC_LIBRARY := $$($1_LIBRARY)
+ $1_LIBRARY :=
+ endif
+ endif
+
ifneq (,$$($1_BIN))
$$(error BIN has been replaced with OBJECT_DIR)
endif
@@ -495,6 +529,12 @@
$1_EXTRA_CXXFLAGS += $$(CXX_FLAG_REORDER)
endif
+ # Pass the library name for static JNI library naming
+ ifneq ($$($1_STATIC_LIBRARY),)
+ $1_EXTRA_CFLAGS += -DLIBRARY_NAME=$$($1_STATIC_LIBRARY)
+ $1_EXTRA_CXXFLAGS += -DLIBRARY_NAME=$$($1_STATIC_LIBRARY)
+ endif
+
# Pick up disabled warnings, if possible on this platform.
ifneq ($(DISABLE_WARNING_PREFIX),)
$1_EXTRA_CFLAGS += $$(addprefix $(DISABLE_WARNING_PREFIX), $$($1_DISABLED_WARNINGS_$(TOOLCHAIN_TYPE)))
@@ -725,7 +765,10 @@
$(ECHO) $(LOG_INFO) "Archiving $$($1_STATIC_LIBRARY)"
$(call LogFailures, $$($1_OBJECT_DIR)/$$($1_SAFE_NAME)_link.log, $$($1_SAFE_NAME)_link, \
$$($1_AR) $$($1_ARFLAGS) $(AR_OUT_OPTION)$$($1_TARGET) $$($1_EXPECTED_OBJS) \
- $$($1_RES) $$($1_LIBS) $$($1_EXTRA_LIBS))
+ $$($1_RES))
+ ifeq ($(STATIC_BUILD), true)
+ $(GetSymbols)
+ endif
endif
ifneq (,$$($1_PROGRAM))
--- a/modules.xml Thu Nov 12 18:27:55 2015 -0800
+++ b/modules.xml Wed Jul 05 21:00:20 2017 +0200
@@ -229,8 +229,11 @@
<to>java.logging</to>
<to>java.management</to>
<to>java.naming</to>
+ <to>java.security.jgss</to>
<to>java.sql</to>
+ <to>java.xml</to>
<to>jdk.management.resource</to>
+ <to>jdk.scripting.nashorn</to>
</export>
<export>
<name>jdk.internal.org.objectweb.asm</name>
--- a/test/lib/sun/hotspot/code/CodeBlob.java Thu Nov 12 18:27:55 2015 -0800
+++ b/test/lib/sun/hotspot/code/CodeBlob.java Wed Jul 05 21:00:20 2017 +0200
@@ -47,22 +47,24 @@
return new CodeBlob(obj);
}
protected CodeBlob(Object[] obj) {
- assert obj.length == 3;
+ assert obj.length == 4;
name = (String) obj[0];
size = (Integer) obj[1];
code_blob_type = BlobType.values()[(Integer) obj[2]];
assert code_blob_type.id == (Integer) obj[2];
+ address = (Long) obj[3];
}
public final String name;
public final int size;
public final BlobType code_blob_type;
-
+ public final long address;
@Override
public String toString() {
return "CodeBlob{"
+ "name=" + name
+ ", size=" + size
+ ", code_blob_type=" + code_blob_type
+ + ", address=" + address
+ '}';
}
}
--- a/test/lib/sun/hotspot/code/NMethod.java Thu Nov 12 18:27:55 2015 -0800
+++ b/test/lib/sun/hotspot/code/NMethod.java Wed Jul 05 21:00:20 2017 +0200
@@ -39,12 +39,12 @@
comp_level = (Integer) obj[1];
insts = (byte[]) obj[2];
compile_id = (Integer) obj[3];
- address = (Long) obj[4];
+ entry_point = (Long) obj[4];
}
public final byte[] insts;
public final int comp_level;
public final int compile_id;
- public final long address;
+ public final long entry_point;
@Override
public String toString() {
@@ -53,7 +53,7 @@
+ ", insts=" + insts
+ ", comp_level=" + comp_level
+ ", compile_id=" + compile_id
- + ", address=" + address
+ + ", entry_point=" + entry_point
+ '}';
}
}