--- a/make/Docs.gmk Fri May 03 14:59:32 2019 -0400
+++ b/make/Docs.gmk Tue May 07 17:30:14 2019 -0400
@@ -32,6 +32,7 @@
include ProcessMarkdown.gmk
include ToolsJdk.gmk
include ZipArchive.gmk
+include TextFileProcessing.gmk
# This is needed to properly setup DOCS_MODULES.
$(eval $(call ReadImportMetaData))
@@ -64,7 +65,7 @@
# URLs
JAVADOC_BASE_URL := https://docs.oracle.com/pls/topic/lookup?ctx=javase$(VERSION_NUMBER)&id=homepage
BUG_SUBMIT_URL := https://bugreport.java.com/bugreport/
-COPYRIGHT_URL := {@docroot}/../legal/copyright.html
+COPYRIGHT_URL := legal/copyright.html
LICENSE_URL := https://www.oracle.com/technetwork/java/javase/terms/license/java$(VERSION_NUMBER)speclicense.html
REDISTRIBUTION_URL := https://www.oracle.com/technetwork/java/redist-137594.html
@@ -148,6 +149,15 @@
HEADER_STYLE := style="margin-top: 14px;"
endif
+# $1 - Relative prefix to COPYRIGHT_URL
+COPYRIGHT_BOTTOM = \
+ <a href="$(strip $1)$(COPYRIGHT_URL)">Copyright</a> \
+ © 1993, $(COPYRIGHT_YEAR), $(FULL_COMPANY_NAME), \
+ $(COMPANY_ADDRESS).<br>All rights reserved. \
+ Use is subject to <a href="$(LICENSE_URL)">license terms</a> and the \
+ <a href="$(REDISTRIBUTION_URL)">documentation redistribution policy</a>. \
+ $(DRAFT_MARKER_STR) <!-- Version $(VERSION_STRING) -->
+
JAVADOC_BOTTOM := \
<a href="$(BUG_SUBMIT_URL)">Report a bug or suggest an enhancement</a><br> \
For further API reference and developer documentation see the \
@@ -157,12 +167,7 @@
of terms, workarounds, and working code examples.<br> \
Java is a trademark or registered trademark of $(FULL_COMPANY_NAME) in \
the US and other countries.<br> \
- <a href="$(COPYRIGHT_URL)">Copyright</a> \
- © 1993, $(COPYRIGHT_YEAR), $(FULL_COMPANY_NAME), \
- $(COMPANY_ADDRESS).<br>All rights reserved. \
- Use is subject to <a href="$(LICENSE_URL)">license terms</a> and the \
- <a href="$(REDISTRIBUTION_URL)">documentation redistribution policy</a>. \
- $(DRAFT_MARKER_STR) <!-- Version $(VERSION_STRING) -->
+ $(call COPYRIGHT_BOTTOM, {@docroot}/../)
JAVADOC_TOP := \
<div style="padding: 6px; text-align: center; font-size: 80%; \
@@ -500,11 +505,11 @@
################################################################################
# Copy JDK specs files
-# For all html documentation in $module/share/specs directories, copy it
+# For all non html/md files in $module/share/specs directories, copy them
# unmodified
ALL_MODULES := $(call FindAllModules)
-COPY_SPEC_FILTER := %.html %.gif %.jpg %.mib %.css
+COPY_SPEC_FILTER := %.gif %.jpg %.mib %.css
$(foreach m, $(ALL_MODULES), \
$(eval SPECS_$m := $(call FindModuleSpecsDirs, $m)) \
@@ -520,6 +525,45 @@
) \
)
+# Create copyright footer files that can be provided as input to pandoc. We
+# need different files for different relative paths to the copyright.html
+# file. The number 0-2 below represent how many extra directory levels down
+# below the specs dir the specs html file is located. Each file name is
+# stored in a variable SPECS_BOTTOM_FILE_$n where $n is 0, 1 or 2.
+SPECS_BOTTOM = <hr/>$(COPYRIGHT_BOTTOM)
+# The legal dir is one ../ below the specs dir, so start with one ../.
+specs_bottom_rel_path := ../
+$(foreach n, 0 1 2, \
+ $(eval SPECS_BOTTOM_FILE_$n := $(SUPPORT_OUTPUTDIR)/docs/full-specs-bottom-$n.txt) \
+ $(eval SPECS_BOTTOM_$n := $(call SPECS_BOTTOM,$(specs_bottom_rel_path))) \
+ $(eval $(SPECS_BOTTOM_FILE_$n): \
+ $(call DependOnVariable, SPECS_BOTTOM_$n) ; \
+ $(PRINTF) '$(SPECS_BOTTOM_$n)' > $$@ \
+ ) \
+ $(eval specs_bottom_rel_path := $(specs_bottom_rel_path)../) \
+)
+
+# For all html files in $module/share/specs directories, copy and add the
+# copyright footer.
+
+$(foreach m, $(ALL_MODULES), \
+ $(eval SPECS_$m := $(call FindModuleSpecsDirs, $m)) \
+ $(foreach d, $(SPECS_$m), \
+ $(foreach f, $(filter %.html, $(call FindFiles, $d)), \
+ $(eval $m_$f_NOF_SUBDIRS := $(words $(subst /, $(SPACE), $(subst $d, , $(dir $f))))) \
+ $(eval $m_$f_NAME := PROCESS_HTML_$m_$(strip $(call RelativePath, $f, $(TOPDIR)))) \
+ $(eval $(call SetupTextFileProcessing, $($m_$f_NAME), \
+ SOURCE_FILES := $f, \
+ SOURCE_BASE_DIR := $d, \
+ OUTPUT_DIR := $(DOCS_OUTPUTDIR)/specs/, \
+ REPLACEMENTS := \
+ </body> => $(SPECS_BOTTOM_$($m_$f_NOF_SUBDIRS))</body>, \
+ )) \
+ $(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
+ ) \
+ ) \
+)
+
ifeq ($(ENABLE_PANDOC), true)
# For all markdown files in $module/share/specs directories, convert them to
# html, if we have pandoc (otherwise we'll just skip this).
@@ -529,15 +573,19 @@
$(foreach m, $(ALL_MODULES), \
$(eval SPECS_$m := $(call FindModuleSpecsDirs, $m)) \
$(foreach d, $(SPECS_$m), \
- $(if $(filter %.md, $(call FindFiles, $d)), \
- $(eval $m_$d_NAME := SPECS_TO_HTML_$m_$(strip $(call RelativePath, $d, $(TOPDIR)))) \
- $(eval $(call SetupProcessMarkdown, $($m_$d_NAME), \
+ $(foreach f, $(filter %.md, $(call FindFiles, $d)), \
+ $(eval $m_$f_NOF_SUBDIRS := $(words $(subst /, $(SPACE), $(subst $d, , $(dir $f))))) \
+ $(eval $m_$f_BOTTOM_FILE := $(SPECS_BOTTOM_FILE_$($m_$f_NOF_SUBDIRS))) \
+ $(eval $m_$f_NAME := SPECS_TO_HTML_$m_$(strip $(call RelativePath, $f, $(TOPDIR)))) \
+ $(eval $(call SetupProcessMarkdown, $($m_$f_NAME), \
SRC := $d, \
- FILES := $(filter %.md, $(call FindFiles, $d)), \
+ FILES := $f, \
DEST := $(DOCS_OUTPUTDIR)/specs/, \
CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \
+ OPTIONS := -A $($m_$f_BOTTOM_FILE), \
+ EXTRA_DEPS := $($m_$f_BOTTOM_FILE), \
)) \
- $(eval JDK_SPECS_TARGETS += $($($m_$d_NAME))) \
+ $(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
) \
) \
)
@@ -556,19 +604,21 @@
$(foreach m, $(ALL_MODULES), \
$(eval MAN_$m := $(call FindModuleManDirs, $m)) \
$(foreach d, $(MAN_$m), \
- $(if $(filter %.md, $(call FindFiles, $d)), \
- $(eval $m_$d_NAME := MAN_TO_HTML_$m_$(strip $(call RelativePath, $d, $(TOPDIR)))) \
- $(eval $(call SetupProcessMarkdown, $($m_$d_NAME), \
+ $(foreach f, $(filter %.md, $(call FindFiles, $d)), \
+ $(eval $m_$f_NAME := MAN_TO_HTML_$m_$(strip $(call RelativePath, $f, $(TOPDIR)))) \
+ $(eval $(call SetupProcessMarkdown, $($m_$f_NAME), \
SRC := $d, \
- FILES := $(filter %.md, $(call FindFiles, $d)), \
+ FILES := $f, \
DEST := $(DOCS_OUTPUTDIR)/specs/man, \
FILTER := $(PANDOC_HTML_MANPAGE_FILTER), \
CSS := $(GLOBAL_SPECS_DEFAULT_CSS_FILE), \
REPLACEMENTS := @@VERSION_SHORT@@ => $(VERSION_SHORT), \
+ OPTIONS := -A $(SPECS_BOTTOM_FILE_1), \
EXTRA_DEPS := $(PANDOC_HTML_MANPAGE_FILTER) \
- $(PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT), \
+ $(PANDOC_HTML_MANPAGE_FILTER_JAVASCRIPT) \
+ $(SPECS_BOTTOM_FILE_1), \
)) \
- $(eval JDK_SPECS_TARGETS += $($($m_$d_NAME))) \
+ $(eval JDK_SPECS_TARGETS += $($($m_$f_NAME))) \
) \
) \
)
@@ -580,19 +630,23 @@
# Special treatment for generated documentation
JDWP_PROTOCOL := $(SUPPORT_OUTPUTDIR)/gensrc/jdk.jdi/jdwp-protocol.html
-$(eval $(call SetupCopyFiles, COPY_JDWP_PROTOCOL, \
- FILES := $(JDWP_PROTOCOL), \
- DEST := $(DOCS_OUTPUTDIR)/specs/jdwp, \
+$(eval $(call SetupTextFileProcessing, PROCESS_JDWP_PROTOCOL, \
+ SOURCE_FILES := $(JDWP_PROTOCOL), \
+ OUTPUT_DIR := $(DOCS_OUTPUTDIR)/specs/jdwp, \
+ REPLACEMENTS := \
+ </body> => $(SPECS_BOTTOM_1)</body>, \
))
-JDK_SPECS_TARGETS += $(COPY_JDWP_PROTOCOL)
+JDK_SPECS_TARGETS += $(PROCESS_JDWP_PROTOCOL)
# Get jvmti.html from the main jvm variant (all variants' jvmti.html are identical).
JVMTI_HTML ?= $(HOTSPOT_OUTPUTDIR)/variant-$(JVM_VARIANT_MAIN)/gensrc/jvmtifiles/jvmti.html
-$(eval $(call SetupCopyFiles, COPY_JVMTI_HTML, \
- FILES := $(JVMTI_HTML), \
- DEST := $(DOCS_OUTPUTDIR)/specs, \
+$(eval $(call SetupTextFileProcessing, PROCESS_JVMTI_HTML, \
+ SOURCE_FILES := $(JVMTI_HTML), \
+ OUTPUT_DIR := $(DOCS_OUTPUTDIR)/specs/, \
+ REPLACEMENTS := \
+ </body> => $(SPECS_BOTTOM_0)</body>, \
))
-JDK_SPECS_TARGETS += $(COPY_JVMTI_HTML)
+JDK_SPECS_TARGETS += $(PROCESS_JVMTI_HTML)
################################################################################
# Optional target which bundles all generated javadocs into a zip archive.
@@ -610,6 +664,10 @@
ZIP_TARGETS += $(BUILD_JAVADOC_ZIP)
################################################################################
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, Docs-post.gmk))
+
+################################################################################
docs-jdk-api-javadoc: $(JDK_API_JAVADOC_TARGETS) $(JDK_API_CUSTOM_TARGETS)
--- a/make/InitSupport.gmk Fri May 03 14:59:32 2019 -0400
+++ b/make/InitSupport.gmk Tue May 07 17:30:14 2019 -0400
@@ -387,7 +387,7 @@
fi
# Re-run configure with the same arguments (and possibly some additional),
# must be done after patching.
- ( cd $(OUTPUTDIR) && PATH="$(ORIGINAL_PATH)" \
+ ( cd $(CONFIGURE_START_DIR) && PATH="$(ORIGINAL_PATH)" \
$(BASH) $(topdir)/configure $(CONFIGURE_COMMAND_LINE) $(COMPARE_BUILD_CONF))
endef
--- a/make/common/TextFileProcessing.gmk Fri May 03 14:59:32 2019 -0400
+++ b/make/common/TextFileProcessing.gmk Tue May 07 17:30:14 2019 -0400
@@ -58,7 +58,7 @@
# OUTPUT_DIR the directory where we store the processed files.
# OUTPUT_FILE the name of the resulting file. Only allowed if processing a
# single file.
-# SOURCE_BASE_DIR a common root to all SOURCE_DIRS.
+# SOURCE_BASE_DIR a common root to all SOURCE_DIRS or SOURCE_FILES.
# If specified, files will keep the path relative to the base in the
# OUTPUT_DIR. Otherwise, the hierarchy will be flattened into the OUTPUT_DIR.
# INCLUDE_FILES only include files matching these patterns (used only with
@@ -84,9 +84,6 @@
ifneq ($$($1_SOURCE_DIRS),)
$$(error Cannot use both SOURCE_FILES and SOURCE_DIRS (in $1))
endif
- ifneq ($$($1_SOURCE_BASE_DIR),)
- $$(error Cannot use SOURCE_BASE_DIR without SOURCE_DIRS (in $1))
- endif
ifneq ($$($1_EXCLUDE_FILES)$$($1_INCLUDE_FILES),)
$$(error Cannot INCLUDE/EXCLUDE_FILES with SOURCE_FILES (in $1))
endif
@@ -155,9 +152,10 @@
# Convert the REPLACEMENTS syntax ( A => B ; C => D ; ...) to a sed command
# line (-e "s/A/B/g" -e "s/C/D/g" ...), basically by replacing '=>' with '/'
# and ';' with '/g" -e "s/', and adjusting for edge cases.
+ # '&' has special meaning in sed so needs to be escaped.
$1_REPLACEMENTS_COMMAND_LINE := $(SED) -e 's$$($1_SEP)$$(subst $$(SPACE);$$(SPACE),$$($1_SEP)g' \
-e 's$$($1_SEP),$$(subst $$(SPACE)=>$$(SPACE),$$($1_SEP),$$(subst $$(SPACE)=>$$(SPACE);$$(SPACE),$$($1_SEP)$$($1_SEP)g' \
- -e 's$$($1_SEP),$$(strip $$($1_REPLACEMENTS)))))$$($1_SEP)g'
+ -e 's$$($1_SEP),$$(subst &,\&,$$(strip $$($1_REPLACEMENTS))))))$$($1_SEP)g'
else
# We don't have any replacements, just pipe the file through cat.
$1_REPLACEMENTS_COMMAND_LINE := $(CAT)
--- a/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java Fri May 03 14:59:32 2019 -0400
+++ b/make/jdk/src/classes/build/tools/cldrconverter/CLDRConverter.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -346,17 +346,26 @@
if (sb.indexOf("root") == -1) {
sb.append("root");
}
- Bundle b = new Bundle(id, sb.toString(), null, null);
- // Insert the bundle for root at the top so that it will get
- // processed first.
- if ("root".equals(id)) {
- retList.add(0, b);
- } else {
- retList.add(b);
- }
+ retList.add(new Bundle(id, sb.toString(), null, null));
}
}
}
+
+ // Sort the bundles based on id. This will make sure all the parent bundles are
+ // processed first, e.g., for en_GB bundle, en_001, and "root" comes before
+ // en_GB. In order for "root" to come at the beginning, "root" is replaced with
+ // empty string on comparison.
+ retList.sort((o1, o2) -> {
+ String id1 = o1.getID();
+ String id2 = o2.getID();
+ if(id1.equals("root")) {
+ id1 = "";
+ }
+ if(id2.equals("root")) {
+ id2 = "";
+ }
+ return id1.compareTo(id2);
+ });
return retList;
}
--- a/src/hotspot/cpu/x86/assembler_x86.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp Tue May 07 17:30:14 2019 -0400
@@ -1894,6 +1894,69 @@
emit_int8((unsigned char)(0xC0 | encode));
}
+void Assembler::pabsb(XMMRegister dst, XMMRegister src) {
+ assert(VM_Version::supports_ssse3(), "");
+ InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
+ int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8(0x1C);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::pabsw(XMMRegister dst, XMMRegister src) {
+ assert(VM_Version::supports_ssse3(), "");
+ InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
+ int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8(0x1D);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::pabsd(XMMRegister dst, XMMRegister src) {
+ assert(VM_Version::supports_ssse3(), "");
+ InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+ int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8(0x1E);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::vpabsb(XMMRegister dst, XMMRegister src, int vector_len) {
+ assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
+ vector_len == AVX_256bit? VM_Version::supports_avx2() :
+ vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
+ int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8((unsigned char)0x1C);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::vpabsw(XMMRegister dst, XMMRegister src, int vector_len) {
+ assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
+ vector_len == AVX_256bit? VM_Version::supports_avx2() :
+ vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
+ int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8((unsigned char)0x1D);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::vpabsd(XMMRegister dst, XMMRegister src, int vector_len) {
+ assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
+ vector_len == AVX_256bit? VM_Version::supports_avx2() :
+ vector_len == AVX_512bit? VM_Version::supports_evex() : 0, "");
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+ int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8((unsigned char)0x1E);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
+void Assembler::evpabsq(XMMRegister dst, XMMRegister src, int vector_len) {
+ assert(UseAVX > 2, "");
+ InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+ attributes.set_is_evex_instruction();
+ int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8((unsigned char)0x1F);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
void Assembler::decl(Address dst) {
// Don't use it directly. Use MacroAssembler::decrement() instead.
InstructionMark im(this);
@@ -3416,10 +3479,19 @@
InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
int encode = vex_prefix_and_encode(dst->encoding(), 0, src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_3A, &attributes);
emit_int8(0x00);
- emit_int8(0xC0 | encode);
+ emit_int8((unsigned char)(0xC0 | encode));
emit_int8(imm8);
}
+void Assembler::vpermq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+ assert(UseAVX > 2, "requires AVX512F");
+ InstructionAttr attributes(vector_len, /* rex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+ attributes.set_is_evex_instruction();
+ int encode = vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8((unsigned char)0x36);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
void Assembler::vperm2i128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8) {
assert(VM_Version::supports_avx2(), "");
InstructionAttr attributes(AVX_256bit, /* rex_w */ false, /* legacy_mode */ true, /* no_mask_reg */ true, /* uses_vl */ false);
@@ -3884,6 +3956,14 @@
emit_int8((unsigned char)(0xC0 | encode));
}
+void Assembler::pmovsxbw(XMMRegister dst, XMMRegister src) {
+ assert(VM_Version::supports_sse4_1(), "");
+ InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
+ int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8(0x20);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
+
void Assembler::vpmovzxbw(XMMRegister dst, Address src, int vector_len) {
assert(VM_Version::supports_avx(), "");
InstructionMark im(this);
@@ -3905,6 +3985,15 @@
emit_int8((unsigned char) (0xC0 | encode));
}
+void Assembler::vpmovsxbw(XMMRegister dst, XMMRegister src, int vector_len) {
+ assert(vector_len == AVX_128bit? VM_Version::supports_avx() :
+ vector_len == AVX_256bit? VM_Version::supports_avx2() :
+ vector_len == AVX_512bit? VM_Version::supports_avx512bw() : 0, "");
+ InstructionAttr attributes(vector_len, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
+ int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38, &attributes);
+ emit_int8(0x20);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
void Assembler::evpmovzxbw(XMMRegister dst, KRegister mask, Address src, int vector_len) {
assert(VM_Version::supports_avx512vlbw(), "");
@@ -6277,6 +6366,26 @@
emit_int8((unsigned char)(0xC0 | encode));
}
+void Assembler::evpsraq(XMMRegister dst, XMMRegister src, int shift, int vector_len) {
+ assert(UseAVX > 2, "requires AVX512");
+ assert ((VM_Version::supports_avx512vl() || vector_len == 2), "requires AVX512vl");
+ InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+ attributes.set_is_evex_instruction();
+ int encode = vex_prefix_and_encode(xmm4->encoding(), dst->encoding(), src->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
+ emit_int8((unsigned char)0x72);
+ emit_int8((unsigned char)(0xC0 | encode));
+ emit_int8(shift & 0xFF);
+}
+
+void Assembler::evpsraq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len) {
+ assert(UseAVX > 2, "requires AVX512");
+ assert ((VM_Version::supports_avx512vl() || vector_len == 2), "requires AVX512vl");
+ InstructionAttr attributes(vector_len, /* vex_w */ true, /* legacy_mode */ false, /* no_mask_reg */ true, /* uses_vl */ true);
+ attributes.set_is_evex_instruction();
+ int encode = vex_prefix_and_encode(dst->encoding(), src->encoding(), shift->encoding(), VEX_SIMD_66, VEX_OPCODE_0F, &attributes);
+ emit_int8((unsigned char)0xE2);
+ emit_int8((unsigned char)(0xC0 | encode));
+}
// logical operations packed integers
void Assembler::pand(XMMRegister dst, XMMRegister src) {
--- a/src/hotspot/cpu/x86/assembler_x86.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp Tue May 07 17:30:14 2019 -0400
@@ -1102,6 +1102,15 @@
void cvttpd2dq(XMMRegister dst, XMMRegister src);
+ //Abs of packed Integer values
+ void pabsb(XMMRegister dst, XMMRegister src);
+ void pabsw(XMMRegister dst, XMMRegister src);
+ void pabsd(XMMRegister dst, XMMRegister src);
+ void vpabsb(XMMRegister dst, XMMRegister src, int vector_len);
+ void vpabsw(XMMRegister dst, XMMRegister src, int vector_len);
+ void vpabsd(XMMRegister dst, XMMRegister src, int vector_len);
+ void evpabsq(XMMRegister dst, XMMRegister src, int vector_len);
+
// Divide Scalar Double-Precision Floating-Point Values
void divsd(XMMRegister dst, Address src);
void divsd(XMMRegister dst, XMMRegister src);
@@ -1589,6 +1598,7 @@
// Pemutation of 64bit words
void vpermq(XMMRegister dst, XMMRegister src, int imm8, int vector_len);
void vpermq(XMMRegister dst, XMMRegister src, int imm8);
+ void vpermq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
void vperm2i128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8);
void vperm2f128(XMMRegister dst, XMMRegister nds, XMMRegister src, int imm8);
void evpermi2q(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
@@ -1668,6 +1678,10 @@
void evpmovdb(Address dst, XMMRegister src, int vector_len);
+ // Sign extend moves
+ void pmovsxbw(XMMRegister dst, XMMRegister src);
+ void vpmovsxbw(XMMRegister dst, XMMRegister src, int vector_len);
+
// Multiply add
void pmaddwd(XMMRegister dst, XMMRegister src);
void vpmaddwd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
@@ -2094,6 +2108,8 @@
void vpsrad(XMMRegister dst, XMMRegister src, int shift, int vector_len);
void vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
void vpsrad(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
+ void evpsraq(XMMRegister dst, XMMRegister src, int shift, int vector_len);
+ void evpsraq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
// And packed integers
void pand(XMMRegister dst, XMMRegister src);
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetC1_x86.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetC1_x86.cpp Tue May 07 17:30:14 2019 -0400
@@ -46,12 +46,14 @@
// Apply storeval barrier to newval.
ShenandoahBarrierSet::assembler()->storeval_barrier(masm->masm(), newval, tmp1);
+#ifdef _LP64
if (UseCompressedOops) {
__ encode_heap_oop(cmpval);
__ mov(rscratch1, newval);
__ encode_heap_oop(rscratch1);
newval = rscratch1;
}
+#endif
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), result, Address(addr, 0), cmpval, newval, false, tmp1, tmp2);
}
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Tue May 07 17:30:14 2019 -0400
@@ -1003,25 +1003,25 @@
}
}
-void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src) {
+void MacroAssembler::andpd(XMMRegister dst, AddressLiteral src, Register scratch_reg) {
// Used in sign-masking with aligned address.
assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
if (reachable(src)) {
Assembler::andpd(dst, as_Address(src));
} else {
- lea(rscratch1, src);
- Assembler::andpd(dst, Address(rscratch1, 0));
- }
-}
-
-void MacroAssembler::andps(XMMRegister dst, AddressLiteral src) {
+ lea(scratch_reg, src);
+ Assembler::andpd(dst, Address(scratch_reg, 0));
+ }
+}
+
+void MacroAssembler::andps(XMMRegister dst, AddressLiteral src, Register scratch_reg) {
// Used in sign-masking with aligned address.
assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
if (reachable(src)) {
Assembler::andps(dst, as_Address(src));
} else {
- lea(rscratch1, src);
- Assembler::andps(dst, Address(rscratch1, 0));
+ lea(scratch_reg, src);
+ Assembler::andps(dst, Address(scratch_reg, 0));
}
}
@@ -3340,13 +3340,13 @@
Assembler::vmovdqu(dst, src);
}
-void MacroAssembler::vmovdqu(XMMRegister dst, AddressLiteral src) {
+void MacroAssembler::vmovdqu(XMMRegister dst, AddressLiteral src, Register scratch_reg) {
if (reachable(src)) {
vmovdqu(dst, as_Address(src));
}
else {
- lea(rscratch1, src);
- vmovdqu(dst, Address(rscratch1, 0));
+ lea(scratch_reg, src);
+ vmovdqu(dst, Address(scratch_reg, 0));
}
}
@@ -3698,14 +3698,14 @@
}
}
-void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src) {
+void MacroAssembler::xorpd(XMMRegister dst, AddressLiteral src, Register scratch_reg) {
// Used in sign-bit flipping with aligned address.
assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
if (reachable(src)) {
Assembler::xorpd(dst, as_Address(src));
} else {
- lea(rscratch1, src);
- Assembler::xorpd(dst, Address(rscratch1, 0));
+ lea(scratch_reg, src);
+ Assembler::xorpd(dst, Address(scratch_reg, 0));
}
}
@@ -3726,14 +3726,14 @@
}
}
-void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src) {
+void MacroAssembler::xorps(XMMRegister dst, AddressLiteral src, Register scratch_reg) {
// Used in sign-bit flipping with aligned address.
assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
if (reachable(src)) {
Assembler::xorps(dst, as_Address(src));
} else {
- lea(rscratch1, src);
- Assembler::xorps(dst, Address(rscratch1, 0));
+ lea(scratch_reg, src);
+ Assembler::xorps(dst, Address(scratch_reg, 0));
}
}
@@ -3799,12 +3799,12 @@
Assembler::vpaddw(dst, nds, src, vector_len);
}
-void MacroAssembler::vpand(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
+void MacroAssembler::vpand(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg) {
if (reachable(src)) {
Assembler::vpand(dst, nds, as_Address(src), vector_len);
} else {
- lea(rscratch1, src);
- Assembler::vpand(dst, nds, Address(rscratch1, 0), vector_len);
+ lea(scratch_reg, src);
+ Assembler::vpand(dst, nds, Address(scratch_reg, 0), vector_len);
}
}
@@ -3873,6 +3873,22 @@
Assembler::vpsraw(dst, nds, shift, vector_len);
}
+void MacroAssembler::evpsraq(XMMRegister dst, XMMRegister nds, XMMRegister shift, int vector_len) {
+ assert(UseAVX > 2,"");
+ if (!VM_Version::supports_avx512vl() && vector_len < 2) {
+ vector_len = 2;
+ }
+ Assembler::evpsraq(dst, nds, shift, vector_len);
+}
+
+void MacroAssembler::evpsraq(XMMRegister dst, XMMRegister nds, int shift, int vector_len) {
+ assert(UseAVX > 2,"");
+ if (!VM_Version::supports_avx512vl() && vector_len < 2) {
+ vector_len = 2;
+ }
+ Assembler::evpsraq(dst, nds, shift, vector_len);
+}
+
void MacroAssembler::vpsrlw(XMMRegister dst, XMMRegister nds, XMMRegister shift, int vector_len) {
assert(((dst->encoding() < 16 && shift->encoding() < 16 && nds->encoding() < 16) || VM_Version::supports_avx512vlbw()),"XMM register should be 0-15");
Assembler::vpsrlw(dst, nds, shift, vector_len);
@@ -3913,21 +3929,21 @@
Assembler::pshuflw(dst, src, mode);
}
-void MacroAssembler::vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
+void MacroAssembler::vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg) {
if (reachable(src)) {
vandpd(dst, nds, as_Address(src), vector_len);
} else {
- lea(rscratch1, src);
- vandpd(dst, nds, Address(rscratch1, 0), vector_len);
- }
-}
-
-void MacroAssembler::vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
+ lea(scratch_reg, src);
+ vandpd(dst, nds, Address(scratch_reg, 0), vector_len);
+ }
+}
+
+void MacroAssembler::vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg) {
if (reachable(src)) {
vandps(dst, nds, as_Address(src), vector_len);
} else {
- lea(rscratch1, src);
- vandps(dst, nds, Address(rscratch1, 0), vector_len);
+ lea(scratch_reg, src);
+ vandps(dst, nds, Address(scratch_reg, 0), vector_len);
}
}
@@ -3995,23 +4011,161 @@
vxorpd(dst, nds, src, Assembler::AVX_128bit);
}
-void MacroAssembler::vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
+void MacroAssembler::vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg) {
if (reachable(src)) {
vxorpd(dst, nds, as_Address(src), vector_len);
} else {
- lea(rscratch1, src);
- vxorpd(dst, nds, Address(rscratch1, 0), vector_len);
- }
-}
-
-void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
+ lea(scratch_reg, src);
+ vxorpd(dst, nds, Address(scratch_reg, 0), vector_len);
+ }
+}
+
+void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg) {
if (reachable(src)) {
vxorps(dst, nds, as_Address(src), vector_len);
} else {
- lea(rscratch1, src);
- vxorps(dst, nds, Address(rscratch1, 0), vector_len);
- }
-}
+ lea(scratch_reg, src);
+ vxorps(dst, nds, Address(scratch_reg, 0), vector_len);
+ }
+}
+
+void MacroAssembler::vpxor(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg) {
+ if (UseAVX > 1 || (vector_len < 1)) {
+ if (reachable(src)) {
+ Assembler::vpxor(dst, nds, as_Address(src), vector_len);
+ } else {
+ lea(scratch_reg, src);
+ Assembler::vpxor(dst, nds, Address(scratch_reg, 0), vector_len);
+ }
+ }
+ else {
+ MacroAssembler::vxorpd(dst, nds, src, vector_len, scratch_reg);
+ }
+}
+
+//-------------------------------------------------------------------------------------------
+#ifdef COMPILER2
+// Generic instructions support for use in .ad files C2 code generation
+
+void MacroAssembler::vabsnegd(int opcode, XMMRegister dst, Register scr) {
+ if (opcode == Op_AbsVD) {
+ andpd(dst, ExternalAddress(StubRoutines::x86::vector_double_sign_mask()), scr);
+ } else {
+ assert((opcode == Op_NegVD),"opcode should be Op_NegD");
+ xorpd(dst, ExternalAddress(StubRoutines::x86::vector_double_sign_flip()), scr);
+ }
+}
+
+void MacroAssembler::vabsnegd(int opcode, XMMRegister dst, XMMRegister src, int vector_len, Register scr) {
+ if (opcode == Op_AbsVD) {
+ vandpd(dst, src, ExternalAddress(StubRoutines::x86::vector_double_sign_mask()), vector_len, scr);
+ } else {
+ assert((opcode == Op_NegVD),"opcode should be Op_NegD");
+ vxorpd(dst, src, ExternalAddress(StubRoutines::x86::vector_double_sign_flip()), vector_len, scr);
+ }
+}
+
+void MacroAssembler::vabsnegf(int opcode, XMMRegister dst, Register scr) {
+ if (opcode == Op_AbsVF) {
+ andps(dst, ExternalAddress(StubRoutines::x86::vector_float_sign_mask()), scr);
+ } else {
+ assert((opcode == Op_NegVF),"opcode should be Op_NegF");
+ xorps(dst, ExternalAddress(StubRoutines::x86::vector_float_sign_flip()), scr);
+ }
+}
+
+void MacroAssembler::vabsnegf(int opcode, XMMRegister dst, XMMRegister src, int vector_len, Register scr) {
+ if (opcode == Op_AbsVF) {
+ vandps(dst, src, ExternalAddress(StubRoutines::x86::vector_float_sign_mask()), vector_len, scr);
+ } else {
+ assert((opcode == Op_NegVF),"opcode should be Op_NegF");
+ vxorps(dst, src, ExternalAddress(StubRoutines::x86::vector_float_sign_flip()), vector_len, scr);
+ }
+}
+
+void MacroAssembler::vextendbw(bool sign, XMMRegister dst, XMMRegister src) {
+ if (sign) {
+ pmovsxbw(dst, src);
+ } else {
+ pmovzxbw(dst, src);
+ }
+}
+
+void MacroAssembler::vextendbw(bool sign, XMMRegister dst, XMMRegister src, int vector_len) {
+ if (sign) {
+ vpmovsxbw(dst, src, vector_len);
+ } else {
+ vpmovzxbw(dst, src, vector_len);
+ }
+}
+
+void MacroAssembler::vshiftd(int opcode, XMMRegister dst, XMMRegister src) {
+ if (opcode == Op_RShiftVI) {
+ psrad(dst, src);
+ } else if (opcode == Op_LShiftVI) {
+ pslld(dst, src);
+ } else {
+ assert((opcode == Op_URShiftVI),"opcode should be Op_URShiftVI");
+ psrld(dst, src);
+ }
+}
+
+void MacroAssembler::vshiftd(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+ if (opcode == Op_RShiftVI) {
+ vpsrad(dst, nds, src, vector_len);
+ } else if (opcode == Op_LShiftVI) {
+ vpslld(dst, nds, src, vector_len);
+ } else {
+ assert((opcode == Op_URShiftVI),"opcode should be Op_URShiftVI");
+ vpsrld(dst, nds, src, vector_len);
+ }
+}
+
+void MacroAssembler::vshiftw(int opcode, XMMRegister dst, XMMRegister src) {
+ if ((opcode == Op_RShiftVS) || (opcode == Op_RShiftVB)) {
+ psraw(dst, src);
+ } else if ((opcode == Op_LShiftVS) || (opcode == Op_LShiftVB)) {
+ psllw(dst, src);
+ } else {
+ assert(((opcode == Op_URShiftVS) || (opcode == Op_URShiftVB)),"opcode should be one of Op_URShiftVS or Op_URShiftVB");
+ psrlw(dst, src);
+ }
+}
+
+void MacroAssembler::vshiftw(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+ if ((opcode == Op_RShiftVS) || (opcode == Op_RShiftVB)) {
+ vpsraw(dst, nds, src, vector_len);
+ } else if ((opcode == Op_LShiftVS) || (opcode == Op_LShiftVB)) {
+ vpsllw(dst, nds, src, vector_len);
+ } else {
+ assert(((opcode == Op_URShiftVS) || (opcode == Op_URShiftVB)),"opcode should be one of Op_URShiftVS or Op_URShiftVB");
+ vpsrlw(dst, nds, src, vector_len);
+ }
+}
+
+void MacroAssembler::vshiftq(int opcode, XMMRegister dst, XMMRegister src) {
+ if (opcode == Op_RShiftVL) {
+ psrlq(dst, src); // using srl to implement sra on pre-avs512 systems
+ } else if (opcode == Op_LShiftVL) {
+ psllq(dst, src);
+ } else {
+ assert((opcode == Op_URShiftVL),"opcode should be Op_URShiftVL");
+ psrlq(dst, src);
+ }
+}
+
+void MacroAssembler::vshiftq(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
+ if (opcode == Op_RShiftVL) {
+ evpsraq(dst, nds, src, vector_len);
+ } else if (opcode == Op_LShiftVL) {
+ vpsllq(dst, nds, src, vector_len);
+ } else {
+ assert((opcode == Op_URShiftVL),"opcode should be Op_URShiftVL");
+ vpsrlq(dst, nds, src, vector_len);
+ }
+}
+#endif
+//-------------------------------------------------------------------------------------------
void MacroAssembler::clear_jweak_tag(Register possibly_jweak) {
const int32_t inverted_jweak_mask = ~static_cast<int32_t>(JNIHandles::weak_tag_mask);
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp Tue May 07 17:30:14 2019 -0400
@@ -877,12 +877,12 @@
// Floating
void andpd(XMMRegister dst, Address src) { Assembler::andpd(dst, src); }
- void andpd(XMMRegister dst, AddressLiteral src);
+ void andpd(XMMRegister dst, AddressLiteral src, Register scratch_reg = rscratch1);
void andpd(XMMRegister dst, XMMRegister src) { Assembler::andpd(dst, src); }
void andps(XMMRegister dst, XMMRegister src) { Assembler::andps(dst, src); }
void andps(XMMRegister dst, Address src) { Assembler::andps(dst, src); }
- void andps(XMMRegister dst, AddressLiteral src);
+ void andps(XMMRegister dst, AddressLiteral src, Register scratch_reg = rscratch1);
void comiss(XMMRegister dst, XMMRegister src) { Assembler::comiss(dst, src); }
void comiss(XMMRegister dst, Address src) { Assembler::comiss(dst, src); }
@@ -1066,8 +1066,8 @@
// these are private because users should be doing movflt/movdbl
+ void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); }
void movss(Address dst, XMMRegister src) { Assembler::movss(dst, src); }
- void movss(XMMRegister dst, XMMRegister src) { Assembler::movss(dst, src); }
void movss(XMMRegister dst, Address src) { Assembler::movss(dst, src); }
void movss(XMMRegister dst, AddressLiteral src);
@@ -1105,7 +1105,7 @@
void vmovdqu(Address dst, XMMRegister src);
void vmovdqu(XMMRegister dst, Address src);
void vmovdqu(XMMRegister dst, XMMRegister src);
- void vmovdqu(XMMRegister dst, AddressLiteral src);
+ void vmovdqu(XMMRegister dst, AddressLiteral src, Register scratch_reg = rscratch1);
void evmovdquq(XMMRegister dst, Address src, int vector_len) { Assembler::evmovdquq(dst, src, vector_len); }
void evmovdquq(XMMRegister dst, XMMRegister src, int vector_len) { Assembler::evmovdquq(dst, src, vector_len); }
void evmovdquq(Address dst, XMMRegister src, int vector_len) { Assembler::evmovdquq(dst, src, vector_len); }
@@ -1183,12 +1183,12 @@
// Bitwise Logical XOR of Packed Double-Precision Floating-Point Values
void xorpd(XMMRegister dst, XMMRegister src);
void xorpd(XMMRegister dst, Address src) { Assembler::xorpd(dst, src); }
- void xorpd(XMMRegister dst, AddressLiteral src);
+ void xorpd(XMMRegister dst, AddressLiteral src, Register scratch_reg = rscratch1);
// Bitwise Logical XOR of Packed Single-Precision Floating-Point Values
void xorps(XMMRegister dst, XMMRegister src);
void xorps(XMMRegister dst, Address src) { Assembler::xorps(dst, src); }
- void xorps(XMMRegister dst, AddressLiteral src);
+ void xorps(XMMRegister dst, AddressLiteral src, Register scratch_reg = rscratch1);
// Shuffle Bytes
void pshufb(XMMRegister dst, XMMRegister src) { Assembler::pshufb(dst, src); }
@@ -1215,7 +1215,7 @@
void vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vpand(dst, nds, src, vector_len); }
void vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vpand(dst, nds, src, vector_len); }
- void vpand(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
+ void vpand(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg = rscratch1);
void vpbroadcastw(XMMRegister dst, XMMRegister src, int vector_len);
void vpbroadcastw(XMMRegister dst, Address src, int vector_len) { Assembler::vpbroadcastw(dst, src, vector_len); }
@@ -1241,6 +1241,9 @@
void vpsraw(XMMRegister dst, XMMRegister nds, XMMRegister shift, int vector_len);
void vpsraw(XMMRegister dst, XMMRegister nds, int shift, int vector_len);
+ void evpsraq(XMMRegister dst, XMMRegister nds, XMMRegister shift, int vector_len);
+ void evpsraq(XMMRegister dst, XMMRegister nds, int shift, int vector_len);
+
void vpsrlw(XMMRegister dst, XMMRegister nds, XMMRegister shift, int vector_len);
void vpsrlw(XMMRegister dst, XMMRegister nds, int shift, int vector_len);
@@ -1260,11 +1263,11 @@
void vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vandpd(dst, nds, src, vector_len); }
void vandpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vandpd(dst, nds, src, vector_len); }
- void vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
+ void vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg = rscratch1);
void vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vandps(dst, nds, src, vector_len); }
void vandps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vandps(dst, nds, src, vector_len); }
- void vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
+ void vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg = rscratch1);
void vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vdivsd(dst, nds, src); }
void vdivsd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vdivsd(dst, nds, src); }
@@ -1297,11 +1300,11 @@
void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vxorpd(dst, nds, src, vector_len); }
void vxorpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vxorpd(dst, nds, src, vector_len); }
- void vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
+ void vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg = rscratch1);
void vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vxorps(dst, nds, src, vector_len); }
void vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vxorps(dst, nds, src, vector_len); }
- void vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
+ void vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg = rscratch1);
void vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
if (UseAVX > 1 || (vector_len < 1)) // vpxor 256 bit is available only in AVX2
@@ -1315,6 +1318,7 @@
else
Assembler::vxorpd(dst, nds, src, vector_len);
}
+ void vpxor(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len, Register scratch_reg = rscratch1);
// Simple version for AVX2 256bit vectors
void vpxor(XMMRegister dst, XMMRegister src) { Assembler::vpxor(dst, dst, src, true); }
@@ -1601,6 +1605,22 @@
void movl2ptr(Register dst, Address src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(movl(dst, src)); }
void movl2ptr(Register dst, Register src) { LP64_ONLY(movslq(dst, src)) NOT_LP64(if (dst != src) movl(dst, src)); }
+#ifdef COMPILER2
+ // Generic instructions support for use in .ad files C2 code generation
+ void vabsnegd(int opcode, XMMRegister dst, Register scr);
+ void vabsnegd(int opcode, XMMRegister dst, XMMRegister src, int vector_len, Register scr);
+ void vabsnegf(int opcode, XMMRegister dst, Register scr);
+ void vabsnegf(int opcode, XMMRegister dst, XMMRegister src, int vector_len, Register scr);
+ void vextendbw(bool sign, XMMRegister dst, XMMRegister src, int vector_len);
+ void vextendbw(bool sign, XMMRegister dst, XMMRegister src);
+ void vshiftd(int opcode, XMMRegister dst, XMMRegister src);
+ void vshiftd(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
+ void vshiftw(int opcode, XMMRegister dst, XMMRegister src);
+ void vshiftw(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
+ void vshiftq(int opcode, XMMRegister dst, XMMRegister src);
+ void vshiftq(int opcode, XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
+#endif
+
// C2 compiled method's prolog code.
void verified_entry(int framesize, int stack_bang_size, bool fp_mode_24b, bool is_stub);
--- a/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_32.cpp Tue May 07 17:30:14 2019 -0400
@@ -602,7 +602,59 @@
return start;
}
-
+ //---------------------------------------------------------------------------------------------------
+
+ address generate_vector_mask(const char *stub_name, int32_t mask) {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", stub_name);
+ address start = __ pc();
+
+ for (int i = 0; i < 16; i++) {
+ __ emit_data(mask, relocInfo::none, 0);
+ }
+
+ return start;
+ }
+
+ address generate_vector_mask_long_double(const char *stub_name, int32_t maskhi, int32_t masklo) {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", stub_name);
+ address start = __ pc();
+
+ for (int i = 0; i < 8; i++) {
+ __ emit_data(masklo, relocInfo::none, 0);
+ __ emit_data(maskhi, relocInfo::none, 0);
+ }
+
+ return start;
+ }
+
+ //----------------------------------------------------------------------------------------------------
+
+ address generate_vector_byte_perm_mask(const char *stub_name) {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", stub_name);
+ address start = __ pc();
+
+ __ emit_data(0x00000001, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+ __ emit_data(0x00000003, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+ __ emit_data(0x00000005, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+ __ emit_data(0x00000007, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+ __ emit_data(0x00000002, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+ __ emit_data(0x00000004, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+ __ emit_data(0x00000006, relocInfo::none, 0);
+ __ emit_data(0x00000000, relocInfo::none, 0);
+
+ return start;
+ }
//----------------------------------------------------------------------------------------------------
// Non-destructive plausibility checks for oops
@@ -3823,6 +3875,14 @@
//------------------------------------------------------------------------------------------------------------------------
// entry points that are platform specific
+ StubRoutines::x86::_vector_float_sign_mask = generate_vector_mask("vector_float_sign_mask", 0x7FFFFFFF);
+ StubRoutines::x86::_vector_float_sign_flip = generate_vector_mask("vector_float_sign_flip", 0x80000000);
+ StubRoutines::x86::_vector_double_sign_mask = generate_vector_mask_long_double("vector_double_sign_mask", 0x7FFFFFFF, 0xFFFFFFFF);
+ StubRoutines::x86::_vector_double_sign_flip = generate_vector_mask_long_double("vector_double_sign_flip", 0x80000000, 0x00000000);
+ StubRoutines::x86::_vector_short_to_byte_mask = generate_vector_mask("vector_short_to_byte_mask", 0x00ff00ff);
+ StubRoutines::x86::_vector_byte_perm_mask = generate_vector_byte_perm_mask("vector_byte_perm_mask");
+ StubRoutines::x86::_vector_long_sign_mask = generate_vector_mask_long_double("vector_long_sign_mask", 0x80000000, 0x00000000);
+
// support for verify_oop (must happen after universe_init)
StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Tue May 07 17:30:14 2019 -0400
@@ -979,6 +979,40 @@
return start;
}
+ address generate_vector_mask(const char *stub_name, int64_t mask) {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", stub_name);
+ address start = __ pc();
+
+ __ emit_data64(mask, relocInfo::none);
+ __ emit_data64(mask, relocInfo::none);
+ __ emit_data64(mask, relocInfo::none);
+ __ emit_data64(mask, relocInfo::none);
+ __ emit_data64(mask, relocInfo::none);
+ __ emit_data64(mask, relocInfo::none);
+ __ emit_data64(mask, relocInfo::none);
+ __ emit_data64(mask, relocInfo::none);
+
+ return start;
+ }
+
+ address generate_vector_byte_perm_mask(const char *stub_name) {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", stub_name);
+ address start = __ pc();
+
+ __ emit_data64(0x0000000000000001, relocInfo::none);
+ __ emit_data64(0x0000000000000003, relocInfo::none);
+ __ emit_data64(0x0000000000000005, relocInfo::none);
+ __ emit_data64(0x0000000000000007, relocInfo::none);
+ __ emit_data64(0x0000000000000000, relocInfo::none);
+ __ emit_data64(0x0000000000000002, relocInfo::none);
+ __ emit_data64(0x0000000000000004, relocInfo::none);
+ __ emit_data64(0x0000000000000006, relocInfo::none);
+
+ return start;
+ }
+
// Non-destructive plausibility checks for oops
//
// Arguments:
@@ -5871,6 +5905,13 @@
StubRoutines::x86::_float_sign_flip = generate_fp_mask("float_sign_flip", 0x8000000080000000);
StubRoutines::x86::_double_sign_mask = generate_fp_mask("double_sign_mask", 0x7FFFFFFFFFFFFFFF);
StubRoutines::x86::_double_sign_flip = generate_fp_mask("double_sign_flip", 0x8000000000000000);
+ StubRoutines::x86::_vector_float_sign_mask = generate_vector_mask("vector_float_sign_mask", 0x7FFFFFFF7FFFFFFF);
+ StubRoutines::x86::_vector_float_sign_flip = generate_vector_mask("vector_float_sign_flip", 0x8000000080000000);
+ StubRoutines::x86::_vector_double_sign_mask = generate_vector_mask("vector_double_sign_mask", 0x7FFFFFFFFFFFFFFF);
+ StubRoutines::x86::_vector_double_sign_flip = generate_vector_mask("vector_double_sign_flip", 0x8000000000000000);
+ StubRoutines::x86::_vector_short_to_byte_mask = generate_vector_mask("vector_short_to_byte_mask", 0x00ff00ff00ff00ff);
+ StubRoutines::x86::_vector_byte_perm_mask = generate_vector_byte_perm_mask("vector_byte_perm_mask");
+ StubRoutines::x86::_vector_long_sign_mask = generate_vector_mask("vector_long_sign_mask", 0x8000000000000000);
// support for verify_oop (must happen after universe_init)
StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
--- a/src/hotspot/cpu/x86/stubRoutines_x86.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/stubRoutines_x86.cpp Tue May 07 17:30:14 2019 -0400
@@ -43,6 +43,13 @@
address StubRoutines::x86::_upper_word_mask_addr = NULL;
address StubRoutines::x86::_shuffle_byte_flip_mask_addr = NULL;
address StubRoutines::x86::_k256_adr = NULL;
+address StubRoutines::x86::_vector_short_to_byte_mask = NULL;
+address StubRoutines::x86::_vector_float_sign_mask = NULL;
+address StubRoutines::x86::_vector_float_sign_flip = NULL;
+address StubRoutines::x86::_vector_double_sign_mask = NULL;
+address StubRoutines::x86::_vector_double_sign_flip = NULL;
+address StubRoutines::x86::_vector_byte_perm_mask = NULL;
+address StubRoutines::x86::_vector_long_sign_mask = NULL;
#ifdef _LP64
address StubRoutines::x86::_k256_W_adr = NULL;
address StubRoutines::x86::_k512_W_addr = NULL;
--- a/src/hotspot/cpu/x86/stubRoutines_x86.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/stubRoutines_x86.hpp Tue May 07 17:30:14 2019 -0400
@@ -102,6 +102,7 @@
static address double_sign_flip() {
return _double_sign_flip;
}
+
#else // !LP64
private:
@@ -139,6 +140,13 @@
//k256 table for sha256
static juint _k256[];
static address _k256_adr;
+ static address _vector_short_to_byte_mask;
+ static address _vector_float_sign_mask;
+ static address _vector_float_sign_flip;
+ static address _vector_double_sign_mask;
+ static address _vector_double_sign_flip;
+ static address _vector_byte_perm_mask;
+ static address _vector_long_sign_mask;
#ifdef _LP64
static juint _k256_W[];
static address _k256_W_adr;
@@ -212,6 +220,33 @@
static address upper_word_mask_addr() { return _upper_word_mask_addr; }
static address shuffle_byte_flip_mask_addr() { return _shuffle_byte_flip_mask_addr; }
static address k256_addr() { return _k256_adr; }
+
+ static address vector_short_to_byte_mask() {
+ return _vector_short_to_byte_mask;
+ }
+ static address vector_float_sign_mask() {
+ return _vector_float_sign_mask;
+ }
+
+ static address vector_float_sign_flip() {
+ return _vector_float_sign_flip;
+ }
+
+ static address vector_double_sign_mask() {
+ return _vector_double_sign_mask;
+ }
+
+ static address vector_double_sign_flip() {
+ return _vector_double_sign_flip;
+ }
+
+ static address vector_byte_perm_mask() {
+ return _vector_byte_perm_mask;
+ }
+
+ static address vector_long_sign_mask() {
+ return _vector_long_sign_mask;
+ }
#ifdef _LP64
static address k256_W_addr() { return _k256_W_adr; }
static address k512_W_addr() { return _k512_W_addr; }
--- a/src/hotspot/cpu/x86/x86.ad Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/x86.ad Tue May 07 17:30:14 2019 -0400
@@ -1372,14 +1372,20 @@
static address double_signmask() { return (address)double_signmask_pool; }
static address double_signflip() { return (address)double_signflip_pool; }
#endif
-
-
+ static address vector_short_to_byte_mask() { return StubRoutines::x86::vector_short_to_byte_mask(); }
+ static address vector_byte_perm_mask() { return StubRoutines::x86::vector_byte_perm_mask(); }
+ static address vector_long_sign_mask() { return StubRoutines::x86::vector_long_sign_mask(); }
+
+//=============================================================================
const bool Matcher::match_rule_supported(int opcode) {
if (!has_match_rule(opcode))
return false;
bool ret_value = true;
switch (opcode) {
+ case Op_AbsVL:
+ if (UseAVX < 3)
+ ret_value = false;
case Op_PopCountI:
case Op_PopCountL:
if (!UsePopCountInstruction)
@@ -1402,6 +1408,9 @@
if (UseAVX < 3) // only EVEX : vector connectivity becomes an issue here
ret_value = false;
break;
+ case Op_AbsVB:
+ case Op_AbsVS:
+ case Op_AbsVI:
case Op_AddReductionVI:
if (UseSSE < 3) // requires at least SSE3
ret_value = false;
@@ -1447,9 +1456,19 @@
ret_value = false;
break;
case Op_MulAddVS2VI:
+ case Op_RShiftVL:
+ case Op_AbsVD:
+ case Op_NegVD:
if (UseSSE < 2)
ret_value = false;
break;
+ case Op_MulVB:
+ case Op_LShiftVB:
+ case Op_RShiftVB:
+ case Op_URShiftVB:
+ if (UseSSE < 4)
+ ret_value = false;
+ break;
#ifdef _LP64
case Op_MaxD:
case Op_MaxF:
@@ -1470,24 +1489,42 @@
bool ret_value = match_rule_supported(opcode);
if (ret_value) {
switch (opcode) {
+ case Op_AbsVB:
case Op_AddVB:
case Op_SubVB:
if ((vlen == 64) && (VM_Version::supports_avx512bw() == false))
ret_value = false;
break;
- case Op_URShiftVS:
- case Op_RShiftVS:
- case Op_LShiftVS:
- case Op_MulVS:
+ case Op_AbsVS:
case Op_AddVS:
case Op_SubVS:
+ case Op_MulVS:
+ case Op_LShiftVS:
+ case Op_RShiftVS:
+ case Op_URShiftVS:
if ((vlen == 32) && (VM_Version::supports_avx512bw() == false))
ret_value = false;
break;
+ case Op_MulVB:
+ case Op_LShiftVB:
+ case Op_RShiftVB:
+ case Op_URShiftVB:
+ if ((vlen == 32 && UseAVX < 2) ||
+ ((vlen == 64) && (VM_Version::supports_avx512bw() == false)))
+ ret_value = false;
+ break;
+ case Op_NegVF:
+ if ((vlen == 16) && (VM_Version::supports_avx512dq() == false))
+ ret_value = false;
+ break;
case Op_CMoveVF:
if (vlen != 8)
ret_value = false;
break;
+ case Op_NegVD:
+ if ((vlen == 8) && (VM_Version::supports_avx512dq() == false))
+ ret_value = false;
+ break;
case Op_CMoveVD:
if (vlen != 4)
ret_value = false;
@@ -7302,6 +7339,186 @@
// --------------------------------- MUL --------------------------------------
+// Byte vector mul
+instruct mul4B_reg(vecS dst, vecS src1, vecS src2, vecS tmp, rRegI scratch) %{
+ predicate(UseSSE > 3 && n->as_Vector()->length() == 4);
+ match(Set dst (MulVB src1 src2));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{"pmovsxbw $tmp,$src1\n\t"
+ "pmovsxbw $dst,$src2\n\t"
+ "pmullw $tmp,$dst\n\t"
+ "movdqu $dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "pand $dst,$tmp\n\t"
+ "packuswb $dst,$dst\t! mul packed4B" %}
+ ins_encode %{
+ __ pmovsxbw($tmp$$XMMRegister, $src1$$XMMRegister);
+ __ pmovsxbw($dst$$XMMRegister, $src2$$XMMRegister);
+ __ pmullw($tmp$$XMMRegister, $dst$$XMMRegister);
+ __ movdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ pand($dst$$XMMRegister, $tmp$$XMMRegister);
+ __ packuswb($dst$$XMMRegister, $dst$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct mul8B_reg(vecD dst, vecD src1, vecD src2, vecD tmp, rRegI scratch) %{
+ predicate(UseSSE > 3 && n->as_Vector()->length() == 8);
+ match(Set dst (MulVB src1 src2));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{"pmovsxbw $tmp,$src1\n\t"
+ "pmovsxbw $dst,$src2\n\t"
+ "pmullw $tmp,$dst\n\t"
+ "movdqu $dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "pand $dst,$tmp\n\t"
+ "packuswb $dst,$dst\t! mul packed8B" %}
+ ins_encode %{
+ __ pmovsxbw($tmp$$XMMRegister, $src1$$XMMRegister);
+ __ pmovsxbw($dst$$XMMRegister, $src2$$XMMRegister);
+ __ pmullw($tmp$$XMMRegister, $dst$$XMMRegister);
+ __ movdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ pand($dst$$XMMRegister, $tmp$$XMMRegister);
+ __ packuswb($dst$$XMMRegister, $dst$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct mul16B_reg(vecX dst, vecX src1, vecX src2, vecX tmp1, vecX tmp2, rRegI scratch) %{
+ predicate(UseSSE > 3 && n->as_Vector()->length() == 16);
+ match(Set dst (MulVB src1 src2));
+ effect(TEMP dst, TEMP tmp1, TEMP tmp2, TEMP scratch);
+ format %{"pmovsxbw $tmp1,$src1\n\t"
+ "pmovsxbw $tmp2,$src2\n\t"
+ "pmullw $tmp1,$tmp2\n\t"
+ "pshufd $tmp2,$src1,0xEE\n\t"
+ "pshufd $dst,$src2,0xEE\n\t"
+ "pmovsxbw $tmp2,$tmp2\n\t"
+ "pmovsxbw $dst,$dst\n\t"
+ "pmullw $tmp2,$dst\n\t"
+ "movdqu $dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "pand $tmp2,$dst\n\t"
+ "pand $dst,$tmp1\n\t"
+ "packuswb $dst,$tmp2\t! mul packed16B" %}
+ ins_encode %{
+ __ pmovsxbw($tmp1$$XMMRegister, $src1$$XMMRegister);
+ __ pmovsxbw($tmp2$$XMMRegister, $src2$$XMMRegister);
+ __ pmullw($tmp1$$XMMRegister, $tmp2$$XMMRegister);
+ __ pshufd($tmp2$$XMMRegister, $src1$$XMMRegister, 0xEE);
+ __ pshufd($dst$$XMMRegister, $src2$$XMMRegister, 0xEE);
+ __ pmovsxbw($tmp2$$XMMRegister, $tmp2$$XMMRegister);
+ __ pmovsxbw($dst$$XMMRegister, $dst$$XMMRegister);
+ __ pmullw($tmp2$$XMMRegister, $dst$$XMMRegister);
+ __ movdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ pand($tmp2$$XMMRegister, $dst$$XMMRegister);
+ __ pand($dst$$XMMRegister, $tmp1$$XMMRegister);
+ __ packuswb($dst$$XMMRegister, $tmp2$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vmul16B_reg_avx(vecX dst, vecX src1, vecX src2, vecX tmp, rRegI scratch) %{
+ predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+ match(Set dst (MulVB src1 src2));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{"vpmovsxbw $tmp,$src1\n\t"
+ "vpmovsxbw $dst,$src2\n\t"
+ "vpmullw $tmp,$tmp,$dst\n\t"
+ "vmovdqu $dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "vpand $dst,$dst,$tmp\n\t"
+ "vextracti128_high $tmp,$dst\n\t"
+ "vpackuswb $dst,$dst,$dst\n\t! mul packed16B" %}
+ ins_encode %{
+ int vector_len = 1;
+ __ vpmovsxbw($tmp$$XMMRegister, $src1$$XMMRegister, vector_len);
+ __ vpmovsxbw($dst$$XMMRegister, $src2$$XMMRegister, vector_len);
+ __ vpmullw($tmp$$XMMRegister, $tmp$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vmovdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ vpand($dst$$XMMRegister, $dst$$XMMRegister, $tmp$$XMMRegister, vector_len);
+ __ vextracti128_high($tmp$$XMMRegister, $dst$$XMMRegister);
+ __ vpackuswb($dst$$XMMRegister, $dst$$XMMRegister, $tmp$$XMMRegister, 0);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vmul32B_reg_avx(vecY dst, vecY src1, vecY src2, vecY tmp1, vecY tmp2, rRegI scratch) %{
+ predicate(UseAVX > 1 && n->as_Vector()->length() == 32);
+ match(Set dst (MulVB src1 src2));
+ effect(TEMP dst, TEMP tmp1, TEMP tmp2, TEMP scratch);
+ format %{"vextracti128_high $tmp1,$src1\n\t"
+ "vextracti128_high $dst,$src2\n\t"
+ "vpmovsxbw $tmp1,$tmp1\n\t"
+ "vpmovsxbw $dst,$dst\n\t"
+ "vpmullw $tmp1,$tmp1,$dst\n\t"
+ "vpmovsxbw $tmp2,$src1\n\t"
+ "vpmovsxbw $dst,$src2\n\t"
+ "vpmullw $tmp2,$tmp2,$dst\n\t"
+ "vmovdqu $dst, [0x00ff00ff0x00ff00ff]\n\t"
+ "vpbroadcastd $dst, $dst\n\t"
+ "vpand $tmp1,$tmp1,$dst\n\t"
+ "vpand $dst,$dst,$tmp2\n\t"
+ "vpackuswb $dst,$dst,$tmp1\n\t"
+ "vpermq $dst, $dst, 0xD8\t! mul packed32B" %}
+ ins_encode %{
+ int vector_len = 1;
+ __ vextracti128_high($tmp1$$XMMRegister, $src1$$XMMRegister);
+ __ vextracti128_high($dst$$XMMRegister, $src2$$XMMRegister);
+ __ vpmovsxbw($tmp1$$XMMRegister, $tmp1$$XMMRegister, vector_len);
+ __ vpmovsxbw($dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpmullw($tmp1$$XMMRegister, $tmp1$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpmovsxbw($tmp2$$XMMRegister, $src1$$XMMRegister, vector_len);
+ __ vpmovsxbw($dst$$XMMRegister, $src2$$XMMRegister, vector_len);
+ __ vpmullw($tmp2$$XMMRegister, $tmp2$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vmovdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ vpbroadcastd($dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpand($tmp1$$XMMRegister, $tmp1$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpand($dst$$XMMRegister, $dst$$XMMRegister, $tmp2$$XMMRegister, vector_len);
+ __ vpackuswb($dst$$XMMRegister, $dst$$XMMRegister, $tmp1$$XMMRegister, vector_len);
+ __ vpermq($dst$$XMMRegister, $dst$$XMMRegister, 0xD8, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vmul64B_reg_avx(vecZ dst, vecZ src1, vecZ src2, vecZ tmp1, vecZ tmp2, rRegI scratch) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 64);
+ match(Set dst (MulVB src1 src2));
+ effect(TEMP dst, TEMP tmp1, TEMP tmp2, TEMP scratch);
+ format %{"vextracti64x4_high $tmp1,$src1\n\t"
+ "vextracti64x4_high $dst,$src2\n\t"
+ "vpmovsxbw $tmp1,$tmp1\n\t"
+ "vpmovsxbw $dst,$dst\n\t"
+ "vpmullw $tmp1,$tmp1,$dst\n\t"
+ "vpmovsxbw $tmp2,$src1\n\t"
+ "vpmovsxbw $dst,$src2\n\t"
+ "vpmullw $tmp2,$tmp2,$dst\n\t"
+ "vmovdqu $dst, [0x00ff00ff0x00ff00ff]\n\t"
+ "vpbroadcastd $dst, $dst\n\t"
+ "vpand $tmp1,$tmp1,$dst\n\t"
+ "vpand $tmp2,$tmp2,$dst\n\t"
+ "vpackuswb $dst,$tmp1,$tmp2\n\t"
+ "evmovdquq $tmp2,[0x0604020007050301]\n\t"
+ "vpermq $dst,$tmp2,$dst,0x01\t! mul packed64B" %}
+
+ ins_encode %{
+ int vector_len = 2;
+ __ vextracti64x4_high($tmp1$$XMMRegister, $src1$$XMMRegister);
+ __ vextracti64x4_high($dst$$XMMRegister, $src2$$XMMRegister);
+ __ vpmovsxbw($tmp1$$XMMRegister, $tmp1$$XMMRegister, vector_len);
+ __ vpmovsxbw($dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpmullw($tmp1$$XMMRegister, $tmp1$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpmovsxbw($tmp2$$XMMRegister, $src1$$XMMRegister, vector_len);
+ __ vpmovsxbw($dst$$XMMRegister, $src2$$XMMRegister, vector_len);
+ __ vpmullw($tmp2$$XMMRegister, $tmp2$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vmovdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ vpbroadcastd($dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpand($tmp1$$XMMRegister, $tmp1$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpand($tmp2$$XMMRegister, $tmp2$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpackuswb($dst$$XMMRegister, $tmp1$$XMMRegister, $tmp2$$XMMRegister, vector_len);
+ __ evmovdquq($tmp2$$XMMRegister, ExternalAddress(vector_byte_perm_mask()), vector_len, $scratch$$Register);
+ __ vpermq($dst$$XMMRegister, $tmp2$$XMMRegister, $dst$$XMMRegister, vector_len);
+
+ %}
+ ins_pipe( pipe_slow );
+%}
+
// Shorts/Chars vector mul
instruct vmul2S(vecS dst, vecS src) %{
predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
@@ -8024,20 +8241,6 @@
ins_pipe( pipe_slow );
%}
-// ------------------------------ Shift ---------------------------------------
-
-// Left and right shift count vectors are the same on x86
-// (only lowest bits of xmm reg are used for count).
-instruct vshiftcnt(vecS dst, rRegI cnt) %{
- match(Set dst (LShiftCntV cnt));
- match(Set dst (RShiftCntV cnt));
- format %{ "movd $dst,$cnt\t! load shift count" %}
- ins_encode %{
- __ movdl($dst$$XMMRegister, $cnt$$Register);
- %}
- ins_pipe( pipe_slow );
-%}
-
// --------------------------------- Sqrt --------------------------------------
// Floating point vector sqrt
@@ -8195,1092 +8398,478 @@
ins_pipe( pipe_slow );
%}
-// ------------------------------ LeftShift -----------------------------------
-
-// Shorts/Chars vector left shift
-instruct vsll2S(vecS dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVS dst shift));
- format %{ "psllw $dst,$shift\t! left shift packed2S" %}
- ins_encode %{
- __ psllw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2S_imm(vecS dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVS dst shift));
- format %{ "psllw $dst,$shift\t! left shift packed2S" %}
- ins_encode %{
- __ psllw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2S_reg(vecS dst, vecS src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed2S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2S_reg_imm(vecS dst, vecS src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed2S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4S(vecD dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVS dst shift));
- format %{ "psllw $dst,$shift\t! left shift packed4S" %}
- ins_encode %{
- __ psllw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4S_imm(vecD dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVS dst shift));
- format %{ "psllw $dst,$shift\t! left shift packed4S" %}
- ins_encode %{
- __ psllw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4S_reg(vecD dst, vecD src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed4S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4S_reg_imm(vecD dst, vecD src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed4S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll8S(vecX dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 8);
- match(Set dst (LShiftVS dst shift));
- format %{ "psllw $dst,$shift\t! left shift packed8S" %}
- ins_encode %{
- __ psllw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll8S_imm(vecX dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 8);
- match(Set dst (LShiftVS dst shift));
- format %{ "psllw $dst,$shift\t! left shift packed8S" %}
- ins_encode %{
- __ psllw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll8S_reg(vecX dst, vecX src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed8S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll8S_reg_imm(vecX dst, vecX src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed8S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll16S_reg(vecY dst, vecY src, vecS shift) %{
+// ------------------------------ Shift ---------------------------------------
+
+// Left and right shift count vectors are the same on x86
+// (only lowest bits of xmm reg are used for count).
+instruct vshiftcnt(vecS dst, rRegI cnt) %{
+ match(Set dst (LShiftCntV cnt));
+ match(Set dst (RShiftCntV cnt));
+ format %{ "movdl $dst,$cnt\t! load shift count" %}
+ ins_encode %{
+ __ movdl($dst$$XMMRegister, $cnt$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshiftcntimm(vecS dst, immI8 cnt, rRegI tmp) %{
+ match(Set dst cnt);
+ effect(TEMP tmp);
+ format %{ "movl $tmp,$cnt\t"
+ "movdl $dst,$tmp\t! load shift count" %}
+ ins_encode %{
+ __ movl($tmp$$Register, $cnt$$constant);
+ __ movdl($dst$$XMMRegister, $tmp$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// Byte vector shift
+instruct vshift4B(vecS dst, vecS src, vecS shift, vecS tmp, rRegI scratch) %{
+ predicate(UseSSE > 3 && n->as_Vector()->length() == 4);
+ match(Set dst (LShiftVB src shift));
+ match(Set dst (RShiftVB src shift));
+ match(Set dst (URShiftVB src shift));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{"vextendbw $tmp,$src\n\t"
+ "vshiftw $tmp,$shift\n\t"
+ "movdqu $dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "pand $dst,$tmp\n\t"
+ "packuswb $dst,$dst\n\t ! packed4B shift" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+
+ __ vextendbw(opcode, $tmp$$XMMRegister, $src$$XMMRegister);
+ __ vshiftw(opcode, $tmp$$XMMRegister, $shift$$XMMRegister);
+ __ movdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ pand($dst$$XMMRegister, $tmp$$XMMRegister);
+ __ packuswb($dst$$XMMRegister, $dst$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift8B(vecD dst, vecD src, vecS shift, vecD tmp, rRegI scratch) %{
+ predicate(UseSSE > 3 && n->as_Vector()->length() == 8);
+ match(Set dst (LShiftVB src shift));
+ match(Set dst (RShiftVB src shift));
+ match(Set dst (URShiftVB src shift));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{"vextendbw $tmp,$src\n\t"
+ "vshiftw $tmp,$shift\n\t"
+ "movdqu $dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "pand $dst,$tmp\n\t"
+ "packuswb $dst,$dst\n\t ! packed8B shift" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+
+ __ vextendbw(opcode, $tmp$$XMMRegister, $src$$XMMRegister);
+ __ vshiftw(opcode, $tmp$$XMMRegister, $shift$$XMMRegister);
+ __ movdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ pand($dst$$XMMRegister, $tmp$$XMMRegister);
+ __ packuswb($dst$$XMMRegister, $dst$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift16B(vecX dst, vecX src, vecS shift, vecX tmp1, vecX tmp2, rRegI scratch) %{
+ predicate(UseSSE > 3 && UseAVX <= 1 && n->as_Vector()->length() == 16);
+ match(Set dst (LShiftVB src shift));
+ match(Set dst (RShiftVB src shift));
+ match(Set dst (URShiftVB src shift));
+ effect(TEMP dst, TEMP tmp1, TEMP tmp2, TEMP scratch);
+ format %{"vextendbw $tmp1,$src\n\t"
+ "vshiftw $tmp1,$shift\n\t"
+ "pshufd $tmp2,$src\n\t"
+ "vextendbw $tmp2,$tmp2\n\t"
+ "vshiftw $tmp2,$shift\n\t"
+ "movdqu $dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "pand $tmp2,$dst\n\t"
+ "pand $dst,$tmp1\n\t"
+ "packuswb $dst,$tmp2\n\t! packed16B shift" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+
+ __ vextendbw(opcode, $tmp1$$XMMRegister, $src$$XMMRegister);
+ __ vshiftw(opcode, $tmp1$$XMMRegister, $shift$$XMMRegister);
+ __ pshufd($tmp2$$XMMRegister, $src$$XMMRegister, 0xE);
+ __ vextendbw(opcode, $tmp2$$XMMRegister, $tmp2$$XMMRegister);
+ __ vshiftw(opcode, $tmp2$$XMMRegister, $shift$$XMMRegister);
+ __ movdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ pand($tmp2$$XMMRegister, $dst$$XMMRegister);
+ __ pand($dst$$XMMRegister, $tmp1$$XMMRegister);
+ __ packuswb($dst$$XMMRegister, $tmp2$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift16B_avx(vecX dst, vecX src, vecS shift, vecX tmp, rRegI scratch) %{
predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed16S" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll16S_reg_imm(vecY dst, vecY src, immI8 shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed16S" %}
- ins_encode %{
+ match(Set dst (LShiftVB src shift));
+ match(Set dst (RShiftVB src shift));
+ match(Set dst (URShiftVB src shift));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{"vextendbw $tmp,$src\n\t"
+ "vshiftw $tmp,$tmp,$shift\n\t"
+ "vpand $tmp,$tmp,[0x00ff00ff0x00ff00ff]\n\t"
+ "vextracti128_high $dst,$tmp\n\t"
+ "vpackuswb $dst,$tmp,$dst\n\t! packed16B shift" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+
int vector_len = 1;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll32S_reg(vecZ dst, vecZ src, vecS shift) %{
- predicate(UseAVX > 2 && VM_Version::supports_avx512bw() && n->as_Vector()->length() == 32);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed32S" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll32S_reg_imm(vecZ dst, vecZ src, immI8 shift) %{
- predicate(UseAVX > 2 && VM_Version::supports_avx512bw() && n->as_Vector()->length() == 32);
- match(Set dst (LShiftVS src shift));
- format %{ "vpsllw $dst,$src,$shift\t! left shift packed32S" %}
- ins_encode %{
+ __ vextendbw(opcode, $tmp$$XMMRegister, $src$$XMMRegister, vector_len);
+ __ vshiftw(opcode, $tmp$$XMMRegister, $tmp$$XMMRegister, $shift$$XMMRegister, vector_len);
+ __ vpand($tmp$$XMMRegister, $tmp$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), vector_len, $scratch$$Register);
+ __ vextracti128_high($dst$$XMMRegister, $tmp$$XMMRegister);
+ __ vpackuswb($dst$$XMMRegister, $tmp$$XMMRegister, $dst$$XMMRegister, 0);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift32B_avx(vecY dst, vecY src, vecS shift, vecY tmp, rRegI scratch) %{
+ predicate(UseAVX > 1 && n->as_Vector()->length() == 32);
+ match(Set dst (LShiftVB src shift));
+ match(Set dst (RShiftVB src shift));
+ match(Set dst (URShiftVB src shift));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{"vextracti128_high $tmp,$src\n\t"
+ "vextendbw $tmp,$tmp\n\t"
+ "vextendbw $dst,$src\n\t"
+ "vshiftw $tmp,$tmp,$shift\n\t"
+ "vshiftw $dst,$dst,$shift\n\t"
+ "vpand $tmp,$tmp,[0x00ff00ff0x00ff00ff]\n\t"
+ "vpand $dst,$dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "vpackuswb $dst,$dst,$tmp\n\t"
+ "vpermq $dst,$dst,0xD8\n\t! packed32B shift" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+
+ int vector_len = 1;
+ __ vextracti128_high($tmp$$XMMRegister, $src$$XMMRegister);
+ __ vextendbw(opcode, $tmp$$XMMRegister, $tmp$$XMMRegister, vector_len);
+ __ vextendbw(opcode, $dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ __ vshiftw(opcode, $tmp$$XMMRegister, $tmp$$XMMRegister, $shift$$XMMRegister, vector_len);
+ __ vshiftw(opcode, $dst$$XMMRegister, $dst$$XMMRegister, $shift$$XMMRegister, vector_len);
+ __ vpand($tmp$$XMMRegister, $tmp$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), vector_len, $scratch$$Register);
+ __ vpand($dst$$XMMRegister, $dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), vector_len, $scratch$$Register);
+ __ vpackuswb($dst$$XMMRegister, $dst$$XMMRegister, $tmp$$XMMRegister, vector_len);
+ __ vpermq($dst$$XMMRegister, $dst$$XMMRegister, 0xD8, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift64B_avx(vecZ dst, vecZ src, vecS shift, vecZ tmp1, vecZ tmp2, rRegI scratch) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 64);
+ match(Set dst (LShiftVB src shift));
+ match(Set dst (RShiftVB src shift));
+ match(Set dst (URShiftVB src shift));
+ effect(TEMP dst, TEMP tmp1, TEMP tmp2, TEMP scratch);
+ format %{"vextracti64x4 $tmp1,$src\n\t"
+ "vextendbw $tmp1,$tmp1\n\t"
+ "vextendbw $tmp2,$src\n\t"
+ "vshiftw $tmp1,$tmp1,$shift\n\t"
+ "vshiftw $tmp2,$tmp2,$shift\n\t"
+ "vmovdqu $dst,[0x00ff00ff0x00ff00ff]\n\t"
+ "vpbroadcastd $dst,$dst\n\t"
+ "vpand $tmp1,$tmp1,$dst\n\t"
+ "vpand $tmp2,$tmp2,$dst\n\t"
+ "vpackuswb $dst,$tmp1,$tmp2\n\t"
+ "evmovdquq $tmp2, [0x0604020007050301]\n\t"
+ "vpermq $dst,$tmp2,$dst\n\t! packed64B shift" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+
int vector_len = 2;
- __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-// Integers vector left shift
-instruct vsll2I(vecD dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVI dst shift));
- format %{ "pslld $dst,$shift\t! left shift packed2I" %}
- ins_encode %{
- __ pslld($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2I_imm(vecD dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVI dst shift));
- format %{ "pslld $dst,$shift\t! left shift packed2I" %}
- ins_encode %{
- __ pslld($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2I_reg(vecD dst, vecD src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVI src shift));
- format %{ "vpslld $dst,$src,$shift\t! left shift packed2I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpslld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVI src shift));
- format %{ "vpslld $dst,$src,$shift\t! left shift packed2I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpslld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4I(vecX dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVI dst shift));
- format %{ "pslld $dst,$shift\t! left shift packed4I" %}
- ins_encode %{
- __ pslld($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4I_imm(vecX dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVI dst shift));
- format %{ "pslld $dst,$shift\t! left shift packed4I" %}
- ins_encode %{
- __ pslld($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4I_reg(vecX dst, vecX src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVI src shift));
- format %{ "vpslld $dst,$src,$shift\t! left shift packed4I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpslld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVI src shift));
- format %{ "vpslld $dst,$src,$shift\t! left shift packed4I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpslld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll8I_reg(vecY dst, vecY src, vecS shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
- match(Set dst (LShiftVI src shift));
- format %{ "vpslld $dst,$src,$shift\t! left shift packed8I" %}
- ins_encode %{
- int vector_len = 1;
- __ vpslld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll8I_reg_imm(vecY dst, vecY src, immI8 shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
- match(Set dst (LShiftVI src shift));
- format %{ "vpslld $dst,$src,$shift\t! left shift packed8I" %}
- ins_encode %{
- int vector_len = 1;
- __ vpslld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll16I_reg(vecZ dst, vecZ src, vecS shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
- match(Set dst (LShiftVI src shift));
- format %{ "vpslld $dst,$src,$shift\t! left shift packed16I" %}
- ins_encode %{
- int vector_len = 2;
- __ vpslld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll16I_reg_imm(vecZ dst, vecZ src, immI8 shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
- match(Set dst (LShiftVI src shift));
- format %{ "vpslld $dst,$src,$shift\t! left shift packed16I" %}
- ins_encode %{
- int vector_len = 2;
- __ vpslld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-// Longs vector left shift
-instruct vsll2L(vecX dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVL dst shift));
- format %{ "psllq $dst,$shift\t! left shift packed2L" %}
- ins_encode %{
- __ psllq($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2L_imm(vecX dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVL dst shift));
- format %{ "psllq $dst,$shift\t! left shift packed2L" %}
- ins_encode %{
- __ psllq($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2L_reg(vecX dst, vecX src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVL src shift));
- format %{ "vpsllq $dst,$src,$shift\t! left shift packed2L" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll2L_reg_imm(vecX dst, vecX src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (LShiftVL src shift));
- format %{ "vpsllq $dst,$src,$shift\t! left shift packed2L" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4L_reg(vecY dst, vecY src, vecS shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVL src shift));
- format %{ "vpsllq $dst,$src,$shift\t! left shift packed4L" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll4L_reg_imm(vecY dst, vecY src, immI8 shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
- match(Set dst (LShiftVL src shift));
- format %{ "vpsllq $dst,$src,$shift\t! left shift packed4L" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll8L_reg(vecZ dst, vecZ src, vecS shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
- match(Set dst (LShiftVL src shift));
- format %{ "vpsllq $dst,$src,$shift\t! left shift packed8L" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsll8L_reg_imm(vecZ dst, vecZ src, immI8 shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
- match(Set dst (LShiftVL src shift));
- format %{ "vpsllq $dst,$src,$shift\t! left shift packed8L" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-// ----------------------- LogicalRightShift -----------------------------------
+ __ vextracti64x4($tmp1$$XMMRegister, $src$$XMMRegister, 1);
+ __ vextendbw(opcode, $tmp1$$XMMRegister, $tmp1$$XMMRegister, vector_len);
+ __ vextendbw(opcode, $tmp2$$XMMRegister, $src$$XMMRegister, vector_len);
+ __ vshiftw(opcode, $tmp1$$XMMRegister, $tmp1$$XMMRegister, $shift$$XMMRegister, vector_len);
+ __ vshiftw(opcode, $tmp2$$XMMRegister, $tmp2$$XMMRegister, $shift$$XMMRegister, vector_len);
+ __ vmovdqu($dst$$XMMRegister, ExternalAddress(vector_short_to_byte_mask()), $scratch$$Register);
+ __ vpbroadcastd($dst$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpand($tmp1$$XMMRegister, $tmp1$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpand($tmp2$$XMMRegister, $tmp2$$XMMRegister, $dst$$XMMRegister, vector_len);
+ __ vpackuswb($dst$$XMMRegister, $tmp1$$XMMRegister, $tmp2$$XMMRegister, vector_len);
+ __ evmovdquq($tmp2$$XMMRegister, ExternalAddress(vector_byte_perm_mask()), vector_len, $scratch$$Register);
+ __ vpermq($dst$$XMMRegister, $tmp2$$XMMRegister, $dst$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
// Shorts vector logical right shift produces incorrect Java result
// for negative data because java code convert short value into int with
// sign extension before a shift. But char vectors are fine since chars are
// unsigned values.
-
-instruct vsrl2S(vecS dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVS dst shift));
- format %{ "psrlw $dst,$shift\t! logical right shift packed2S" %}
- ins_encode %{
- __ psrlw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2S_imm(vecS dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVS dst shift));
- format %{ "psrlw $dst,$shift\t! logical right shift packed2S" %}
- ins_encode %{
- __ psrlw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2S_reg(vecS dst, vecS src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+// Shorts/Chars vector left shift
+instruct vshist2S(vecS dst, vecS src, vecS shift) %{
+ predicate(n->as_Vector()->length() == 2);
+ match(Set dst (LShiftVS src shift));
+ match(Set dst (RShiftVS src shift));
match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed2S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2S_reg_imm(vecS dst, vecS src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed2S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4S(vecD dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (URShiftVS dst shift));
- format %{ "psrlw $dst,$shift\t! logical right shift packed4S" %}
- ins_encode %{
- __ psrlw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4S_imm(vecD dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (URShiftVS dst shift));
- format %{ "psrlw $dst,$shift\t! logical right shift packed4S" %}
- ins_encode %{
- __ psrlw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4S_reg(vecD dst, vecD src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+ format %{ "vshiftw $dst,$src,$shift\t! shift packed2S" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ if (UseAVX == 0) {
+ if ($dst$$XMMRegister != $src$$XMMRegister)
+ __ movflt($dst$$XMMRegister, $src$$XMMRegister);
+ __ vshiftw(opcode, $dst$$XMMRegister, $shift$$XMMRegister);
+ } else {
+ int vector_len = 0;
+ __ vshiftw(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift4S(vecD dst, vecD src, vecS shift) %{
+ predicate(n->as_Vector()->length() == 4);
+ match(Set dst (LShiftVS src shift));
+ match(Set dst (RShiftVS src shift));
match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed4S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4S_reg_imm(vecD dst, vecD src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+ format %{ "vshiftw $dst,$src,$shift\t! shift packed4S" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ if (UseAVX == 0) {
+ if ($dst$$XMMRegister != $src$$XMMRegister)
+ __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
+ __ vshiftw(opcode, $dst$$XMMRegister, $shift$$XMMRegister);
+
+ } else {
+ int vector_len = 0;
+ __ vshiftw(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift8S(vecX dst, vecX src, vecS shift) %{
+ predicate(n->as_Vector()->length() == 8);
+ match(Set dst (LShiftVS src shift));
+ match(Set dst (RShiftVS src shift));
match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed4S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl8S(vecX dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 8);
- match(Set dst (URShiftVS dst shift));
- format %{ "psrlw $dst,$shift\t! logical right shift packed8S" %}
- ins_encode %{
- __ psrlw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl8S_imm(vecX dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 8);
- match(Set dst (URShiftVS dst shift));
- format %{ "psrlw $dst,$shift\t! logical right shift packed8S" %}
- ins_encode %{
- __ psrlw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl8S_reg(vecX dst, vecX src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+ format %{ "vshiftw $dst,$src,$shift\t! shift packed8S" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ if (UseAVX == 0) {
+ if ($dst$$XMMRegister != $src$$XMMRegister)
+ __ movdqu($dst$$XMMRegister, $src$$XMMRegister);
+ __ vshiftw(opcode, $dst$$XMMRegister, $shift$$XMMRegister);
+ } else {
+ int vector_len = 0;
+ __ vshiftw(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift16S(vecY dst, vecY src, vecS shift) %{
+ predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+ match(Set dst (LShiftVS src shift));
+ match(Set dst (RShiftVS src shift));
match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed8S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl8S_reg_imm(vecX dst, vecX src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
- match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed8S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl16S_reg(vecY dst, vecY src, vecS shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
- match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed16S" %}
+ format %{ "vshiftw $dst,$src,$shift\t! shift packed16S" %}
ins_encode %{
int vector_len = 1;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl16S_reg_imm(vecY dst, vecY src, immI8 shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+ int opcode = this->as_Mach()->ideal_Opcode();
+ __ vshiftw(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift32S(vecZ dst, vecZ src, vecS shift) %{
+ predicate(UseAVX > 2 && VM_Version::supports_avx512bw() && n->as_Vector()->length() == 32);
+ match(Set dst (LShiftVS src shift));
+ match(Set dst (RShiftVS src shift));
match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed16S" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl32S_reg(vecZ dst, vecZ src, vecS shift) %{
- predicate(UseAVX > 2 && VM_Version::supports_avx512bw() && n->as_Vector()->length() == 32);
- match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed32S" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl32S_reg_imm(vecZ dst, vecZ src, immI8 shift) %{
- predicate(UseAVX > 2 && VM_Version::supports_avx512bw() && n->as_Vector()->length() == 32);
- match(Set dst (URShiftVS src shift));
- format %{ "vpsrlw $dst,$src,$shift\t! logical right shift packed32S" %}
+ format %{ "vshiftw $dst,$src,$shift\t! shift packed32S" %}
ins_encode %{
int vector_len = 2;
- __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-// Integers vector logical right shift
-instruct vsrl2I(vecD dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVI dst shift));
- format %{ "psrld $dst,$shift\t! logical right shift packed2I" %}
- ins_encode %{
- __ psrld($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2I_imm(vecD dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVI dst shift));
- format %{ "psrld $dst,$shift\t! logical right shift packed2I" %}
- ins_encode %{
- __ psrld($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2I_reg(vecD dst, vecD src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVI src shift));
- format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed2I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+ int opcode = this->as_Mach()->ideal_Opcode();
+ __ vshiftw(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// Integers vector left shift
+instruct vshift2I(vecD dst, vecD src, vecS shift) %{
+ predicate(n->as_Vector()->length() == 2);
+ match(Set dst (LShiftVI src shift));
+ match(Set dst (RShiftVI src shift));
match(Set dst (URShiftVI src shift));
- format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed2I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4I(vecX dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (URShiftVI dst shift));
- format %{ "psrld $dst,$shift\t! logical right shift packed4I" %}
- ins_encode %{
- __ psrld($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4I_imm(vecX dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (URShiftVI dst shift));
- format %{ "psrld $dst,$shift\t! logical right shift packed4I" %}
- ins_encode %{
- __ psrld($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4I_reg(vecX dst, vecX src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+ format %{ "vshiftd $dst,$src,$shift\t! shift packed2I" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ if (UseAVX == 0) {
+ if ($dst$$XMMRegister != $src$$XMMRegister)
+ __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
+ __ vshiftd(opcode, $dst$$XMMRegister, $shift$$XMMRegister);
+ } else {
+ int vector_len = 0;
+ __ vshiftd(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift4I(vecX dst, vecX src, vecS shift) %{
+ predicate(n->as_Vector()->length() == 4);
+ match(Set dst (LShiftVI src shift));
+ match(Set dst (RShiftVI src shift));
match(Set dst (URShiftVI src shift));
- format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed4I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+ format %{ "vshiftd $dst,$src,$shift\t! shift packed4I" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ if (UseAVX == 0) {
+ if ($dst$$XMMRegister != $src$$XMMRegister)
+ __ movdqu($dst$$XMMRegister, $src$$XMMRegister);
+ __ vshiftd(opcode, $dst$$XMMRegister, $shift$$XMMRegister);
+ } else {
+ int vector_len = 0;
+ __ vshiftd(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift8I(vecY dst, vecY src, vecS shift) %{
+ predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+ match(Set dst (LShiftVI src shift));
+ match(Set dst (RShiftVI src shift));
match(Set dst (URShiftVI src shift));
- format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed4I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl8I_reg(vecY dst, vecY src, vecS shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
- match(Set dst (URShiftVI src shift));
- format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed8I" %}
+ format %{ "vshiftd $dst,$src,$shift\t! shift packed8I" %}
ins_encode %{
int vector_len = 1;
- __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl8I_reg_imm(vecY dst, vecY src, immI8 shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+ int opcode = this->as_Mach()->ideal_Opcode();
+ __ vshiftd(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift16I(vecZ dst, vecZ src, vecS shift) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
+ match(Set dst (LShiftVI src shift));
+ match(Set dst (RShiftVI src shift));
match(Set dst (URShiftVI src shift));
- format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed8I" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl16I_reg(vecZ dst, vecZ src, vecS shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
- match(Set dst (URShiftVI src shift));
- format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed16I" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl16I_reg_imm(vecZ dst, vecZ src, immI8 shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
- match(Set dst (URShiftVI src shift));
- format %{ "vpsrld $dst,$src,$shift\t! logical right shift packed16I" %}
+ format %{ "vshiftd $dst,$src,$shift\t! shift packed16I" %}
ins_encode %{
int vector_len = 2;
- __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-// Longs vector logical right shift
-instruct vsrl2L(vecX dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVL dst shift));
- format %{ "psrlq $dst,$shift\t! logical right shift packed2L" %}
- ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ __ vshiftd(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// Longs vector shift
+instruct vshift2L(vecX dst, vecX src, vecS shift) %{
+ predicate(n->as_Vector()->length() == 2);
+ match(Set dst (LShiftVL src shift));
+ match(Set dst (URShiftVL src shift));
+ format %{ "vshiftq $dst,$src,$shift\t! shift packed2L" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ if (UseAVX == 0) {
+ if ($dst$$XMMRegister != $src$$XMMRegister)
+ __ movdqu($dst$$XMMRegister, $src$$XMMRegister);
+ __ vshiftq(opcode, $dst$$XMMRegister, $shift$$XMMRegister);
+ } else {
+ int vector_len = 0;
+ __ vshiftq(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ }
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift4L(vecY dst, vecY src, vecS shift) %{
+ predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+ match(Set dst (LShiftVL src shift));
+ match(Set dst (URShiftVL src shift));
+ format %{ "vshiftq $dst,$src,$shift\t! left shift packed4L" %}
+ ins_encode %{
+ int vector_len = 1;
+ int opcode = this->as_Mach()->ideal_Opcode();
+ __ vshiftq(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vshift8L(vecZ dst, vecZ src, vecS shift) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
+ match(Set dst (LShiftVL src shift));
+ match(Set dst (RShiftVL src shift));
+ match(Set dst (URShiftVL src shift));
+ format %{ "vshiftq $dst,$src,$shift\t! shift packed8L" %}
+ ins_encode %{
+ int vector_len = 2;
+ int opcode = this->as_Mach()->ideal_Opcode();
+ __ vshiftq(opcode, $dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// -------------------ArithmeticRightShift -----------------------------------
+// Long vector arithmetic right shift
+instruct vsra2L_reg(vecX dst, vecX src, vecS shift, vecX tmp, rRegI scratch) %{
+ predicate(UseSSE >= 2 && n->as_Vector()->length() == 2);
+ match(Set dst (RShiftVL src shift));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{ "movdqu $dst,$src\n\t"
+ "psrlq $dst,$shift\n\t"
+ "movdqu $tmp,[0x8000000000000000]\n\t"
+ "psrlq $tmp,$shift\n\t"
+ "pxor $dst,$tmp\n\t"
+ "psubq $dst,$tmp\t! arithmetic right shift packed2L" %}
+ ins_encode %{
+ __ movdqu($dst$$XMMRegister, $src$$XMMRegister);
__ psrlq($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2L_imm(vecX dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVL dst shift));
- format %{ "psrlq $dst,$shift\t! logical right shift packed2L" %}
- ins_encode %{
- __ psrlq($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2L_reg(vecX dst, vecX src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVL src shift));
- format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed2L" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl2L_reg_imm(vecX dst, vecX src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (URShiftVL src shift));
- format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed2L" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4L_reg(vecY dst, vecY src, vecS shift) %{
+ __ movdqu($tmp$$XMMRegister, ExternalAddress(vector_long_sign_mask()), $scratch$$Register);
+ __ psrlq($tmp$$XMMRegister, $shift$$XMMRegister);
+ __ pxor($dst$$XMMRegister, $tmp$$XMMRegister);
+ __ psubq($dst$$XMMRegister, $tmp$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vsra2L_reg_evex(vecX dst, vecX src, vecS shift) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 2);
+ match(Set dst (RShiftVL src shift));
+ format %{ "evpsraq $dst,$src,$shift\t! arithmetic right shift packed2L" %}
+ ins_encode %{
+ int vector_len = 0;
+ __ evpsraq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vsra4L_reg(vecY dst, vecY src, vecS shift, vecY tmp, rRegI scratch) %{
predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
- match(Set dst (URShiftVL src shift));
- format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed4L" %}
+ match(Set dst (RShiftVL src shift));
+ effect(TEMP dst, TEMP tmp, TEMP scratch);
+ format %{ "vpsrlq $dst,$src,$shift\n\t"
+ "vmovdqu $tmp,[0x8000000000000000]\n\t"
+ "vpsrlq $tmp,$tmp,$shift\n\t"
+ "vpxor $dst,$dst,$tmp\n\t"
+ "vpsubq $dst,$dst,$tmp\t! arithmetic right shift packed4L" %}
ins_encode %{
int vector_len = 1;
__ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl4L_reg_imm(vecY dst, vecY src, immI8 shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
- match(Set dst (URShiftVL src shift));
- format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed4L" %}
+ __ vmovdqu($tmp$$XMMRegister, ExternalAddress(vector_long_sign_mask()), $scratch$$Register);
+ __ vpsrlq($tmp$$XMMRegister, $tmp$$XMMRegister, $shift$$XMMRegister, vector_len);
+ __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $tmp$$XMMRegister, vector_len);
+ __ vpsubq($dst$$XMMRegister, $dst$$XMMRegister, $tmp$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vsra4L_reg_evex(vecY dst, vecY src, vecS shift) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 4);
+ match(Set dst (RShiftVL src shift));
+ format %{ "evpsraq $dst,$src,$shift\t! arithmetic right shift packed4L" %}
ins_encode %{
int vector_len = 1;
- __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl8L_reg(vecZ dst, vecZ src, vecS shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
- match(Set dst (URShiftVL src shift));
- format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed8L" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsrl8L_reg_imm(vecZ dst, vecZ src, immI8 shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
- match(Set dst (URShiftVL src shift));
- format %{ "vpsrlq $dst,$src,$shift\t! logical right shift packed8L" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-// ------------------- ArithmeticRightShift -----------------------------------
-
-// Shorts/Chars vector arithmetic right shift
-instruct vsra2S(vecS dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (RShiftVS dst shift));
- format %{ "psraw $dst,$shift\t! arithmetic right shift packed2S" %}
- ins_encode %{
- __ psraw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra2S_imm(vecS dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (RShiftVS dst shift));
- format %{ "psraw $dst,$shift\t! arithmetic right shift packed2S" %}
- ins_encode %{
- __ psraw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra2S_reg(vecS dst, vecS src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed2S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra2S_reg_imm(vecS dst, vecS src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed2S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra4S(vecD dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (RShiftVS dst shift));
- format %{ "psraw $dst,$shift\t! arithmetic right shift packed4S" %}
- ins_encode %{
- __ psraw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra4S_imm(vecD dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (RShiftVS dst shift));
- format %{ "psraw $dst,$shift\t! arithmetic right shift packed4S" %}
- ins_encode %{
- __ psraw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra4S_reg(vecD dst, vecD src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed4S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra4S_reg_imm(vecD dst, vecD src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed4S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra8S(vecX dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 8);
- match(Set dst (RShiftVS dst shift));
- format %{ "psraw $dst,$shift\t! arithmetic right shift packed8S" %}
- ins_encode %{
- __ psraw($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra8S_imm(vecX dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 8);
- match(Set dst (RShiftVS dst shift));
- format %{ "psraw $dst,$shift\t! arithmetic right shift packed8S" %}
- ins_encode %{
- __ psraw($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra8S_reg(vecX dst, vecX src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed8S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra8S_reg_imm(vecX dst, vecX src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed8S" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra16S_reg(vecY dst, vecY src, vecS shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed16S" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra16S_reg_imm(vecY dst, vecY src, immI8 shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed16S" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra32S_reg(vecZ dst, vecZ src, vecS shift) %{
- predicate(UseAVX > 2 && VM_Version::supports_avx512bw() && n->as_Vector()->length() == 32);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed32S" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra32S_reg_imm(vecZ dst, vecZ src, immI8 shift) %{
- predicate(UseAVX > 2 && VM_Version::supports_avx512bw() && n->as_Vector()->length() == 32);
- match(Set dst (RShiftVS src shift));
- format %{ "vpsraw $dst,$src,$shift\t! arithmetic right shift packed32S" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-// Integers vector arithmetic right shift
-instruct vsra2I(vecD dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (RShiftVI dst shift));
- format %{ "psrad $dst,$shift\t! arithmetic right shift packed2I" %}
- ins_encode %{
- __ psrad($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra2I_imm(vecD dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 2);
- match(Set dst (RShiftVI dst shift));
- format %{ "psrad $dst,$shift\t! arithmetic right shift packed2I" %}
- ins_encode %{
- __ psrad($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra2I_reg(vecD dst, vecD src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (RShiftVI src shift));
- format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed2I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
- match(Set dst (RShiftVI src shift));
- format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed2I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra4I(vecX dst, vecS shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (RShiftVI dst shift));
- format %{ "psrad $dst,$shift\t! arithmetic right shift packed4I" %}
- ins_encode %{
- __ psrad($dst$$XMMRegister, $shift$$XMMRegister);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra4I_imm(vecX dst, immI8 shift) %{
- predicate(UseAVX == 0 && n->as_Vector()->length() == 4);
- match(Set dst (RShiftVI dst shift));
- format %{ "psrad $dst,$shift\t! arithmetic right shift packed4I" %}
- ins_encode %{
- __ psrad($dst$$XMMRegister, (int)$shift$$constant);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra4I_reg(vecX dst, vecX src, vecS shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
- match(Set dst (RShiftVI src shift));
- format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed4I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
- predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
- match(Set dst (RShiftVI src shift));
- format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed4I" %}
- ins_encode %{
- int vector_len = 0;
- __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra8I_reg(vecY dst, vecY src, vecS shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
- match(Set dst (RShiftVI src shift));
- format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed8I" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra8I_reg_imm(vecY dst, vecY src, immI8 shift) %{
- predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
- match(Set dst (RShiftVI src shift));
- format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed8I" %}
- ins_encode %{
- int vector_len = 1;
- __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra16I_reg(vecZ dst, vecZ src, vecS shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
- match(Set dst (RShiftVI src shift));
- format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed16I" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-instruct vsra16I_reg_imm(vecZ dst, vecZ src, immI8 shift) %{
- predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
- match(Set dst (RShiftVI src shift));
- format %{ "vpsrad $dst,$src,$shift\t! arithmetic right shift packed16I" %}
- ins_encode %{
- int vector_len = 2;
- __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector_len);
- %}
- ins_pipe( pipe_slow );
-%}
-
-// There are no longs vector arithmetic right shift instructions.
-
+ __ evpsraq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
// --------------------------------- AND --------------------------------------
@@ -9708,6 +9297,291 @@
ins_pipe( pipe_slow );
%}
+// --------------------------------- ABS --------------------------------------
+// a = |a|
+instruct vabs4B_reg(vecS dst, vecS src) %{
+ predicate(UseSSE > 2 && n->as_Vector()->length() == 4);
+ match(Set dst (AbsVB src));
+ format %{ "pabsb $dst,$src\t# $dst = |$src| abs packed4B" %}
+ ins_encode %{
+ __ pabsb($dst$$XMMRegister, $src$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs8B_reg(vecD dst, vecD src) %{
+ predicate(UseSSE > 2 && n->as_Vector()->length() == 8);
+ match(Set dst (AbsVB src));
+ format %{ "pabsb $dst,$src\t# $dst = |$src| abs packed8B" %}
+ ins_encode %{
+ __ pabsb($dst$$XMMRegister, $src$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs16B_reg(vecX dst, vecX src) %{
+ predicate(UseSSE > 2 && n->as_Vector()->length() == 16);
+ match(Set dst (AbsVB src));
+ format %{ "pabsb $dst,$src\t# $dst = |$src| abs packed16B" %}
+ ins_encode %{
+ __ pabsb($dst$$XMMRegister, $src$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs32B_reg(vecY dst, vecY src) %{
+ predicate(UseAVX > 1 && n->as_Vector()->length() == 32);
+ match(Set dst (AbsVB src));
+ format %{ "vpabsb $dst,$src\t# $dst = |$src| abs packed32B" %}
+ ins_encode %{
+ int vector_len = 1;
+ __ vpabsb($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs64B_reg(vecZ dst, vecZ src) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 64);
+ match(Set dst (AbsVB src));
+ format %{ "vpabsb $dst,$src\t# $dst = |$src| abs packed64B" %}
+ ins_encode %{
+ int vector_len = 2;
+ __ vpabsb($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs2S_reg(vecD dst, vecD src) %{
+ predicate(UseSSE > 2 && n->as_Vector()->length() == 2);
+ match(Set dst (AbsVS src));
+ format %{ "pabsw $dst,$src\t# $dst = |$src| abs packed2S" %}
+ ins_encode %{
+ __ pabsw($dst$$XMMRegister, $src$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs4S_reg(vecD dst, vecD src) %{
+ predicate(UseSSE > 2 && n->as_Vector()->length() == 4);
+ match(Set dst (AbsVS src));
+ format %{ "pabsw $dst,$src\t# $dst = |$src| abs packed4S" %}
+ ins_encode %{
+ __ pabsw($dst$$XMMRegister, $src$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs8S_reg(vecX dst, vecX src) %{
+ predicate(UseSSE > 2 && n->as_Vector()->length() == 8);
+ match(Set dst (AbsVS src));
+ format %{ "pabsw $dst,$src\t# $dst = |$src| abs packed8S" %}
+ ins_encode %{
+ __ pabsw($dst$$XMMRegister, $src$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs16S_reg(vecY dst, vecY src) %{
+ predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+ match(Set dst (AbsVS src));
+ format %{ "vpabsw $dst,$src\t# $dst = |$src| abs packed16S" %}
+ ins_encode %{
+ int vector_len = 1;
+ __ vpabsw($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs32S_reg(vecZ dst, vecZ src) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 32);
+ match(Set dst (AbsVS src));
+ format %{ "vpabsw $dst,$src\t# $dst = |$src| abs packed32S" %}
+ ins_encode %{
+ int vector_len = 2;
+ __ vpabsw($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs2I_reg(vecD dst, vecD src) %{
+ predicate(UseSSE > 2 && n->as_Vector()->length() == 2);
+ match(Set dst (AbsVI src));
+ format %{ "pabsd $dst,$src\t# $dst = |$src| abs packed2I" %}
+ ins_encode %{
+ __ pabsd($dst$$XMMRegister, $src$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs4I_reg(vecX dst, vecX src) %{
+ predicate(UseSSE > 2 && n->as_Vector()->length() == 4);
+ match(Set dst (AbsVI src));
+ format %{ "pabsd $dst,$src\t# $dst = |$src| abs packed4I" %}
+ ins_encode %{
+ __ pabsd($dst$$XMMRegister, $src$$XMMRegister);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs8I_reg(vecY dst, vecY src) %{
+ predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+ match(Set dst (AbsVI src));
+ format %{ "vpabsd $dst,$src\t# $dst = |$src| abs packed8I" %}
+ ins_encode %{
+ int vector_len = 1;
+ __ vpabsd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs16I_reg(vecZ dst, vecZ src) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
+ match(Set dst (AbsVI src));
+ format %{ "vpabsd $dst,$src\t# $dst = |$src| abs packed16I" %}
+ ins_encode %{
+ int vector_len = 2;
+ __ vpabsd($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs2L_reg(vecX dst, vecX src) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 2);
+ match(Set dst (AbsVL src));
+ format %{ "evpabsq $dst,$src\t# $dst = |$src| abs packed2L" %}
+ ins_encode %{
+ int vector_len = 0;
+ __ evpabsq($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs4L_reg(vecY dst, vecY src) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 4);
+ match(Set dst (AbsVL src));
+ format %{ "evpabsq $dst,$src\t# $dst = |$src| abs packed4L" %}
+ ins_encode %{
+ int vector_len = 1;
+ __ evpabsq($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabs8L_reg(vecZ dst, vecZ src) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
+ match(Set dst (AbsVL src));
+ format %{ "evpabsq $dst,$src\t# $dst = |$src| abs packed8L" %}
+ ins_encode %{
+ int vector_len = 2;
+ __ evpabsq($dst$$XMMRegister, $src$$XMMRegister, vector_len);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+// --------------------------------- ABSNEG --------------------------------------
+
+instruct vabsneg2D(vecX dst, vecX src, rRegI scratch) %{
+ predicate(UseSSE >= 2 && n->as_Vector()->length() == 2);
+ match(Set dst (AbsVD src));
+ match(Set dst (NegVD src));
+ effect(TEMP scratch);
+ format %{ "vabsnegd $dst,$src,[mask]\t# absneg packed2D" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ if ($dst$$XMMRegister != $src$$XMMRegister)
+ __ movdqu($dst$$XMMRegister, $src$$XMMRegister);
+ __ vabsnegd(opcode, $dst$$XMMRegister, $scratch$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabsneg4D(vecY dst, vecY src, rRegI scratch) %{
+ predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+ match(Set dst (AbsVD src));
+ match(Set dst (NegVD src));
+ effect(TEMP scratch);
+ format %{ "vabsnegd $dst,$src,[mask]\t# absneg packed4D" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ int vector_len = 1;
+ __ vabsnegd(opcode, $dst$$XMMRegister, $src$$XMMRegister, vector_len, $scratch$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabsneg8D(vecZ dst, vecZ src, rRegI scratch) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 8);
+ match(Set dst (AbsVD src));
+ match(Set dst (NegVD src));
+ effect(TEMP scratch);
+ format %{ "vabsnegd $dst,$src,[mask]\t# absneg packed8D" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ int vector_len = 2;
+ __ vabsnegd(opcode, $dst$$XMMRegister, $src$$XMMRegister, vector_len, $scratch$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabsneg2F(vecD dst, vecD src, rRegI scratch) %{
+ predicate(UseSSE > 0 && n->as_Vector()->length() == 2);
+ match(Set dst (AbsVF src));
+ match(Set dst (NegVF src));
+ effect(TEMP scratch);
+ format %{ "vabsnegf $dst,$src,[mask]\t# absneg packed2F" %}
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ if ($dst$$XMMRegister != $src$$XMMRegister)
+ __ movdqu($dst$$XMMRegister, $src$$XMMRegister);
+ __ vabsnegf(opcode, $dst$$XMMRegister, $scratch$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabsneg4F(vecX dst, rRegI scratch) %{
+ predicate(UseSSE > 0 && n->as_Vector()->length() == 4);
+ match(Set dst (AbsVF dst));
+ match(Set dst (NegVF dst));
+ effect(TEMP scratch);
+ format %{ "vabsnegf $dst,[mask]\t# absneg packed4F" %}
+ ins_cost(150);
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ __ vabsnegf(opcode, $dst$$XMMRegister, $scratch$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabsneg8F(vecY dst, vecY src, rRegI scratch) %{
+ predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+ match(Set dst (AbsVF src));
+ match(Set dst (NegVF src));
+ effect(TEMP scratch);
+ format %{ "vabsnegf $dst,$src,[mask]\t# absneg packed8F" %}
+ ins_cost(150);
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ int vector_len = 1;
+ __ vabsnegf(opcode, $dst$$XMMRegister, $src$$XMMRegister, vector_len, $scratch$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+instruct vabsneg16F(vecZ dst, vecZ src, rRegI scratch) %{
+ predicate(UseAVX > 2 && n->as_Vector()->length() == 16);
+ match(Set dst (AbsVF src));
+ match(Set dst (NegVF src));
+ effect(TEMP scratch);
+ format %{ "vabsnegf $dst,$src,[mask]\t# absneg packed16F" %}
+ ins_cost(150);
+ ins_encode %{
+ int opcode = this->as_Mach()->ideal_Opcode();
+ int vector_len = 2;
+ __ vabsnegf(opcode, $dst$$XMMRegister, $src$$XMMRegister, vector_len, $scratch$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
// --------------------------------- FMA --------------------------------------
// a * b + c
--- a/src/hotspot/cpu/x86/x86_32.ad Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/x86_32.ad Tue May 07 17:30:14 2019 -0400
@@ -8949,6 +8949,28 @@
ins_pipe(ialu_reg_reg_alu0);
%}
+// Integer Absolute Instructions
+instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, eFlagsReg cr)
+%{
+ match(Set dst (AbsI src));
+ effect(TEMP dst, TEMP tmp, KILL cr);
+ format %{ "movl $tmp, $src\n\t"
+ "sarl $tmp, 31\n\t"
+ "movl $dst, $src\n\t"
+ "xorl $dst, $tmp\n\t"
+ "subl $dst, $tmp\n"
+ %}
+ ins_encode %{
+ __ movl($tmp$$Register, $src$$Register);
+ __ sarl($tmp$$Register, 31);
+ __ movl($dst$$Register, $src$$Register);
+ __ xorl($dst$$Register, $tmp$$Register);
+ __ subl($dst$$Register, $tmp$$Register);
+ %}
+
+ ins_pipe(ialu_reg_reg);
+%}
+
//----------Long Instructions------------------------------------------------
// Add Long Register with Register
instruct addL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
--- a/src/hotspot/cpu/x86/x86_64.ad Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/cpu/x86/x86_64.ad Tue May 07 17:30:14 2019 -0400
@@ -8181,6 +8181,52 @@
ins_pipe( pipe_cmpxchg );
%}
+//----------Abs Instructions-------------------------------------------
+
+// Integer Absolute Instructions
+instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr)
+%{
+ match(Set dst (AbsI src));
+ effect(TEMP dst, TEMP tmp, KILL cr);
+ format %{ "movl $tmp, $src\n\t"
+ "sarl $tmp, 31\n\t"
+ "movl $dst, $src\n\t"
+ "xorl $dst, $tmp\n\t"
+ "subl $dst, $tmp\n"
+ %}
+ ins_encode %{
+ __ movl($tmp$$Register, $src$$Register);
+ __ sarl($tmp$$Register, 31);
+ __ movl($dst$$Register, $src$$Register);
+ __ xorl($dst$$Register, $tmp$$Register);
+ __ subl($dst$$Register, $tmp$$Register);
+ %}
+
+ ins_pipe(ialu_reg_reg);
+%}
+
+// Long Absolute Instructions
+instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr)
+%{
+ match(Set dst (AbsL src));
+ effect(TEMP dst, TEMP tmp, KILL cr);
+ format %{ "movq $tmp, $src\n\t"
+ "sarq $tmp, 63\n\t"
+ "movq $dst, $src\n\t"
+ "xorq $dst, $tmp\n\t"
+ "subq $dst, $tmp\n"
+ %}
+ ins_encode %{
+ __ movq($tmp$$Register, $src$$Register);
+ __ sarq($tmp$$Register, 63);
+ __ movq($dst$$Register, $src$$Register);
+ __ xorq($dst$$Register, $tmp$$Register);
+ __ subq($dst$$Register, $tmp$$Register);
+ %}
+
+ ins_pipe(ialu_reg_reg);
+%}
+
//----------Subtraction Instructions-------------------------------------------
// Integer Subtraction Instructions
--- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -302,7 +302,6 @@
address stub = NULL;
address pc = NULL;
- //%note os_trap_1
if (info != NULL && uc != NULL && thread != NULL) {
pc = (address) os::Linux::ucontext_get_pc(uc);
@@ -311,17 +310,17 @@
// si_addr may not be valid due to a bug in the linux-ppc64 kernel (see
// comment below). Use get_stack_bang_address instead of si_addr.
// If SIGSEGV is caused due to a branch to an invalid address an
- // "Instruction Storage" interruption is generated and 'pc' (NIP) already
+ // "Instruction Storage Interrupt" is generated and 'pc' (NIP) already
// contains the invalid address. Otherwise, the SIGSEGV is caused due to
// load/store instruction trying to load/store from/to an invalid address
- // and causing a "Data Storage" interruption, so we inspect the intruction
+ // and causing a "Data Storage Interrupt", so we inspect the intruction
// in order to extract the faulty data addresss.
address addr;
if ((ucontext_get_trap(uc) & 0x0F00 /* no IRQ reply bits */) == 0x0400) {
- // Instruction interruption
+ // Instruction Storage Interrupt (ISI)
addr = pc;
} else {
- // Data interruption (0x0300): extract faulty data address
+ // Data Storage Interrupt (DSI), i.e. 0x0300: extract faulty data address
addr = ((NativeInstruction*)pc)->get_stack_bang_address(uc);
}
--- a/src/hotspot/share/adlc/formssel.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/adlc/formssel.cpp Tue May 07 17:30:14 2019 -0400
@@ -3808,7 +3808,7 @@
"MaxI","MinI","MaxF","MinF","MaxD","MinD",
"MaxV", "MinV",
"MulI","MulL","MulF","MulD",
- "MulVS","MulVI","MulVL","MulVF","MulVD",
+ "MulVB","MulVS","MulVI","MulVL","MulVF","MulVD",
"OrI","OrL",
"OrV",
"XorI","XorL",
@@ -4175,10 +4175,10 @@
static const char *vector_list[] = {
"AddVB","AddVS","AddVI","AddVL","AddVF","AddVD",
"SubVB","SubVS","SubVI","SubVL","SubVF","SubVD",
- "MulVS","MulVI","MulVL","MulVF","MulVD",
+ "MulVB","MulVS","MulVI","MulVL","MulVF","MulVD",
"CMoveVD", "CMoveVF",
"DivVF","DivVD",
- "AbsVF","AbsVD",
+ "AbsVB","AbsVS","AbsVI","AbsVL","AbsVF","AbsVD",
"NegVF","NegVD",
"SqrtVD","SqrtVF",
"AndV" ,"XorV" ,"OrV",
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp Tue May 07 17:30:14 2019 -0400
@@ -1988,8 +1988,9 @@
}
if (cha_monomorphic_target != NULL) {
+ assert(!target->can_be_statically_bound() || target == cha_monomorphic_target, "");
assert(!cha_monomorphic_target->is_abstract(), "");
- if (!target->is_final_method() && !target->is_private()) {
+ if (!cha_monomorphic_target->can_be_statically_bound(actual_recv)) {
// If we inlined because CHA revealed only a single target method,
// then we are dependent on that target method not getting overridden
// by dynamic class loading. Be sure to test the "static" receiver
--- a/src/hotspot/share/ci/ciMethod.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/ci/ciMethod.cpp Tue May 07 17:30:14 2019 -0400
@@ -765,6 +765,14 @@
}
// ------------------------------------------------------------------
+// ciMethod::can_be_statically_bound
+//
+// Tries to determine whether a method can be statically bound in some context.
+bool ciMethod::can_be_statically_bound(ciInstanceKlass* context) const {
+ return (holder() == context) && can_be_statically_bound();
+}
+
+// ------------------------------------------------------------------
// ciMethod::resolve_invoke
//
// Given a known receiver klass, find the target for the call.
--- a/src/hotspot/share/ci/ciMethod.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/ci/ciMethod.hpp Tue May 07 17:30:14 2019 -0400
@@ -352,6 +352,8 @@
bool is_unboxing_method() const;
bool is_object_initializer() const;
+ bool can_be_statically_bound(ciInstanceKlass* context) const;
+
// Replay data methods
void dump_name_as_ascii(outputStream* st);
void dump_replay_data(outputStream* st);
--- a/src/hotspot/share/classfile/vmSymbols.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/classfile/vmSymbols.cpp Tue May 07 17:30:14 2019 -0400
@@ -363,6 +363,9 @@
case vmIntrinsics::_isInstance:
case vmIntrinsics::_currentThread:
case vmIntrinsics::_dabs:
+ case vmIntrinsics::_fabs:
+ case vmIntrinsics::_iabs:
+ case vmIntrinsics::_labs:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
@@ -404,6 +407,9 @@
case vmIntrinsics::_longBitsToDouble:
case vmIntrinsics::_currentThread:
case vmIntrinsics::_dabs:
+ case vmIntrinsics::_fabs:
+ case vmIntrinsics::_iabs:
+ case vmIntrinsics::_labs:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
@@ -567,6 +573,9 @@
case vmIntrinsics::_doubleToRawLongBits:
case vmIntrinsics::_longBitsToDouble:
case vmIntrinsics::_dabs:
+ case vmIntrinsics::_fabs:
+ case vmIntrinsics::_iabs:
+ case vmIntrinsics::_labs:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dsin:
case vmIntrinsics::_dcos:
--- a/src/hotspot/share/classfile/vmSymbols.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/classfile/vmSymbols.hpp Tue May 07 17:30:14 2019 -0400
@@ -472,6 +472,7 @@
template(float_int_signature, "(F)I") \
template(double_long_signature, "(D)J") \
template(double_double_signature, "(D)D") \
+ template(float_float_signature, "(F)F") \
template(int_float_signature, "(I)F") \
template(long_int_signature, "(J)I") \
template(long_long_signature, "(J)J") \
@@ -771,6 +772,9 @@
do_name(fma_name, "fma") \
\
do_intrinsic(_dabs, java_lang_Math, abs_name, double_double_signature, F_S) \
+ do_intrinsic(_fabs, java_lang_Math, abs_name, float_float_signature, F_S) \
+ do_intrinsic(_iabs, java_lang_Math, abs_name, int_int_signature, F_S) \
+ do_intrinsic(_labs, java_lang_Math, abs_name, long_long_signature, F_S) \
do_intrinsic(_dsin, java_lang_Math, sin_name, double_double_signature, F_S) \
do_intrinsic(_dcos, java_lang_Math, cos_name, double_double_signature, F_S) \
do_intrinsic(_dtan, java_lang_Math, tan_name, double_double_signature, F_S) \
--- a/src/hotspot/share/code/dependencies.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/code/dependencies.cpp Tue May 07 17:30:14 2019 -0400
@@ -108,6 +108,7 @@
void Dependencies::assert_unique_concrete_method(ciKlass* ctxk, ciMethod* uniqm) {
check_ctxk(ctxk);
+ check_unique_method(ctxk, uniqm);
assert_common_2(unique_concrete_method, ctxk, uniqm);
}
@@ -180,6 +181,7 @@
void Dependencies::assert_unique_concrete_method(Klass* ctxk, Method* uniqm) {
check_ctxk(ctxk);
+ check_unique_method(ctxk, uniqm);
assert_common_2(unique_concrete_method, DepValue(_oop_recorder, ctxk), DepValue(_oop_recorder, uniqm));
}
--- a/src/hotspot/share/code/dependencies.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/code/dependencies.hpp Tue May 07 17:30:14 2019 -0400
@@ -27,6 +27,7 @@
#include "ci/ciCallSite.hpp"
#include "ci/ciKlass.hpp"
+#include "ci/ciMethod.hpp"
#include "ci/ciMethodHandle.hpp"
#include "classfile/systemDictionary.hpp"
#include "code/compressedStream.hpp"
@@ -341,6 +342,9 @@
check_ctxk(ctxk);
assert(!is_concrete_klass(ctxk->as_instance_klass()), "must be abstract");
}
+ static void check_unique_method(ciKlass* ctxk, ciMethod* m) {
+ assert(!m->can_be_statically_bound(ctxk->as_instance_klass()), "redundant");
+ }
void assert_common_1(DepType dept, ciBaseObject* x);
void assert_common_2(DepType dept, ciBaseObject* x0, ciBaseObject* x1);
@@ -368,6 +372,11 @@
check_ctxk(ctxk);
assert(ctxk->is_abstract(), "must be abstract");
}
+ static void check_unique_method(Klass* ctxk, Method* m) {
+ // Graal can register redundant dependencies
+ assert(UseJVMCICompiler || !m->can_be_statically_bound(InstanceKlass::cast(ctxk)), "redundant");
+ }
+
void assert_common_1(DepType dept, DepValue x);
void assert_common_2(DepType dept, DepValue x0, DepValue x1);
--- a/src/hotspot/share/compiler/compileBroker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/compiler/compileBroker.cpp Tue May 07 17:30:14 2019 -0400
@@ -70,7 +70,6 @@
#if INCLUDE_JVMCI
#include "jvmci/jvmciEnv.hpp"
#include "jvmci/jvmciRuntime.hpp"
-#include "runtime/vframe.hpp"
#endif
#ifdef COMPILER2
#include "opto/c2compiler.hpp"
@@ -1063,20 +1062,22 @@
}
#if INCLUDE_JVMCI
- if (UseJVMCICompiler && blocking && !UseJVMCINativeLibrary) {
+ if (UseJVMCICompiler && blocking) {
// Don't allow blocking compiles for requests triggered by JVMCI.
if (thread->is_Compiler_thread()) {
blocking = false;
}
- // Don't allow blocking compiles if inside a class initializer or while performing class loading
- vframeStream vfst((JavaThread*) thread);
- for (; !vfst.at_end(); vfst.next()) {
- if (vfst.method()->is_static_initializer() ||
- (vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) &&
- vfst.method()->name() == vmSymbols::loadClass_name())) {
- blocking = false;
- break;
+ if (!UseJVMCINativeLibrary) {
+ // Don't allow blocking compiles if inside a class initializer or while performing class loading
+ vframeStream vfst((JavaThread*) thread);
+ for (; !vfst.at_end(); vfst.next()) {
+ if (vfst.method()->is_static_initializer() ||
+ (vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) &&
+ vfst.method()->name() == vmSymbols::loadClass_name())) {
+ blocking = false;
+ break;
+ }
}
}
@@ -2063,7 +2064,7 @@
compilable = ciEnv::MethodCompilable_never;
} else {
JVMCICompileState compile_state(task, system_dictionary_modification_counter);
- JVMCIEnv env(&compile_state, __FILE__, __LINE__);
+ JVMCIEnv env(thread, &compile_state, __FILE__, __LINE__);
methodHandle method(thread, target_handle);
env.runtime()->compile_method(&env, jvmci, method, osr_bci);
--- a/src/hotspot/share/compiler/compileBroker.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/compiler/compileBroker.hpp Tue May 07 17:30:14 2019 -0400
@@ -229,7 +229,6 @@
static JavaThread* make_thread(jobject thread_oop, CompileQueue* queue, AbstractCompiler* comp, TRAPS);
static void init_compiler_sweeper_threads();
static void possibly_add_compiler_threads();
- 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, bool excluded);
static void preload_classes (const methodHandle& method, TRAPS);
@@ -285,6 +284,7 @@
return NULL;
}
+ static bool compilation_is_complete(const methodHandle& method, int osr_bci, int comp_level);
static bool compilation_is_in_queue(const methodHandle& method);
static void print_compile_queues(outputStream* st);
static void print_directives(outputStream* st);
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Tue May 07 17:30:14 2019 -0400
@@ -1036,7 +1036,7 @@
void G1CollectedHeap::verify_before_full_collection(bool explicit_gc) {
assert(!GCCause::is_user_requested_gc(gc_cause()) || explicit_gc, "invariant");
- assert(used() == recalculate_used(), "Should be equal");
+ assert_used_and_recalculate_used_equal(this);
_verifier->verify_region_sets_optional();
_verifier->verify_before_gc(G1HeapVerifier::G1VerifyFull);
_verifier->check_bitmaps("Full GC Start");
@@ -1092,7 +1092,7 @@
// the full GC has compacted objects and updated TAMS but not updated
// the prev bitmap.
if (G1VerifyBitmaps) {
- GCTraceTime(Debug, gc)("Clear Prev Bitmap for Verification");
+ GCTraceTime(Debug, gc) tm("Clear Prev Bitmap for Verification");
_cm->clear_prev_bitmap(workers());
}
// This call implicitly verifies that the next bitmap is clear after Full GC.
@@ -4539,9 +4539,7 @@
_archive_allocator->clear_used();
}
}
- assert(used() == recalculate_used(),
- "inconsistent used(), value: " SIZE_FORMAT " recalculated: " SIZE_FORMAT,
- used(), recalculate_used());
+ assert_used_and_recalculate_used_equal(this);
}
// Methods for the mutator alloc region
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Tue May 07 17:30:14 2019 -0400
@@ -354,6 +354,15 @@
assert(Thread::current()->is_VM_thread(), "current thread is not VM thread"); \
} while (0)
+#define assert_used_and_recalculate_used_equal(g1h) \
+ do { \
+ size_t cur_used_bytes = g1h->used(); \
+ size_t recal_used_bytes = g1h->recalculate_used(); \
+ assert(cur_used_bytes == recal_used_bytes, "Used(" SIZE_FORMAT ") is not" \
+ " same as recalculated used(" SIZE_FORMAT ").", \
+ cur_used_bytes, recal_used_bytes); \
+ } while (0)
+
const char* young_gc_name() const;
// The young region list.
--- a/src/hotspot/share/gc/g1/g1FullCollector.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1FullCollector.cpp Tue May 07 17:30:14 2019 -0400
@@ -289,6 +289,6 @@
// fail. At the end of the GC, the original mark word values
// (including hash values) are restored to the appropriate
// objects.
- GCTraceTime(Info, gc, verify)("Verifying During GC (full)");
+ GCTraceTime(Info, gc, verify) tm("Verifying During GC (full)");
_heap->verify(VerifyOption_G1UseFullMarking);
}
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp Tue May 07 17:30:14 2019 -0400
@@ -65,7 +65,6 @@
_gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms):");
_gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms):");
_gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms):");
- _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering (ms):");
_gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms):");
if (G1HotCardCache::default_use_cache()) {
@@ -406,7 +405,7 @@
trace_phase(_gc_par_phases[GCWorkerStart], false);
debug_phase(_gc_par_phases[ExtRootScan]);
- for (int i = ExtRootScanSubPhasesStart; i <= ExtRootScanSubPhasesEnd; i++) {
+ for (int i = ExtRootScanSubPhasesFirst; i <= ExtRootScanSubPhasesLast; i++) {
trace_phase(_gc_par_phases[i]);
}
if (G1HotCardCache::default_use_cache()) {
@@ -531,7 +530,6 @@
"CMRefRoots",
"WaitForStrongCLD",
"WeakCLDRoots",
- "SATBFiltering",
"UpdateRS",
"ScanHCC",
"ScanRS",
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp Tue May 07 17:30:14 2019 -0400
@@ -60,7 +60,6 @@
CMRefRoots,
WaitForStrongCLD,
WeakCLDRoots,
- SATBFiltering,
UpdateRS,
ScanHCC,
ScanRS,
@@ -82,8 +81,8 @@
GCParPhasesSentinel
};
- static const GCParPhases ExtRootScanSubPhasesStart = ThreadRoots;
- static const GCParPhases ExtRootScanSubPhasesEnd = SATBFiltering;
+ static const GCParPhases ExtRootScanSubPhasesFirst = ThreadRoots;
+ static const GCParPhases ExtRootScanSubPhasesLast = WeakCLDRoots;
enum GCScanRSWorkItems {
ScanRSScannedCards,
--- a/src/hotspot/share/gc/g1/g1Policy.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1Policy.cpp Tue May 07 17:30:14 2019 -0400
@@ -487,10 +487,7 @@
assert(max_survivor_regions() + _g1h->num_used_regions() <= _g1h->max_regions(),
"Maximum survivor regions %u plus used regions %u exceeds max regions %u",
max_survivor_regions(), _g1h->num_used_regions(), _g1h->max_regions());
-
- assert(_g1h->used() == _g1h->recalculate_used(),
- "sanity, used: " SIZE_FORMAT " recalculate_used: " SIZE_FORMAT,
- _g1h->used(), _g1h->recalculate_used());
+ assert_used_and_recalculate_used_equal(_g1h);
phase_times()->record_cur_collection_start_sec(start_time_sec);
_pending_cards = _g1h->pending_card_num();
@@ -581,8 +578,8 @@
void G1Policy::record_collection_pause_end(double pause_time_ms, size_t cards_scanned, size_t heap_used_bytes_before_gc) {
double end_time_sec = os::elapsedTime();
+ assert_used_and_recalculate_used_equal(_g1h);
size_t cur_used_bytes = _g1h->used();
- assert(cur_used_bytes == _g1h->recalculate_used(), "It should!");
bool this_pause_included_initial_mark = false;
bool this_pause_was_young_only = collector_state()->in_young_only_phase();
--- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.cpp Tue May 07 17:30:14 2019 -0400
@@ -122,16 +122,6 @@
assert(closures->second_pass_weak_clds() == NULL, "Should be null if not tracing metadata.");
}
- // During conc marking we have to filter the per-thread SATB buffers
- // to make sure we remove any oops into the CSet (which will show up
- // as implicitly live).
- {
- G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i);
- if (_process_strong_tasks.try_claim_task(G1RP_PS_filter_satb_buffers) && _g1h->collector_state()->mark_or_rebuild_in_progress()) {
- G1BarrierSet::satb_mark_queue_set().filter_thread_buffers();
- }
- }
-
_process_strong_tasks.all_tasks_completed(n_workers());
}
--- a/src/hotspot/share/gc/g1/g1RootProcessor.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.hpp Tue May 07 17:30:14 2019 -0400
@@ -65,7 +65,6 @@
G1RP_PS_CodeCache_oops_do,
AOT_ONLY(G1RP_PS_aot_oops_do COMMA)
JVMCI_ONLY(G1RP_PS_JVMCI_oops_do COMMA)
- G1RP_PS_filter_satb_buffers,
G1RP_PS_refProcessor_oops_do,
// Leave this one last.
G1RP_PS_NumElements
--- a/src/hotspot/share/gc/shared/satbMarkQueue.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.cpp Tue May 07 17:30:14 2019 -0400
@@ -189,18 +189,6 @@
Threads::threads_do(&closure);
}
-void SATBMarkQueueSet::filter_thread_buffers() {
- class FilterThreadBufferClosure : public ThreadClosure {
- SATBMarkQueueSet* _qset;
- public:
- FilterThreadBufferClosure(SATBMarkQueueSet* qset) : _qset(qset) {}
- virtual void do_thread(Thread* t) {
- _qset->satb_queue_for_thread(t).filter();
- }
- } closure(this);
- Threads::threads_do(&closure);
-}
-
bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl) {
BufferNode* nd = get_completed_buffer();
if (nd != NULL) {
--- a/src/hotspot/share/gc/shared/satbMarkQueue.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/shared/satbMarkQueue.hpp Tue May 07 17:30:14 2019 -0400
@@ -125,9 +125,6 @@
size_t buffer_enqueue_threshold() const { return _buffer_enqueue_threshold; }
virtual void filter(SATBMarkQueue* queue) = 0;
- // Filter all the currently-active SATB buffers.
- void filter_thread_buffers();
-
// If there exists some completed buffer, pop and process it, and
// return true. Otherwise return false. Processing a buffer
// consists of applying the closure to the active range of the
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Tue May 07 17:30:14 2019 -0400
@@ -1333,8 +1333,8 @@
}
}
}
- if (ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) {
- CallNode* call = ctrl->in(0)->as_CallJava();
+ if ((ctrl->is_Proj() && ctrl->in(0)->is_CallJava()) || ctrl->is_CallJava()) {
+ CallNode* call = ctrl->is_Proj() ? ctrl->in(0)->as_CallJava() : ctrl->as_CallJava();
CallProjections projs;
call->extract_projections(&projs, false, false);
@@ -1362,7 +1362,7 @@
if (idx < n->outcnt()) {
Node* u = n->raw_out(idx);
Node* c = phase->ctrl_or_self(u);
- if (c == ctrl) {
+ if (phase->is_dominator(call, c) && phase->is_dominator(c, projs.fallthrough_proj)) {
stack.set_index(idx+1);
assert(!u->is_CFG(), "");
stack.push(u, 0);
@@ -1404,14 +1404,11 @@
}
}
} else {
- // assert(n_clone->outcnt() > 0, "");
- // assert(n->outcnt() > 0, "");
stack.pop();
clones.pop();
}
} while (stack.size() > 0);
assert(stack.size() == 0 && clones.size() == 0, "");
- ctrl = projs.fallthrough_catchproj;
}
}
@@ -1950,6 +1947,9 @@
head->verify_strip_mined(0);
}
move_heap_stable_test_out_of_loop(iff, phase);
+
+ AutoNodeBudget node_budget(phase);
+
if (loop->policy_unswitching(phase)) {
if (head->is_strip_mined()) {
OuterStripMinedLoopNode* outer = head->as_CountedLoop()->outer_loop();
--- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp Tue May 07 17:30:14 2019 -0400
@@ -45,10 +45,13 @@
FLAG_SET_DEFAULT(ShenandoahGCHeuristics, "passive");
FLAG_SET_DEFAULT(ShenandoahSATBBarrier, false);
+ FLAG_SET_DEFAULT(ShenandoahLoadRefBarrier, false);
FLAG_SET_DEFAULT(ShenandoahKeepAliveBarrier, false);
FLAG_SET_DEFAULT(ShenandoahStoreValEnqueueBarrier, false);
FLAG_SET_DEFAULT(ShenandoahCASBarrier, false);
FLAG_SET_DEFAULT(ShenandoahCloneBarrier, false);
+
+ FLAG_SET_DEFAULT(ShenandoahVerifyOptoBarriers, false);
#endif
#ifdef _LP64
@@ -106,6 +109,7 @@
// C2 barrier verification is only reliable when all default barriers are enabled
if (ShenandoahVerifyOptoBarriers &&
(!FLAG_IS_DEFAULT(ShenandoahSATBBarrier) ||
+ !FLAG_IS_DEFAULT(ShenandoahLoadRefBarrier) ||
!FLAG_IS_DEFAULT(ShenandoahKeepAliveBarrier) ||
!FLAG_IS_DEFAULT(ShenandoahStoreValEnqueueBarrier) ||
!FLAG_IS_DEFAULT(ShenandoahCASBarrier) ||
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp Tue May 07 17:30:14 2019 -0400
@@ -619,6 +619,7 @@
guarantee(HumongousThresholdWords == 0, "we should only set it once");
HumongousThresholdWords = RegionSizeWords * ShenandoahHumongousThreshold / 100;
+ HumongousThresholdWords = align_down(HumongousThresholdWords, MinObjAlignment);
assert (HumongousThresholdWords <= RegionSizeWords, "sanity");
guarantee(HumongousThresholdBytes == 0, "we should only set it once");
@@ -643,13 +644,14 @@
//
// The whole thing is mitigated if Elastic TLABs are enabled.
//
+ guarantee(MaxTLABSizeWords == 0, "we should only set it once");
+ MaxTLABSizeWords = MIN2(ShenandoahElasticTLAB ? RegionSizeWords : (RegionSizeWords / 8), HumongousThresholdWords);
+ MaxTLABSizeWords = align_down(MaxTLABSizeWords, MinObjAlignment);
+
guarantee(MaxTLABSizeBytes == 0, "we should only set it once");
- MaxTLABSizeBytes = MIN2(ShenandoahElasticTLAB ? RegionSizeBytes : (RegionSizeBytes / 8), HumongousThresholdBytes);
+ MaxTLABSizeBytes = MaxTLABSizeWords * HeapWordSize;
assert (MaxTLABSizeBytes > MinTLABSize, "should be larger");
- guarantee(MaxTLABSizeWords == 0, "we should only set it once");
- MaxTLABSizeWords = MaxTLABSizeBytes / HeapWordSize;
-
log_info(gc, init)("Regions: " SIZE_FORMAT " x " SIZE_FORMAT "%s",
RegionCount, byte_size_in_proper_unit(RegionSizeBytes), proper_unit_for_byte_size(RegionSizeBytes));
log_info(gc, init)("Humongous object threshold: " SIZE_FORMAT "%s",
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp Tue May 07 17:30:14 2019 -0400
@@ -32,6 +32,8 @@
HeapWord* ShenandoahHeapRegion::allocate(size_t size, ShenandoahAllocRequest::Type type) {
_heap->assert_heaplock_or_safepoint();
+ assert(is_object_aligned(size), "alloc size breaks alignment: " SIZE_FORMAT, size);
+
HeapWord* obj = top();
if (pointer_delta(end(), obj) >= size) {
make_regular_allocation();
@@ -39,7 +41,9 @@
HeapWord* new_top = obj + size;
set_top(new_top);
- assert(is_aligned(obj) && is_aligned(new_top), "checking alignment");
+
+ assert(is_object_aligned(new_top), "new top breaks alignment: " PTR_FORMAT, p2i(new_top));
+ assert(is_object_aligned(obj), "obj is not aligned: " PTR_FORMAT, p2i(obj));
return obj;
} else {
--- a/src/hotspot/share/gc/z/zGranuleMap.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/z/zGranuleMap.hpp Tue May 07 17:30:14 2019 -0400
@@ -35,10 +35,10 @@
friend class ZGranuleMapIterator<T>;
private:
- T* const _map;
+ const size_t _size;
+ T* const _map;
size_t index_for_addr(uintptr_t addr) const;
- size_t size() const;
public:
ZGranuleMap();
--- a/src/hotspot/share/gc/z/zGranuleMap.inline.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/gc/z/zGranuleMap.inline.hpp Tue May 07 17:30:14 2019 -0400
@@ -31,11 +31,12 @@
template <typename T>
inline ZGranuleMap<T>::ZGranuleMap() :
- _map(MmapArrayAllocator<T>::allocate(size(), mtGC)) {}
+ _size(ZAddressOffsetMax >> ZGranuleSizeShift),
+ _map(MmapArrayAllocator<T>::allocate(_size, mtGC)) {}
template <typename T>
inline ZGranuleMap<T>::~ZGranuleMap() {
- MmapArrayAllocator<T>::free(_map, size());
+ MmapArrayAllocator<T>::free(_map, _size);
}
template <typename T>
@@ -43,17 +44,12 @@
assert(!ZAddress::is_null(addr), "Invalid address");
const size_t index = ZAddress::offset(addr) >> ZGranuleSizeShift;
- assert(index < size(), "Invalid index");
+ assert(index < _size, "Invalid index");
return index;
}
template <typename T>
-inline size_t ZGranuleMap<T>::size() const {
- return ZAddressOffsetMax >> ZGranuleSizeShift;
-}
-
-template <typename T>
inline T ZGranuleMap<T>::get(uintptr_t addr) const {
const size_t index = index_for_addr(addr);
return _map[index];
@@ -83,7 +79,7 @@
template <typename T>
inline bool ZGranuleMapIterator<T>::next(T* value) {
- if (_next < _map->size()) {
+ if (_next < _map->_size) {
*value = _map->_map[_next++];
return true;
}
@@ -94,7 +90,7 @@
template <typename T>
inline bool ZGranuleMapIterator<T>::next(T** value) {
- if (_next < _map->size()) {
+ if (_next < _map->_size) {
*value = _map->_map + _next++;
return true;
}
--- a/src/hotspot/share/interpreter/abstractInterpreter.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/interpreter/abstractInterpreter.cpp Tue May 07 17:30:14 2019 -0400
@@ -28,6 +28,7 @@
#include "compiler/disassembler.hpp"
#include "interpreter/bytecodeHistogram.hpp"
#include "interpreter/bytecodeInterpreter.hpp"
+#include "interpreter/bytecodeStream.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/interp_masm.hpp"
@@ -36,6 +37,8 @@
#include "memory/metaspaceShared.hpp"
#include "memory/resourceArea.hpp"
#include "oops/arrayOop.hpp"
+#include "oops/constantPool.hpp"
+#include "oops/cpCache.inline.hpp"
#include "oops/methodData.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
@@ -240,9 +243,36 @@
// 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(const methodHandle& method, int bci) {
- Bytecodes::Code code = method()->code_at(bci);
+ BytecodeStream s(method, bci);
+ Bytecodes::Code code = s.next();
+
+ if (Bytecodes::is_invoke(code)) {
+ assert(!Bytecodes::must_rewrite(code), "invokes aren't rewritten");
+ ConstantPool* cpool = method()->constants();
+
+ Bytecode invoke_bc(s.bytecode());
- if (!Bytecodes::must_rewrite(code)) {
+ switch (code) {
+ case Bytecodes::_invokedynamic: {
+ assert(invoke_bc.has_index_u4(code), "sanity");
+ int method_index = invoke_bc.get_index_u4(code);
+ return cpool->invokedynamic_cp_cache_entry_at(method_index)->is_f1_null();
+ }
+ case Bytecodes::_invokevirtual: // fall-through
+ case Bytecodes::_invokeinterface: // fall-through
+ case Bytecodes::_invokespecial: // fall-through
+ case Bytecodes::_invokestatic: {
+ if (cpool->has_preresolution()) {
+ return false; // might have been reached
+ }
+ assert(!invoke_bc.has_index_u4(code), "sanity");
+ int method_index = invoke_bc.get_index_u2_cpcache(code);
+ Method* resolved_method = ConstantPool::method_at_if_loaded(cpool, method_index);
+ return (resolved_method == NULL);
+ }
+ default: ShouldNotReachHere();
+ }
+ } else if (!Bytecodes::must_rewrite(code)) {
// might have been reached
return false;
}
--- a/src/hotspot/share/interpreter/bytecodeStream.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/interpreter/bytecodeStream.hpp Tue May 07 17:30:14 2019 -0400
@@ -170,6 +170,10 @@
// Construction
BytecodeStream(const methodHandle& method) : BaseBytecodeStream(method) { }
+ BytecodeStream(const methodHandle& method, int bci) : BaseBytecodeStream(method) {
+ set_start(bci);
+ }
+
// Iteration
Bytecodes::Code next() {
Bytecodes::Code raw_code, code;
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Tue May 07 17:30:14 2019 -0400
@@ -62,12 +62,17 @@
return *this;
}
-void JNIHandleMark::push_jni_handle_block() {
- JavaThread* thread = JavaThread::current();
+static void requireInHotSpot(const char* caller, JVMCI_TRAPS) {
+ if (!JVMCIENV->is_hotspot()) {
+ JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot call %s from JVMCI shared library", caller));
+ }
+}
+
+void JNIHandleMark::push_jni_handle_block(JavaThread* thread) {
if (thread != NULL) {
// Allocate a new block for JNI handles.
// Inlined code from jni_PushLocalFrame()
- JNIHandleBlock* java_handles = ((JavaThread*)thread)->active_handles();
+ JNIHandleBlock* java_handles = thread->active_handles();
JNIHandleBlock* compile_handles = JNIHandleBlock::allocate_block(thread);
assert(compile_handles != NULL && java_handles != NULL, "should not be NULL");
compile_handles->set_pop_frame_link(java_handles);
@@ -75,8 +80,7 @@
}
}
-void JNIHandleMark::pop_jni_handle_block() {
- JavaThread* thread = JavaThread::current();
+void JNIHandleMark::pop_jni_handle_block(JavaThread* thread) {
if (thread != NULL) {
// Release our JNI handle block
JNIHandleBlock* compile_handles = thread->active_handles();
@@ -111,25 +115,88 @@
return Handle(Thread::current(), arg);
}
-// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
+// Bring the JVMCI compiler thread into the VM state.
+#define JVMCI_VM_ENTRY_MARK \
+ ThreadInVMfromNative __tiv(thread); \
+ ResetNoHandleMark rnhm; \
+ HandleMarkCleaner __hm(thread); \
+ Thread* THREAD = thread; \
+ debug_only(VMNativeEntryWrapper __vew;)
+
+// Native method block that transitions current thread to '_thread_in_vm'.
+#define C2V_BLOCK(result_type, name, signature) \
+ TRACE_CALL(result_type, jvmci_ ## name signature) \
+ JVMCI_VM_ENTRY_MARK; \
+ ResourceMark rm; \
+ JNI_JVMCIENV(thread, env);
+
+static Thread* get_current_thread() {
+ return Thread::current_or_null_safe();
+}
+
+// Entry to native method implementation that transitions
+// current thread to '_thread_in_vm'.
#define C2V_VMENTRY(result_type, name, signature) \
JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+ Thread* base_thread = get_current_thread(); \
+ if (base_thread == NULL) { \
+ env->ThrowNew(JNIJVMCI::InternalError::clazz(), \
+ err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \
+ return; \
+ } \
+ assert(base_thread->is_Java_thread(), "just checking");\
+ JavaThread* thread = (JavaThread*) base_thread; \
JVMCITraceMark jtm("CompilerToVM::" #name); \
- TRACE_CALL(result_type, jvmci_ ## name signature) \
- JVMCI_VM_ENTRY_MARK; \
- ResourceMark rm; \
- JNI_JVMCIENV(env);
+ C2V_BLOCK(result_type, name, signature)
+
+#define C2V_VMENTRY_(result_type, name, signature, result) \
+ JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+ Thread* base_thread = get_current_thread(); \
+ if (base_thread == NULL) { \
+ env->ThrowNew(JNIJVMCI::InternalError::clazz(), \
+ err_msg("Cannot call into HotSpot from JVMCI shared library without attaching current thread")); \
+ return result; \
+ } \
+ assert(base_thread->is_Java_thread(), "just checking");\
+ JavaThread* thread = (JavaThread*) base_thread; \
+ JVMCITraceMark jtm("CompilerToVM::" #name); \
+ C2V_BLOCK(result_type, name, signature)
+
+#define C2V_VMENTRY_NULL(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, NULL)
+#define C2V_VMENTRY_0(result_type, name, signature) C2V_VMENTRY_(result_type, name, signature, 0)
+
+// Entry to native method implementation that does not transition
+// current thread to '_thread_in_vm'.
+#define C2V_VMENTRY_PREFIX(result_type, name, signature) \
+ JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+ Thread* base_thread = get_current_thread();
#define C2V_END }
+#define JNI_THROW(caller, name, msg) do { \
+ jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \
+ if (__throw_res != JNI_OK) { \
+ tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \
+ } \
+ return; \
+ } while (0);
+
+#define JNI_THROW_(caller, name, msg, result) do { \
+ jint __throw_res = env->ThrowNew(JNIJVMCI::name::clazz(), msg); \
+ if (__throw_res != JNI_OK) { \
+ tty->print_cr("Throwing " #name " in " caller " returned %d", __throw_res); \
+ } \
+ return result; \
+ } while (0)
+
jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS);
-C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv* env))
+C2V_VMENTRY_NULL(jobjectArray, readConfiguration, (JNIEnv* env))
jobjectArray config = readConfiguration0(env, JVMCI_CHECK_NULL);
return config;
}
-C2V_VMENTRY(jobject, getFlagValue, (JNIEnv* env, jobject c2vm, jobject name_handle))
+C2V_VMENTRY_NULL(jobject, getFlagValue, (JNIEnv* env, jobject c2vm, jobject name_handle))
#define RETURN_BOXED_LONG(value) jvalue p; p.j = (jlong) (value); JVMCIObject box = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); return box.as_jobject();
#define RETURN_BOXED_DOUBLE(value) jvalue p; p.d = (jdouble) (value); JVMCIObject box = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL); return box.as_jobject();
JVMCIObject name = JVMCIENV->wrap(name_handle);
@@ -170,10 +237,8 @@
#undef RETURN_BOXED_DOUBLE
C2V_END
-C2V_VMENTRY(jobject, getObjectAtAddress, (JNIEnv* env, jobject c2vm, jlong oop_address))
- if (env != JavaThread::current()->jni_environment()) {
- JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
- }
+C2V_VMENTRY_NULL(jobject, getObjectAtAddress, (JNIEnv* env, jobject c2vm, jlong oop_address))
+ requireInHotSpot("getObjectAtAddress", JVMCI_CHECK_NULL);
if (oop_address == 0) {
JVMCI_THROW_MSG_NULL(InternalError, "Handle must be non-zero");
}
@@ -184,7 +249,7 @@
return JNIHandles::make_local(obj);
C2V_END
-C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_NULL(jbyteArray, getBytecode, (JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
int code_size = method->code_size();
@@ -262,12 +327,12 @@
return JVMCIENV->get_jbyteArray(result);
C2V_END
-C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jint, getExceptionTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
return method->exception_table_length();
C2V_END
-C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jlong, getExceptionTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
if (method->exception_table_length() == 0) {
return 0L;
@@ -275,11 +340,8 @@
return (jlong) (address) method->exception_table_start();
C2V_END
-C2V_VMENTRY(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject executable_handle))
- if (env != JavaThread::current()->jni_environment()) {
- JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
- }
-
+C2V_VMENTRY_NULL(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject executable_handle))
+ requireInHotSpot("asResolvedJavaMethod", JVMCI_CHECK_NULL);
oop executable = JNIHandles::resolve(executable_handle);
oop mirror = NULL;
int slot = 0;
@@ -298,7 +360,7 @@
return JVMCIENV->get_jobject(result);
}
-C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))
+C2V_VMENTRY_NULL(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))
methodHandle method;
JVMCIObject base_object = JVMCIENV->wrap(base);
if (base_object.is_null()) {
@@ -321,7 +383,7 @@
return JVMCIENV->get_jobject(result);
}
-C2V_VMENTRY(jobject, getConstantPool, (JNIEnv* env, jobject, jobject object_handle))
+C2V_VMENTRY_NULL(jobject, getConstantPool, (JNIEnv* env, jobject, jobject object_handle))
constantPoolHandle cp;
JVMCIObject object = JVMCIENV->wrap(object_handle);
if (object.is_null()) {
@@ -341,7 +403,7 @@
return JVMCIENV->get_jobject(result);
}
-C2V_VMENTRY(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed))
+C2V_VMENTRY_NULL(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed))
JVMCIKlassHandle klass(THREAD);
JVMCIObject base_object = JVMCIENV->wrap(base);
jlong base_address = 0;
@@ -384,7 +446,7 @@
return JVMCIENV->get_jobject(result);
}
-C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
+C2V_VMENTRY_NULL(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
Klass* holder = JVMCIENV->asKlass(jvmci_type);
if (holder->is_interface()) {
@@ -400,7 +462,7 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jobject, getImplementor, (JNIEnv* env, jobject, jobject jvmci_type))
+C2V_VMENTRY_NULL(jobject, getImplementor, (JNIEnv* env, jobject, jobject jvmci_type))
Klass* klass = JVMCIENV->asKlass(jvmci_type);
if (!klass->is_interface()) {
THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
@@ -417,12 +479,12 @@
return JVMCIENV->get_jobject(implementor);
C2V_END
-C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
return method->is_ignored_by_security_stack_walk();
C2V_END
-C2V_VMENTRY(jboolean, isCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jboolean, isCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
constantPoolHandle cp = method->constMethod()->constants();
assert(!cp.is_null(), "npe");
@@ -430,17 +492,17 @@
return !method->is_not_compilable(CompLevel_full_optimization) && !cp->has_dynamic_constant();
C2V_END
-C2V_VMENTRY(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
return !Inline || CompilerOracle::should_not_inline(method) || method->dont_inline();
C2V_END
-C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
return CompilerOracle::should_inline(method) || method->force_inline();
C2V_END
-C2V_VMENTRY(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
+C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
JVMCIObject name = JVMCIENV->wrap(jname);
const char* str = JVMCIENV->as_utf8_string(name);
TempNewSymbol class_name = SymbolTable::new_symbol(str, CHECK_NULL);
@@ -465,6 +527,9 @@
if (resolve) {
resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0);
+ if (resolved_klass == NULL) {
+ JVMCI_THROW_MSG_NULL(ClassNotFoundException, str);
+ }
} else {
if (class_name->char_at(0) == 'L' &&
class_name->char_at(class_name->utf8_length()-1) == ';') {
@@ -483,7 +548,6 @@
TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(),
class_name->utf8_length()-2-fd.dimension(),
CHECK_0);
- // naked oop "k" is OK here -- we assign back into it
resolved_klass = SystemDictionary::find(strippedsym,
class_loader,
protection_domain,
@@ -502,10 +566,8 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
- if (env != JavaThread::current()->jni_environment()) {
- JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
- }
+C2V_VMENTRY_NULL(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
+ requireInHotSpot("lookupClass", JVMCI_CHECK_NULL);
if (mirror == NULL) {
return NULL;
}
@@ -518,55 +580,56 @@
return JVMCIENV->get_jobject(result);
}
-C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+C2V_VMENTRY_NULL(jobject, resolveConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
oop result = cp->resolve_constant_at(index, CHECK_NULL);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
C2V_END
-C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+C2V_VMENTRY_NULL(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
C2V_END
-C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+C2V_VMENTRY_0(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
return cp->name_and_type_ref_index_at(index);
C2V_END
-C2V_VMENTRY(jobject, lookupNameInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
+C2V_VMENTRY_NULL(jobject, lookupNameInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
JVMCIObject sym = JVMCIENV->create_string(cp->name_ref_at(which), JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(sym);
C2V_END
-C2V_VMENTRY(jobject, lookupSignatureInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
+C2V_VMENTRY_NULL(jobject, lookupSignatureInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
JVMCIObject sym = JVMCIENV->create_string(cp->signature_ref_at(which), JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(sym);
C2V_END
-C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+C2V_VMENTRY_0(jint, lookupKlassRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
return cp->klass_ref_index_at(index);
C2V_END
-C2V_VMENTRY(jobject, resolveTypeInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+C2V_VMENTRY_NULL(jobject, resolveTypeInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
Klass* klass = cp->klass_at(index, CHECK_NULL);
JVMCIKlassHandle resolved_klass(THREAD, klass);
if (resolved_klass->is_instance_klass()) {
- bool linked = InstanceKlass::cast(resolved_klass())->link_class_or_fail(CHECK_NULL);
- if (!linked) {
- return NULL;
+ InstanceKlass::cast(resolved_klass())->link_class(CHECK_NULL);
+ if (!InstanceKlass::cast(resolved_klass())->is_linked()) {
+ // link_class() should not return here if there is an issue.
+ JVMCI_THROW_MSG_NULL(InternalError, err_msg("Class %s must be linked", resolved_klass()->external_name()));
}
}
JVMCIObject klassObject = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(klassObject);
C2V_END
-C2V_VMENTRY(jobject, lookupKlassInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
+C2V_VMENTRY_NULL(jobject, lookupKlassInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
Klass* loading_klass = cp->pool_holder();
bool is_accessible = false;
@@ -594,13 +657,13 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+C2V_VMENTRY_NULL(jobject, lookupAppendixInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(appendix_oop));
C2V_END
-C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
+C2V_VMENTRY_NULL(jobject, lookupMethodInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
InstanceKlass* pool_holder = cp->pool_holder();
Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
@@ -609,12 +672,12 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+C2V_VMENTRY_0(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
return cp->remap_instruction_operand_from_cache(index);
C2V_END
-C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))
+C2V_VMENTRY_NULL(jobject, resolveFieldInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
fieldDescriptor fd;
@@ -632,7 +695,7 @@
return JVMCIENV->get_jobject(field_holder);
C2V_END
-C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
+C2V_VMENTRY_0(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
Klass* klass = JVMCIENV->asKlass(jvmci_type);
Method* method = JVMCIENV->asMethod(jvmci_method);
if (klass->is_interface()) {
@@ -650,7 +713,7 @@
return LinkResolver::vtable_index_of_interface_method(klass, method);
C2V_END
-C2V_VMENTRY(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
+C2V_VMENTRY_NULL(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
Klass* recv_klass = JVMCIENV->asKlass(receiver_jvmci_type);
Klass* caller_klass = JVMCIENV->asKlass(caller_jvmci_type);
methodHandle method = JVMCIENV->asMethod(jvmci_method);
@@ -697,13 +760,13 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv* env, jobject, jobject jvmci_type))
+C2V_VMENTRY_0(jboolean, hasFinalizableSubclass,(JNIEnv* env, jobject, jobject jvmci_type))
Klass* klass = JVMCIENV->asKlass(jvmci_type);
assert(klass != NULL, "method must not be called for primitive types");
return Dependencies::find_finalizable_subclass(klass) != NULL;
C2V_END
-C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv* env, jobject, jobject jvmci_type))
+C2V_VMENTRY_NULL(jobject, getClassInitializer, (JNIEnv* env, jobject, jobject jvmci_type))
Klass* klass = JVMCIENV->asKlass(jvmci_type);
if (!klass->is_instance_klass()) {
return NULL;
@@ -713,7 +776,7 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv* env, jobject, jlong addr))
+C2V_VMENTRY_0(jlong, getMaxCallTargetOffset, (JNIEnv* env, jobject, jlong addr))
address target_addr = (address) addr;
if (target_addr != 0x0) {
int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
@@ -730,10 +793,10 @@
method->set_dont_inline(true);
C2V_END
-C2V_VMENTRY(jint, installCode, (JNIEnv *env, jobject, jobject target, jobject compiled_code,
+C2V_VMENTRY_0(jint, installCode, (JNIEnv *env, jobject, jobject target, jobject compiled_code,
jobject installed_code, jlong failed_speculations_address, jbyteArray speculations_obj))
HandleMark hm;
- JNIHandleMark jni_hm;
+ JNIHandleMark jni_hm(thread);
JVMCIObject target_handle = JVMCIENV->wrap(target);
JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);
@@ -791,7 +854,7 @@
return result;
C2V_END
-C2V_VMENTRY(jint, getMetadata, (JNIEnv *env, jobject, jobject target, jobject compiled_code, jobject metadata))
+C2V_VMENTRY_0(jint, getMetadata, (JNIEnv *env, jobject, jobject target, jobject compiled_code, jobject metadata))
#if INCLUDE_AOT
HandleMark hm;
assert(JVMCIENV->is_hotspot(), "AOT code is executed only in HotSpot mode");
@@ -872,7 +935,7 @@
stats->_osr.reset();
C2V_END
-C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv* env, jobject, jobject installedCode))
+C2V_VMENTRY_NULL(jobject, disassembleCodeBlob, (JNIEnv* env, jobject, jobject installedCode))
HandleMark hm;
if (installedCode == NULL) {
@@ -909,7 +972,7 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv* env, jobject, jobject jvmci_method, int bci))
+C2V_VMENTRY_NULL(jobject, getStackTraceElement, (JNIEnv* env, jobject, jobject jvmci_method, int bci))
HandleMark hm;
methodHandle method = JVMCIENV->asMethod(jvmci_method);
@@ -917,12 +980,10 @@
return JVMCIENV->get_jobject(element);
C2V_END
-C2V_VMENTRY(jobject, executeHotSpotNmethod, (JNIEnv* env, jobject, jobject args, jobject hs_nmethod))
- if (env != JavaThread::current()->jni_environment()) {
- // The incoming arguments array would have to contain JavaConstants instead of regular objects
- // and the return value would have to be wrapped as a JavaConstant.
- JVMCI_THROW_MSG_NULL(InternalError, "Wrapping of arguments is currently unsupported");
- }
+C2V_VMENTRY_NULL(jobject, executeHotSpotNmethod, (JNIEnv* env, jobject, jobject args, jobject hs_nmethod))
+ // The incoming arguments array would have to contain JavaConstants instead of regular objects
+ // and the return value would have to be wrapped as a JavaConstant.
+ requireInHotSpot("executeHotSpotNmethod", JVMCI_CHECK_NULL);
HandleMark hm;
@@ -968,7 +1029,7 @@
}
C2V_END
-C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_NULL(jlongArray, getLineNumberTable, (JNIEnv* env, jobject, jobject jvmci_method))
Method* method = JVMCIENV->asMethod(jvmci_method);
if (!method->has_linenumber_table()) {
return NULL;
@@ -995,7 +1056,7 @@
return (jlongArray) JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jlong, getLocalVariableTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
Method* method = JVMCIENV->asMethod(jvmci_method);
if (!method->has_localvariable_table()) {
return 0;
@@ -1003,7 +1064,7 @@
return (jlong) (address) method->localvariable_table_start();
C2V_END
-C2V_VMENTRY(jint, getLocalVariableTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jint, getLocalVariableTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
Method* method = JVMCIENV->asMethod(jvmci_method);
return method->localvariable_table_length();
C2V_END
@@ -1037,18 +1098,23 @@
JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK);
C2V_END
-C2V_VMENTRY(jobject, readUncompressedOop, (JNIEnv* env, jobject, jlong addr))
+C2V_VMENTRY_NULL(jobject, readUncompressedOop, (JNIEnv* env, jobject, jlong addr))
oop ret = RawAccess<>::oop_load((oop*)(address)addr);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(ret));
C2V_END
-C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv* env, jobject))
+C2V_VMENTRY_NULL(jlongArray, collectCounters, (JNIEnv* env, jobject))
+ // Returns a zero length array if counters aren't enabled
JVMCIPrimitiveArray array = JVMCIENV->new_longArray(JVMCICounterSize, JVMCI_CHECK_NULL);
- JavaThread::collect_counters(JVMCIENV, array);
+ if (JVMCICounterSize > 0) {
+ jlong* temp_array = NEW_RESOURCE_ARRAY(jlong, JVMCICounterSize);
+ JavaThread::collect_counters(temp_array, JVMCICounterSize);
+ JVMCIENV->copy_longs_from(temp_array, array, 0, JVMCICounterSize);
+ }
return (jlongArray) JVMCIENV->get_jobject(array);
C2V_END
-C2V_VMENTRY(int, allocateCompileId, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci))
+C2V_VMENTRY_0(int, allocateCompileId, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci))
HandleMark hm;
if (jvmci_method == NULL) {
JVMCI_THROW_0(NullPointerException);
@@ -1061,17 +1127,17 @@
C2V_END
-C2V_VMENTRY(jboolean, isMature, (JNIEnv* env, jobject, jlong metaspace_method_data))
+C2V_VMENTRY_0(jboolean, isMature, (JNIEnv* env, jobject, jlong metaspace_method_data))
MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
return mdo != NULL && mdo->is_mature();
C2V_END
-C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci, int comp_level))
+C2V_VMENTRY_0(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci, int comp_level))
Method* method = JVMCIENV->asMethod(jvmci_method);
return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
C2V_END
-C2V_VMENTRY(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))
+C2V_VMENTRY_NULL(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))
JVMCIObject sym = JVMCIENV->create_string((Symbol*)(address)symbol, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(sym);
C2V_END
@@ -1102,16 +1168,14 @@
JavaCalls::call(result, method, args, CHECK);
}
-C2V_VMENTRY(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))
+C2V_VMENTRY_NULL(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))
if (!thread->has_last_Java_frame()) {
return NULL;
}
Handle visitor(THREAD, JNIHandles::resolve_non_null(visitor_handle));
- if (env != JavaThread::current()->jni_environment()) {
- JVMCI_THROW_MSG_NULL(InternalError, "getNextStackFrame is only supported for HotSpot stack walking");
- }
+ requireInHotSpot("iterateFrames", JVMCI_CHECK_NULL);
HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
Handle frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
@@ -1283,7 +1347,7 @@
}
C2V_END
-C2V_VMENTRY(jint, isResolvedInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+C2V_VMENTRY_0(jint, isResolvedInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
if (cp_cache_entry->is_resolved(Bytecodes::_invokehandle)) {
@@ -1324,7 +1388,7 @@
C2V_END
-C2V_VMENTRY(jobject, getSignaturePolymorphicHolders, (JNIEnv* env, jobject))
+C2V_VMENTRY_NULL(jobject, getSignaturePolymorphicHolders, (JNIEnv* env, jobject))
JVMCIObjectArray holders = JVMCIENV->new_String_array(2, JVMCI_CHECK_NULL);
JVMCIObject mh = JVMCIENV->create_string("Ljava/lang/invoke/MethodHandle;", JVMCI_CHECK_NULL);
JVMCIObject vh = JVMCIENV->create_string("Ljava/lang/invoke/VarHandle;", JVMCI_CHECK_NULL);
@@ -1333,7 +1397,7 @@
return JVMCIENV->get_jobject(holders);
C2V_END
-C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv* env, jobject))
+C2V_VMENTRY_0(jboolean, shouldDebugNonSafepoints, (JNIEnv* env, jobject))
//see compute_recording_non_safepoints in debugInfroRec.cpp
if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
return true;
@@ -1348,9 +1412,7 @@
JVMCI_THROW_MSG(NullPointerException, "stack frame is null");
}
- if (env != JavaThread::current()->jni_environment()) {
- JVMCI_THROW_MSG(InternalError, "getNextStackFrame is only supported for HotSpot stack walking");
- }
+ requireInHotSpot("materializeVirtualObjects", JVMCI_CHECK);
JVMCIENV->HotSpotStackFrameReference_initialize(JVMCI_CHECK);
@@ -1465,20 +1527,76 @@
HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, hs_frame, JNI_TRUE);
C2V_END
-C2V_VMENTRY(void, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length))
+// Creates a scope where the current thread is attached and detached
+// from HotSpot if it wasn't already attached when entering the scope.
+extern "C" void jio_printf(const char *fmt, ...);
+class AttachDetach : public StackObj {
+ public:
+ bool _attached;
+ AttachDetach(JNIEnv* env, Thread* current_thread) {
+ if (current_thread == NULL) {
+ extern struct JavaVM_ main_vm;
+ JNIEnv* hotspotEnv;
+ jint res = main_vm.AttachCurrentThread((void**)&hotspotEnv, NULL);
+ _attached = res == JNI_OK;
+ static volatile int report_attach_error = 0;
+ if (res != JNI_OK && report_attach_error == 0 && Atomic::cmpxchg(1, &report_attach_error, 0) == 0) {
+ // Only report an attach error once
+ jio_printf("Warning: attaching current thread to VM failed with %d (future attach errors are suppressed)\n", res);
+ }
+ } else {
+ _attached = false;
+ }
+ }
+ ~AttachDetach() {
+ if (_attached && get_current_thread() != NULL) {
+ extern struct JavaVM_ main_vm;
+ jint res = main_vm.DetachCurrentThread();
+ static volatile int report_detach_error = 0;
+ if (res != JNI_OK && report_detach_error == 0 && Atomic::cmpxchg(1, &report_detach_error, 0) == 0) {
+ // Only report an attach error once
+ jio_printf("Warning: detaching current thread from VM failed with %d (future attach errors are suppressed)\n", res);
+ }
+ }
+ }
+};
+
+C2V_VMENTRY_PREFIX(jint, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length, bool flush, bool can_throw))
+ AttachDetach ad(env, base_thread);
+ bool use_tty = true;
+ if (base_thread == NULL) {
+ if (!ad._attached) {
+ // Can only use tty if the current thread is attached
+ return 0;
+ }
+ base_thread = get_current_thread();
+ }
+ JVMCITraceMark jtm("writeDebugOutput");
+ assert(base_thread->is_Java_thread(), "just checking");
+ JavaThread* thread = (JavaThread*) base_thread;
+ C2V_BLOCK(void, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length))
if (bytes == NULL) {
- JVMCI_THROW(NullPointerException);
+ if (can_throw) {
+ JVMCI_THROW_0(NullPointerException);
+ }
+ return -1;
}
JVMCIPrimitiveArray array = JVMCIENV->wrap(bytes);
// Check if offset and length are non negative.
if (offset < 0 || length < 0) {
- JVMCI_THROW(ArrayIndexOutOfBoundsException);
+ if (can_throw) {
+ JVMCI_THROW_0(ArrayIndexOutOfBoundsException);
+ }
+ return -2;
}
// Check if the range is valid.
int array_length = JVMCIENV->get_length(array);
if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array_length)) {
- JVMCI_THROW(ArrayIndexOutOfBoundsException);
+ if (can_throw) {
+ JVMCI_THROW_0(ArrayIndexOutOfBoundsException);
+ }
+ return -2;
}
jbyte buffer[O_BUFLEN];
while (length > 0) {
@@ -1488,13 +1606,17 @@
length -= O_BUFLEN;
offset += O_BUFLEN;
}
+ if (flush) {
+ tty->flush();
+ }
+ return 0;
C2V_END
C2V_VMENTRY(void, flushDebugOutput, (JNIEnv* env, jobject))
tty->flush();
C2V_END
-C2V_VMENTRY(int, methodDataProfileDataSize, (JNIEnv* env, jobject, jlong metaspace_method_data, jint position))
+C2V_VMENTRY_0(int, methodDataProfileDataSize, (JNIEnv* env, jobject, jlong metaspace_method_data, jint position))
MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
ProfileData* profile_data = mdo->data_at(position);
if (mdo->is_valid(profile_data)) {
@@ -1512,7 +1634,7 @@
JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Invalid profile data position %d", position));
C2V_END
-C2V_VMENTRY(jlong, getFingerprint, (JNIEnv* env, jobject, jlong metaspace_klass))
+C2V_VMENTRY_0(jlong, getFingerprint, (JNIEnv* env, jobject, jlong metaspace_klass))
#if INCLUDE_AOT
Klass *k = (Klass*) (address) metaspace_klass;
if (k->is_instance_klass()) {
@@ -1525,7 +1647,7 @@
#endif
C2V_END
-C2V_VMENTRY(jobject, getHostClass, (JNIEnv* env, jobject, jobject jvmci_type))
+C2V_VMENTRY_NULL(jobject, getHostClass, (JNIEnv* env, jobject, jobject jvmci_type))
InstanceKlass* k = InstanceKlass::cast(JVMCIENV->asKlass(jvmci_type));
InstanceKlass* host = k->unsafe_anonymous_host();
JVMCIKlassHandle handle(THREAD, host);
@@ -1533,7 +1655,7 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jobject, getInterfaces, (JNIEnv* env, jobject, jobject jvmci_type))
+C2V_VMENTRY_NULL(jobject, getInterfaces, (JNIEnv* env, jobject, jobject jvmci_type))
if (jvmci_type == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1560,7 +1682,7 @@
return JVMCIENV->get_jobject(interfaces);
C2V_END
-C2V_VMENTRY(jobject, getComponentType, (JNIEnv* env, jobject, jobject jvmci_type))
+C2V_VMENTRY_NULL(jobject, getComponentType, (JNIEnv* env, jobject, jobject jvmci_type))
if (jvmci_type == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1600,7 +1722,7 @@
}
C2V_END
-C2V_VMENTRY(int, interpreterFrameSize, (JNIEnv* env, jobject, jobject bytecode_frame_handle))
+C2V_VMENTRY_0(int, interpreterFrameSize, (JNIEnv* env, jobject, jobject bytecode_frame_handle))
if (bytecode_frame_handle == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1648,12 +1770,12 @@
}
C2V_END
-C2V_VMENTRY(int, getIdentityHashCode, (JNIEnv* env, jobject, jobject object))
+C2V_VMENTRY_0(int, getIdentityHashCode, (JNIEnv* env, jobject, jobject object))
Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
return obj->identity_hash();
C2V_END
-C2V_VMENTRY(jboolean, isInternedString, (JNIEnv* env, jobject, jobject object))
+C2V_VMENTRY_0(jboolean, isInternedString, (JNIEnv* env, jobject, jobject object))
Handle str = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
if (!java_lang_String::is_instance(str())) {
return false;
@@ -1664,7 +1786,7 @@
C2V_END
-C2V_VMENTRY(jobject, unboxPrimitive, (JNIEnv* env, jobject, jobject object))
+C2V_VMENTRY_NULL(jobject, unboxPrimitive, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1678,7 +1800,7 @@
return JVMCIENV->get_jobject(boxResult);
C2V_END
-C2V_VMENTRY(jobject, boxPrimitive, (JNIEnv* env, jobject, jobject object))
+C2V_VMENTRY_NULL(jobject, boxPrimitive, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1722,7 +1844,7 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, jobject holder))
+C2V_VMENTRY_NULL(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, jobject holder))
if (holder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1751,7 +1873,7 @@
return JVMCIENV->get_jobjectArray(methods);
C2V_END
-C2V_VMENTRY(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, jobject holder))
+C2V_VMENTRY_NULL(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, jobject holder))
if (holder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1780,7 +1902,7 @@
return JVMCIENV->get_jobjectArray(methods);
C2V_END
-C2V_VMENTRY(jobject, readFieldValue, (JNIEnv* env, jobject, jobject object, jobject field, jboolean is_volatile))
+C2V_VMENTRY_NULL(jobject, readFieldValue, (JNIEnv* env, jobject, jobject object, jobject field, jboolean is_volatile))
if (object == NULL || field == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1848,7 +1970,7 @@
return JVMCIENV->get_jobject(result);
C2V_END
-C2V_VMENTRY(jboolean, isInstance, (JNIEnv* env, jobject, jobject holder, jobject object))
+C2V_VMENTRY_0(jboolean, isInstance, (JNIEnv* env, jobject, jobject holder, jobject object))
if (object == NULL || holder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1857,7 +1979,7 @@
return obj->is_a(klass);
C2V_END
-C2V_VMENTRY(jboolean, isAssignableFrom, (JNIEnv* env, jobject, jobject holder, jobject otherHolder))
+C2V_VMENTRY_0(jboolean, isAssignableFrom, (JNIEnv* env, jobject, jobject holder, jobject otherHolder))
if (holder == NULL || otherHolder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1866,7 +1988,7 @@
return otherKlass->is_subtype_of(klass);
C2V_END
-C2V_VMENTRY(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, jobject holder))
+C2V_VMENTRY_0(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, jobject holder))
if (holder == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1877,7 +1999,7 @@
return false;
C2V_END
-C2V_VMENTRY(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))
+C2V_VMENTRY_NULL(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1897,7 +2019,7 @@
C2V_END
-C2V_VMENTRY(jobject, asString, (JNIEnv* env, jobject, jobject object))
+C2V_VMENTRY_NULL(jobject, asString, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1908,14 +2030,14 @@
C2V_END
-C2V_VMENTRY(jboolean, equals, (JNIEnv* env, jobject, jobject x, jlong xHandle, jobject y, jlong yHandle))
+C2V_VMENTRY_0(jboolean, equals, (JNIEnv* env, jobject, jobject x, jlong xHandle, jobject y, jlong yHandle))
if (x == NULL || y == NULL) {
JVMCI_THROW_0(NullPointerException);
}
return JVMCIENV->resolve_handle(xHandle) == JVMCIENV->resolve_handle(yHandle);
C2V_END
-C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv* env, jobject, jobject object))
+C2V_VMENTRY_NULL(jobject, getJavaMirror, (JNIEnv* env, jobject, jobject object))
if (object == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1934,7 +2056,7 @@
C2V_END
-C2V_VMENTRY(jint, getArrayLength, (JNIEnv* env, jobject, jobject x))
+C2V_VMENTRY_0(jint, getArrayLength, (JNIEnv* env, jobject, jobject x))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1946,7 +2068,7 @@
C2V_END
-C2V_VMENTRY(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))
+C2V_VMENTRY_NULL(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1986,7 +2108,7 @@
C2V_END
-C2V_VMENTRY(jint, arrayBaseOffset, (JNIEnv* env, jobject, jobject kind))
+C2V_VMENTRY_0(jint, arrayBaseOffset, (JNIEnv* env, jobject, jobject kind))
if (kind == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -1994,7 +2116,7 @@
return arrayOopDesc::header_size(type) * HeapWordSize;
C2V_END
-C2V_VMENTRY(jint, arrayIndexScale, (JNIEnv* env, jobject, jobject kind))
+C2V_VMENTRY_0(jint, arrayIndexScale, (JNIEnv* env, jobject, jobject kind))
if (kind == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -2002,7 +2124,7 @@
return type2aelembytes(type);
C2V_END
-C2V_VMENTRY(jbyte, getByte, (JNIEnv* env, jobject, jobject x, long displacement))
+C2V_VMENTRY_0(jbyte, getByte, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -2010,7 +2132,7 @@
return xobj->byte_field(displacement);
}
-C2V_VMENTRY(jshort, getShort, (JNIEnv* env, jobject, jobject x, long displacement))
+C2V_VMENTRY_0(jshort, getShort, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -2018,7 +2140,7 @@
return xobj->short_field(displacement);
}
-C2V_VMENTRY(jint, getInt, (JNIEnv* env, jobject, jobject x, long displacement))
+C2V_VMENTRY_0(jint, getInt, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -2026,7 +2148,7 @@
return xobj->int_field(displacement);
}
-C2V_VMENTRY(jlong, getLong, (JNIEnv* env, jobject, jobject x, long displacement))
+C2V_VMENTRY_0(jlong, getLong, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -2034,7 +2156,7 @@
return xobj->long_field(displacement);
}
-C2V_VMENTRY(jobject, getObject, (JNIEnv* env, jobject, jobject x, long displacement))
+C2V_VMENTRY_NULL(jobject, getObject, (JNIEnv* env, jobject, jobject x, long displacement))
if (x == NULL) {
JVMCI_THROW_0(NullPointerException);
}
@@ -2052,30 +2174,38 @@
}
}
-C2V_VMENTRY(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))
+static void requireJVMCINativeLibrary(JVMCI_TRAPS) {
if (!UseJVMCINativeLibrary) {
- JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");
+ JVMCI_THROW_MSG(UnsupportedOperationException, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");
}
- if (!JVMCIENV->is_hotspot()) {
- JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "Cannot call registerNativeMethods from JVMCI shared library");
+}
+
+static JavaVM* requireNativeLibraryJavaVM(const char* caller, JVMCI_TRAPS) {
+ JavaVM* javaVM = JVMCIEnv::get_shared_library_javavm();
+ if (javaVM == NULL) {
+ JVMCI_THROW_MSG_NULL(IllegalStateException, err_msg("Require JVMCI shared library to be initialized in %s", caller));
}
+ return javaVM;
+}
+
+C2V_VMENTRY_NULL(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))
+ requireJVMCINativeLibrary(JVMCI_CHECK_NULL);
+ requireInHotSpot("registerNativeMethods", JVMCI_CHECK_NULL);
void* shared_library = JVMCIEnv::get_shared_library_handle();
if (shared_library == NULL) {
// Ensure the JVMCI shared library runtime is initialized.
- JVMCIEnv __peer_jvmci_env__(false, __FILE__, __LINE__);
+ JVMCIEnv __peer_jvmci_env__(thread, false, __FILE__, __LINE__);
JVMCIEnv* peerEnv = &__peer_jvmci_env__;
HandleMark hm;
JVMCIRuntime* runtime = JVMCI::compiler_runtime();
JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(peerEnv);
if (peerEnv->has_pending_exception()) {
peerEnv->describe_pending_exception(true);
- JVMCI_THROW_MSG_0(InternalError, "Error initializing JVMCI runtime");
}
shared_library = JVMCIEnv::get_shared_library_handle();
- }
-
- if (shared_library == NULL) {
- JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "JVMCI shared library is unavailable");
+ if (shared_library == NULL) {
+ JVMCI_THROW_MSG_0(InternalError, "Error initializing JVMCI runtime");
+ }
}
if (mirror == NULL) {
@@ -2113,15 +2243,18 @@
st.print_raw(pure_name);
st.print_raw(long_name);
os::print_jni_name_suffix_on(&st, args_size);
- jni_name = st.as_string();
- entry = (address) os::dll_lookup(shared_library, jni_name);
+ char* jni_long_name = st.as_string();
+ entry = (address) os::dll_lookup(shared_library, jni_long_name);
+ if (entry == NULL) {
+ JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [neither %s nor %s exist in %s]",
+ method->name_and_sig_as_C_string(),
+ jni_name, jni_long_name, JVMCIEnv::get_shared_library_path()));
+ }
}
- if (entry == NULL) {
- JVMCI_THROW_MSG_0(UnsatisfiedLinkError, method->name_and_sig_as_C_string());
- }
+
if (method->has_native_function() && entry != method->native_function()) {
- JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("Cannot overwrite existing native implementation for %s",
- method->name_and_sig_as_C_string()));
+ JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("%s [cannot re-link from " PTR_FORMAT " to " PTR_FORMAT "]",
+ method->name_and_sig_as_C_string(), p2i(method->native_function()), p2i(entry)));
}
method->set_native_function(entry, Method::native_bind_event_is_interesting);
if (PrintJNIResolving) {
@@ -2141,11 +2274,102 @@
return (jlongArray) JVMCIENV->get_jobject(result);
}
-C2V_VMENTRY(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))
+C2V_VMENTRY_PREFIX(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject c2vm))
+ if (base_thread == NULL) {
+ // Called from unattached JVMCI shared library thread
+ return false;
+ }
+ JVMCITraceMark jtm("isCurrentThreadAttached");
+ assert(base_thread->is_Java_thread(), "just checking");
+ JavaThread* thread = (JavaThread*) base_thread;
+ if (thread->jni_environment() == env) {
+ C2V_BLOCK(jboolean, isCurrentThreadAttached, (JNIEnv* env, jobject))
+ requireJVMCINativeLibrary(JVMCI_CHECK_0);
+ JavaVM* javaVM = requireNativeLibraryJavaVM("isCurrentThreadAttached", JVMCI_CHECK_0);
+ JNIEnv* peerEnv;
+ return javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) == JNI_OK;
+ }
+ return true;
+C2V_END
+
+C2V_VMENTRY_PREFIX(jboolean, attachCurrentThread, (JNIEnv* env, jobject c2vm, jboolean as_daemon))
+ if (base_thread == NULL) {
+ // Called from unattached JVMCI shared library thread
+ extern struct JavaVM_ main_vm;
+ JNIEnv* hotspotEnv;
+ jint res = as_daemon ? main_vm.AttachCurrentThreadAsDaemon((void**)&hotspotEnv, NULL) :
+ main_vm.AttachCurrentThread((void**)&hotspotEnv, NULL);
+ if (res != JNI_OK) {
+ JNI_THROW_("attachCurrentThread", InternalError, err_msg("Trying to attach thread returned %d", res), false);
+ }
+ return true;
+ }
+ JVMCITraceMark jtm("attachCurrentThread");
+ assert(base_thread->is_Java_thread(), "just checking");\
+ JavaThread* thread = (JavaThread*) base_thread;
+ if (thread->jni_environment() == env) {
+ // Called from HotSpot
+ C2V_BLOCK(jboolean, attachCurrentThread, (JNIEnv* env, jobject, jboolean))
+ requireJVMCINativeLibrary(JVMCI_CHECK_0);
+ JavaVM* javaVM = requireNativeLibraryJavaVM("attachCurrentThread", JVMCI_CHECK_0);
+ JavaVMAttachArgs attach_args;
+ attach_args.version = JNI_VERSION_1_2;
+ attach_args.name = thread->name();
+ attach_args.group = NULL;
+ JNIEnv* peerEnv;
+ if (javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) == JNI_OK) {
+ return false;
+ }
+ jint res = as_daemon ? javaVM->AttachCurrentThreadAsDaemon((void**)&peerEnv, &attach_args) :
+ javaVM->AttachCurrentThread((void**)&peerEnv, &attach_args);
+ if (res == JNI_OK) {
+ guarantee(peerEnv != NULL, "must be");
+ return true;
+ }
+ JVMCI_THROW_MSG_0(InternalError, err_msg("Error %d while attaching %s", res, attach_args.name));
+ }
+ // Called from JVMCI shared library
+ return false;
+C2V_END
+
+C2V_VMENTRY_PREFIX(void, detachCurrentThread, (JNIEnv* env, jobject c2vm))
+ if (base_thread == NULL) {
+ // Called from unattached JVMCI shared library thread
+ JNI_THROW("detachCurrentThread", IllegalStateException, err_msg("Cannot detach non-attached thread"));
+ }
+ JVMCITraceMark jtm("detachCurrentThread");
+ assert(base_thread->is_Java_thread(), "just checking");\
+ JavaThread* thread = (JavaThread*) base_thread;
+ if (thread->jni_environment() == env) {
+ // Called from HotSpot
+ C2V_BLOCK(void, detachCurrentThread, (JNIEnv* env, jobject))
+ requireJVMCINativeLibrary(JVMCI_CHECK);
+ requireInHotSpot("detachCurrentThread", JVMCI_CHECK);
+ JavaVM* javaVM = requireNativeLibraryJavaVM("detachCurrentThread", JVMCI_CHECK);
+ JNIEnv* peerEnv;
+ if (javaVM->GetEnv((void**)&peerEnv, JNI_VERSION_1_2) != JNI_OK) {
+ JVMCI_THROW_MSG(IllegalStateException, err_msg("Cannot detach non-attached thread: %s", thread->name()));
+ }
+ jint res = javaVM->DetachCurrentThread();
+ if (res != JNI_OK) {
+ JVMCI_THROW_MSG(InternalError, err_msg("Error %d while attaching %s", res, thread->name()));
+ }
+ } else {
+ // Called from attached JVMCI shared library thread
+ extern struct JavaVM_ main_vm;
+ jint res = main_vm.DetachCurrentThread();
+ if (res != JNI_OK) {
+ JNI_THROW("detachCurrentThread", InternalError, err_msg("Cannot detach non-attached thread"));
+ }
+ }
+C2V_END
+
+C2V_VMENTRY_0(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))
+ requireJVMCINativeLibrary(JVMCI_CHECK_0);
if (obj_handle == NULL) {
return 0L;
}
- JVMCIEnv __peer_jvmci_env__(!JVMCIENV->is_hotspot(), __FILE__, __LINE__);
+ JVMCIEnv __peer_jvmci_env__(thread, !JVMCIENV->is_hotspot(), __FILE__, __LINE__);
JVMCIEnv* peerEnv = &__peer_jvmci_env__;
JVMCIEnv* thisEnv = JVMCIENV;
@@ -2216,7 +2440,8 @@
return (jlong) peerEnv->make_global(result).as_jobject();
}
-C2V_VMENTRY(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))
+C2V_VMENTRY_NULL(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))
+ requireJVMCINativeLibrary(JVMCI_CHECK_NULL);
if (obj_handle == 0L) {
return NULL;
}
@@ -2234,7 +2459,7 @@
JVMCIENV->asNmethod(code);
}
-C2V_VMENTRY(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
+C2V_VMENTRY_NULL(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
JVMCIObject code = JVMCIENV->wrap(code_handle);
CodeBlob* cb = JVMCIENV->asCodeBlob(code);
if (cb == NULL) {
@@ -2246,10 +2471,8 @@
return JVMCIENV->get_jbyteArray(result);
}
-C2V_VMENTRY(jobject, asReflectionExecutable, (JNIEnv* env, jobject, jobject jvmci_method))
- if (env != JavaThread::current()->jni_environment()) {
- JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
- }
+C2V_VMENTRY_NULL(jobject, asReflectionExecutable, (JNIEnv* env, jobject, jobject jvmci_method))
+ requireInHotSpot("asReflectionExecutable", JVMCI_CHECK_NULL);
methodHandle m = JVMCIENV->asMethod(jvmci_method);
oop executable;
if (m->is_initializer()) {
@@ -2264,10 +2487,8 @@
return JNIHandles::make_local(THREAD, executable);
}
-C2V_VMENTRY(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmci_type, jint index))
- if (env != JavaThread::current()->jni_environment()) {
- JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
- }
+C2V_VMENTRY_NULL(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmci_type, jint index))
+ requireInHotSpot("asReflectionField", JVMCI_CHECK_NULL);
Klass* klass = JVMCIENV->asKlass(jvmci_type);
if (!klass->is_instance_klass()) {
JVMCI_THROW_MSG_NULL(IllegalArgumentException,
@@ -2284,7 +2505,7 @@
return JNIHandles::make_local(env, reflected);
}
-C2V_VMENTRY(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current))
+C2V_VMENTRY_NULL(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current))
FailedSpeculation* head = *((FailedSpeculation**)(address) failed_speculations_address);
int result_length = 0;
for (FailedSpeculation* fs = head; fs != NULL; fs = fs->next()) {
@@ -2316,7 +2537,7 @@
return JVMCIENV->get_jobjectArray(result);
}
-C2V_VMENTRY(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, jobject jvmci_method))
+C2V_VMENTRY_0(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, jobject jvmci_method))
methodHandle method = JVMCIENV->asMethod(jvmci_method);
MethodData* method_data = method->method_data();
if (method_data == NULL) {
@@ -2331,7 +2552,7 @@
FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);
}
-C2V_VMENTRY(bool, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
+C2V_VMENTRY_0(bool, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
JVMCIPrimitiveArray speculation_handle = JVMCIENV->wrap(speculation_obj);
int speculation_len = JVMCIENV->get_length(speculation_handle);
char* speculation = NEW_RESOURCE_ARRAY(char, speculation_len);
@@ -2431,7 +2652,7 @@
{CC "iterateFrames", CC "([" RESOLVED_METHOD "[" RESOLVED_METHOD "I" INSPECTED_FRAME_VISITOR ")" OBJECT, FN_PTR(iterateFrames)},
{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 "writeDebugOutput", CC "([BIIZZ)I", FN_PTR(writeDebugOutput)},
{CC "flushDebugOutput", CC "()V", FN_PTR(flushDebugOutput)},
{CC "methodDataProfileDataSize", CC "(JI)I", FN_PTR(methodDataProfileDataSize)},
{CC "getFingerprint", CC "(J)J", FN_PTR(getFingerprint)},
@@ -2469,6 +2690,9 @@
{CC "getObject", CC "(" OBJECTCONSTANT "J)" OBJECTCONSTANT, FN_PTR(getObject)},
{CC "deleteGlobalHandle", CC "(J)V", FN_PTR(deleteGlobalHandle)},
{CC "registerNativeMethods", CC "(" CLASS ")[J", FN_PTR(registerNativeMethods)},
+ {CC "isCurrentThreadAttached", CC "()Z", FN_PTR(isCurrentThreadAttached)},
+ {CC "attachCurrentThread", CC "(Z)Z", FN_PTR(attachCurrentThread)},
+ {CC "detachCurrentThread", CC "()V", FN_PTR(detachCurrentThread)},
{CC "translate", CC "(" OBJECT ")J", FN_PTR(translate)},
{CC "unhand", CC "(J)" OBJECT, FN_PTR(unhand)},
{CC "updateHotSpotNmethod", CC "(" HS_NMETHOD ")V", FN_PTR(updateHotSpotNmethod)},
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp Tue May 07 17:30:14 2019 -0400
@@ -160,13 +160,14 @@
};
class JNIHandleMark : public StackObj {
+ JavaThread* _thread;
public:
- JNIHandleMark() { push_jni_handle_block(); }
- ~JNIHandleMark() { pop_jni_handle_block(); }
+ JNIHandleMark(JavaThread* thread) : _thread(thread) { push_jni_handle_block(thread); }
+ ~JNIHandleMark() { pop_jni_handle_block(_thread); }
private:
- static void push_jni_handle_block();
- static void pop_jni_handle_block();
+ static void push_jni_handle_block(JavaThread* thread);
+ static void pop_jni_handle_block(JavaThread* thread);
};
#endif // SHARE_JVMCI_JVMCICOMPILERTOVM_HPP
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp Tue May 07 17:30:14 2019 -0400
@@ -129,11 +129,10 @@
}
}
-JNIEnv* JVMCIEnv::attach_shared_library() {
+JNIEnv* JVMCIEnv::init_shared_library(JavaThread* thread) {
if (_shared_library_javavm == NULL) {
MutexLocker locker(JVMCI_lock);
if (_shared_library_javavm == NULL) {
-
char path[JVM_MAXPATHLEN];
char ebuf[1024];
if (JVMCILibPath != NULL) {
@@ -179,85 +178,107 @@
}
}
}
- JNIEnv* env;
- if (_shared_library_javavm->AttachCurrentThread((void**)&env, NULL) == JNI_OK) {
- guarantee(env != NULL, "missing env");
- return env;
- }
- fatal("Error attaching current thread to JVMCI shared library JNI interface");
return NULL;
}
-void JVMCIEnv::init_env_mode_runtime(JNIEnv* parent_env) {
+void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) {
+ assert(thread != NULL, "npe");
// By default there is only one runtime which is the compiler runtime.
_runtime = JVMCI::compiler_runtime();
+ _env = NULL;
+ _pop_frame_on_close = false;
+ _detach_on_close = false;
if (!UseJVMCINativeLibrary) {
// In HotSpot mode, JNI isn't used at all.
_is_hotspot = true;
- _env = NULL;
return;
}
if (parent_env != NULL) {
// If the parent JNI environment is non-null then figure out whether it
// is a HotSpot or shared library JNIEnv and set the state appropriately.
- JavaThread* thread = JavaThread::current();
- if (thread->jni_environment() == parent_env) {
+ _is_hotspot = thread->jni_environment() == parent_env;
+ if (_is_hotspot) {
// Select the Java runtime
_runtime = JVMCI::java_runtime();
- _is_hotspot = true;
- _env = NULL;
return;
}
+ _env = parent_env;
+ return;
+ }
+
+ // Running in JVMCI shared library mode so ensure the shared library
+ // is loaded and initialized and get a shared library JNIEnv
+ _is_hotspot = false;
+ _env = init_shared_library(thread);
+
+ if (_env != NULL) {
+ // Creating the JVMCI shared library VM also attaches the current thread
+ _detach_on_close = true;
+ } else {
+ _shared_library_javavm->GetEnv((void**)&parent_env, JNI_VERSION_1_2);
+ if (parent_env != NULL) {
+ // Even though there's a parent JNI env, there's no guarantee
+ // it was opened by a JVMCIEnv scope and thus may not have
+ // pushed a local JNI frame. As such, we use a new JNI local
+ // frame in this scope to ensure local JNI refs are collected
+ // in a timely manner after leaving this scope.
+ _env = parent_env;
+ } else {
+ ResourceMark rm; // Thread name is resource allocated
+ JavaVMAttachArgs attach_args;
+ attach_args.version = JNI_VERSION_1_2;
+ attach_args.name = thread->name();
+ attach_args.group = NULL;
+ if (_shared_library_javavm->AttachCurrentThread((void**)&_env, &attach_args) != JNI_OK) {
+ fatal("Error attaching current thread (%s) to JVMCI shared library JNI interface", attach_args.name);
+ }
+ _detach_on_close = true;
+ }
}
- // Running in JVMCI shared library mode so get a shared library JNIEnv
- _is_hotspot = false;
- _env = attach_shared_library();
- assert(parent_env == NULL || _env == parent_env, "must be");
+ assert(_env != NULL, "missing env");
+ assert(_throw_to_caller == false, "must be");
- if (parent_env == NULL) {
- // There is no parent shared library JNI env so push
- // a JNI local frame to release all local handles in
- // this JVMCIEnv scope when it's closed.
- assert(_throw_to_caller == false, "must be");
- JNIAccessMark jni(this);
- jint result = _env->PushLocalFrame(32);
- if (result != JNI_OK) {
- char message[256];
- jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
- JVMCIRuntime::exit_on_pending_exception(this, message);
- }
+ JNIAccessMark jni(this);
+ jint result = _env->PushLocalFrame(32);
+ if (result != JNI_OK) {
+ char message[256];
+ jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
+ JVMCIRuntime::exit_on_pending_exception(this, message);
}
+ _pop_frame_on_close = true;
}
-JVMCIEnv::JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line):
+JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line):
_throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {
- init_env_mode_runtime(NULL);
+ init_env_mode_runtime(thread, NULL);
}
JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
_throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {
- init_env_mode_runtime(NULL);
+ init_env_mode_runtime(thread, NULL);
}
-JVMCIEnv::JVMCIEnv(JNIEnv* parent_env, const char* file, int line):
+JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line):
_throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {
- init_env_mode_runtime(parent_env);
+ init_env_mode_runtime(thread, parent_env);
assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");
}
-void JVMCIEnv::init(bool is_hotspot, const char* file, int line) {
+void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) {
_compile_state = NULL;
_throw_to_caller = false;
_file = file;
_line = line;
if (is_hotspot) {
_env = NULL;
+ _pop_frame_on_close = false;
+ _detach_on_close = false;
_is_hotspot = true;
_runtime = JVMCI::java_runtime();
} else {
- init_env_mode_runtime(NULL);
+ init_env_mode_runtime(thread, NULL);
}
}
@@ -324,7 +345,7 @@
}
}
} else {
- if (!is_hotspot()) {
+ if (_pop_frame_on_close) {
// Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
JNIAccessMark jni(this);
jni()->PopLocalFrame(NULL);
@@ -335,6 +356,10 @@
jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
JVMCIRuntime::exit_on_pending_exception(this, message);
}
+
+ if (_detach_on_close) {
+ get_shared_library_javavm()->DetachCurrentThread();
+ }
}
}
@@ -463,26 +488,38 @@
}
}
-void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes) {
- if (size_in_bytes == 0) {
+void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) {
+ if (length == 0) {
+ return;
+ }
+ if (is_hotspot()) {
+ memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length);
+ } else {
+ JNIAccessMark jni(this);
+ jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest);
+ }
+}
+void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
+ if (length == 0) {
return;
}
if (is_hotspot()) {
- memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), size_in_bytes);
+ memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length);
} else {
JNIAccessMark jni(this);
- jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, size_in_bytes, dest);
+ jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src);
}
}
-void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes) {
- if (size_in_bytes == 0) {
+
+void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) {
+ if (length == 0) {
return;
}
if (is_hotspot()) {
- memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, size_in_bytes);
+ memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong));
} else {
JNIAccessMark jni(this);
- jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, size_in_bytes, src);
+ jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src);
}
}
@@ -612,6 +649,8 @@
DO_THROW(IllegalArgumentException)
DO_THROW(InvalidInstalledCodeException)
DO_THROW(UnsatisfiedLinkError)
+DO_THROW(UnsupportedOperationException)
+DO_THROW(ClassNotFoundException)
#undef DO_THROW
@@ -888,7 +927,7 @@
return JVMCIObject();
}
jobject file_name = NULL;
- if (file_name != NULL) {
+ if (file_name_sym != NULL) {
file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
if (jni()->ExceptionCheck()) {
return JVMCIObject();
@@ -1323,14 +1362,15 @@
assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type");
oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant));
return Handle(THREAD, obj);
- } else {
- assert(isa_IndirectHotSpotObjectConstantImpl(constant), "wrong type");
+ } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) {
jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant);
oop result = resolve_handle(object_handle);
if (result == NULL) {
JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle());
}
return Handle(THREAD, result);
+ } else {
+ JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle());
}
}
--- a/src/hotspot/share/jvmci/jvmciEnv.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciEnv.hpp Tue May 07 17:30:14 2019 -0400
@@ -36,15 +36,6 @@
class JVMCICompiler;
class JVMCIRuntime;
-// Bring the JVMCI compiler thread into the VM state.
-#define JVMCI_VM_ENTRY_MARK \
- JavaThread* thread = JavaThread::current(); \
- ThreadInVMfromNative __tiv(thread); \
- ResetNoHandleMark rnhm; \
- HandleMarkCleaner __hm(thread); \
- Thread* THREAD = thread; \
- debug_only(VMNativeEntryWrapper __vew;)
-
#define JVMCI_EXCEPTION_CONTEXT \
JavaThread* thread=JavaThread::current(); \
Thread* THREAD = thread;
@@ -154,24 +145,25 @@
static void* _shared_library_handle; // result of os::dll_load
static JavaVM* _shared_library_javavm; // result of calling JNI_CreateJavaVM in shared library
- // Attaches the current thread to the JavaVM in the shared library,
- // initializing the shared library VM first if necessary.
- // Returns the JNI interface pointer of the current thread.
- // The _shared_library_* fields are initialized by the first
- // call to this method.
- static JNIEnv* attach_shared_library();
+ // Initializes the shared library JavaVM if not already initialized.
+ // Returns the JNI interface pointer for the current thread
+ // if initialization was performed by this call, NULL if
+ // initialization was performed by a previous call.
+ static JNIEnv* init_shared_library(JavaThread* thread);
// Initializes the _env, _mode and _runtime fields.
- void init_env_mode_runtime(JNIEnv* parent_env);
+ void init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env);
- void init(bool is_hotspot, const char* file, int line);
+ void init(JavaThread* thread, bool is_hotspot, const char* file, int line);
- JNIEnv* _env; // JNI env for calling into shared library
- JVMCIRuntime* _runtime; // Access to a HotSpotJVMCIRuntime
- bool _is_hotspot; // Which heap is the HotSpotJVMCIRuntime in
- bool _throw_to_caller; // Propagate an exception raised in this env to the caller?
- const char* _file; // The file and ...
- int _line; // ... line where this JNIEnv was created
+ JNIEnv* _env; // JNI env for calling into shared library
+ bool _pop_frame_on_close; // Must pop frame on close?
+ bool _detach_on_close; // Must detach on close?
+ JVMCIRuntime* _runtime; // Access to a HotSpotJVMCIRuntime
+ bool _is_hotspot; // Which heap is the HotSpotJVMCIRuntime in
+ bool _throw_to_caller; // Propagate an exception raised in this env to the caller?
+ const char* _file; // The file and ...
+ int _line; // ... line where this JNIEnv was created
// Translates an exception on the HotSpot heap to an exception on
// the shared library heap. The translation includes the stack and
@@ -185,12 +177,12 @@
// scope closes so that it will be propagated back to Java.
// The JVMCIEnv destructor translates the exception object for the
// Java runtime if necessary.
- JVMCIEnv(JNIEnv* env, const char* file, int line);
+ JVMCIEnv(JavaThread* thread, JNIEnv* env, const char* file, int line);
// Opens a JVMCIEnv scope for a compilation scheduled by the CompileBroker.
// An exception occurring within the scope must not be propagated back to
// the CompileBroker.
- JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line);
+ JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line);
// Opens a JNIEnv scope for a call from within the VM. An exception occurring
// within the scope must not be propagated back to the caller.
@@ -198,20 +190,20 @@
// Opens a JNIEnv scope for accessing `for_object`. An exception occurring
// within the scope must not be propagated back to the caller.
- JVMCIEnv(JVMCIObject for_object, const char* file, int line) {
+ JVMCIEnv(JavaThread* thread, JVMCIObject for_object, const char* file, int line) {
// A JNI call to access an object in the shared library heap
// can block or take a long time so do not allow such access
// on the VM thread.
assert(for_object.is_hotspot() || !Thread::current()->is_VM_thread(),
"cannot open JVMCIEnv scope when in the VM thread for accessing a shared library heap object");
- init(for_object.is_hotspot(), file, line);
+ init(thread, for_object.is_hotspot(), file, line);
}
// Opens a JNIEnv scope for the HotSpot runtime if `is_hotspot` is true
// otherwise for the shared library runtime. An exception occurring
// within the scope must not be propagated back to the caller.
- JVMCIEnv(bool is_hotspot, const char* file, int line) {
- init(is_hotspot, file, line);
+ JVMCIEnv(JavaThread* thread, bool is_hotspot, const char* file, int line) {
+ init(thread, is_hotspot, file, line);
}
~JVMCIEnv();
@@ -247,8 +239,10 @@
long get_long_at(JVMCIPrimitiveArray array, int index);
void put_long_at(JVMCIPrimitiveArray array, int index, jlong value);
- void copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes);
- void copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes);
+ void copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length);
+ void copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length);
+
+ void copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length);
JVMCIObjectArray initialize_intrinsics(JVMCI_TRAPS);
@@ -323,6 +317,8 @@
DO_THROW(IllegalArgumentException)
DO_THROW(InvalidInstalledCodeException)
DO_THROW(UnsatisfiedLinkError)
+ DO_THROW(UnsupportedOperationException)
+ DO_THROW(ClassNotFoundException)
#undef DO_THROW
--- a/src/hotspot/share/jvmci/jvmciExceptions.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciExceptions.hpp Tue May 07 17:30:14 2019 -0400
@@ -32,8 +32,8 @@
#define JVMCIENV __jvmci_env__
#define JVMCI_TRAPS JVMCIEnv* JVMCIENV
-#define JNI_JVMCIENV(env) \
- JVMCIEnv __stack_jvmci_env__(env, __FILE__, __LINE__); \
+#define JNI_JVMCIENV(thread, env) \
+ JVMCIEnv __stack_jvmci_env__(thread, env, __FILE__, __LINE__); \
JVMCIEnv* JVMCIENV = &__stack_jvmci_env__
#define THREAD_JVMCIENV(thread) \
--- a/src/hotspot/share/jvmci/jvmciJavaClasses.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciJavaClasses.cpp Tue May 07 17:30:14 2019 -0400
@@ -356,6 +356,43 @@
jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
}
+// Dumps symbols for public <init>() and <init>(String) methods of
+// non-abstract Throwable subtypes known by the VM. This is to
+// support the use of reflection in jdk.vm.ci.hotspot.TranslatedException.create().
+class ThrowableInitDumper : public SymbolClosure {
+ private:
+ fileStream* _st;
+ public:
+ ThrowableInitDumper(fileStream* st) { _st = st; }
+ void do_symbol(Symbol** p) {
+ Thread* THREAD = Thread::current();
+ Symbol* name = *p;
+ if (name == NULL) {
+ return;
+ }
+ Klass* k = SystemDictionary::resolve_or_null(name, CHECK_EXIT);
+ if (k != NULL && k->is_instance_klass()) {
+ InstanceKlass* iklass = InstanceKlass::cast(k);
+ if (iklass->is_subclass_of(SystemDictionary::Throwable_klass()) && iklass->is_public() && !iklass->is_abstract()) {
+ const char* class_name = NULL;
+ Array<Method*>* methods = iklass->methods();
+ for (int i = 0; i < methods->length(); i++) {
+ Method* m = methods->at(i);
+ if (m->name() == vmSymbols::object_initializer_name() &&
+ m->is_public() &&
+ (m->signature() == vmSymbols::void_method_signature() || m->signature() == vmSymbols::string_void_signature())) {
+ if (class_name == NULL) {
+ class_name = name->as_C_string();
+ _st->print_cr("class %s", class_name);
+ }
+ _st->print_cr("method %s %s %s", class_name, m->name()->as_C_string(), m->signature()->as_C_string());
+ }
+ }
+ }
+ }
+ }
+};
+
#define IN_CLASS(fullClassName) current_class_name = vmSymbols::fullClassName()->as_C_string()
/**
* Initializes the JNI method and field ids used in JNIJVMCI.
@@ -441,6 +478,8 @@
fileStream* st = JVMCIGlobals::get_jni_config_file();
DUMP_ALL_NATIVE_METHODS(vmSymbols::jdk_vm_ci_hotspot_CompilerToVM());
+ ThrowableInitDumper dumper(st);
+ vmSymbols::symbols_do(&dumper);
st->flush();
tty->print_cr("Dumped JVMCI shared library JNI configuration to %s", JVMCILibDumpJNIConfig);
--- a/src/hotspot/share/jvmci/jvmciJavaClasses.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciJavaClasses.hpp Tue May 07 17:30:14 2019 -0400
@@ -381,12 +381,18 @@
start_class(InternalError, java_lang_InternalError) \
jvmci_constructor(InternalError, "(Ljava/lang/String;)V") \
end_class \
+ start_class(ClassNotFoundException, java_lang_ClassNotFoundException) \
+ jvmci_constructor(ClassNotFoundException, "(Ljava/lang/String;)V") \
+ end_class \
start_class(InvalidInstalledCodeException, jdk_vm_ci_code_InvalidInstalledCodeException) \
jvmci_constructor(InvalidInstalledCodeException, "(Ljava/lang/String;)V") \
end_class \
start_class(UnsatisfiedLinkError, java_lang_UnsatisfiedLinkError) \
jvmci_constructor(UnsatisfiedLinkError, "(Ljava/lang/String;)V") \
end_class \
+ start_class(UnsupportedOperationException, java_lang_UnsupportedOperationException) \
+ jvmci_constructor(UnsupportedOperationException, "(Ljava/lang/String;)V") \
+ end_class \
start_class(StackTraceElement, java_lang_StackTraceElement) \
object_field(StackTraceElement, declaringClass, "Ljava/lang/String;") \
object_field(StackTraceElement, methodName, "Ljava/lang/String;") \
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Tue May 07 17:30:14 2019 -0400
@@ -655,7 +655,7 @@
// private static JVMCIRuntime JVMCI.initializeRuntime()
JVM_ENTRY_NO_ENV(jobject, JVM_GetJVMCIRuntime(JNIEnv *env, jclass c))
- JNI_JVMCIENV(env);
+ JNI_JVMCIENV(thread, env);
if (!EnableJVMCI) {
JVMCI_THROW_MSG_NULL(InternalError, "JVMCI is not enabled");
}
@@ -877,7 +877,7 @@
fatal("check TLAB allocation code for address space conflicts");
#endif
- JNI_JVMCIENV(env);
+ JNI_JVMCIENV(thread, env);
if (!EnableJVMCI) {
JVMCI_THROW_MSG(InternalError, "JVMCI is not enabled");
@@ -1353,6 +1353,10 @@
compile_state->set_failure(true, "No OSR during boostrap");
return;
}
+ if (JVMCI::shutdown_called()) {
+ compile_state->set_failure(false, "Avoiding compilation during shutdown");
+ return;
+ }
HandleMark hm;
JVMCIObject receiver = get_HotSpotJVMCIRuntime(JVMCIENV);
--- a/src/hotspot/share/jvmci/jvmci_globals.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmci_globals.cpp Tue May 07 17:30:14 2019 -0400
@@ -83,7 +83,7 @@
}
FLAG_SET_DEFAULT(EnableJVMCI, true);
if (BootstrapJVMCI && UseJVMCINativeLibrary) {
- jio_fprintf(defaultStream::error_stream(), "-XX:+BootstrapJVMCI is not compatible with -XX:+UseJVMCINativeLibrary");
+ jio_fprintf(defaultStream::error_stream(), "-XX:+BootstrapJVMCI is not compatible with -XX:+UseJVMCINativeLibrary\n");
return false;
}
}
--- a/src/hotspot/share/jvmci/jvmci_globals.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmci_globals.hpp Tue May 07 17:30:14 2019 -0400
@@ -53,7 +53,10 @@
"Prints properties used by the JVMCI compiler and exits") \
\
experimental(bool, BootstrapJVMCI, false, \
- "Bootstrap JVMCI before running Java main method") \
+ "Bootstrap JVMCI before running Java main method. This " \
+ "initializes the compile queue with a small set of methods " \
+ "and processes the queue until it is empty. Combining this with " \
+ "-XX:-TieredCompilation makes JVMCI compile more of itself.") \
\
experimental(bool, EagerJVMCI, false, \
"Force eager JVMCI initialization") \
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp Tue May 07 17:30:14 2019 -0400
@@ -246,6 +246,10 @@
\
nonstatic_field(ObjArrayKlass, _element_klass, Klass*) \
\
+ volatile_nonstatic_field(ObjectMonitor, _cxq, ObjectWaiter*) \
+ volatile_nonstatic_field(ObjectMonitor, _EntryList, ObjectWaiter*) \
+ volatile_nonstatic_field(ObjectMonitor, _succ, Thread*) \
+ \
volatile_nonstatic_field(oopDesc, _mark, markOop) \
volatile_nonstatic_field(oopDesc, _metadata._klass, Klass*) \
\
@@ -347,6 +351,7 @@
declare_toplevel_type(JVMCIEnv) \
declare_toplevel_type(LocalVariableTableElement) \
declare_toplevel_type(narrowKlass) \
+ declare_toplevel_type(ObjectWaiter) \
declare_toplevel_type(Symbol*) \
declare_toplevel_type(vtableEntry) \
\
--- a/src/hotspot/share/oops/cpCache.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/oops/cpCache.cpp Tue May 07 17:30:14 2019 -0400
@@ -506,7 +506,7 @@
switch (invoke_code) {
case Bytecodes::_invokeinterface:
assert(f1->is_klass(), "");
- return klassItable::method_for_itable_index((InstanceKlass*)f1, f2_as_index());
+ return f2_as_interface_method();
case Bytecodes::_invokestatic:
case Bytecodes::_invokespecial:
assert(!has_appendix(), "");
--- a/src/hotspot/share/oops/instanceKlass.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/oops/instanceKlass.cpp Tue May 07 17:30:14 2019 -0400
@@ -2965,6 +2965,13 @@
// On-stack replacement stuff
void InstanceKlass::add_osr_nmethod(nmethod* n) {
+#ifndef PRODUCT
+ if (TieredCompilation) {
+ nmethod * prev = lookup_osr_nmethod(n->method(), n->osr_entry_bci(), n->comp_level(), true);
+ assert(prev == NULL || !prev->is_in_use(),
+ "redundunt OSR recompilation detected. memory leak in CodeCache!");
+ }
+#endif
// only one compilation can be active
{
// This is a short non-blocking critical region, so the no safepoint check is ok.
@@ -3083,7 +3090,9 @@
}
osr = osr->osr_link();
}
- if (best != NULL && best->comp_level() >= comp_level && match_level == false) {
+
+ assert(match_level == false || best == NULL, "shouldn't pick up anything if match_level is set");
+ if (best != NULL && best->comp_level() >= comp_level) {
return best;
}
return NULL;
--- a/src/hotspot/share/oops/klass.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/oops/klass.cpp Tue May 07 17:30:14 2019 -0400
@@ -733,8 +733,9 @@
st->cr();
}
+#define BULLET " - "
+
void Klass::oop_print_on(oop obj, outputStream* st) {
- ResourceMark rm;
// print title
st->print_cr("%s ", internal_name());
obj->print_address_on(st);
@@ -742,10 +743,13 @@
if (WizardMode) {
// print header
obj->mark()->print_on(st);
+ st->cr();
+ st->print(BULLET"prototype_header: " INTPTR_FORMAT, p2i(_prototype_header));
+ st->cr();
}
// print class
- st->print(" - klass: ");
+ st->print(BULLET"klass: ");
obj->klass()->print_value_on(st);
st->cr();
}
--- a/src/hotspot/share/oops/markOop.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/oops/markOop.cpp Tue May 07 17:30:14 2019 -0400
@@ -25,45 +25,40 @@
#include "precompiled.hpp"
#include "oops/markOop.hpp"
#include "runtime/thread.inline.hpp"
-#include "runtime/objectMonitor.inline.hpp"
+#include "runtime/objectMonitor.hpp"
void markOopDesc::print_on(outputStream* st) const {
- if (is_marked()) {
+ if (is_marked()) { // last bits = 11
st->print(" marked(" INTPTR_FORMAT ")", value());
- } else if (has_monitor()) {
+ } else if (has_monitor()) { // last bits = 10
// have to check has_monitor() before is_locked()
st->print(" monitor(" INTPTR_FORMAT ")=", value());
ObjectMonitor* mon = monitor();
if (mon == NULL) {
st->print("NULL (this should never be seen!)");
} else {
- st->print("{contentions=0x%08x,waiters=0x%08x"
- ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
- mon->contentions(), mon->waiters(), mon->recursions(),
- p2i(mon->owner()));
+ mon->print_on(st);
}
- } else if (is_locked()) {
- st->print(" locked(" INTPTR_FORMAT ")->", value());
- if (is_neutral()) {
+ } else if (is_locked()) { // last bits != 01 => 00
+ // thin locked
+ st->print(" locked(" INTPTR_FORMAT ")", value());
+ } else {
+ st->print(" mark(");
+ // Biased bit is 3rd rightmost bit
+ if (is_neutral()) { // last bits = 001
st->print("is_neutral");
if (has_no_hash()) {
st->print(" no_hash");
} else {
st->print(" hash=" INTPTR_FORMAT, hash());
}
- st->print(" age=%d", age());
- } else if (has_bias_pattern()) {
+ } else if (has_bias_pattern()) { // last bits = 101
st->print("is_biased");
JavaThread* jt = biased_locker();
- st->print(" biased_locker=" INTPTR_FORMAT, p2i(jt));
+ st->print(" biased_locker=" INTPTR_FORMAT " epoch=%d", p2i(jt), bias_epoch());
} else {
st->print("??");
}
- } else {
- assert(is_unlocked() || has_bias_pattern(), "just checking");
- st->print("mark(");
- if (has_bias_pattern()) st->print("biased,");
- st->print("hash " INTPTR_FORMAT ",", hash());
- st->print("age %d)", age());
+ st->print(" age=%d)", age());
}
}
--- a/src/hotspot/share/oops/method.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/oops/method.cpp Tue May 07 17:30:14 2019 -0400
@@ -624,6 +624,10 @@
return can_be_statically_bound(method_holder()->access_flags());
}
+bool Method::can_be_statically_bound(InstanceKlass* context) const {
+ return (method_holder() == context) && can_be_statically_bound();
+}
+
bool Method::is_accessor() const {
return is_getter() || is_setter();
}
--- a/src/hotspot/share/oops/method.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/oops/method.hpp Tue May 07 17:30:14 2019 -0400
@@ -619,6 +619,7 @@
// true if method needs no dynamic dispatch (final and/or no vtable entry)
bool can_be_statically_bound() const;
+ bool can_be_statically_bound(InstanceKlass* context) const;
bool can_be_statically_bound(AccessFlags class_access_flags) const;
// returns true if the method has any backward branches.
--- a/src/hotspot/share/opto/bytecodeInfo.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/bytecodeInfo.cpp Tue May 07 17:30:14 2019 -0400
@@ -321,6 +321,35 @@
return false;
}
+bool InlineTree::is_not_reached(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile) {
+ if (!UseInterpreter) {
+ return false; // -Xcomp
+ }
+ if (profile.count() > 0) {
+ return false; // reachable according to profile
+ }
+ if (!callee_method->was_executed_more_than(0)) {
+ return true; // callee was never executed
+ }
+ if (caller_method->is_not_reached(caller_bci)) {
+ return true; // call site not resolved
+ }
+ if (profile.count() == -1) {
+ return false; // immature profile; optimistically treat as reached
+ }
+ assert(profile.count() == 0, "sanity");
+
+ // Profile info is scarce.
+ // Try to guess: check if the call site belongs to a start block.
+ // Call sites in a start block should be reachable if no exception is thrown earlier.
+ ciMethodBlocks* caller_blocks = caller_method->get_method_blocks();
+ bool is_start_block = caller_blocks->block_containing(caller_bci)->start_bci() == 0;
+ if (is_start_block) {
+ return false; // treat the call reached as part of start block
+ }
+ return true; // give up and treat the call site as not reached
+}
+
//-----------------------------try_to_inline-----------------------------------
// return true if ok
// Relocated from "InliningClosure::try_to_inline"
@@ -372,7 +401,7 @@
// inline constructors even if they are not reached.
} else if (forced_inline()) {
// Inlining was forced by CompilerOracle, ciReplay or annotation
- } else if (profile.count() == 0) {
+ } else if (is_not_reached(callee_method, caller_method, caller_bci, profile)) {
// don't inline unreached call sites
set_msg("call site not reached");
return false;
--- a/src/hotspot/share/opto/c2compiler.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/c2compiler.cpp Tue May 07 17:30:14 2019 -0400
@@ -460,6 +460,9 @@
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
case vmIntrinsics::_dabs:
+ case vmIntrinsics::_fabs:
+ case vmIntrinsics::_iabs:
+ case vmIntrinsics::_labs:
case vmIntrinsics::_datan2:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dexp:
--- a/src/hotspot/share/opto/classes.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/classes.hpp Tue May 07 17:30:14 2019 -0400
@@ -30,6 +30,7 @@
macro(AbsD)
macro(AbsF)
macro(AbsI)
+macro(AbsL)
macro(AddD)
macro(AddF)
macro(AddI)
@@ -335,6 +336,7 @@
macro(SubVL)
macro(SubVF)
macro(SubVD)
+macro(MulVB)
macro(MulVS)
macro(MulVI)
macro(MulReductionVI)
@@ -349,6 +351,10 @@
macro(FmaVF)
macro(DivVF)
macro(DivVD)
+macro(AbsVB)
+macro(AbsVS)
+macro(AbsVI)
+macro(AbsVL)
macro(AbsVF)
macro(AbsVD)
macro(NegVF)
--- a/src/hotspot/share/opto/doCall.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/doCall.cpp Tue May 07 17:30:14 2019 -0400
@@ -1152,14 +1152,19 @@
cha_monomorphic_target = NULL;
}
}
+
if (cha_monomorphic_target != NULL) {
// Hardwiring a virtual.
- // If we inlined because CHA revealed only a single target method,
- // then we are dependent on that target method not getting overridden
- // by dynamic class loading. Be sure to test the "static" receiver
- // dest_method here, as opposed to the actual receiver, which may
- // falsely lead us to believe that the receiver is final or private.
- dependencies()->assert_unique_concrete_method(actual_receiver, cha_monomorphic_target);
+ assert(!callee->can_be_statically_bound(), "should have been handled earlier");
+ assert(!cha_monomorphic_target->is_abstract(), "");
+ if (!cha_monomorphic_target->can_be_statically_bound(actual_receiver)) {
+ // If we inlined because CHA revealed only a single target method,
+ // then we are dependent on that target method not getting overridden
+ // by dynamic class loading. Be sure to test the "static" receiver
+ // dest_method here, as opposed to the actual receiver, which may
+ // falsely lead us to believe that the receiver is final or private.
+ dependencies()->assert_unique_concrete_method(actual_receiver, cha_monomorphic_target);
+ }
return cha_monomorphic_target;
}
--- a/src/hotspot/share/opto/library_call.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/library_call.cpp Tue May 07 17:30:14 2019 -0400
@@ -227,6 +227,7 @@
bool runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName);
bool inline_math_native(vmIntrinsics::ID id);
bool inline_math(vmIntrinsics::ID id);
+ bool inline_double_math(vmIntrinsics::ID id);
template <typename OverflowOp>
bool inline_math_overflow(Node* arg1, Node* arg2);
void inline_math_mathExact(Node* math, Node* test);
@@ -533,6 +534,9 @@
case vmIntrinsics::_dcos:
case vmIntrinsics::_dtan:
case vmIntrinsics::_dabs:
+ case vmIntrinsics::_fabs:
+ case vmIntrinsics::_iabs:
+ case vmIntrinsics::_labs:
case vmIntrinsics::_datan2:
case vmIntrinsics::_dsqrt:
case vmIntrinsics::_dexp:
@@ -1793,7 +1797,7 @@
// public static double Math.sqrt(double)
// public static double Math.log(double)
// public static double Math.log10(double)
-bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
+bool LibraryCallKit::inline_double_math(vmIntrinsics::ID id) {
Node* arg = round_double_node(argument(0));
Node* n = NULL;
switch (id) {
@@ -1805,6 +1809,23 @@
return true;
}
+//------------------------------inline_math-----------------------------------
+// public static float Math.abs(float)
+// public static int Math.abs(int)
+// public static long Math.abs(long)
+bool LibraryCallKit::inline_math(vmIntrinsics::ID id) {
+ Node* arg = argument(0);
+ Node* n = NULL;
+ switch (id) {
+ case vmIntrinsics::_fabs: n = new AbsFNode( arg); break;
+ case vmIntrinsics::_iabs: n = new AbsINode( arg); break;
+ case vmIntrinsics::_labs: n = new AbsLNode( arg); break;
+ default: fatal_unexpected_iid(id); break;
+ }
+ set_result(_gvn.transform(n));
+ return true;
+}
+
//------------------------------runtime_math-----------------------------
bool LibraryCallKit::runtime_math(const TypeFunc* call_type, address funcAddr, const char* funcName) {
assert(call_type == OptoRuntime::Math_DD_D_Type() || call_type == OptoRuntime::Math_D_D_Type(),
@@ -1855,8 +1876,11 @@
runtime_math(OptoRuntime::Math_D_D_Type(), FN_PTR(SharedRuntime::dlog10), "LOG10");
// These intrinsics are supported on all hardware
- case vmIntrinsics::_dsqrt: return Matcher::match_rule_supported(Op_SqrtD) ? inline_math(id) : false;
- case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_math(id) : false;
+ case vmIntrinsics::_dsqrt: return Matcher::match_rule_supported(Op_SqrtD) ? inline_double_math(id) : false;
+ case vmIntrinsics::_dabs: return Matcher::has_match_rule(Op_AbsD) ? inline_double_math(id) : false;
+ case vmIntrinsics::_fabs: return Matcher::match_rule_supported(Op_AbsF) ? inline_math(id) : false;
+ case vmIntrinsics::_iabs: return Matcher::match_rule_supported(Op_AbsI) ? inline_math(id) : false;
+ case vmIntrinsics::_labs: return Matcher::match_rule_supported(Op_AbsL) ? inline_math(id) : false;
case vmIntrinsics::_dexp:
return StubRoutines::dexp() != NULL ?
--- a/src/hotspot/share/opto/memnode.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/memnode.cpp Tue May 07 17:30:14 2019 -0400
@@ -1047,11 +1047,11 @@
// Try harder before giving up. Unify base pointers with casts (e.g., raw/non-raw pointers).
intptr_t st_off = 0;
Node* st_base = AddPNode::Ideal_base_and_offset(st_adr, phase, st_off);
- if (ld_base == NULL) return NULL;
- if (st_base == NULL) return NULL;
- if (ld_base->uncast() != st_base->uncast()) return NULL;
- if (ld_off != st_off) return NULL;
- if (ld_off == Type::OffsetBot) return NULL;
+ if (ld_base == NULL) return NULL;
+ if (st_base == NULL) return NULL;
+ if (!ld_base->eqv_uncast(st_base, /*keep_deps=*/true)) return NULL;
+ if (ld_off != st_off) return NULL;
+ if (ld_off == Type::OffsetBot) return NULL;
// Same base, same offset.
// Possible improvement for arrays: check index value instead of absolute offset.
@@ -1062,6 +1062,7 @@
// (Actually, we haven't yet proven the Q's are the same.)
// In other words, we are loading from a casted version of
// the same pointer-and-offset that we stored to.
+ // Casted version may carry a dependency and it is respected.
// Thus, we are able to replace L by V.
}
// Now prove that we have a LoadQ matched to a StoreQ, for some Q.
--- a/src/hotspot/share/opto/node.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/node.cpp Tue May 07 17:30:14 2019 -0400
@@ -891,13 +891,15 @@
//-----------------------------uncast---------------------------------------
// %%% Temporary, until we sort out CheckCastPP vs. CastPP.
// Strip away casting. (It is depth-limited.)
-Node* Node::uncast() const {
+// Optionally, keep casts with dependencies.
+Node* Node::uncast(bool keep_deps) const {
// Should be inline:
//return is_ConstraintCast() ? uncast_helper(this) : (Node*) this;
- if (is_ConstraintCast())
- return uncast_helper(this);
- else
+ if (is_ConstraintCast()) {
+ return uncast_helper(this, keep_deps);
+ } else {
return (Node*) this;
+ }
}
// Find out of current node that matches opcode.
@@ -929,7 +931,7 @@
//---------------------------uncast_helper-------------------------------------
-Node* Node::uncast_helper(const Node* p) {
+Node* Node::uncast_helper(const Node* p, bool keep_deps) {
#ifdef ASSERT
uint depth_count = 0;
const Node* orig_p = p;
@@ -947,6 +949,9 @@
if (p == NULL || p->req() != 2) {
break;
} else if (p->is_ConstraintCast()) {
+ if (keep_deps && p->as_ConstraintCast()->carry_dependency()) {
+ break; // stop at casts with dependencies
+ }
p = p->in(1);
} else {
break;
--- a/src/hotspot/share/opto/node.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/node.hpp Tue May 07 17:30:14 2019 -0400
@@ -456,10 +456,10 @@
void setup_is_top();
// Strip away casting. (It is depth-limited.)
- Node* uncast() const;
+ Node* uncast(bool keep_deps = false) const;
// Return whether two Nodes are equivalent, after stripping casting.
- bool eqv_uncast(const Node* n) const {
- return (this->uncast() == n->uncast());
+ bool eqv_uncast(const Node* n, bool keep_deps = false) const {
+ return (this->uncast(keep_deps) == n->uncast(keep_deps));
}
// Find out of current node that matches opcode.
@@ -470,7 +470,7 @@
bool has_out_with(int opcode1, int opcode2, int opcode3, int opcode4);
private:
- static Node* uncast_helper(const Node* n);
+ static Node* uncast_helper(const Node* n, bool keep_deps);
// Add an output edge to the end of the list
void add_out( Node *n ) {
--- a/src/hotspot/share/opto/parse.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/parse.hpp Tue May 07 17:30:14 2019 -0400
@@ -88,6 +88,10 @@
ciMethod* caller_method,
JVMState* jvms,
WarmCallInfo* wci_result);
+ bool is_not_reached(ciMethod* callee_method,
+ ciMethod* caller_method,
+ int caller_bci,
+ ciCallProfile& profile);
void print_inlining(ciMethod* callee_method, int caller_bci,
ciMethod* caller_method, bool success) const;
--- a/src/hotspot/share/opto/subnode.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/subnode.hpp Tue May 07 17:30:14 2019 -0400
@@ -350,6 +350,17 @@
virtual uint ideal_reg() const { return Op_RegI; }
};
+//------------------------------AbsLNode---------------------------------------
+// Absolute value a long. Since a naive graph involves control flow, we
+// "match" it in the ideal world (so the control flow can be removed).
+class AbsLNode : public AbsNode {
+public:
+ AbsLNode( Node *in1 ) : AbsNode(in1) {}
+ virtual int Opcode() const;
+ const Type *bottom_type() const { return TypeLong::LONG; }
+ virtual uint ideal_reg() const { return Op_RegL; }
+};
+
//------------------------------AbsFNode---------------------------------------
// Absolute value a float, a common float-point idiom with a cheap hardware
// implemention on most chips. Since a naive graph involves control flow, we
--- a/src/hotspot/share/opto/superword.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/superword.cpp Tue May 07 17:30:14 2019 -0400
@@ -2453,6 +2453,7 @@
}
} else if (opc == Op_SqrtF || opc == Op_SqrtD ||
opc == Op_AbsF || opc == Op_AbsD ||
+ opc == Op_AbsI || opc == Op_AbsL ||
opc == Op_NegF || opc == Op_NegD ||
opc == Op_PopCountI) {
assert(n->req() == 2, "only one input expected");
--- a/src/hotspot/share/opto/vectornode.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/vectornode.cpp Tue May 07 17:30:14 2019 -0400
@@ -70,8 +70,8 @@
return Op_SubVD;
case Op_MulI:
switch (bt) {
- case T_BOOLEAN:
- case T_BYTE: return 0; // Unimplemented
+ case T_BOOLEAN:return 0;
+ case T_BYTE: return Op_MulVB;
case T_CHAR:
case T_SHORT: return Op_MulVS;
case T_INT: return Op_MulVI;
@@ -104,6 +104,18 @@
case Op_DivD:
assert(bt == T_DOUBLE, "must be");
return Op_DivVD;
+ case Op_AbsI:
+ switch (bt) {
+ case T_BOOLEAN:
+ case T_CHAR: return 0; // abs does not make sense for unsigned
+ case T_BYTE: return Op_AbsVB;
+ case T_SHORT: return Op_AbsVS;
+ case T_INT: return Op_AbsVI;
+ default: ShouldNotReachHere(); return 0;
+ }
+ case Op_AbsL:
+ assert(bt == T_LONG, "must be");
+ return Op_AbsVL;
case Op_AbsF:
assert(bt == T_FLOAT, "must be");
return Op_AbsVF;
@@ -350,6 +362,7 @@
case Op_SubVF: return new SubVFNode(n1, n2, vt);
case Op_SubVD: return new SubVDNode(n1, n2, vt);
+ case Op_MulVB: return new MulVBNode(n1, n2, vt);
case Op_MulVS: return new MulVSNode(n1, n2, vt);
case Op_MulVI: return new MulVINode(n1, n2, vt);
case Op_MulVL: return new MulVLNode(n1, n2, vt);
@@ -359,6 +372,10 @@
case Op_DivVF: return new DivVFNode(n1, n2, vt);
case Op_DivVD: return new DivVDNode(n1, n2, vt);
+ case Op_AbsVB: return new AbsVBNode(n1, vt);
+ case Op_AbsVS: return new AbsVSNode(n1, vt);
+ case Op_AbsVI: return new AbsVINode(n1, vt);
+ case Op_AbsVL: return new AbsVLNode(n1, vt);
case Op_AbsVF: return new AbsVFNode(n1, vt);
case Op_AbsVD: return new AbsVDNode(n1, vt);
--- a/src/hotspot/share/opto/vectornode.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/opto/vectornode.hpp Tue May 07 17:30:14 2019 -0400
@@ -224,6 +224,14 @@
virtual int Opcode() const;
};
+//------------------------------MulVBNode--------------------------------------
+// Vector multiply byte
+class MulVBNode : public VectorNode {
+ public:
+ MulVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {}
+ virtual int Opcode() const;
+};
+
//------------------------------MulVSNode--------------------------------------
// Vector multiply short
class MulVSNode : public VectorNode {
@@ -360,6 +368,38 @@
virtual int Opcode() const;
};
+//------------------------------AbsVBNode--------------------------------------
+// Vector Abs byte
+class AbsVBNode : public VectorNode {
+public:
+ AbsVBNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
+ virtual int Opcode() const;
+};
+
+//------------------------------AbsVSNode--------------------------------------
+// Vector Abs short
+class AbsVSNode : public VectorNode {
+public:
+ AbsVSNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
+ virtual int Opcode() const;
+};
+
+//------------------------------AbsVINode--------------------------------------
+// Vector Abs int
+class AbsVINode : public VectorNode {
+public:
+ AbsVINode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
+ virtual int Opcode() const;
+};
+
+//------------------------------AbsVLNode--------------------------------------
+// Vector Abs long
+class AbsVLNode : public VectorNode {
+public:
+ AbsVLNode(Node* in, const TypeVect* vt) : VectorNode(in, vt) {}
+ virtual int Opcode() const;
+};
+
//------------------------------AbsVFNode--------------------------------------
// Vector Abs float
class AbsVFNode : public VectorNode {
--- a/src/hotspot/share/prims/jvmti.xml Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/prims/jvmti.xml Tue May 07 17:30:14 2019 -0400
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="jvmti.xsl"?>
<!--
- Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
-->
<!DOCTYPE specification [
- <!ELEMENT specification (title, copyright, intro*, functionsection, errorsection,
+ <!ELEMENT specification (title, intro*, functionsection, errorsection,
eventsection, datasection, issuessection, changehistory)>
<!ATTLIST specification label CDATA #REQUIRED
majorversion CDATA #REQUIRED
@@ -34,8 +34,6 @@
<!ELEMENT title (#PCDATA|jvmti|tm)*>
<!ATTLIST title subtitle CDATA #REQUIRED>
- <!ELEMENT copyright ANY>
-
<!ELEMENT intro ANY>
<!ATTLIST intro id CDATA #IMPLIED
label CDATA "">
@@ -367,10 +365,6 @@
<tm>JVM</tm> Tool Interface
</title>
- <copyright>
- Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
- </copyright>
-
<intro id="whatIs" label="What is the JVM Tool Interface?">
The <tm>JVM</tm> Tool Interface (<jvmti/>)
is a programming interface used by development and monitoring tools.
--- a/src/hotspot/share/prims/jvmti.xsl Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/prims/jvmti.xsl Tue May 07 17:30:14 2019 -0400
@@ -1,6 +1,6 @@
-<?xml version="1.0"?>
+<?xml version="1.0"?>
<!--
- Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -20,14 +20,14 @@
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.
-
+
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:import href="jvmtiLib.xsl"/>
-<xsl:output method="html" indent="yes"
+<xsl:output method="html" indent="yes"
doctype-system="about:legacy-compat"/>
<xsl:param name="development"></xsl:param>
@@ -119,7 +119,7 @@
<li>
<a href="#DataSection"><b>Data Types</b></a>
<ul>
- <xsl:for-each select="//basetypes">
+ <xsl:for-each select="//basetypes">
<li>
<a>
<xsl:attribute name="href">#<xsl:value-of select="@id"/></xsl:attribute>
@@ -204,7 +204,6 @@
<p id="ChangeHistory"/>
<xsl:apply-templates select="changehistory"/>
</div>
- <xsl:apply-templates select="copyright"/>
</body>
</html>
</xsl:template>
@@ -220,12 +219,6 @@
</h3>
</xsl:template>
-<xsl:template match="copyright">
- <p>
- <xsl:apply-templates/>
- </p>
-</xsl:template>
-
<xsl:template match="functionsection">
<div class="sep"/>
<hr class="thick"/>
@@ -286,7 +279,7 @@
<xsl:apply-templates select="$calltypes" mode="index"/>
</ul>
</xsl:if>
- <xsl:variable name="cattypes"
+ <xsl:variable name="cattypes"
select="(descendant::typedef|descendant::uniontypedef|descendant::capabilitiestypedef|descendant::constants[@kind='enum'])"/>
<xsl:if test="count($cattypes)!=0">
<xsl:value-of select="@label"/> types:
@@ -304,9 +297,9 @@
<xsl:value-of select="@label"/>
</li>
</xsl:for-each>
- </ul>
+ </ul>
</xsl:if>
- <xsl:variable name="catconst"
+ <xsl:variable name="catconst"
select="(descendant::constants[@kind!='enum'])"/>
<xsl:if test="count($catconst)!=0">
<xsl:value-of select="@label"/> flags and constants:
@@ -322,7 +315,7 @@
</a>
</li>
</xsl:for-each>
- </ul>
+ </ul>
</xsl:if>
<xsl:apply-templates select="intro|typedef|uniontypedef|capabilitiestypedef"/>
<div class="sep"/>
@@ -334,7 +327,7 @@
<xsl:attribute name="id">
<xsl:value-of select="@id"/>
</xsl:attribute>
-
+
</hr>
<xsl:apply-templates select="synopsis" mode="body"/>
<blockquote>
@@ -505,7 +498,7 @@
<xsl:when test="contains(@callbacksafe,'safe')">
This function may be called from the callbacks to the
<a href="#Heap">Heap</a> iteration functions, or from the
- event handlers for the
+ event handlers for the
<a href="#GarbageCollectionStart"><code>GarbageCollectionStart</code></a>,
<a href="#GarbageCollectionFinish"><code>GarbageCollectionFinish</code></a>,
and <a href="#ObjectFree"><code>ObjectFree</code></a> events.
@@ -536,7 +529,7 @@
<xsl:for-each select="parameters">
<xsl:apply-templates select="param[position()=1]" mode="signature"/>
<xsl:for-each select="param[position()>1]">
- <xsl:text>,
+ <xsl:text>,
</xsl:text>
<xsl:apply-templates select="." mode="signature"/>
</xsl:for-each>
@@ -932,7 +925,7 @@
</a>
<xsl:apply-templates select="description" mode="brief"/>
</td>
- </tr>
+ </tr>
</xsl:when>
<xsl:otherwise>
<tr>
@@ -949,12 +942,12 @@
</a>
<xsl:apply-templates select="description" mode="brief"/>
</td>
- </tr>
+ </tr>
<tr>
<td>
<pre>
<xsl:apply-templates select="definition"/>
- </pre>
+ </pre>
</td>
</tr>
</xsl:otherwise>
@@ -977,7 +970,7 @@
<xsl:when test=".=''">
<code>
<xsl:value-of select="@id"/>
- </code>
+ </code>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
@@ -994,7 +987,7 @@
<xsl:when test=".=''">
<code>
<xsl:value-of select="@id"/>
- </code>
+ </code>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
@@ -1010,7 +1003,7 @@
<xsl:when test=".=''">
<code>
<xsl:value-of select="@id"/>
- </code>
+ </code>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
@@ -1038,7 +1031,7 @@
<xsl:template match="eventphaselist">
<xsl:variable name="phase" select="@phase"/>
<ul>
- <xsl:for-each select="//eventsection/event[@phase=$phase]">
+ <xsl:for-each select="//eventsection/event[@phase=$phase]">
<li>
<a>
<xsl:attribute name="href">#<xsl:value-of select="@id"/></xsl:attribute>
@@ -1064,7 +1057,7 @@
<cite>
<xsl:text>The Java™ Virtual Machine Specification</xsl:text>
<xsl:if test="count(@chapter)=1">
- <xsl:text>, Chapter </xsl:text>
+ <xsl:text>, Chapter </xsl:text>
<xsl:value-of select="@chapter"/>
</xsl:if>
</cite>
@@ -1155,18 +1148,18 @@
<tr>
<td colspan="2">
<b>Optional Functionality:</b> might not be implemented for all
- virtual machines.
+ virtual machines.
<xsl:choose>
<xsl:when test="count(required)=1">
- The following capability
+ The following capability
</xsl:when>
<xsl:otherwise>
One of the following capabilities
</xsl:otherwise>
</xsl:choose>
- (as returned by
+ (as returned by
<a href="#GetCapabilities"><code>GetCapabilities</code></a>)
- must be true to use this
+ must be true to use this
<xsl:choose>
<xsl:when test="ancestor::function">
function.
@@ -1322,8 +1315,8 @@
<xsl:when test="contains($haserrors,'yes')">
<tr>
<td colspan="2">
- This function returns either a
- <a href="#universal-error">universal error</a>
+ This function returns either a
+ <a href="#universal-error">universal error</a>
or one of the following errors
</td>
</tr>
@@ -1342,7 +1335,7 @@
<xsl:otherwise>
<tr>
<td colspan="{$fullRowColspan}">
- This function returns a
+ This function returns a
<a href="#universal-error">universal error</a>
</td>
</tr>
@@ -1370,7 +1363,7 @@
<xsl:attribute name="href">#jvmtiCapabilities.<xsl:value-of select="@id"/></xsl:attribute>
<code>
<xsl:value-of select="@id"/>
- </code>
+ </code>
</a>.
Use <a href="#AddCapabilities"><code>AddCapabilities</code></a>.
</td>
@@ -1412,7 +1405,7 @@
</tr>
</xsl:if>
</xsl:template>
-
+
<xsl:template match="param" mode="errors2">
<xsl:variable name="haserrors2">
<xsl:apply-templates mode="haserrors2"/>
@@ -1439,7 +1432,7 @@
</tr>
</xsl:if>
</xsl:template>
-
+
<xsl:template match="description" mode="haserrors">
</xsl:template>
@@ -1684,7 +1677,7 @@
</xsl:attribute>
<code>
<xsl:value-of select="ancestor::param/@id"/>
- </code>
+ </code>
</a>
</xsl:template>
@@ -1858,7 +1851,7 @@
</td>
<td>
<pre>
- <xsl:text>void *reserved</xsl:text>
+ <xsl:text>void *reserved</xsl:text>
<xsl:value-of select="$index"/>
<xsl:text>;</xsl:text>
</pre>
--- a/src/hotspot/share/prims/whitebox.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/prims/whitebox.cpp Tue May 07 17:30:14 2019 -0400
@@ -1080,6 +1080,24 @@
return result;
WB_END
+WB_ENTRY(void, WB_MarkMethodProfiled(JNIEnv* env, jobject o, jobject method))
+ jmethodID jmid = reflected_method_to_jmid(thread, env, method);
+ CHECK_JNI_EXCEPTION(env);
+ methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
+
+ MethodData* mdo = mh->method_data();
+ if (mdo == NULL) {
+ Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR);
+ mdo = mh->method_data();
+ }
+ mdo->init();
+ InvocationCounter* icnt = mdo->invocation_counter();
+ InvocationCounter* bcnt = mdo->backedge_counter();
+ // set i-counter according to TieredThresholdPolicy::is_method_profiled
+ icnt->set(InvocationCounter::wait_for_compile, Tier4MinInvocationThreshold);
+ bcnt->set(InvocationCounter::wait_for_compile, Tier4CompileThreshold);
+WB_END
+
WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
CHECK_JNI_EXCEPTION(env);
@@ -2209,6 +2227,8 @@
CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation},
{CC"enqueueInitializerForCompilation0",
CC"(Ljava/lang/Class;I)Z", (void*)&WB_EnqueueInitializerForCompilation},
+ {CC"markMethodProfiled",
+ CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_MarkMethodProfiled},
{CC"clearMethodState0",
CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState},
{CC"lockCompilation", CC"()V", (void*)&WB_LockCompilation},
--- a/src/hotspot/share/runtime/deoptimization.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/deoptimization.cpp Tue May 07 17:30:14 2019 -0400
@@ -674,8 +674,7 @@
int top_frame_expression_stack_adjustment = 0;
methodHandle mh(thread, iframe->interpreter_frame_method());
OopMapCache::compute_one_oop_map(mh, iframe->interpreter_frame_bci(), &mask);
- BytecodeStream str(mh);
- str.set_start(iframe->interpreter_frame_bci());
+ BytecodeStream str(mh, iframe->interpreter_frame_bci());
int max_bci = mh->code_size();
// Get to the next bytecode if possible
assert(str.bci() < max_bci, "bci in interpreter frame out of bounds");
--- a/src/hotspot/share/runtime/java.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/java.cpp Tue May 07 17:30:14 2019 -0400
@@ -526,11 +526,31 @@
vm_direct_exit(code);
}
+ // We'd like to add an entry to the XML log to show that the VM is
+ // terminating, but we can't safely do that here. The logic to make
+ // XML termination logging safe is tied to the termination of the
+ // VMThread, and it doesn't terminate on this exit path. See 8222534.
+
if (VMThread::vm_thread() != NULL) {
+ if (thread->is_Java_thread()) {
+ // We must be "in_vm" for the code below to work correctly.
+ // Historically there must have been some exit path for which
+ // that was not the case and so we set it explicitly - even
+ // though we no longer know what that path may be.
+ ((JavaThread*)thread)->set_thread_state(_thread_in_vm);
+ }
+
// Fire off a VM_Exit operation to bring VM to a safepoint and exit
VM_Exit op(code);
- if (thread->is_Java_thread())
- ((JavaThread*)thread)->set_thread_state(_thread_in_vm);
+
+ // 4945125 The vm thread comes to a safepoint during exit.
+ // GC vm_operations can get caught at the safepoint, and the
+ // heap is unparseable if they are caught. Grab the Heap_lock
+ // to prevent this. The GC vm_operations will not be able to
+ // queue until after we release it, but we never do that as we
+ // are terminating the VM process.
+ MutexLocker ml(Heap_lock);
+
VMThread::execute(&op);
// should never reach here; but in case something wrong with VM Thread.
vm_direct_exit(code);
--- a/src/hotspot/share/runtime/objectMonitor.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/objectMonitor.cpp Tue May 07 17:30:14 2019 -0400
@@ -1926,3 +1926,11 @@
DEBUG_ONLY(InitDone = true;)
}
+
+void ObjectMonitor::print_on(outputStream* st) const {
+ // The minimal things to print for markOop printing, more can be added for debugging and logging.
+ st->print("{contentions=0x%08x,waiters=0x%08x"
+ ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}",
+ contentions(), waiters(), recursions(),
+ p2i(owner()));
+}
--- a/src/hotspot/share/runtime/objectMonitor.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/objectMonitor.hpp Tue May 07 17:30:14 2019 -0400
@@ -139,6 +139,7 @@
friend class ObjectSynchronizer;
friend class ObjectWaiter;
friend class VMStructs;
+ JVMCI_ONLY(friend class JVMCIVMStructs;)
volatile markOop _header; // displaced object header word - mark
void* volatile _object; // backward object pointer - strong root
@@ -291,6 +292,9 @@
void notify(TRAPS);
void notifyAll(TRAPS);
+ void print() const { print_on(tty); }
+ void print_on(outputStream* st) const;
+
// Use the following at your own risk
intptr_t complete_exit(TRAPS);
void reenter(intptr_t recursions, TRAPS);
--- a/src/hotspot/share/runtime/thread.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/thread.cpp Tue May 07 17:30:14 2019 -0400
@@ -1575,18 +1575,15 @@
return !JVMCICountersExcludeCompiler || !thread->is_Compiler_thread();
}
-void JavaThread::collect_counters(JVMCIEnv* jvmci_env, JVMCIPrimitiveArray array) {
- if (JVMCICounterSize > 0) {
- JavaThreadIteratorWithHandle jtiwh;
- int len = jvmci_env->get_length(array);
- for (int i = 0; i < len; i++) {
- jvmci_env->put_long_at(array, i, _jvmci_old_thread_counters[i]);
- }
- for (; JavaThread *tp = jtiwh.next(); ) {
- if (jvmci_counters_include(tp)) {
- for (int i = 0; i < len; i++) {
- jvmci_env->put_long_at(array, i, jvmci_env->get_long_at(array, i) + tp->_jvmci_counters[i]);
- }
+void JavaThread::collect_counters(jlong* array, int length) {
+ assert(length == JVMCICounterSize, "wrong value");
+ for (int i = 0; i < length; i++) {
+ array[i] = _jvmci_old_thread_counters[i];
+ }
+ for (JavaThreadIteratorWithHandle jtiwh; JavaThread *tp = jtiwh.next(); ) {
+ if (jvmci_counters_include(tp)) {
+ for (int i = 0; i < length; i++) {
+ array[i] += tp->_jvmci_counters[i];
}
}
}
--- a/src/hotspot/share/runtime/thread.hpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/thread.hpp Tue May 07 17:30:14 2019 -0400
@@ -1152,7 +1152,7 @@
public:
static jlong* _jvmci_old_thread_counters;
- static void collect_counters(JVMCIEnv* JVMCIENV, JVMCIPrimitiveArray array);
+ static void collect_counters(jlong* array, int length);
private:
#endif // INCLUDE_JVMCI
--- a/src/hotspot/share/runtime/tieredThresholdPolicy.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/tieredThresholdPolicy.cpp Tue May 07 17:30:14 2019 -0400
@@ -353,6 +353,16 @@
TieredStopAtLevel > CompLevel_full_profile &&
max_method != NULL && is_method_profiled(max_method)) {
max_task->set_comp_level(CompLevel_limited_profile);
+
+ if (CompileBroker::compilation_is_complete(max_method, max_task->osr_bci(), CompLevel_limited_profile)) {
+ if (PrintTieredEvents) {
+ print_event(REMOVE_FROM_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
+ }
+ compile_queue->remove_and_mark_stale(max_task);
+ max_method->clear_queued_for_compilation();
+ return NULL;
+ }
+
if (PrintTieredEvents) {
print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
}
--- a/src/hotspot/share/runtime/vmOperations.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/vmOperations.cpp Tue May 07 17:30:14 2019 -0400
@@ -30,6 +30,7 @@
#include "gc/shared/isGCActiveMark.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
+#include "logging/logConfiguration.hpp"
#include "memory/heapInspection.hpp"
#include "memory/resourceArea.hpp"
#include "oops/symbol.hpp"
@@ -437,14 +438,14 @@
if (thr->is_Compiler_thread()) {
#if INCLUDE_JVMCI
CompilerThread* ct = (CompilerThread*) thr;
- if (ct->compiler() == NULL || !ct->compiler()->is_jvmci() || !UseJVMCINativeLibrary) {
+ if (ct->compiler() == NULL || !ct->compiler()->is_jvmci()) {
num_active_compiler_thread++;
} else {
- // When using a compiler in a JVMCI shared library, it's possible
- // for one compiler thread to grab a lock in the shared library,
- // enter HotSpot and go to sleep on the shutdown safepoint. Another
- // JVMCI shared library compiler thread can then attempt to grab the
- // lock and thus never make progress.
+ // A JVMCI compiler thread never accesses VM data structures
+ // while in _thread_in_native state so there's no need to wait
+ // for it and potentially add a 300 millisecond delay to VM
+ // shutdown.
+ num_active--;
}
#else
num_active_compiler_thread++;
@@ -469,6 +470,16 @@
}
void VM_Exit::doit() {
+
+ if (VerifyBeforeExit) {
+ HandleMark hm(VMThread::vm_thread());
+ // Among other things, this ensures that Eden top is correct.
+ Universe::heap()->prepare_for_verify();
+ // Silent verification so as not to pollute normal output,
+ // unless we really asked for it.
+ Universe::verify();
+ }
+
CompileBroker::set_should_block();
// Wait for a short period for threads in native to block. Any thread
@@ -480,10 +491,17 @@
set_vm_exited();
+ // We'd like to call IdealGraphPrinter::clean_up() to finalize the
+ // XML logging, but we can't safely do that here. The logic to make
+ // XML termination logging safe is tied to the termination of the
+ // VMThread, and it doesn't terminate on this exit path. See 8222534.
+
// cleanup globals resources before exiting. exit_globals() currently
// cleans up outputStream resources and PerfMemory resources.
exit_globals();
+ LogConfiguration::finalize();
+
// Check for exit hook
exit_hook_t exit_hook = Arguments::exit_hook();
if (exit_hook != NULL) {
--- a/src/hotspot/share/runtime/vmStructs.cpp Fri May 03 14:59:32 2019 -0400
+++ b/src/hotspot/share/runtime/vmStructs.cpp Tue May 07 17:30:14 2019 -0400
@@ -1758,6 +1758,10 @@
declare_c2_type(ReverseBytesLNode, Node) \
declare_c2_type(ReductionNode, Node) \
declare_c2_type(VectorNode, Node) \
+ declare_c2_type(AbsVBNode, VectorNode) \
+ declare_c2_type(AbsVSNode, VectorNode) \
+ declare_c2_type(AbsVINode, VectorNode) \
+ declare_c2_type(AbsVLNode, VectorNode) \
declare_c2_type(AddVBNode, VectorNode) \
declare_c2_type(AddVSNode, VectorNode) \
declare_c2_type(AddVINode, VectorNode) \
@@ -1774,6 +1778,7 @@
declare_c2_type(SubVLNode, VectorNode) \
declare_c2_type(SubVFNode, VectorNode) \
declare_c2_type(SubVDNode, VectorNode) \
+ declare_c2_type(MulVBNode, VectorNode) \
declare_c2_type(MulVSNode, VectorNode) \
declare_c2_type(MulVLNode, VectorNode) \
declare_c2_type(MulReductionVLNode, ReductionNode) \
@@ -1782,6 +1787,8 @@
declare_c2_type(MulVFNode, VectorNode) \
declare_c2_type(MulReductionVFNode, ReductionNode) \
declare_c2_type(MulVDNode, VectorNode) \
+ declare_c2_type(NegVFNode, VectorNode) \
+ declare_c2_type(NegVDNode, VectorNode) \
declare_c2_type(FmaVDNode, VectorNode) \
declare_c2_type(FmaVFNode, VectorNode) \
declare_c2_type(CMoveVFNode, VectorNode) \
--- a/src/java.base/share/classes/java/lang/Math.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/java/lang/Math.java Tue May 07 17:30:14 2019 -0400
@@ -1353,6 +1353,7 @@
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
+ @HotSpotIntrinsicCandidate
public static int abs(int a) {
return (a < 0) ? -a : a;
}
@@ -1370,6 +1371,7 @@
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
+ @HotSpotIntrinsicCandidate
public static long abs(long a) {
return (a < 0) ? -a : a;
}
@@ -1394,6 +1396,7 @@
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
+ @HotSpotIntrinsicCandidate
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
--- a/src/java.base/share/classes/java/lang/String.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/java/lang/String.java Tue May 07 17:30:14 2019 -0400
@@ -75,7 +75,7 @@
* System.out.println("abc");
* String cde = "cde";
* System.out.println("abc" + cde);
- * String c = "abc".substring(2,3);
+ * String c = "abc".substring(2, 3);
* String d = cde.substring(1, 2);
* </pre></blockquote>
* <p>
@@ -2160,27 +2160,48 @@
* @since 1.5
*/
public String replace(CharSequence target, CharSequence replacement) {
- String tgtStr = target.toString();
+ String trgtStr = target.toString();
String replStr = replacement.toString();
- int j = indexOf(tgtStr);
- if (j < 0) {
- return this;
- }
- int tgtLen = tgtStr.length();
- int tgtLen1 = Math.max(tgtLen, 1);
int thisLen = length();
+ int trgtLen = trgtStr.length();
+ int replLen = replStr.length();
+
+ if (trgtLen > 0) {
+ if (trgtLen == 1 && replLen == 1) {
+ return replace(trgtStr.charAt(0), replStr.charAt(0));
+ }
- int newLenHint = thisLen - tgtLen + replStr.length();
- if (newLenHint < 0) {
- throw new OutOfMemoryError();
+ boolean thisIsLatin1 = this.isLatin1();
+ boolean trgtIsLatin1 = trgtStr.isLatin1();
+ boolean replIsLatin1 = replStr.isLatin1();
+ String ret = (thisIsLatin1 && trgtIsLatin1 && replIsLatin1)
+ ? StringLatin1.replace(value, thisLen,
+ trgtStr.value, trgtLen,
+ replStr.value, replLen)
+ : StringUTF16.replace(value, thisLen, thisIsLatin1,
+ trgtStr.value, trgtLen, trgtIsLatin1,
+ replStr.value, replLen, replIsLatin1);
+ if (ret != null) {
+ return ret;
+ }
+ return this;
+
+ } else { // trgtLen == 0
+ int resultLen;
+ try {
+ resultLen = Math.addExact(thisLen, Math.multiplyExact(
+ Math.addExact(thisLen, 1), replLen));
+ } catch (ArithmeticException ignored) {
+ throw new OutOfMemoryError();
+ }
+
+ StringBuilder sb = new StringBuilder(resultLen);
+ sb.append(replStr);
+ for (int i = 0; i < thisLen; ++i) {
+ sb.append(charAt(i)).append(replStr);
+ }
+ return sb.toString();
}
- StringBuilder sb = new StringBuilder(newLenHint);
- int i = 0;
- do {
- 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();
}
/**
--- a/src/java.base/share/classes/java/lang/StringLatin1.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/java/lang/StringLatin1.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,14 @@
final class StringLatin1 {
+ /**
+ * The maximum size of array to allocate (unless necessary).
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
public static char charAt(byte[] value, int index) {
if (index < 0 || index >= value.length) {
throw new StringIndexOutOfBoundsException(index);
@@ -304,7 +312,7 @@
}
if (i < len) {
if (canEncode(newChar)) {
- byte buf[] = new byte[len];
+ byte[] buf = StringConcatHelper.newArray(len);
for (int j = 0; j < i; j++) { // TBD arraycopy?
buf[j] = value[j];
}
@@ -330,6 +338,64 @@
return null; // for string to return this;
}
+ public static String replace(byte[] value, int valLen, byte[] targ,
+ int targLen, byte[] repl, int replLen)
+ {
+ assert targLen > 0;
+ int i, j, p = 0;
+ if (valLen == 0 || (i = indexOf(value, valLen, targ, targLen, 0)) < 0) {
+ return null; // for string to return this;
+ }
+
+ // find and store indices of substrings to replace
+ int[] pos = new int[16];
+ pos[0] = i;
+ i += targLen;
+ while ((j = indexOf(value, valLen, targ, targLen, i)) > 0) {
+ if (++p == pos.length) {
+ int cap = p + (p >> 1);
+ // overflow-conscious code
+ if (cap - MAX_ARRAY_SIZE > 0) {
+ if (p == MAX_ARRAY_SIZE) {
+ throw new OutOfMemoryError();
+ }
+ cap = MAX_ARRAY_SIZE;
+ }
+ pos = Arrays.copyOf(pos, cap);
+ }
+ pos[p] = j;
+ i = j + targLen;
+ }
+
+ int resultLen;
+ try {
+ resultLen = Math.addExact(valLen,
+ Math.multiplyExact(++p, replLen - targLen));
+ } catch (ArithmeticException ignored) {
+ throw new OutOfMemoryError();
+ }
+ if (resultLen == 0) {
+ return "";
+ }
+
+ byte[] result = StringConcatHelper.newArray(resultLen);
+ int posFrom = 0, posTo = 0;
+ for (int q = 0; q < p; ++q) {
+ int nextPos = pos[q];
+ while (posFrom < nextPos) {
+ result[posTo++] = value[posFrom++];
+ }
+ posFrom += targLen;
+ for (int k = 0; k < replLen; ++k) {
+ result[posTo++] = repl[k];
+ }
+ }
+ while (posFrom < valLen) {
+ result[posTo++] = value[posFrom++];
+ }
+ return new String(result, LATIN1);
+ }
+
// case insensitive
public static boolean regionMatchesCI(byte[] value, int toffset,
byte[] other, int ooffset, int len) {
--- a/src/java.base/share/classes/java/lang/StringUTF16.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/java/lang/StringUTF16.java Tue May 07 17:30:14 2019 -0400
@@ -574,7 +574,7 @@
}
}
if (i < len) {
- byte buf[] = new byte[value.length];
+ byte[] buf = new byte[value.length];
for (int j = 0; j < i; j++) {
putChar(buf, j, getChar(value, j)); // TBD:arraycopy?
}
@@ -582,21 +582,145 @@
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);
+ }
+ // 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 String replace(byte[] value, int valLen, boolean valLat1,
+ byte[] targ, int targLen, boolean targLat1,
+ byte[] repl, int replLen, boolean replLat1)
+ {
+ assert targLen > 0;
+ assert !valLat1 || !targLat1 || !replLat1;
+
+ // Possible combinations of the arguments/result encodings:
+ // +---+--------+--------+--------+-----------------------+
+ // | # | VALUE | TARGET | REPL | RESULT |
+ // +===+========+========+========+=======================+
+ // | 1 | Latin1 | Latin1 | UTF16 | null or UTF16 |
+ // +---+--------+--------+--------+-----------------------+
+ // | 2 | Latin1 | UTF16 | Latin1 | null |
+ // +---+--------+--------+--------+-----------------------+
+ // | 3 | Latin1 | UTF16 | UTF16 | null |
+ // +---+--------+--------+--------+-----------------------+
+ // | 4 | UTF16 | Latin1 | Latin1 | null or UTF16 |
+ // +---+--------+--------+--------+-----------------------+
+ // | 5 | UTF16 | Latin1 | UTF16 | null or UTF16 |
+ // +---+--------+--------+--------+-----------------------+
+ // | 6 | UTF16 | UTF16 | Latin1 | null, Latin1 or UTF16 |
+ // +---+--------+--------+--------+-----------------------+
+ // | 7 | UTF16 | UTF16 | UTF16 | null or UTF16 |
+ // +---+--------+--------+--------+-----------------------+
+
+ if (String.COMPACT_STRINGS && valLat1 && !targLat1) {
+ // combinations 2 or 3
+ return null; // for string to return this;
+ }
+
+ int i = (String.COMPACT_STRINGS && valLat1)
+ ? StringLatin1.indexOf(value, targ) :
+ (String.COMPACT_STRINGS && targLat1)
+ ? indexOfLatin1(value, targ)
+ : indexOf(value, targ);
+ if (i < 0) {
+ return null; // for string to return this;
+ }
+
+ // find and store indices of substrings to replace
+ int j, p = 0;
+ int[] pos = new int[16];
+ pos[0] = i;
+ i += targLen;
+ while ((j = ((String.COMPACT_STRINGS && valLat1)
+ ? StringLatin1.indexOf(value, valLen, targ, targLen, i) :
+ (String.COMPACT_STRINGS && targLat1)
+ ? indexOfLatin1(value, valLen, targ, targLen, i)
+ : indexOf(value, valLen, targ, targLen, i))) > 0)
+ {
+ if (++p == pos.length) {
+ int cap = p + (p >> 1);
+ // overflow-conscious code
+ if (cap - MAX_ARRAY_SIZE > 0) {
+ if (p == MAX_ARRAY_SIZE) {
+ throw new OutOfMemoryError();
+ }
+ cap = MAX_ARRAY_SIZE;
+ }
+ pos = Arrays.copyOf(pos, cap);
+ }
+ pos[p] = j;
+ i = j + targLen;
+ }
+
+ int resultLen;
+ try {
+ resultLen = Math.addExact(valLen,
+ Math.multiplyExact(++p, replLen - targLen));
+ } catch (ArithmeticException ignored) {
+ throw new OutOfMemoryError();
+ }
+ if (resultLen == 0) {
+ return "";
+ }
+
+ byte[] result = newBytesFor(resultLen);
+ int posFrom = 0, posTo = 0;
+ for (int q = 0; q < p; ++q) {
+ int nextPos = pos[q];
+ if (String.COMPACT_STRINGS && valLat1) {
+ while (posFrom < nextPos) {
+ char c = (char)(value[posFrom++] & 0xff);
+ putChar(result, posTo++, c);
+ }
+ } else {
+ while (posFrom < nextPos) {
+ putChar(result, posTo++, getChar(value, posFrom++));
+ }
+ }
+ posFrom += targLen;
+ if (String.COMPACT_STRINGS && replLat1) {
+ for (int k = 0; k < replLen; ++k) {
+ char c = (char)(repl[k] & 0xff);
+ putChar(result, posTo++, c);
+ }
+ } else {
+ for (int k = 0; k < replLen; ++k) {
+ putChar(result, posTo++, getChar(repl, k));
+ }
+ }
+ }
+ if (String.COMPACT_STRINGS && valLat1) {
+ while (posFrom < valLen) {
+ char c = (char)(value[posFrom++] & 0xff);
+ putChar(result, posTo++, c);
+ }
+ } else {
+ while (posFrom < valLen) {
+ putChar(result, posTo++, getChar(value, posFrom++));
+ }
+ }
+
+ if (String.COMPACT_STRINGS && replLat1 && !targLat1) {
+ // combination 6
+ byte[] lat1Result = compress(result, 0, resultLen);
+ if (lat1Result != null) {
+ return new String(lat1Result, LATIN1);
+ }
+ }
+ return new String(result, UTF16);
+ }
+
public static boolean regionMatchesCI(byte[] value, int toffset,
byte[] other, int ooffset, int len) {
int last = toffset + len;
@@ -1430,6 +1554,15 @@
static final int MAX_LENGTH = Integer.MAX_VALUE >> 1;
+
+ /**
+ * The maximum size of array to allocate (unless necessary).
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
// Used by trusted callers. Assumes all necessary bounds checks have
// been done by the caller.
--- a/src/java.base/share/classes/java/lang/constant/ClassDesc.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java Tue May 07 17:30:14 2019 -0400
@@ -213,7 +213,7 @@
* @param moreNestedNames the unqualified name(s) of the remaining levels of
* nested class
* @return a {@linkplain ClassDesc} describing the nested class
- * @throws NullPointerException if any argument is {@code null}
+ * @throws NullPointerException if any argument or its contents is {@code null}
* @throws IllegalStateException if this {@linkplain ClassDesc} does not
* describe a class or interface type
* @throws IllegalArgumentException if the nested class name is invalid
@@ -221,6 +221,11 @@
default ClassDesc nested(String firstNestedName, String... moreNestedNames) {
if (!isClassOrInterface())
throw new IllegalStateException("Outer class is not a class or interface type");
+ validateMemberName(firstNestedName, false);
+ requireNonNull(moreNestedNames);
+ for (String addNestedNames : moreNestedNames) {
+ validateMemberName(addNestedNames, false);
+ }
return moreNestedNames.length == 0
? nested(firstNestedName)
: nested(firstNestedName + Stream.of(moreNestedNames).collect(joining("$", "$", "")));
--- a/src/java.base/share/classes/java/net/ServerSocket.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/java/net/ServerSocket.java Tue May 07 17:30:14 2019 -0400
@@ -32,6 +32,7 @@
import java.nio.channels.ServerSocketChannel;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
+import java.util.Objects;
import java.util.Set;
import java.util.Collections;
@@ -81,6 +82,7 @@
* @since 12
*/
protected ServerSocket(SocketImpl impl) {
+ Objects.requireNonNull(impl);
this.impl = impl;
}
--- a/src/java.base/share/classes/java/nio/file/FileSystems.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/java/nio/file/FileSystems.java Tue May 07 17:30:14 2019 -0400
@@ -252,10 +252,8 @@
* Suppose there is a provider identified by the scheme {@code "memory"}
* installed:
* <pre>
- * Map<String,String> env = new HashMap<>();
- * env.put("capacity", "16G");
- * env.put("blockSize", "4k");
- * FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
+ * FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"),
+ * Map.of("capacity", "16G", "blockSize", "4k"));
* </pre>
*
* @param uri
--- a/src/java.base/share/classes/java/util/regex/Pattern.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java Tue May 07 17:30:14 2019 -0400
@@ -1678,7 +1678,13 @@
return;
int j = i;
i += 2;
- int[] newtemp = new int[j + 3*(pLen-i) + 2];
+ int newTempLen;
+ try {
+ newTempLen = Math.addExact(j + 2, Math.multiplyExact(3, pLen - i));
+ } catch (ArithmeticException ae) {
+ throw new OutOfMemoryError();
+ }
+ int[] newtemp = new int[newTempLen];
System.arraycopy(temp, 0, newtemp, 0, j);
boolean inQuote = true;
--- a/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Tue May 07 17:30:14 2019 -0400
@@ -826,6 +826,10 @@
// reading lock
private final ReentrantLock readLock = new ReentrantLock();
+ // closing status
+ private volatile boolean isClosing;
+ private volatile boolean hasDepleted;
+
AppInputStream() {
this.appDataIsAvailable = false;
this.buffer = ByteBuffer.allocate(4096);
@@ -871,8 +875,7 @@
* and returning "-1" on non-fault EOF status.
*/
@Override
- public int read(byte[] b, int off, int len)
- throws IOException {
+ public int read(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException("the target buffer is null");
} else if (off < 0 || len < 0 || len > b.length - off) {
@@ -900,12 +903,40 @@
throw new SocketException("Connection or inbound has closed");
}
+ // Check if the input stream has been depleted.
+ //
+ // Note that the "hasDepleted" rather than the isClosing
+ // filed is checked here, in case the closing process is
+ // still in progress.
+ if (hasDepleted) {
+ if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
+ SSLLogger.fine("The input stream has been depleted");
+ }
+
+ return -1;
+ }
+
// Read the available bytes at first.
//
// Note that the receiving and processing of post-handshake message
// are also synchronized with the read lock.
readLock.lock();
try {
+ // Double check if the Socket is invalid (error or closed).
+ if (conContext.isBroken || conContext.isInboundClosed()) {
+ throw new SocketException(
+ "Connection or inbound has closed");
+ }
+
+ // Double check if the input stream has been depleted.
+ if (hasDepleted) {
+ if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
+ SSLLogger.fine("The input stream is closing");
+ }
+
+ return -1;
+ }
+
int remains = available();
if (remains > 0) {
int howmany = Math.min(remains, len);
@@ -938,7 +969,17 @@
return -1;
}
} finally {
- readLock.unlock();
+ // Check if the input stream is closing.
+ //
+ // If the deplete() did not hold the lock, clean up the
+ // input stream here.
+ try {
+ if (isClosing) {
+ readLockedDeplete();
+ }
+ } finally {
+ readLock.unlock();
+ }
}
}
@@ -1016,34 +1057,48 @@
* socket gracefully, without impact the performance too much.
*/
private void deplete() {
- if (conContext.isInboundClosed()) {
+ if (conContext.isInboundClosed() || isClosing) {
return;
}
- readLock.lock();
- try {
- // double check
- if (conContext.isInboundClosed()) {
- return;
+ isClosing = true;
+ if (readLock.tryLock()) {
+ try {
+ readLockedDeplete();
+ } finally {
+ readLock.unlock();
}
-
- if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
- return;
- }
+ }
+ }
- SSLSocketInputRecord socketInputRecord =
- (SSLSocketInputRecord)conContext.inputRecord;
- try {
- socketInputRecord.deplete(
- conContext.isNegotiated && (getSoTimeout() > 0));
- } catch (IOException ioe) {
- if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
- SSLLogger.warning(
- "input stream close depletion failed", ioe);
- }
+ /**
+ * Try to use up the input records.
+ *
+ * Please don't call this method unless the readLock is held by
+ * the current thread.
+ */
+ private void readLockedDeplete() {
+ // double check
+ if (hasDepleted || conContext.isInboundClosed()) {
+ return;
+ }
+
+ if (!(conContext.inputRecord instanceof SSLSocketInputRecord)) {
+ return;
+ }
+
+ SSLSocketInputRecord socketInputRecord =
+ (SSLSocketInputRecord)conContext.inputRecord;
+ try {
+ socketInputRecord.deplete(
+ conContext.isNegotiated && (getSoTimeout() > 0));
+ } catch (Exception ex) {
+ if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
+ SSLLogger.warning(
+ "input stream close depletion failed", ex);
}
} finally {
- readLock.unlock();
+ hasDepleted = true;
}
}
}
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java Tue May 07 17:30:14 2019 -0400
@@ -40,6 +40,7 @@
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
import org.w3c.dom.Text;
public abstract class IntegrityHmac extends SignatureAlgorithmSpi {
@@ -325,12 +326,13 @@
throw new IllegalArgumentException("element null");
}
- Text hmaclength =
- XMLUtils.selectDsNodeText(element.getFirstChild(), Constants._TAG_HMACOUTPUTLENGTH, 0);
-
- if (hmaclength != null) {
- this.HMACOutputLength = Integer.parseInt(hmaclength.getData());
- this.HMACOutputLengthSet = true;
+ Node n = XMLUtils.selectDsNode(element.getFirstChild(), Constants._TAG_HMACOUTPUTLENGTH, 0);
+ if (n != null) {
+ String hmacLength = XMLUtils.getFullTextChildrenFromNode(n);
+ if (hmacLength != null && !"".equals(hmacLength)) {
+ this.HMACOutputLength = Integer.parseInt(hmacLength);
+ this.HMACOutputLengthSet = true;
+ }
}
}
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java Tue May 07 17:30:14 2019 -0400
@@ -33,7 +33,6 @@
import java.security.SignatureException;
import java.security.interfaces.DSAKey;
import java.security.spec.AlgorithmParameterSpec;
-import java.util.Base64;
import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi;
@@ -41,6 +40,7 @@
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
public class SignatureDSA extends SignatureAlgorithmSpi {
@@ -109,7 +109,7 @@
throws XMLSignatureException {
try {
if (LOG.isDebugEnabled()) {
- LOG.debug("Called DSA.verify() on " + Base64.getMimeEncoder().encodeToString(signature));
+ LOG.debug("Called DSA.verify() on " + XMLUtils.encodeToString(signature));
}
byte[] jcebytes = JavaUtils.convertDsaXMLDSIGtoASN1(signature,
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java Tue May 07 17:30:14 2019 -0400
@@ -33,12 +33,12 @@
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.AlgorithmParameterSpec;
-import java.util.Base64;
import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi;
import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
/**
*
@@ -132,7 +132,7 @@
byte[] jcebytes = SignatureECDSA.convertXMLDSIGtoASN1(signature);
if (LOG.isDebugEnabled()) {
- LOG.debug("Called ECDSA.verify() on " + Base64.getMimeEncoder().encodeToString(signature));
+ LOG.debug("Called ECDSA.verify() on " + XMLUtils.encodeToString(signature));
}
return this.signatureAlgorithm.verify(jcebytes);
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java Tue May 07 17:30:14 2019 -0400
@@ -331,7 +331,7 @@
ns.addMapping(NName, NValue, attribute);
}
} else if (XML_LANG_URI.equals(attribute.getNamespaceURI())
- && (!c14n11 || c14n11 && !"id".equals(NName))) {
+ && (!c14n11 || !"id".equals(NName))) {
xmlattrStack.addXmlnsAttr(attribute);
}
}
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java Tue May 07 17:30:14 2019 -0400
@@ -342,7 +342,7 @@
protected void circumventBugIfNeeded(XMLSignatureInput input)
throws CanonicalizationException, ParserConfigurationException,
IOException, SAXException {
- if (!input.isNeedsToBeExpanded() || inclusiveNSSet.isEmpty() || inclusiveNSSet.isEmpty()) {
+ if (!input.isNeedsToBeExpanded() || inclusiveNSSet.isEmpty()) {
return;
}
Document doc = null;
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java Tue May 07 17:30:14 2019 -0400
@@ -50,7 +50,6 @@
import com.sun.org.apache.xml.internal.security.transforms.Transforms;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.ElementProxy;
-import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants;
import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Attr;
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java Tue May 07 17:30:14 2019 -0400
@@ -26,6 +26,7 @@
import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.DSAKeyValue;
+import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.ECKeyValue;
import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.RSAKeyValue;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
@@ -107,9 +108,14 @@
appendSelf(rsa);
addReturnToSelf();
+ } else if (pk instanceof java.security.interfaces.ECPublicKey) {
+ ECKeyValue ec = new ECKeyValue(getDocument(), pk);
+
+ appendSelf(ec);
+ addReturnToSelf();
} else {
String error = "The given PublicKey type " + pk + " is not supported. Only DSAPublicKey and "
- + "RSAPublicKey types are currently supported";
+ + "RSAPublicKey and ECPublicKey types are currently supported";
throw new IllegalArgumentException(error);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,366 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.sun.org.apache.xml.internal.security.keys.content.keyvalues;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECField;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.EllipticCurve;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Arrays;
+
+import javax.xml.crypto.MarshalException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+
+import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
+import com.sun.org.apache.xml.internal.security.utils.Constants;
+import com.sun.org.apache.xml.internal.security.utils.I18n;
+import com.sun.org.apache.xml.internal.security.utils.Signature11ElementProxy;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+
+public class ECKeyValue extends Signature11ElementProxy implements KeyValueContent {
+
+ /* Supported curve, secp256r1 */
+ private static final Curve SECP256R1 = initializeCurve(
+ "secp256r1 [NIST P-256, X9.62 prime256v1]",
+ "1.2.840.10045.3.1.7",
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+ 1
+ );
+
+ /* Supported curve secp384r1 */
+ private static final Curve SECP384R1 = initializeCurve(
+ "secp384r1 [NIST P-384]",
+ "1.3.132.0.34",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+ 1
+ );
+
+ /* Supported curve secp521r1 */
+ private static final Curve SECP521R1 = initializeCurve(
+ "secp521r1 [NIST P-521]",
+ "1.3.132.0.35",
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+ 1
+ );
+
+ private static Curve initializeCurve(String name, String oid,
+ String sfield, String a, String b,
+ String x, String y, String n, int h) {
+ BigInteger p = bigInt(sfield);
+ ECField field = new ECFieldFp(p);
+ EllipticCurve curve = new EllipticCurve(field, bigInt(a),
+ bigInt(b));
+ ECPoint g = new ECPoint(bigInt(x), bigInt(y));
+ return new Curve(name, oid, curve, g, bigInt(n), h);
+ }
+
+
+ /**
+ * Constructor DSAKeyValue
+ *
+ * @param element
+ * @param baseURI
+ * @throws XMLSecurityException
+ */
+ public ECKeyValue(Element element, String baseURI) throws XMLSecurityException {
+ super(element, baseURI);
+ }
+
+ /**
+ * Constructor DSAKeyValue
+ *
+ * @param doc
+ * @param key
+ * @throws IllegalArgumentException
+ */
+ public ECKeyValue(Document doc, Key key) throws IllegalArgumentException {
+ super(doc);
+
+ addReturnToSelf();
+
+ if (key instanceof ECPublicKey) {
+ ECParameterSpec ecParams = ((ECPublicKey)key).getParams();
+
+ // NamedCurve
+ String oid = getCurveOid(ecParams);
+ if (oid == null) {
+ throw new IllegalArgumentException("Invalid ECParameterSpec");
+ }
+
+ Element namedCurveElement = XMLUtils.createElementInSignature11Space(getDocument(), "NamedCurve");
+ namedCurveElement.setAttributeNS(null, "URI", "urn:oid:" + oid);
+ appendSelf(namedCurveElement);
+ addReturnToSelf();
+
+ // PublicKey
+ ECPoint ecPoint = ((ECPublicKey)key).getW();
+ byte[] secPublicKey = encodePoint(ecPoint, ecParams.getCurve());
+ String encoded = XMLUtils.encodeToString(secPublicKey);
+ Element publicKeyElement = XMLUtils.createElementInSignature11Space(getDocument(), "PublicKey");
+ Text text = getDocument().createTextNode(encoded);
+
+ publicKeyElement.appendChild(text);
+
+ appendSelf(publicKeyElement);
+ addReturnToSelf();
+
+ } else {
+ Object[] exArgs = { Constants._TAG_ECKEYVALUE, key.getClass().getName() };
+
+ throw new IllegalArgumentException(I18n.translate("KeyValue.IllegalArgument", exArgs));
+ }
+ }
+
+ /** {@inheritDoc} */
+ public PublicKey getPublicKey() throws XMLSecurityException {
+ try {
+ ECParameterSpec ecParams = null;
+ Element curElem = getFirstChildElement(getElement());
+ if (curElem == null) {
+ throw new MarshalException("KeyValue must contain at least one type");
+ }
+
+ if ("ECParameters".equals(curElem.getLocalName())
+ && Constants.SignatureSpec11NS.equals(curElem.getNamespaceURI())) {
+ throw new UnsupportedOperationException
+ ("ECParameters not supported");
+ } else if ("NamedCurve".equals(curElem.getLocalName())
+ && Constants.SignatureSpec11NS.equals(curElem.getNamespaceURI())) {
+ String uri = null;
+ if (curElem.hasAttributeNS(null, "URI")) {
+ uri = curElem.getAttributeNS(null, "URI");
+ }
+ // strip off "urn:oid"
+ if (uri.startsWith("urn:oid:")) {
+ String oid = uri.substring("urn:oid:".length());
+ ecParams = getECParameterSpec(oid);
+ if (ecParams == null) {
+ throw new MarshalException("Invalid curve OID");
+ }
+ } else {
+ throw new MarshalException("Invalid NamedCurve URI");
+ }
+ } else {
+ throw new MarshalException("Invalid ECKeyValue");
+ }
+ curElem = getNextSiblingElement(curElem, "PublicKey", Constants.SignatureSpec11NS);
+ ECPoint ecPoint = null;
+
+ try {
+ String content = XMLUtils.getFullTextChildrenFromNode(curElem);
+ ecPoint = decodePoint(XMLUtils.decode(content), ecParams.getCurve());
+ } catch (IOException ioe) {
+ throw new MarshalException("Invalid EC Point", ioe);
+ }
+
+ ECPublicKeySpec spec = new ECPublicKeySpec(ecPoint, ecParams);
+ return KeyFactory.getInstance("EC").generatePublic(spec);
+ } catch (NoSuchAlgorithmException ex) {
+ throw new XMLSecurityException(ex);
+ } catch (InvalidKeySpecException ex) {
+ throw new XMLSecurityException(ex);
+ } catch (MarshalException ex) {
+ throw new XMLSecurityException(ex);
+ }
+ }
+
+ /** {@inheritDoc} */
+ public String getBaseLocalName() {
+ return Constants._TAG_ECKEYVALUE;
+ }
+
+ private static Element getFirstChildElement(Node node) {
+ Node child = node.getFirstChild();
+ while (child != null && child.getNodeType() != Node.ELEMENT_NODE) {
+ child = child.getNextSibling();
+ }
+ return (Element)child;
+ }
+
+ private static Element getNextSiblingElement(Node node, String localName, String namespaceURI)
+ throws MarshalException
+ {
+ return verifyElement(getNextSiblingElement(node), localName, namespaceURI);
+ }
+
+ private static Element getNextSiblingElement(Node node) {
+ Node sibling = node.getNextSibling();
+ while (sibling != null && sibling.getNodeType() != Node.ELEMENT_NODE) {
+ sibling = sibling.getNextSibling();
+ }
+ return (Element)sibling;
+ }
+
+ private static Element verifyElement(Element elem, String localName, String namespaceURI)
+ throws MarshalException
+ {
+ if (elem == null) {
+ throw new MarshalException("Missing " + localName + " element");
+ }
+ String name = elem.getLocalName();
+ String namespace = elem.getNamespaceURI();
+ if (!name.equals(localName) || namespace == null && namespaceURI != null
+ || namespace != null && !namespace.equals(namespaceURI)) {
+ throw new MarshalException("Invalid element name: " +
+ namespace + ":" + name + ", expected " + namespaceURI + ":" + localName);
+ }
+ return elem;
+ }
+
+ private static String getCurveOid(ECParameterSpec params) {
+ // Check that the params represent one of the supported
+ // curves. If there is a match, return the object identifier
+ // of the curve.
+ Curve match;
+ if (matchCurve(params, SECP256R1)) {
+ match = SECP256R1;
+ } else if (matchCurve(params, SECP384R1)) {
+ match = SECP384R1;
+ } else if (matchCurve(params, SECP521R1)) {
+ match = SECP521R1;
+ } else {
+ return null;
+ }
+ return match.getObjectId();
+ }
+
+ private static boolean matchCurve(ECParameterSpec params, Curve curve) {
+ int fieldSize = params.getCurve().getField().getFieldSize();
+ return curve.getCurve().getField().getFieldSize() == fieldSize
+ && curve.getCurve().equals(params.getCurve())
+ && curve.getGenerator().equals(params.getGenerator())
+ && curve.getOrder().equals(params.getOrder())
+ && curve.getCofactor() == params.getCofactor();
+ }
+
+ private static ECPoint decodePoint(byte[] data, EllipticCurve curve)
+ throws IOException {
+ if (data.length == 0 || data[0] != 4) {
+ throw new IOException("Only uncompressed point format " +
+ "supported");
+ }
+ // Per ANSI X9.62, an encoded point is a 1 byte type followed by
+ // ceiling(LOG base 2 field-size / 8) bytes of x and the same of y.
+ int n = (data.length - 1) / 2;
+ if (n != (curve.getField().getFieldSize() + 7) >> 3) {
+ throw new IOException("Point does not match field size");
+ }
+
+ byte[] xb = Arrays.copyOfRange(data, 1, 1 + n);
+ byte[] yb = Arrays.copyOfRange(data, n + 1, n + 1 + n);
+
+ return new ECPoint(new BigInteger(1, xb), new BigInteger(1, yb));
+ }
+
+ private static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
+ // get field size in bytes (rounding up)
+ int n = (curve.getField().getFieldSize() + 7) >> 3;
+ byte[] xb = trimZeroes(point.getAffineX().toByteArray());
+ byte[] yb = trimZeroes(point.getAffineY().toByteArray());
+ if (xb.length > n || yb.length > n) {
+ throw new RuntimeException("Point coordinates do not " +
+ "match field size");
+ }
+ byte[] b = new byte[1 + (n << 1)];
+ b[0] = 4; // uncompressed
+ System.arraycopy(xb, 0, b, n - xb.length + 1, xb.length);
+ System.arraycopy(yb, 0, b, b.length - yb.length, yb.length);
+ return b;
+ }
+
+ private static byte[] trimZeroes(byte[] b) {
+ int i = 0;
+ while (i < b.length - 1 && b[i] == 0) {
+ i++;
+ }
+ if (i == 0) {
+ return b;
+ }
+ return Arrays.copyOfRange(b, i, b.length);
+ }
+
+ private static ECParameterSpec getECParameterSpec(String oid) {
+ if (oid.equals(SECP256R1.getObjectId())) {
+ return SECP256R1;
+ } else if (oid.equals(SECP384R1.getObjectId())) {
+ return SECP384R1;
+ } else if (oid.equals(SECP521R1.getObjectId())) {
+ return SECP521R1;
+ } else {
+ return null;
+ }
+ }
+
+ static final class Curve extends ECParameterSpec {
+ private final String name;
+ private final String oid;
+
+ Curve(String name, String oid, EllipticCurve curve,
+ ECPoint g, BigInteger n, int h) {
+ super(curve, g, n, h);
+ this.name = name;
+ this.oid = oid;
+ }
+
+ private String getName() {
+ return name;
+ }
+
+ private String getObjectId() {
+ return oid;
+ }
+ }
+
+ private static BigInteger bigInt(String s) {
+ return new BigInteger(s, 16);
+ }
+}
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java Tue May 07 17:30:14 2019 -0400
@@ -24,18 +24,18 @@
import java.security.cert.X509Certificate;
import java.util.Arrays;
-import java.util.Base64;
import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Handles SubjectKeyIdentifier (SKI) for X.509v3.
*
- * @see <A HREF="http://docs.oracle.com/javase/1.5.0/docs/api/java/security/cert/X509Extension.html">
+ * @see <A HREF="http://docs.oracle.com/javase/8/docs/api/java/security/cert/X509Extension.html">
* Interface X509Extension</A>
*/
public class XMLX509SKI extends SignatureElementProxy implements XMLX509DataContent {
@@ -138,7 +138,7 @@
System.arraycopy(extensionValue, 4, skidValue, 0, skidValue.length);
if (LOG.isDebugEnabled()) {
- LOG.debug("Base64 of SKI is " + Base64.getMimeEncoder().encodeToString(skidValue));
+ LOG.debug("Base64 of SKI is " + XMLUtils.encodeToString(skidValue));
}
return skidValue;
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java Tue May 07 17:30:14 2019 -0400
@@ -33,6 +33,7 @@
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.DEREncodedKeyValueResolver;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.DSAKeyValueResolver;
+import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.ECKeyValueResolver;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.KeyInfoReferenceResolver;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.RSAKeyValueResolver;
import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.RetrievalMethodResolver;
@@ -295,6 +296,7 @@
keyResolverList.add(new KeyResolver(new DEREncodedKeyValueResolver()));
keyResolverList.add(new KeyResolver(new KeyInfoReferenceResolver()));
keyResolverList.add(new KeyResolver(new X509DigestResolver()));
+ keyResolverList.add(new KeyResolver(new ECKeyValueResolver()));
resolverVector.addAll(keyResolverList);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/ECKeyValueResolver.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,97 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations;
+
+import java.security.PublicKey;
+import java.security.cert.X509Certificate;
+
+import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
+import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.ECKeyValue;
+import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi;
+import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
+import com.sun.org.apache.xml.internal.security.utils.Constants;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import org.w3c.dom.Element;
+
+public class ECKeyValueResolver extends KeyResolverSpi {
+
+ private static final com.sun.org.slf4j.internal.Logger LOG =
+ com.sun.org.slf4j.internal.LoggerFactory.getLogger(ECKeyValueResolver.class);
+
+
+ /**
+ * Method engineResolvePublicKey
+ *
+ * @param element
+ * @param baseURI
+ * @param storage
+ * @return null if no {@link PublicKey} could be obtained
+ */
+ public PublicKey engineLookupAndResolvePublicKey(
+ Element element, String baseURI, StorageResolver storage
+ ) {
+ if (element == null) {
+ return null;
+ }
+ Element ecKeyElement = null;
+ boolean isKeyValue =
+ XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYVALUE);
+ if (isKeyValue) {
+ ecKeyElement =
+ XMLUtils.selectDs11Node(element.getFirstChild(), Constants._TAG_ECKEYVALUE, 0);
+ } else if (XMLUtils.elementIsInSignature11Space(element, Constants._TAG_ECKEYVALUE)) {
+ // this trick is needed to allow the RetrievalMethodResolver to eat a
+ // ds:ECKeyValue directly (without KeyValue)
+ ecKeyElement = element;
+ }
+
+ if (ecKeyElement == null) {
+ return null;
+ }
+
+ try {
+ ECKeyValue ecKeyValue = new ECKeyValue(ecKeyElement, baseURI);
+ return ecKeyValue.getPublicKey();
+ } catch (XMLSecurityException ex) {
+ LOG.debug(ex.getMessage(), ex);
+ //do nothing
+ }
+
+ return null;
+ }
+
+
+ /** {@inheritDoc} */
+ public X509Certificate engineLookupResolveX509Certificate(
+ Element element, String baseURI, StorageResolver storage
+ ) {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public javax.crypto.SecretKey engineLookupAndResolveSecretKey(
+ Element element, String baseURI, StorageResolver storage
+ ) {
+ return null;
+ }
+}
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java Tue May 07 17:30:14 2019 -0400
@@ -44,11 +44,12 @@
public PublicKey engineLookupAndResolvePublicKey(
Element element, String baseURI, StorageResolver storage
) {
- LOG.debug("Can I resolve {}", element.getTagName());
if (element == null) {
return null;
}
+ LOG.debug("Can I resolve {}", element.getTagName());
+
boolean isKeyValue = XMLUtils.elementIsInSignatureSpace(element, Constants._TAG_KEYVALUE);
Element rsaKeyElement = null;
if (isKeyValue) {
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/CertsInFilesystemDirectoryResolver.java Tue May 07 17:30:14 2019 -0400
@@ -35,12 +35,12 @@
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
-import java.util.Base64;
import java.util.Iterator;
import java.util.List;
import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverException;
import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolverSpi;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
/**
* This {@link StorageResolverSpi} makes all raw (binary) {@link X509Certificate}s
@@ -207,7 +207,7 @@
System.out.println();
System.out.println("Base64(SKI())= \""
- + Base64.getMimeEncoder().encodeToString(ski) + "\"");
+ + XMLUtils.encodeToString(ski) + "\"");
System.out.println("cert.getSerialNumber()= \""
+ cert.getSerialNumber().toString() + "\"");
System.out.println("cert.getSubjectX500Principal().getName()= \""
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml Tue May 07 17:30:14 2019 -0400
@@ -643,6 +643,8 @@
DESCRIPTION="Uses an X509 SubjectName to retrieve a certificate from the storages" />
<Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509IssuerSerialResolver"
DESCRIPTION="Uses an X509 IssuerName and IssuerSerial to retrieve a certificate from the storages" />
+ <Resolver JAVACLASS="com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.ECKeyValueResolver"
+ DESCRIPTION="Can extract EC public keys" />
</KeyResolver>
<PrefixMappings>
@@ -665,5 +667,7 @@
prefix="ec" />
<PrefixMapping namespace="http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/#xpathFilter"
prefix="xx" />
+ <PrefixMapping namespace="http://www.w3.org/2009/xmldsig11#"
+ prefix="dsig11" />
</PrefixMappings>
</Configuration>
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Manifest.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Manifest.java Tue May 07 17:30:14 2019 -0400
@@ -23,7 +23,10 @@
package com.sun.org.apache.xml.internal.security.signature;
import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -56,19 +59,24 @@
public class Manifest extends SignatureElementProxy {
/**
- * The maximum number of references per Manifest, if secure validation is enabled.
+ * The default maximum number of references per Manifest, if secure validation is enabled.
*/
public static final int MAXIMUM_REFERENCE_COUNT = 30;
private static final com.sun.org.slf4j.internal.Logger LOG =
com.sun.org.slf4j.internal.LoggerFactory.getLogger(Manifest.class);
+ private static Integer referenceCount =
+ AccessController.doPrivileged(
+ (PrivilegedAction<Integer>) () -> Integer.parseInt(System.getProperty("com.sun.org.apache.xml.internal.security.maxReferences",
+ Integer.toString(MAXIMUM_REFERENCE_COUNT))));
+
/** Field references */
private List<Reference> references;
private Element[] referencesEl;
/** Field verificationResults[] */
- private boolean[] verificationResults;
+ private List<VerifiedReference> verificationResults;
/** Field resolverProperties */
private Map<String, String> resolverProperties;
@@ -135,8 +143,8 @@
I18n.translate("xml.WrongContent", exArgs));
}
- if (secureValidation && le > MAXIMUM_REFERENCE_COUNT) {
- Object exArgs[] = { le, MAXIMUM_REFERENCE_COUNT };
+ if (secureValidation && le > referenceCount) {
+ Object exArgs[] = { le, referenceCount };
throw new XMLSecurityException("signature.tooManyReferences", exArgs);
}
@@ -317,13 +325,13 @@
if (referencesEl.length == 0) {
throw new XMLSecurityException("empty", new Object[]{"References are empty"});
}
- if (secureValidation && referencesEl.length > MAXIMUM_REFERENCE_COUNT) {
- Object exArgs[] = { referencesEl.length, MAXIMUM_REFERENCE_COUNT };
+ if (secureValidation && referencesEl.length > referenceCount) {
+ Object exArgs[] = { referencesEl.length, referenceCount };
throw new XMLSecurityException("signature.tooManyReferences", exArgs);
}
- this.verificationResults = new boolean[referencesEl.length];
+ this.verificationResults = new ArrayList<>(referencesEl.length);
boolean verify = true;
for (int i = 0; i < this.referencesEl.length; i++) {
Reference currentRef =
@@ -335,13 +343,13 @@
try {
boolean currentRefVerified = currentRef.verify();
- this.setVerificationResult(i, currentRefVerified);
-
if (!currentRefVerified) {
verify = false;
}
LOG.debug("The Reference has Type {}", currentRef.getType());
+ List<VerifiedReference> manifestReferences = Collections.emptyList();
+
// was verification successful till now and do we want to verify the Manifest?
if (verify && followManifests && currentRef.typeIsReferenceToManifest()) {
LOG.debug("We have to follow a nested Manifest");
@@ -393,6 +401,8 @@
} else {
LOG.debug("The nested Manifest was valid (good)");
}
+
+ manifestReferences = referencedManifest.getVerificationResults();
} catch (IOException ex) {
throw new ReferenceNotInitializedException(ex);
} catch (ParserConfigurationException ex) {
@@ -401,6 +411,8 @@
throw new ReferenceNotInitializedException(ex);
}
}
+
+ verificationResults.add(new VerifiedReference(currentRefVerified, currentRef.getURI(), manifestReferences));
} catch (ReferenceNotInitializedException ex) {
Object exArgs[] = { currentRef.getURI() };
@@ -414,20 +426,6 @@
}
/**
- * Method setVerificationResult
- *
- * @param index
- * @param verify
- */
- private void setVerificationResult(int index, boolean verify) {
- if (this.verificationResults == null) {
- this.verificationResults = new boolean[this.getLength()];
- }
-
- this.verificationResults[index] = verify;
- }
-
- /**
* After verifying a {@link Manifest} or a {@link SignedInfo} using the
* {@link Manifest#verifyReferences()} or {@link SignedInfo#verify()} methods,
* the individual results can be retrieved with this method.
@@ -455,14 +453,24 @@
}
}
- return this.verificationResults[index];
+ return ((ArrayList<VerifiedReference>)verificationResults).get(index).isValid();
+ }
+
+ /**
+ * Get the list of verification result objects
+ */
+ public List<VerifiedReference> getVerificationResults() {
+ if (verificationResults == null) {
+ return Collections.emptyList();
+ }
+ return Collections.unmodifiableList(verificationResults);
}
/**
* Adds Resource Resolver for retrieving resources at specified {@code URI} attribute
* in {@code reference} element
*
- * @param resolver {@link ResourceResolver} can provide the implemenatin subclass of
+ * @param resolver {@link ResourceResolver} can provide the implementation subclass of
* {@link ResourceResolverSpi} for retrieving resource.
*/
public void addResourceResolver(ResourceResolver resolver) {
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java Tue May 07 17:30:14 2019 -0400
@@ -26,7 +26,6 @@
import java.io.OutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Base64;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
@@ -396,7 +395,7 @@
n = n.getNextSibling();
}
- String base64codedValue = Base64.getMimeEncoder().encodeToString(digestValue);
+ String base64codedValue = XMLUtils.encodeToString(digestValue);
Text t = createText(base64codedValue);
digestValueElement.appendChild(t);
@@ -723,12 +722,17 @@
return getPreCalculatedDigest(input);
}
+ cacheDereferencedElement(input);
+
MessageDigestAlgorithm mda = this.getMessageDigestAlgorithm();
mda.reset();
try (DigesterOutputStream diOs = new DigesterOutputStream(mda);
OutputStream os = new UnsyncBufferedOutputStream(diOs)) {
- XMLSignatureInput output = this.dereferenceURIandPerformTransforms(os);
+
+ XMLSignatureInput output = this.getContentsAfterTransformation(input, os);
+ this.transformsOutput = output;
+
// if signing and c14n11 property == true explicitly add
// C14N11 transform if needed
if (Reference.useC14N11 && !validating && !output.isOutputStreamSet()
@@ -772,7 +776,7 @@
throws ReferenceNotInitializedException {
LOG.debug("Verifying element with pre-calculated digest");
String preCalculatedDigest = input.getPreCalculatedDigest();
- return Base64.getMimeDecoder().decode(preCalculatedDigest);
+ return XMLUtils.decode(preCalculatedDigest);
}
/**
@@ -789,8 +793,8 @@
"signature.Verification.NoSignatureElement", exArgs
);
}
- String content = XMLUtils.getFullTextChildrenFromElement(digestValueElement);
- return Base64.getMimeDecoder().decode(content);
+ String content = XMLUtils.getFullTextChildrenFromNode(digestValueElement);
+ return XMLUtils.decode(content);
}
@@ -809,8 +813,8 @@
if (!equal) {
LOG.warn("Verification failed for URI \"" + this.getURI() + "\"");
- LOG.warn("Expected Digest: " + Base64.getMimeEncoder().encodeToString(elemDig));
- LOG.warn("Actual Digest: " + Base64.getMimeEncoder().encodeToString(calcDig));
+ LOG.warn("Expected Digest: " + XMLUtils.encodeToString(elemDig));
+ LOG.warn("Actual Digest: " + XMLUtils.encodeToString(calcDig));
} else {
LOG.debug("Verification successful for URI \"{}\"", this.getURI());
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/VerifiedReference.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,64 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.sun.org.apache.xml.internal.security.signature;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Holds the result of a Reference validation.
+ */
+public class VerifiedReference {
+
+ private final boolean valid;
+ private final String uri;
+ private final List<VerifiedReference> manifestReferences;
+
+ /**
+ * @param valid Whether this Reference was successfully validated or not
+ * @param uri The URI of this Reference
+ * @param manifestReferences If this reference is a reference to a Manifest, this holds the list
+ * of verified referenes associated with this Manifest
+ */
+ public VerifiedReference(boolean valid, String uri, List<VerifiedReference> manifestReferences) {
+ this.valid = valid;
+ this.uri = uri;
+ if (manifestReferences != null) {
+ this.manifestReferences = manifestReferences;
+ } else {
+ this.manifestReferences = Collections.emptyList();
+ }
+ }
+
+ public boolean isValid() {
+ return valid;
+ }
+
+ public String getUri() {
+ return uri;
+ }
+
+ public List<VerifiedReference> getManifestReferences() {
+ return Collections.unmodifiableList(manifestReferences);
+ }
+}
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java Tue May 07 17:30:14 2019 -0400
@@ -27,7 +27,6 @@
import java.security.Key;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
-import java.util.Base64;
import javax.crypto.SecretKey;
@@ -504,8 +503,8 @@
* @throws XMLSignatureException If there is no content
*/
public byte[] getSignatureValue() throws XMLSignatureException {
- String content = XMLUtils.getFullTextChildrenFromElement(signatureValueElement);
- return Base64.getMimeDecoder().decode(content);
+ String content = XMLUtils.getFullTextChildrenFromNode(signatureValueElement);
+ return XMLUtils.decode(content);
}
/**
@@ -520,7 +519,7 @@
signatureValueElement.removeChild(signatureValueElement.getFirstChild());
}
- String base64codedValue = Base64.getMimeEncoder().encodeToString(bytes);
+ String base64codedValue = XMLUtils.encodeToString(bytes);
if (base64codedValue.length() > 76 && !XMLUtils.ignoreLineBreaks()) {
base64codedValue = "\n" + base64codedValue + "\n";
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformBase64Decode.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformBase64Decode.java Tue May 07 17:30:14 2019 -0400
@@ -24,7 +24,6 @@
import java.io.IOException;
import java.io.OutputStream;
-import java.util.Base64;
import javax.xml.parsers.ParserConfigurationException;
@@ -109,12 +108,12 @@
StringBuilder sb = new StringBuilder();
traverseElement((Element)el, sb);
if (os == null) {
- byte[] decodedBytes = Base64.getMimeDecoder().decode(sb.toString());
+ byte[] decodedBytes = XMLUtils.decode(sb.toString());
XMLSignatureInput output = new XMLSignatureInput(decodedBytes);
output.setSecureValidation(secureValidation);
return output;
}
- byte[] bytes = Base64.getMimeDecoder().decode(sb.toString());
+ byte[] bytes = XMLUtils.decode(sb.toString());
os.write(bytes);
XMLSignatureInput output = new XMLSignatureInput((byte[])null);
output.setSecureValidation(secureValidation);
@@ -125,17 +124,17 @@
if (input.isOctetStream() || input.isNodeSet()) {
if (os == null) {
byte[] base64Bytes = input.getBytes();
- byte[] decodedBytes = Base64.getMimeDecoder().decode(base64Bytes);
+ byte[] decodedBytes = XMLUtils.decode(base64Bytes);
XMLSignatureInput output = new XMLSignatureInput(decodedBytes);
output.setSecureValidation(secureValidation);
return output;
}
if (input.isByteArray() || input.isNodeSet()) {
- byte[] bytes = Base64.getMimeDecoder().decode(input.getBytes());
+ byte[] bytes = XMLUtils.decode(input.getBytes());
os.write(bytes);
} else {
byte[] inputBytes = JavaUtils.getBytesFromStream(input.getOctetStreamReal());
- byte[] bytes = Base64.getMimeDecoder().decode(inputBytes);
+ byte[] bytes = XMLUtils.decode(inputBytes);
os.write(bytes);
}
XMLSignatureInput output = new XMLSignatureInput((byte[])null);
@@ -153,7 +152,7 @@
Element rootNode = doc.getDocumentElement();
StringBuilder sb = new StringBuilder();
traverseElement(rootNode, sb);
- byte[] decodedBytes = Base64.getMimeDecoder().decode(sb.toString());
+ byte[] decodedBytes = XMLUtils.decode(sb.toString());
XMLSignatureInput output = new XMLSignatureInput(decodedBytes);
output.setSecureValidation(secureValidation);
return output;
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXSLT.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXSLT.java Tue May 07 17:30:14 2019 -0400
@@ -84,7 +84,10 @@
Element xsltElement =
XMLUtils.selectNode(transformElement.getFirstChild(), XSLTSpecNS, "stylesheet", 0);
-
+ if (xsltElement == null) {
+ xsltElement =
+ XMLUtils.selectNode(transformElement.getFirstChild(), XSLTSpecNS, "transform", 0);
+ }
if (xsltElement == null) {
Object exArgs[] = { "xslt:stylesheet", "Transform" };
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPathFilterCHGPContainer.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/params/XPathFilterCHGPContainer.java Tue May 07 17:30:14 2019 -0400
@@ -30,6 +30,7 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import org.w3c.dom.Text;
/**
* Implements the parameters for a custom Transform which has a better performance
@@ -204,7 +205,7 @@
getElement().getFirstChild(), this.getBaseNamespace(), type, 0
);
- return XMLUtils.getFullTextChildrenFromElement(xElem);
+ return XMLUtils.getFullTextChildrenFromNode(xElem);
}
/**
@@ -258,11 +259,23 @@
return null;
}
- return XMLUtils.selectNodeText(
+ return selectNodeText(
getFirstChild(), this.getBaseNamespace(), type, 0
);
}
+ private static Text selectNodeText(Node sibling, String uri, String nodeName, int number) {
+ Node n = XMLUtils.selectNode(sibling, uri, nodeName, number);
+ if (n == null) {
+ return null;
+ }
+ n = n.getFirstChild();
+ while (n != null && n.getNodeType() != Node.TEXT_NODE) {
+ n = n.getNextSibling();
+ }
+ return (Text)n;
+ }
+
/**
* Method getHereContextNodeIncludeButSearch
*
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Constants.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Constants.java Tue May 07 17:30:14 2019 -0400
@@ -210,6 +210,9 @@
/** Tag of Element J **/
public static final String _TAG_J = "J";
+ /** Tag of Element ECKeyValue **/
+ public static final String _TAG_ECKEYVALUE = "ECKeyValue";
+
/** Tag of Element Seed **/
public static final String _TAG_SEED = "Seed";
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java Tue May 07 17:30:14 2019 -0400
@@ -24,7 +24,6 @@
import java.math.BigInteger;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.Base64;
import java.util.Map;
import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
@@ -267,7 +266,7 @@
Element e = XMLUtils.createElementInSignatureSpace(getDocument(), localname);
byte[] bytes = XMLUtils.getBytes(bi, bi.bitLength());
- String encodedInt = Base64.getMimeEncoder().encodeToString(bytes);
+ String encodedInt = XMLUtils.encodeToString(bytes);
Document doc = e.getOwnerDocument();
Text text = doc.createTextNode(encodedInt);
@@ -292,7 +291,7 @@
public void addBase64Element(byte[] bytes, String localname) {
if (bytes != null) {
Element el = XMLUtils.createElementInSignatureSpace(getDocument(), localname);
- Text text = getDocument().createTextNode(Base64.getMimeEncoder().encodeToString(bytes));
+ Text text = getDocument().createTextNode(XMLUtils.encodeToString(bytes));
el.appendChild(text);
@@ -326,8 +325,8 @@
public void addBase64Text(byte[] bytes) {
if (bytes != null) {
Text t = XMLUtils.ignoreLineBreaks()
- ? createText(Base64.getMimeEncoder().encodeToString(bytes))
- : createText("\n" + Base64.getMimeEncoder().encodeToString(bytes) + "\n");
+ ? createText(XMLUtils.encodeToString(bytes))
+ : createText("\n" + XMLUtils.encodeToString(bytes) + "\n");
appendSelf(t);
}
}
@@ -367,11 +366,11 @@
public BigInteger getBigIntegerFromChildElement(
String localname, String namespace
) {
- return new BigInteger(1, Base64.getMimeDecoder().decode(
- XMLUtils.selectNodeText(
- getFirstChild(), namespace, localname, 0
- ).getNodeValue()
- ));
+ Node n = XMLUtils.selectNode(getFirstChild(), namespace, localname, 0);
+ if (n != null) {
+ return new BigInteger(1, XMLUtils.decode(XMLUtils.getFullTextChildrenFromNode(n)));
+ }
+ return null;
}
/**
@@ -396,7 +395,7 @@
* @throws XMLSecurityException
*/
public byte[] getBytesFromTextChild() throws XMLSecurityException {
- return Base64.getMimeDecoder().decode(getTextFromTextChild());
+ return XMLUtils.decode(getTextFromTextChild());
}
/**
@@ -406,7 +405,7 @@
* element
*/
public String getTextFromTextChild() {
- return XMLUtils.getFullTextChildrenFromElement(getElement());
+ return XMLUtils.getFullTextChildrenFromNode(getElement());
}
/**
@@ -498,8 +497,9 @@
if (Constants.SignatureSpecNS.equals(namespace)) {
XMLUtils.setDsPrefix(prefix);
- }
- if (EncryptionConstants.EncryptionSpecNS.equals(namespace)) {
+ } else if (Constants.SignatureSpec11NS.equals(namespace)) {
+ XMLUtils.setDs11Prefix(prefix);
+ } else if (EncryptionConstants.EncryptionSpecNS.equals(namespace)) {
XMLUtils.setXencPrefix(prefix);
}
prefixMappings.put(namespace, prefix);
@@ -519,6 +519,7 @@
setNamespacePrefix(
"http://www.nue.et-inf.uni-siegen.de/~geuer-pollmann/#xpathFilter", "xx"
);
+ setNamespacePrefix("http://www.w3.org/2009/xmldsig11#", "dsig11");
}
/**
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Signature11ElementProxy.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Signature11ElementProxy.java Tue May 07 17:30:14 2019 -0400
@@ -47,6 +47,13 @@
setDocument(doc);
setElement(XMLUtils.createElementInSignature11Space(doc, this.getBaseLocalName()));
+
+ String prefix = ElementProxy.getDefaultPrefix(getBaseNamespace());
+ if (prefix == null || prefix.length() == 0) {
+ getElement().setAttributeNS(Constants.NamespaceSpecNS, "xmlns", getBaseNamespace());
+ } else {
+ getElement().setAttributeNS(Constants.NamespaceSpecNS, "xmlns:" + prefix, getBaseNamespace());
+ }
}
/**
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java Tue May 07 17:30:14 2019 -0400
@@ -254,16 +254,21 @@
}
}
+ @Deprecated
+ public static String getFullTextChildrenFromElement(Element element) {
+ return getFullTextChildrenFromNode(element);
+ }
+
/**
- * Method getFullTextChildrenFromElement
+ * Method getFullTextChildrenFromNode
*
- * @param element
+ * @param node
* @return the string of children
*/
- public static String getFullTextChildrenFromElement(Element element) {
+ public static String getFullTextChildrenFromNode(Node node) {
StringBuilder sb = new StringBuilder();
- Node child = element.getFirstChild();
+ Node child = node.getFirstChild();
while (child != null) {
if (child.getNodeType() == Node.TEXT_NODE) {
sb.append(((Text)child).getData());
@@ -682,7 +687,7 @@
while (sibling != null) {
if (sibling.getNamespaceURI() != null && sibling.getNamespaceURI().equals(uri)
&& sibling.getLocalName().equals(nodeName)) {
- if (number == 0){
+ if (number == 0) {
return (Element)sibling;
}
number--;
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/ResourceResolver.java Tue May 07 17:30:14 2019 -0400
@@ -97,7 +97,7 @@
LOG.debug("check resolvability by class {}", resolverTmp.getClass().getName());
- if (resolverTmp != null && resolverTmp.canResolve(context)) {
+ if (resolverTmp.canResolve(context)) {
// Check to see whether the Resolver is allowed
if (context.secureValidation
&& (resolverTmp.resolverSpi instanceof ResolverLocalFilesystem
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java Tue May 07 17:30:14 2019 -0400
@@ -33,9 +33,9 @@
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
-import java.util.Base64;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverContext;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException;
import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi;
@@ -57,7 +57,7 @@
* </PRE>
*
* @see <A HREF="http://www.javaworld.com/javaworld/javatips/jw-javatip42_p.html">Java Tip 42: Write Java apps that work with proxy-based firewalls</A>
- * @see <A HREF="http://docs.oracle.com/javase/1.4.2/docs/guide/net/properties.html">SUN J2SE docs for network properties</A>
+ * @see <A HREF="https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html">JDK docs for network properties</A>
* @see <A HREF="http://metalab.unc.edu/javafaq/javafaq.html#proxy">The JAVA FAQ Question 9.5: How do I make Java work with a proxy server?</A>
*/
public class ResolverDirectHTTP extends ResourceResolverSpi {
@@ -122,7 +122,7 @@
urlConnection = openConnection(url);
String password = user + ":" + pass;
- String encodedPassword = Base64.getMimeEncoder().encodeToString(password.getBytes(StandardCharsets.ISO_8859_1));
+ String encodedPassword = XMLUtils.encodeToString(password.getBytes(StandardCharsets.ISO_8859_1));
// set authentication property in the http header
urlConnection.setRequestProperty("Authorization",
@@ -187,7 +187,7 @@
if (proxyUser != null && proxyPass != null) {
String password = proxyUser + ":" + proxyPass;
- String authString = "Basic " + Base64.getMimeEncoder().encodeToString(password.getBytes(StandardCharsets.ISO_8859_1));
+ String authString = "Basic " + XMLUtils.encodeToString(password.getBytes(StandardCharsets.ISO_8859_1));
urlConnection.setRequestProperty("Proxy-Authorization", authString);
}
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: ApacheCanonicalizer.java 1785016 2017-03-01 18:23:48Z coheigea $
+ * $Id: ApacheCanonicalizer.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: ApacheOctetStreamData.java 1667527 2015-03-18 12:54:20Z mullan $
+ * $Id: ApacheOctetStreamData.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: ApacheTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: ApacheTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMCanonicalXMLC14NMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMCanonicalXMLC14NMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java Tue May 07 17:30:14 2019 -0400
@@ -1,3 +1,7 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -17,7 +21,7 @@
* under the License.
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* $Id$
@@ -33,16 +37,16 @@
import org.w3c.dom.Text;
/**
- * A DOM-based representation of the XML <code>CryptoBinary</code> simple type
+ * A DOM-based representation of the XML {@code CryptoBinary} simple type
* as defined in the W3C specification for XML-Signature Syntax and Processing.
* The XML Schema Definition is defined as:
*
- * <xmp>
+ * <pre>{@code
* <simpleType name="CryptoBinary">
* <restriction base = "base64Binary">
* </restriction>
* </simpleType>
- * </xmp>
+ * }</pre>
*
* @author Sean Mullan
*/
@@ -52,11 +56,11 @@
private final String value;
/**
- * Create a <code>DOMCryptoBinary</code> instance from the specified
- * <code>BigInteger</code>
+ * Create a {@code DOMCryptoBinary} instance from the specified
+ * {@code BigInteger}
*
* @param bigNum the arbitrary-length integer
- * @throws NullPointerException if <code>bigNum</code> is <code>null</code>
+ * @throws NullPointerException if {@code bigNum} is {@code null}
*/
public DOMCryptoBinary(BigInteger bigNum) {
if (bigNum == null) {
@@ -69,7 +73,7 @@
}
/**
- * Creates a <code>DOMCryptoBinary</code> from a node.
+ * Creates a {@code DOMCryptoBinary} from a node.
*
* @param cbNode a CryptoBinary text node
* @throws MarshalException if value cannot be decoded (invalid format)
@@ -84,9 +88,9 @@
}
/**
- * Returns the <code>BigInteger</code> that this object contains.
+ * Returns the {@code BigInteger} that this object contains.
*
- * @return the <code>BigInteger</code> that this object contains
+ * @return the {@code BigInteger} that this object contains
*/
public BigInteger getBigNum() {
return bigNum;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMDigestMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMDigestMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMEnvelopedTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMEnvelopedTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMExcC14NMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMExcC14NMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMHMACSignatureMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMHMACSignatureMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMKeyInfo.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMKeyInfo.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMKeyInfoFactory.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMKeyInfoFactory.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMKeyName.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMKeyName.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java Tue May 07 17:30:14 2019 -0400
@@ -21,18 +21,13 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMKeyValue.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMKeyValue.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.keyinfo.KeyValue;
-
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyException;
@@ -55,6 +50,11 @@
import java.security.spec.RSAPublicKeySpec;
import java.util.Arrays;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.keyinfo.KeyValue;
+
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -500,7 +500,7 @@
throw new MarshalException("Invalid ECParameterSpec");
}
DOMUtils.setAttribute(namedCurveElem, "URI", "urn:oid:" + oid);
- String qname = (prefix == null || prefix.length() == 0)
+ String qname = prefix == null || prefix.length() == 0
? "xmlns" : "xmlns:" + prefix;
namedCurveElem.setAttributeNS("http://www.w3.org/2000/xmlns/",
qname, XMLDSIG_11_XMLNS);
@@ -554,7 +554,7 @@
ECPoint ecPoint = null;
try {
- String content = XMLUtils.getFullTextChildrenFromElement(curElem);
+ String content = XMLUtils.getFullTextChildrenFromNode(curElem);
ecPoint = decodePoint(XMLUtils.decode(content),
ecParams.getCurve());
} catch (IOException ioe) {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMManifest.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMManifest.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMPGPData.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMPGPData.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
@@ -56,7 +56,7 @@
* and optional list of external elements.
*
* @param keyPacket a PGP Key Material Packet as defined in section 5.5 of
- * <a href="http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>. The
+ * <a href="https://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>. The
* array is cloned to prevent subsequent modification.
* @param other a list of {@link XMLStructure}s representing elements from
* an external namespace. The list is defensively copied to prevent
@@ -94,10 +94,10 @@
* optional key packet and list of external elements.
*
* @param keyId a PGP public key id as defined in section 11.2 of
- * <a href="http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>. The
+ * <a href="https://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a>. The
* array is cloned to prevent subsequent modification.
* @param keyPacket a PGP Key Material Packet as defined in section 5.5 of
- * <a href="http://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a> (may
+ * <a href="https://www.ietf.org/rfc/rfc2440.txt">RFC 2440</a> (may
* be {@code null}). The array is cloned to prevent subsequent
* modification.
* @param other a list of {@link XMLStructure}s representing elements from
@@ -157,10 +157,10 @@
String localName = childElem.getLocalName();
String namespace = childElem.getNamespaceURI();
if ("PGPKeyID".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
- String content = XMLUtils.getFullTextChildrenFromElement(childElem);
+ String content = XMLUtils.getFullTextChildrenFromNode(childElem);
pgpKeyId = XMLUtils.decode(content);
} else if ("PGPKeyPacket".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
- String content = XMLUtils.getFullTextChildrenFromElement(childElem);
+ String content = XMLUtils.getFullTextChildrenFromNode(childElem);
pgpKeyPacket = XMLUtils.decode(content);
} else {
other.add
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java Tue May 07 17:30:14 2019 -0400
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* ===========================================================================
@@ -31,7 +31,7 @@
* ===========================================================================
*/
/*
- * $Id: DOMReference.java 1803518 2017-07-31 11:02:52Z coheigea $
+ * $Id: DOMReference.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
@@ -56,7 +56,6 @@
import org.jcp.xml.dsig.internal.DigesterOutputStream;
import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
/**
* DOM-based implementation of Reference.
@@ -244,7 +243,7 @@
// unmarshal DigestValue
Element dvElem = DOMUtils.getNextSiblingElement(dmElem, "DigestValue", XMLSignature.XMLNS);
- String content = XMLUtils.getFullTextChildrenFromElement(dvElem);
+ String content = XMLUtils.getFullTextChildrenFromNode(dvElem);
this.digestValue = XMLUtils.decode(content);
// check for extra elements
@@ -311,6 +310,7 @@
refElem = DOMUtils.createElement(ownerDoc, "Reference",
XMLSignature.XMLNS, dsPrefix);
+
// set attributes
DOMUtils.setAttributeID(refElem, "Id", id);
DOMUtils.setAttribute(refElem, "URI", uri);
@@ -341,7 +341,6 @@
if (digestValue != null) {
digestValueElem.appendChild
(ownerDoc.createTextNode(XMLUtils.encodeToString(digestValue)));
-
}
refElem.appendChild(digestValueElem);
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java Tue May 07 17:30:14 2019 -0400
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* ===========================================================================
@@ -31,7 +31,7 @@
* ===========================================================================
*/
/*
- * $Id: DOMRetrievalMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMRetrievalMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMSignatureMethod.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMSignatureMethod.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMSignatureProperties.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMSignatureProperties.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMSignatureProperty.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMSignatureProperty.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMSignedInfo.java 1820179 2018-01-04 19:09:52Z mullan $
+ * $Id: DOMSignedInfo.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMStructure.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMStructure.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMURIDereferencer.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMURIDereferencer.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMUtils.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMUtils.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMUtils.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMUtils.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
@@ -92,7 +92,7 @@
public static Element createElement(Document doc, String tag,
String nsURI, String prefix)
{
- String qName = (prefix == null || prefix.length() == 0)
+ String qName = prefix == null || prefix.length() == 0
? tag : prefix + ":" + tag;
return doc.createElementNS(nsURI, qName);
}
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMX509Data.java 1789702 2017-03-31 15:15:04Z coheigea $
+ * $Id: DOMX509Data.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
@@ -33,12 +33,13 @@
import java.security.cert.*;
import java.util.*;
-import javax.xml.crypto.*;
+import javax.security.auth.x500.X500Principal;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
-import javax.security.auth.x500.X500Principal;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -115,7 +116,7 @@
} else if ("X509SubjectName".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
newContent.add(childElem.getFirstChild().getNodeValue());
} else if ("X509SKI".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
- String content = XMLUtils.getFullTextChildrenFromElement(childElem);
+ String content = XMLUtils.getFullTextChildrenFromNode(childElem);
newContent.add(XMLUtils.decode(content));
} else if ("X509CRL".equals(localName) && XMLSignature.XMLNS.equals(namespace)) {
newContent.add(unmarshalX509CRL(childElem));
@@ -132,6 +133,7 @@
return content;
}
+ @Override
public void marshal(Node parent, String dsPrefix, DOMCryptoContext context)
throws MarshalException
{
@@ -241,7 +243,7 @@
if (cf == null) {
cf = CertificateFactory.getInstance("X.509");
}
- String content = XMLUtils.getFullTextChildrenFromElement(elem);
+ String content = XMLUtils.getFullTextChildrenFromNode(elem);
return new ByteArrayInputStream(XMLUtils.decode(content));
} catch (CertificateException e) {
throw new MarshalException("Cannot create CertificateFactory", e);
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMX509IssuerSerial.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMX509IssuerSerial.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMXMLObject.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMXMLObject.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java Tue May 07 17:30:14 2019 -0400
@@ -21,7 +21,7 @@
* under the License.
*/
/*
- * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* ===========================================================================
@@ -31,7 +31,7 @@
* ===========================================================================
*/
/*
- * $Id: DOMXMLSignature.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMXMLSignature.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
@@ -508,7 +508,7 @@
throws MarshalException
{
// base64 decode signatureValue
- String content = XMLUtils.getFullTextChildrenFromElement(sigValueElem);
+ String content = XMLUtils.getFullTextChildrenFromNode(sigValueElem);
value = XMLUtils.decode(content);
Attr attr = sigValueElem.getAttributeNodeNS(null, "Id");
@@ -612,6 +612,7 @@
DOMCryptoContext context)
throws MarshalException
{
+ // create SignatureValue element
sigValueElem = DOMUtils.createElement(ownerDoc, "SignatureValue",
XMLSignature.XMLNS, dsPrefix);
if (valueBase64 != null) {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMXMLSignatureFactory.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMXMLSignatureFactory.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
@@ -255,8 +255,6 @@
return new DOMSignatureMethod.SHA384withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512)) {
return new DOMSignatureMethod.SHA512withRSA(params);
- } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512)) {
- return new DOMSignatureMethod.SHA512withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160)) {
return new DOMSignatureMethod.RIPEMD160withRSA(params);
} else if (algorithm.equals(DOMSignatureMethod.RSA_SHA1_MGF1)) {
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java Tue May 07 17:30:14 2019 -0400
@@ -28,10 +28,10 @@
* ===========================================================================
*/
/*
- * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMXPathFilter2Transform.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMXPathFilter2Transform.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMXPathTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMXPathTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java Tue May 07 17:30:14 2019 -0400
@@ -21,10 +21,10 @@
* under the License.
*/
/*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: DOMXSLTTransform.java 1788465 2017-03-24 15:10:51Z coheigea $
+ * $Id: DOMXSLTTransform.java 1854026 2019-02-21 09:30:01Z coheigea $
*/
package org.jcp.xml.dsig.internal.dom;
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java Tue May 07 17:30:14 2019 -0400
@@ -28,10 +28,10 @@
* ===========================================================================
*/
/*
- * Portions copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Portions copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * $Id: XMLDSigRI.java 1804972 2017-08-14 09:59:23Z coheigea $
+ * $Id: XMLDSigRI.java 1833618 2018-06-15 17:36:20Z mullan $
*/
package org.jcp.xml.dsig.internal.dom;
@@ -123,7 +123,7 @@
} else if (algo.equals(Transform.XSLT)) {
return new DOMXSLTTransform();
}
- }
+ }
} catch (Exception ex) {
throw new NoSuchAlgorithmException("Error constructing " +
type + " for " + algo + " using XMLDSig", ex);
--- a/src/java.xml.crypto/share/legal/santuario.md Fri May 03 14:59:32 2019 -0400
+++ b/src/java.xml.crypto/share/legal/santuario.md Tue May 07 17:30:14 2019 -0400
@@ -1,10 +1,10 @@
-## Apache Santuario v2.1.1
+## Apache Santuario v2.1.3
### Apache Santuario Notice
<pre>
Apache Santuario - XML Security for Java
- Copyright 1999-2018 The Apache Software Foundation
+ Copyright 1999-2019 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java Tue May 07 17:30:14 2019 -0400
@@ -612,10 +612,15 @@
* Writes {@code length} bytes from {@code bytes} starting at offset {@code offset} to HotSpot's
* log stream.
*
+ * @param flush specifies if the log stream should be flushed after writing
+ * @param canThrow specifies if an error in the {@code bytes}, {@code offset} or {@code length}
+ * arguments should result in an exception or a negative return value
+ * @return 0 on success, -1 if {@code bytes == null && !canThrow}, -2 if {@code !canThrow} and
+ * copying would cause access of data outside array bounds
* @throws NullPointerException if {@code bytes == null}
* @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds
*/
- native void writeDebugOutput(byte[] bytes, int offset, int length);
+ native int writeDebugOutput(byte[] bytes, int offset, int length, boolean flush, boolean canThrow);
/**
* Flush HotSpot's log stream.
@@ -947,4 +952,18 @@
*/
native boolean addFailedSpeculation(long failedSpeculationsAddress, byte[] speculation);
+ /**
+ * @see HotSpotJVMCIRuntime#isCurrentThreadAttached()
+ */
+ native boolean isCurrentThreadAttached();
+
+ /**
+ * @see HotSpotJVMCIRuntime#attachCurrentThread
+ */
+ native boolean attachCurrentThread(boolean asDaemon);
+
+ /**
+ * @see HotSpotJVMCIRuntime#detachCurrentThread()
+ */
+ native void detachCurrentThread();
}
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Tue May 07 17:30:14 2019 -0400
@@ -46,7 +46,6 @@
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
-import java.util.TreeMap;
import java.util.function.Predicate;
import jdk.internal.misc.Unsafe;
@@ -180,8 +179,8 @@
// Can only do eager initialization of the JVMCI compiler
// once the singleton instance is available.
- if (instance.config.getFlag("EagerJVMCI", Boolean.class)) {
- instance.getCompiler();
+ if (result.config.getFlag("EagerJVMCI", Boolean.class)) {
+ result.getCompiler();
}
}
// Ensures JVMCIRuntime::_HotSpotJVMCIRuntime_instance is
@@ -384,7 +383,25 @@
/**
* Cache for speeding up {@link #fromClass(Class)}.
*/
- @NativeImageReinitialize private volatile ClassValue<WeakReference<HotSpotResolvedJavaType>> resolvedJavaType;
+ @NativeImageReinitialize private volatile ClassValue<WeakReferenceHolder<HotSpotResolvedJavaType>> resolvedJavaType;
+
+ /**
+ * To avoid calling ClassValue.remove to refresh the weak reference, which
+ * under certain circumstances can lead to an infinite loop, we use a
+ * permanent holder with a mutable field that we refresh.
+ */
+ private static class WeakReferenceHolder<T> {
+ private volatile WeakReference<T> ref;
+ WeakReferenceHolder(T value) {
+ set(value);
+ }
+ void set(T value) {
+ ref = new WeakReference<T>(value);
+ }
+ T get() {
+ return ref.get();
+ }
+ };
@NativeImageReinitialize private HashMap<Long, WeakReference<ResolvedJavaType>> resolvedJavaTypes;
@@ -464,7 +481,7 @@
}
if (Option.PrintConfig.getBoolean()) {
- printConfig(configStore, compilerToVm);
+ configStore.printConfig();
}
}
@@ -486,27 +503,25 @@
if (resolvedJavaType == null) {
synchronized (this) {
if (resolvedJavaType == null) {
- resolvedJavaType = new ClassValue<WeakReference<HotSpotResolvedJavaType>>() {
+ resolvedJavaType = new ClassValue<WeakReferenceHolder<HotSpotResolvedJavaType>>() {
@Override
- protected WeakReference<HotSpotResolvedJavaType> computeValue(Class<?> type) {
- return new WeakReference<>(createClass(type));
+ protected WeakReferenceHolder<HotSpotResolvedJavaType> computeValue(Class<?> type) {
+ return new WeakReferenceHolder<>(createClass(type));
}
};
}
}
}
- HotSpotResolvedJavaType javaType = null;
- while (javaType == null) {
- WeakReference<HotSpotResolvedJavaType> type = resolvedJavaType.get(javaClass);
- javaType = type.get();
- if (javaType == null) {
- /*
- * If the referent has become null, clear out the current value and let computeValue
- * above create a new value. Reload the value in a loop because in theory the
- * WeakReference referent can be reclaimed at any point.
- */
- resolvedJavaType.remove(javaClass);
- }
+
+ WeakReferenceHolder<HotSpotResolvedJavaType> ref = resolvedJavaType.get(javaClass);
+ HotSpotResolvedJavaType javaType = ref.get();
+ if (javaType == null) {
+ /*
+ * If the referent has become null, create a new value and
+ * update cached weak reference.
+ */
+ javaType = createClass(javaClass);
+ ref.set(javaType);
}
return javaType;
}
@@ -727,39 +742,21 @@
}
}
- @SuppressFBWarnings(value = "DM_DEFAULT_ENCODING", justification = "no localization here please!")
- private static void printConfigLine(CompilerToVM vm, String format, Object... args) {
- String line = String.format(format, args);
- byte[] lineBytes = line.getBytes();
- vm.writeDebugOutput(lineBytes, 0, lineBytes.length);
- vm.flushDebugOutput();
- }
-
- private static void printConfig(HotSpotVMConfigStore store, CompilerToVM vm) {
- TreeMap<String, VMField> fields = new TreeMap<>(store.getFields());
- for (VMField field : fields.values()) {
- if (!field.isStatic()) {
- printConfigLine(vm, "[vmconfig:instance field] %s %s {offset=%d[0x%x]}%n", field.type, field.name, field.offset, field.offset);
- } else {
- String value = field.value == null ? "null" : field.value instanceof Boolean ? field.value.toString() : String.format("%d[0x%x]", field.value, field.value);
- printConfigLine(vm, "[vmconfig:static field] %s %s = %s {address=0x%x}%n", field.type, field.name, value, field.address);
- }
- }
- TreeMap<String, VMFlag> flags = new TreeMap<>(store.getFlags());
- for (VMFlag flag : flags.values()) {
- printConfigLine(vm, "[vmconfig:flag] %s %s = %s%n", flag.type, flag.name, flag.value);
- }
- TreeMap<String, Long> addresses = new TreeMap<>(store.getAddresses());
- for (Map.Entry<String, Long> e : addresses.entrySet()) {
- printConfigLine(vm, "[vmconfig:address] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue());
- }
- TreeMap<String, Long> constants = new TreeMap<>(store.getConstants());
- for (Map.Entry<String, Long> e : constants.entrySet()) {
- printConfigLine(vm, "[vmconfig:constant] %s = %d[0x%x]%n", e.getKey(), e.getValue(), e.getValue());
- }
- for (VMIntrinsicMethod e : store.getIntrinsics()) {
- printConfigLine(vm, "[vmconfig:intrinsic] %d = %s.%s %s%n", e.id, e.declaringClass, e.name, e.descriptor);
- }
+ /**
+ * Writes {@code length} bytes from {@code bytes} starting at offset {@code offset} to HotSpot's
+ * log stream.
+ *
+ * @param flush specifies if the log stream should be flushed after writing
+ * @param canThrow specifies if an error in the {@code bytes}, {@code offset} or {@code length}
+ * arguments should result in an exception or a negative return value. If
+ * {@code false}, this call will not perform any heap allocation
+ * @return 0 on success, -1 if {@code bytes == null && !canThrow}, -2 if {@code !canThrow} and
+ * copying would cause access of data outside array bounds
+ * @throws NullPointerException if {@code bytes == null}
+ * @throws IndexOutOfBoundsException if copying would cause access of data outside array bounds
+ */
+ public int writeDebugOutput(byte[] bytes, int offset, int length, boolean flush, boolean canThrow) {
+ return compilerToVm.writeDebugOutput(bytes, offset, length, flush, canThrow);
}
/**
@@ -777,7 +774,7 @@
} else if (len == 0) {
return;
}
- compilerToVm.writeDebugOutput(b, off, len);
+ compilerToVm.writeDebugOutput(b, off, len, false, true);
}
@Override
@@ -907,11 +904,13 @@
* the Java VM in the JVMCI shared library, and the remaining values are the first 3
* pointers in the Invocation API function table (i.e., {@code JNIInvokeInterface})
* @throws NullPointerException if {@code clazz == null}
- * @throws IllegalArgumentException if the current execution context is the JVMCI shared library
- * or if {@code clazz} is {@link Class#isPrimitive()}
- * @throws UnsatisfiedLinkError if the JVMCI shared library is not available, a native method in
- * {@code clazz} is already linked or the JVMCI shared library does not contain a
- * JNI-compatible symbol for a native method in {@code clazz}
+ * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e.
+ * {@code -XX:-UseJVMCINativeLibrary})
+ * @throws IllegalStateException if the current execution context is the JVMCI shared library
+ * @throws IllegalArgumentException if {@code clazz} is {@link Class#isPrimitive()}
+ * @throws UnsatisfiedLinkError if there's a problem linking a native method in {@code clazz}
+ * (no matching JNI symbol or the native method is already linked to a different
+ * address)
*/
public long[] registerNativeMethods(Class<?> clazz) {
return compilerToVm.registerNativeMethods(clazz);
@@ -935,6 +934,8 @@
*
* @param obj an object for which an equivalent instance in the peer runtime is requested
* @return a JNI global reference to the mirror of {@code obj} in the peer runtime
+ * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e.
+ * {@code -XX:-UseJVMCINativeLibrary})
* @throws IllegalArgumentException if {@code obj} is not of a translatable type
*
* @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#global_and_local_references"
@@ -950,7 +951,9 @@
*
* @param handle a JNI global reference to an object in the current runtime
* @return the object referred to by {@code handle}
- * @throws ClassCastException if the returned object cannot be case to {@code type}
+ * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e.
+ * {@code -XX:-UseJVMCINativeLibrary})
+ * @throws ClassCastException if the returned object cannot be cast to {@code type}
*
* @see "https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#global_and_local_references"
*
@@ -960,6 +963,44 @@
}
/**
+ * Determines if the current thread is attached to the peer runtime.
+ *
+ * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e.
+ * {@code -XX:-UseJVMCINativeLibrary})
+ * @throws IllegalStateException if the peer runtime has not been initialized
+ */
+ public boolean isCurrentThreadAttached() {
+ return compilerToVm.isCurrentThreadAttached();
+ }
+
+ /**
+ * Ensures the current thread is attached to the peer runtime.
+ *
+ * @param asDaemon if the thread is not yet attached, should it be attached as a daemon
+ * @return {@code true} if this call attached the current thread, {@code false} if the current
+ * thread was already attached
+ * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e.
+ * {@code -XX:-UseJVMCINativeLibrary})
+ * @throws IllegalStateException if the peer runtime has not been initialized or there is an
+ * error while trying to attach the thread
+ */
+ public boolean attachCurrentThread(boolean asDaemon) {
+ return compilerToVm.attachCurrentThread(asDaemon);
+ }
+
+ /**
+ * Detaches the current thread from the peer runtime.
+ *
+ * @throws UnsupportedOperationException if the JVMCI shared library is not enabled (i.e.
+ * {@code -XX:-UseJVMCINativeLibrary})
+ * @throws IllegalStateException if the peer runtime has not been initialized or if the current
+ * thread is not attached or if there is an error while trying to detach the thread
+ */
+ public void detachCurrentThread() {
+ compilerToVm.detachCurrentThread();
+ }
+
+ /**
* Informs HotSpot that no method whose module is in {@code modules} is to be compiled
* with {@link #compileMethod}.
*
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigStore.java Tue May 07 17:30:14 2019 -0400
@@ -193,8 +193,7 @@
private static void printConfigLine(CompilerToVM vm, String format, Object... args) {
String line = String.format(format, args);
byte[] lineBytes = line.getBytes();
- vm.writeDebugOutput(lineBytes, 0, lineBytes.length);
- vm.flushDebugOutput();
+ vm.writeDebugOutput(lineBytes, 0, lineBytes.length, true, true);
}
}
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java Tue May 07 17:30:14 2019 -0400
@@ -49,16 +49,23 @@
return this;
}
- @Override
- public String toString() {
- return getMessage();
- }
+ private static Throwable create(String className, String message) {
+ // Try create with reflection first.
+ try {
+ Class<?> cls = Class.forName(className);
+ if (message == null) {
+ return (Throwable) cls.getConstructor().newInstance();
+ }
+ cls.getDeclaredConstructor(String.class);
+ return (Throwable) cls.getConstructor(String.class).newInstance(message);
+ } catch (Throwable ignore) {
+ }
- private static TranslatedException create(String className, String message) {
if (className.equals(TranslatedException.class.getName())) {
// Chop the class name when boxing another TranslatedException
return new TranslatedException(message);
}
+
if (message == null) {
return new TranslatedException(className);
}
@@ -147,7 +154,7 @@
Throwable throwable = create(exceptionClassName, exceptionMessage);
int stackTraceDepth = Integer.parseInt(parts[i++]);
- StackTraceElement[] suffix = parent == null ? new StackTraceElement[0] : getStackTraceSuffix();
+ StackTraceElement[] suffix = getStackTraceSuffix();
StackTraceElement[] stackTrace = new StackTraceElement[stackTraceDepth + suffix.length];
for (int j = 0; j < stackTraceDepth; j++) {
String className = parts[i++];
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,13 +38,13 @@
* @return the simple name
*/
public static String getSimpleName(Class<?> clazz, boolean withEnclosingClass) {
- final String simpleName = clazz.getSimpleName();
+ final String simpleName = safeSimpleName(clazz);
if (simpleName.length() != 0) {
if (withEnclosingClass) {
String prefix = "";
Class<?> enclosingClass = clazz;
while ((enclosingClass = enclosingClass.getEnclosingClass()) != null) {
- prefix = enclosingClass.getSimpleName() + "." + prefix;
+ prefix = safeSimpleName(enclosingClass) + "." + prefix;
}
return prefix + simpleName;
}
@@ -63,6 +63,29 @@
return name.substring(index + 1);
}
+ private static String safeSimpleName(Class<?> clazz) {
+ try {
+ return clazz.getSimpleName();
+ } catch (InternalError e) {
+ // Scala inner class names do not always start with '$',
+ // causing Class.getSimpleName to throw an InternalError
+ Class<?> enclosingClass = clazz.getEnclosingClass();
+ String fqn = clazz.getName();
+ if (enclosingClass == null) {
+ // Should never happen given logic in
+ // Class.getSimpleName but best be safe
+ return fqn;
+ }
+ String enclosingFQN = enclosingClass.getName();
+ int length = fqn.length();
+ if (enclosingFQN.length() >= length) {
+ // Should also never happen
+ return fqn;
+ }
+ return fqn.substring(enclosingFQN.length());
+ }
+ }
+
/**
* Converts a type name in internal form to an external form.
*
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java Tue May 07 17:30:14 2019 -0400
@@ -283,6 +283,17 @@
}
/**
+ * A Java {@code char} has a maximal UTF8 length of 3.
+ */
+ private static final int MAX_UNICODE_IN_UTF8_LENGTH = 3;
+
+ /**
+ * {@link DataOutputStream#writeUTF(String)} only supports values whose UTF8 encoding length is
+ * less than 65535.
+ */
+ private static final int MAX_UTF8_PROPERTY_STRING_LENGTH = 65535 / MAX_UNICODE_IN_UTF8_LENGTH;
+
+ /**
* Serializes the {@linkplain #getSavedProperties() saved system properties} to a byte array for
* the purpose of {@linkplain #initializeSavedProperties(byte[]) initializing} the initial
* properties in the JVMCI shared library.
@@ -292,25 +303,48 @@
if (IS_IN_NATIVE_IMAGE) {
throw new InternalError("Can only serialize saved properties in HotSpot runtime");
}
- Map<String, String> props = Services.getSavedProperties();
+ return serializeProperties(Services.getSavedProperties());
+ }
+ private static byte[] serializeProperties(Map<String, String> props) throws IOException {
// Compute size of output on the assumption that
// all system properties have ASCII names and values
- int estimate = 4;
+ int estimate = 4 + 4;
+ int nonUtf8Props = 0;
for (Map.Entry<String, String> e : props.entrySet()) {
String name = e.getKey();
String value = e.getValue();
estimate += (2 + (name.length())) + (2 + (value.length()));
+ if (name.length() > MAX_UTF8_PROPERTY_STRING_LENGTH || value.length() > MAX_UTF8_PROPERTY_STRING_LENGTH) {
+ nonUtf8Props++;
+ }
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(estimate);
DataOutputStream out = new DataOutputStream(baos);
- out.writeInt(props.size());
+ out.writeInt(props.size() - nonUtf8Props);
+ out.writeInt(nonUtf8Props);
for (Map.Entry<String, String> e : props.entrySet()) {
String name = e.getKey();
String value = e.getValue();
- out.writeUTF(name);
- out.writeUTF(value);
+ if (name.length() <= MAX_UTF8_PROPERTY_STRING_LENGTH && value.length() <= MAX_UTF8_PROPERTY_STRING_LENGTH) {
+ out.writeUTF(name);
+ out.writeUTF(value);
+ }
+ }
+ if (nonUtf8Props != 0) {
+ for (Map.Entry<String, String> e : props.entrySet()) {
+ String name = e.getKey();
+ String value = e.getValue();
+ if (name.length() > MAX_UTF8_PROPERTY_STRING_LENGTH || value.length() > MAX_UTF8_PROPERTY_STRING_LENGTH) {
+ byte[] utf8Name = name.getBytes("UTF-8");
+ byte[] utf8Value = value.getBytes("UTF-8");
+ out.writeInt(utf8Name.length);
+ out.write(utf8Name);
+ out.writeInt(utf8Value.length);
+ out.write(utf8Value);
+ }
+ }
}
return baos.toByteArray();
}
@@ -325,13 +359,33 @@
if (!IS_IN_NATIVE_IMAGE) {
throw new InternalError("Can only initialize saved properties in JVMCI shared library runtime");
}
+ savedProperties = Collections.unmodifiableMap(deserializeProperties(serializedProperties));
+ }
+
+ private static Map<String, String> deserializeProperties(byte[] serializedProperties) throws IOException {
DataInputStream in = new DataInputStream(new ByteArrayInputStream(serializedProperties));
- Map<String, String> props = new HashMap<>(in.readInt());
+ int utf8Props = in.readInt();
+ int nonUtf8Props = in.readInt();
+ Map<String, String> props = new HashMap<>(utf8Props + nonUtf8Props);
+ int index = 0;
while (in.available() != 0) {
- String name = in.readUTF();
- String value = in.readUTF();
- props.put(name, value);
+ if (index < utf8Props) {
+ String name = in.readUTF();
+ String value = in.readUTF();
+ props.put(name, value);
+ } else {
+ int nameLen = in.readInt();
+ byte[] nameBytes = new byte[nameLen];
+ in.read(nameBytes);
+ int valueLen = in.readInt();
+ byte[] valueBytes = new byte[valueLen];
+ in.read(valueBytes);
+ String name = new String(nameBytes, "UTF-8");
+ String value = new String(valueBytes, "UTF-8");
+ props.put(name, value);
+ }
+ index++;
}
- savedProperties = Collections.unmodifiableMap(props);
+ return props;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/SuppressFBWarnings.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.services;
+
+/**
+ * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
+ */
+@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/src/jdk.internal.vm.ci/share/classes/module-info.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.ci/share/classes/module-info.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,9 @@
exports jdk.vm.ci.runtime to
jdk.internal.vm.compiler,
jdk.internal.vm.compiler.management;
+ exports jdk.vm.ci.meta to jdk.internal.vm.compiler;
+ exports jdk.vm.ci.code to jdk.internal.vm.compiler;
+ exports jdk.vm.ci.hotspot to jdk.internal.vm.compiler;
uses jdk.vm.ci.services.JVMCIServiceLocator;
uses jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
import com.sun.management.ThreadMXBean;
/**
- * Implementation of {@link JMXService} for JDK 11 and later.
+ * Implementation of {@link JMXService} for JDK 13 and later.
*/
@ServiceProvider(JMXService.class)
public class JMXServiceProvider extends JMXService {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.amd64/src/org/graalvm/compiler/asm/amd64/AMD64Assembler.java Tue May 07 17:30:14 2019 -0400
@@ -3003,6 +3003,18 @@
emitByte(0x99);
}
+ public final void repStosb() {
+ emitByte(0xf3);
+ rexw();
+ emitByte(0xaa);
+ }
+
+ public final void repStosq() {
+ emitByte(0xf3);
+ rexw();
+ emitByte(0xab);
+ }
+
public final void cmovq(ConditionFlag cc, Register dst, Register src) {
prefixq(dst, src);
emitByte(0x0F);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java Tue May 07 17:30:14 2019 -0400
@@ -121,6 +121,7 @@
import org.graalvm.compiler.lir.amd64.AMD64ShiftOp;
import org.graalvm.compiler.lir.amd64.AMD64SignExtendOp;
import org.graalvm.compiler.lir.amd64.AMD64Unary;
+import org.graalvm.compiler.lir.amd64.AMD64ZeroMemoryOp;
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary;
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorBinary.AVXBinaryOp;
import org.graalvm.compiler.lir.amd64.vector.AMD64VectorUnary;
@@ -1102,6 +1103,12 @@
return new AMD64MathPowOp().emitLIRWrapper(getLIRGen(), x, y);
}
+ @Override
+ public void emitZeroMemory(Value address, Value length) {
+ RegisterValue lengthReg = moveToReg(AMD64.rcx, length);
+ getLIRGen().append(new AMD64ZeroMemoryOp(getAMD64LIRGen().asAddressValue(address), lengthReg));
+ }
+
protected AMD64LIRGenerator getAMD64LIRGen() {
return (AMD64LIRGenerator) getLIRGen();
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/GraalOptions.java Tue May 07 17:30:14 2019 -0400
@@ -279,9 +279,13 @@
@Option(help = "Enable inlining decision tracing in stubs and snippets.", type = OptionType.Debug)
public static final OptionKey<Boolean> TraceInliningForStubsAndSnippets = new OptionKey<>(false);
- @Option(help = "Use Graal-generated stubs for complicated LIR operations instead of embedding all the emitted code.")
+ @Option(help = "Use Graal-generated stubs for complicated LIR operations instead of embedding all the emitted code.", type = OptionType.Expert)
public static final OptionKey<Boolean> UseGraalStubs = new OptionKey<>(true);
@Option(help = "Encode and decode snippets and substitutions before parsing to test libgraal code path. This option is ignored in the context of libgraal.")
public static final OptionKey<Boolean> UseEncodedGraphs = new OptionKey<>(false);
+
+ @Option(help = "If applicable, use bulk zeroing instructions when the zeroing size in bytes exceeds this threshold.", type = OptionType.Expert)
+ public static final OptionKey<Integer> MinimalBulkZeroingSize = new OptionKey<>(2048);
+
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/type/FloatStamp.java Tue May 07 17:30:14 2019 -0400
@@ -318,8 +318,10 @@
/*
* There are many forms of NaNs and any operations on them can silently convert them into
* the canonical NaN.
+ *
+ * We need to exclude 0 here since it can contain -0.0 && 0.0 .
*/
- return (Double.compare(lowerBound, upperBound) == 0 && nonNaN);
+ return (Double.compare(lowerBound, upperBound) == 0 && nonNaN) && lowerBound != 0;
}
private static FloatStamp stampForConstant(Constant constant) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/BciBlockMappingTest.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,1416 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import org.graalvm.compiler.java.BciBlockMapping;
+import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
+import org.junit.Test;
+
+/**
+ * Tests that the {@link BciBlockMapping} can handle code with a lot of blocks. The test code is
+ * derived from the {@code ImplicitStringConcatShapes} test in OpenJDK.
+ */
+public class BciBlockMappingTest extends GraalCompilerTest {
+
+ @Test
+ public void test() {
+ parseEager("run", AllowAssumptions.NO);
+ }
+
+ @SuppressWarnings("unused")
+ public static void blackhole(String expected, String actual) {
+ }
+
+ static double aDouble = -96.0d;
+
+ public void run() {
+ blackhole("-96.0", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("\u045176", "" + aDouble);
+ blackhole("92", "" + aDouble);
+ blackhole("51", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("-54", "" + aDouble);
+ blackhole("-87.0", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("19", "" + aDouble);
+ blackhole("-41", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("T", "" + aDouble);
+ blackhole("-42.0", "" + aDouble);
+ blackhole("25", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("-1410065408", "" + aDouble);
+ blackhole("8.0", "" + aDouble);
+ blackhole("55.0", "" + aDouble);
+ blackhole("97000000", "" + aDouble);
+ blackhole("-9900", "" + aDouble);
+ blackhole("935228928", "" + aDouble);
+ blackhole("-8400", "" + aDouble);
+ blackhole("C(82)", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("true", "" + aDouble);
+ blackhole("3900", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("94000000", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("true", "" + aDouble);
+ blackhole("5500", "" + aDouble);
+ blackhole("-2900", "" + aDouble);
+ blackhole("-194313216", "" + aDouble);
+ blackhole("12", "" + aDouble);
+ blackhole("C(87)", "" + aDouble);
+ blackhole("91", "" + aDouble);
+ blackhole("21", "" + aDouble);
+ blackhole("18", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("\u045180", "" + aDouble);
+ blackhole("C", "" + aDouble);
+ blackhole("75", "" + aDouble);
+ blackhole("-43", "" + aDouble);
+ blackhole("80", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("-52.0", "" + aDouble);
+ blackhole("75000000", "" + aDouble);
+ blackhole("44", "" + aDouble);
+ blackhole("-1705032704", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("83.0", "" + aDouble);
+ blackhole("I", "" + aDouble);
+ blackhole("94.0", "" + aDouble);
+ blackhole("12.0", "" + aDouble);
+ blackhole("-99.0", "" + aDouble);
+ blackhole("17.0", "" + aDouble);
+ blackhole("-84.0", "" + aDouble);
+ blackhole("58000000", "" + aDouble);
+ blackhole("-55000000", "" + aDouble);
+ blackhole("1460392448", "" + aDouble);
+ blackhole("C(70)", "" + aDouble);
+ blackhole("\u04511", "" + aDouble);
+ blackhole("8000", "" + aDouble);
+ blackhole("18", "" + aDouble);
+ blackhole("-1000000", "" + aDouble);
+ blackhole("1000000", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("false", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("-2000000", "" + aDouble);
+ blackhole("-820130816", "" + aDouble);
+ blackhole("null", "" + aDouble);
+ blackhole("25000000", "" + aDouble);
+ blackhole("-96.0-96.0", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0\u045176", "" + aDouble);
+ blackhole("-96.092", "" + aDouble);
+ blackhole("-96.051", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0-54", "" + aDouble);
+ blackhole("-96.0-87.0", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.019", "" + aDouble);
+ blackhole("-96.0-41", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0T", "" + aDouble);
+ blackhole("-96.0-42.0", "" + aDouble);
+ blackhole("-96.025", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0-1410065408", "" + aDouble);
+ blackhole("-96.08.0", "" + aDouble);
+ blackhole("-96.055.0", "" + aDouble);
+ blackhole("-96.097000000", "" + aDouble);
+ blackhole("-96.0-9900", "" + aDouble);
+ blackhole("-96.0935228928", "" + aDouble);
+ blackhole("-96.0-8400", "" + aDouble);
+ blackhole("-96.0C(82)", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0true", "" + aDouble);
+ blackhole("-96.03900", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.094000000", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0true", "" + aDouble);
+ blackhole("-96.05500", "" + aDouble);
+ blackhole("-96.0-2900", "" + aDouble);
+ blackhole("-96.0-194313216", "" + aDouble);
+ blackhole("-96.012", "" + aDouble);
+ blackhole("-96.0C(87)", "" + aDouble);
+ blackhole("-96.091", "" + aDouble);
+ blackhole("-96.021", "" + aDouble);
+ blackhole("-96.018", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0\u045180", "" + aDouble);
+ blackhole("-96.0C", "" + aDouble);
+ blackhole("-96.075", "" + aDouble);
+ blackhole("-96.0-43", "" + aDouble);
+ blackhole("-96.080", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0-52.0", "" + aDouble);
+ blackhole("-96.075000000", "" + aDouble);
+ blackhole("-96.044", "" + aDouble);
+ blackhole("-96.0-1705032704", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.083.0", "" + aDouble);
+ blackhole("-96.0I", "" + aDouble);
+ blackhole("-96.094.0", "" + aDouble);
+ blackhole("-96.012.0", "" + aDouble);
+ blackhole("-96.0-99.0", "" + aDouble);
+ blackhole("-96.017.0", "" + aDouble);
+ blackhole("-96.0-84.0", "" + aDouble);
+ blackhole("-96.058000000", "" + aDouble);
+ blackhole("-96.0-55000000", "" + aDouble);
+ blackhole("-96.01460392448", "" + aDouble);
+ blackhole("-96.0C(70)", "" + aDouble);
+ blackhole("-96.0\u04511", "" + aDouble);
+ blackhole("-96.08000", "" + aDouble);
+ blackhole("-96.018", "" + aDouble);
+ blackhole("-96.0-1000000", "" + aDouble);
+ blackhole("-96.01000000", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0false", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.0-2000000", "" + aDouble);
+ blackhole("-96.0-820130816", "" + aDouble);
+ blackhole("-96.0null", "" + aDouble);
+ blackhole("-96.025000000", "" + aDouble);
+ blackhole("null-96.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045176", "" + aDouble);
+ blackhole("null92", "" + aDouble);
+ blackhole("null51", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-54", "" + aDouble);
+ blackhole("null-87.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null19", "" + aDouble);
+ blackhole("null-41", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullT", "" + aDouble);
+ blackhole("null-42.0", "" + aDouble);
+ blackhole("null25", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-1410065408", "" + aDouble);
+ blackhole("null8.0", "" + aDouble);
+ blackhole("null55.0", "" + aDouble);
+ blackhole("null97000000", "" + aDouble);
+ blackhole("null-9900", "" + aDouble);
+ blackhole("null935228928", "" + aDouble);
+ blackhole("null-8400", "" + aDouble);
+ blackhole("nullC(82)", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null3900", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null94000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null5500", "" + aDouble);
+ blackhole("null-2900", "" + aDouble);
+ blackhole("null-194313216", "" + aDouble);
+ blackhole("null12", "" + aDouble);
+ blackhole("nullC(87)", "" + aDouble);
+ blackhole("null91", "" + aDouble);
+ blackhole("null21", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045180", "" + aDouble);
+ blackhole("nullC", "" + aDouble);
+ blackhole("null75", "" + aDouble);
+ blackhole("null-43", "" + aDouble);
+ blackhole("null80", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-52.0", "" + aDouble);
+ blackhole("null75000000", "" + aDouble);
+ blackhole("null44", "" + aDouble);
+ blackhole("null-1705032704", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null83.0", "" + aDouble);
+ blackhole("nullI", "" + aDouble);
+ blackhole("null94.0", "" + aDouble);
+ blackhole("null12.0", "" + aDouble);
+ blackhole("null-99.0", "" + aDouble);
+ blackhole("null17.0", "" + aDouble);
+ blackhole("null-84.0", "" + aDouble);
+ blackhole("null58000000", "" + aDouble);
+ blackhole("null-55000000", "" + aDouble);
+ blackhole("null1460392448", "" + aDouble);
+ blackhole("nullC(70)", "" + aDouble);
+ blackhole("null\u04511", "" + aDouble);
+ blackhole("null8000", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("null-1000000", "" + aDouble);
+ blackhole("null1000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullfalse", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-2000000", "" + aDouble);
+ blackhole("null-820130816", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null25000000", "" + aDouble);
+ blackhole("\u045176-96.0", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176\u045176", "" + aDouble);
+ blackhole("\u04517692", "" + aDouble);
+ blackhole("\u04517651", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176-54", "" + aDouble);
+ blackhole("\u045176-87.0", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u04517619", "" + aDouble);
+ blackhole("\u045176-41", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176T", "" + aDouble);
+ blackhole("\u045176-42.0", "" + aDouble);
+ blackhole("\u04517625", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176-1410065408", "" + aDouble);
+ blackhole("\u0451768.0", "" + aDouble);
+ blackhole("\u04517655.0", "" + aDouble);
+ blackhole("\u04517697000000", "" + aDouble);
+ blackhole("\u045176-9900", "" + aDouble);
+ blackhole("\u045176935228928", "" + aDouble);
+ blackhole("\u045176-8400", "" + aDouble);
+ blackhole("\u045176C(82)", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176true", "" + aDouble);
+ blackhole("\u0451763900", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u04517694000000", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176true", "" + aDouble);
+ blackhole("\u0451765500", "" + aDouble);
+ blackhole("\u045176-2900", "" + aDouble);
+ blackhole("\u045176-194313216", "" + aDouble);
+ blackhole("\u04517612", "" + aDouble);
+ blackhole("\u045176C(87)", "" + aDouble);
+ blackhole("\u04517691", "" + aDouble);
+ blackhole("\u04517621", "" + aDouble);
+ blackhole("\u04517618", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176\u045180", "" + aDouble);
+ blackhole("\u045176C", "" + aDouble);
+ blackhole("\u04517675", "" + aDouble);
+ blackhole("\u045176-43", "" + aDouble);
+ blackhole("\u04517680", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176-52.0", "" + aDouble);
+ blackhole("\u04517675000000", "" + aDouble);
+ blackhole("\u04517644", "" + aDouble);
+ blackhole("\u045176-1705032704", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u04517683.0", "" + aDouble);
+ blackhole("\u045176I", "" + aDouble);
+ blackhole("\u04517694.0", "" + aDouble);
+ blackhole("\u04517612.0", "" + aDouble);
+ blackhole("\u045176-99.0", "" + aDouble);
+ blackhole("\u04517617.0", "" + aDouble);
+ blackhole("\u045176-84.0", "" + aDouble);
+ blackhole("\u04517658000000", "" + aDouble);
+ blackhole("\u045176-55000000", "" + aDouble);
+ blackhole("\u0451761460392448", "" + aDouble);
+ blackhole("\u045176C(70)", "" + aDouble);
+ blackhole("\u045176\u04511", "" + aDouble);
+ blackhole("\u0451768000", "" + aDouble);
+ blackhole("\u04517618", "" + aDouble);
+ blackhole("\u045176-1000000", "" + aDouble);
+ blackhole("\u0451761000000", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176false", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u045176-2000000", "" + aDouble);
+ blackhole("\u045176-820130816", "" + aDouble);
+ blackhole("\u045176null", "" + aDouble);
+ blackhole("\u04517625000000", "" + aDouble);
+ blackhole("92-96.0", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92\u045176", "" + aDouble);
+ blackhole("9292", "" + aDouble);
+ blackhole("9251", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92-54", "" + aDouble);
+ blackhole("92-87.0", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("9219", "" + aDouble);
+ blackhole("92-41", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92T", "" + aDouble);
+ blackhole("92-42.0", "" + aDouble);
+ blackhole("9225", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92-1410065408", "" + aDouble);
+ blackhole("928.0", "" + aDouble);
+ blackhole("9255.0", "" + aDouble);
+ blackhole("9297000000", "" + aDouble);
+ blackhole("92-9900", "" + aDouble);
+ blackhole("92935228928", "" + aDouble);
+ blackhole("92-8400", "" + aDouble);
+ blackhole("92C(82)", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92true", "" + aDouble);
+ blackhole("923900", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("9294000000", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92true", "" + aDouble);
+ blackhole("925500", "" + aDouble);
+ blackhole("92-2900", "" + aDouble);
+ blackhole("92-194313216", "" + aDouble);
+ blackhole("9212", "" + aDouble);
+ blackhole("92C(87)", "" + aDouble);
+ blackhole("9291", "" + aDouble);
+ blackhole("9221", "" + aDouble);
+ blackhole("9218", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92\u045180", "" + aDouble);
+ blackhole("92C", "" + aDouble);
+ blackhole("9275", "" + aDouble);
+ blackhole("92-43", "" + aDouble);
+ blackhole("9280", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92-52.0", "" + aDouble);
+ blackhole("9275000000", "" + aDouble);
+ blackhole("9244", "" + aDouble);
+ blackhole("92-1705032704", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("9283.0", "" + aDouble);
+ blackhole("92I", "" + aDouble);
+ blackhole("9294.0", "" + aDouble);
+ blackhole("9212.0", "" + aDouble);
+ blackhole("92-99.0", "" + aDouble);
+ blackhole("9217.0", "" + aDouble);
+ blackhole("92-84.0", "" + aDouble);
+ blackhole("9258000000", "" + aDouble);
+ blackhole("92-55000000", "" + aDouble);
+ blackhole("921460392448", "" + aDouble);
+ blackhole("92C(70)", "" + aDouble);
+ blackhole("92\u04511", "" + aDouble);
+ blackhole("928000", "" + aDouble);
+ blackhole("9218", "" + aDouble);
+ blackhole("92-1000000", "" + aDouble);
+ blackhole("921000000", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92false", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("92-2000000", "" + aDouble);
+ blackhole("92-820130816", "" + aDouble);
+ blackhole("92null", "" + aDouble);
+ blackhole("9225000000", "" + aDouble);
+ blackhole("51-96.0", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51\u045176", "" + aDouble);
+ blackhole("5192", "" + aDouble);
+ blackhole("5151", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51-54", "" + aDouble);
+ blackhole("51-87.0", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("5119", "" + aDouble);
+ blackhole("51-41", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51T", "" + aDouble);
+ blackhole("51-42.0", "" + aDouble);
+ blackhole("5125", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51-1410065408", "" + aDouble);
+ blackhole("518.0", "" + aDouble);
+ blackhole("5155.0", "" + aDouble);
+ blackhole("5197000000", "" + aDouble);
+ blackhole("51-9900", "" + aDouble);
+ blackhole("51935228928", "" + aDouble);
+ blackhole("51-8400", "" + aDouble);
+ blackhole("51C(82)", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51true", "" + aDouble);
+ blackhole("513900", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("5194000000", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51true", "" + aDouble);
+ blackhole("515500", "" + aDouble);
+ blackhole("51-2900", "" + aDouble);
+ blackhole("51-194313216", "" + aDouble);
+ blackhole("5112", "" + aDouble);
+ blackhole("51C(87)", "" + aDouble);
+ blackhole("5191", "" + aDouble);
+ blackhole("5121", "" + aDouble);
+ blackhole("5118", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51\u045180", "" + aDouble);
+ blackhole("51C", "" + aDouble);
+ blackhole("5175", "" + aDouble);
+ blackhole("51-43", "" + aDouble);
+ blackhole("5180", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51-52.0", "" + aDouble);
+ blackhole("5175000000", "" + aDouble);
+ blackhole("5144", "" + aDouble);
+ blackhole("51-1705032704", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("5183.0", "" + aDouble);
+ blackhole("51I", "" + aDouble);
+ blackhole("5194.0", "" + aDouble);
+ blackhole("5112.0", "" + aDouble);
+ blackhole("51-99.0", "" + aDouble);
+ blackhole("5117.0", "" + aDouble);
+ blackhole("51-84.0", "" + aDouble);
+ blackhole("5158000000", "" + aDouble);
+ blackhole("51-55000000", "" + aDouble);
+ blackhole("511460392448", "" + aDouble);
+ blackhole("51C(70)", "" + aDouble);
+ blackhole("51\u04511", "" + aDouble);
+ blackhole("518000", "" + aDouble);
+ blackhole("5118", "" + aDouble);
+ blackhole("51-1000000", "" + aDouble);
+ blackhole("511000000", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51false", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("51-2000000", "" + aDouble);
+ blackhole("51-820130816", "" + aDouble);
+ blackhole("51null", "" + aDouble);
+ blackhole("5125000000", "" + aDouble);
+ blackhole("null-96.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045176", "" + aDouble);
+ blackhole("null92", "" + aDouble);
+ blackhole("null51", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-54", "" + aDouble);
+ blackhole("null-87.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null19", "" + aDouble);
+ blackhole("null-41", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullT", "" + aDouble);
+ blackhole("null-42.0", "" + aDouble);
+ blackhole("null25", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-1410065408", "" + aDouble);
+ blackhole("null8.0", "" + aDouble);
+ blackhole("null55.0", "" + aDouble);
+ blackhole("null97000000", "" + aDouble);
+ blackhole("null-9900", "" + aDouble);
+ blackhole("null935228928", "" + aDouble);
+ blackhole("null-8400", "" + aDouble);
+ blackhole("nullC(82)", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null3900", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null94000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null5500", "" + aDouble);
+ blackhole("null-2900", "" + aDouble);
+ blackhole("null-194313216", "" + aDouble);
+ blackhole("null12", "" + aDouble);
+ blackhole("nullC(87)", "" + aDouble);
+ blackhole("null91", "" + aDouble);
+ blackhole("null21", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045180", "" + aDouble);
+ blackhole("nullC", "" + aDouble);
+ blackhole("null75", "" + aDouble);
+ blackhole("null-43", "" + aDouble);
+ blackhole("null80", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-52.0", "" + aDouble);
+ blackhole("null75000000", "" + aDouble);
+ blackhole("null44", "" + aDouble);
+ blackhole("null-1705032704", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null83.0", "" + aDouble);
+ blackhole("nullI", "" + aDouble);
+ blackhole("null94.0", "" + aDouble);
+ blackhole("null12.0", "" + aDouble);
+ blackhole("null-99.0", "" + aDouble);
+ blackhole("null17.0", "" + aDouble);
+ blackhole("null-84.0", "" + aDouble);
+ blackhole("null58000000", "" + aDouble);
+ blackhole("null-55000000", "" + aDouble);
+ blackhole("null1460392448", "" + aDouble);
+ blackhole("nullC(70)", "" + aDouble);
+ blackhole("null\u04511", "" + aDouble);
+ blackhole("null8000", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("null-1000000", "" + aDouble);
+ blackhole("null1000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullfalse", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-2000000", "" + aDouble);
+ blackhole("null-820130816", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null25000000", "" + aDouble);
+ blackhole("-54-96.0", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54\u045176", "" + aDouble);
+ blackhole("-5492", "" + aDouble);
+ blackhole("-5451", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54-54", "" + aDouble);
+ blackhole("-54-87.0", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-5419", "" + aDouble);
+ blackhole("-54-41", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54T", "" + aDouble);
+ blackhole("-54-42.0", "" + aDouble);
+ blackhole("-5425", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54-1410065408", "" + aDouble);
+ blackhole("-548.0", "" + aDouble);
+ blackhole("-5455.0", "" + aDouble);
+ blackhole("-5497000000", "" + aDouble);
+ blackhole("-54-9900", "" + aDouble);
+ blackhole("-54935228928", "" + aDouble);
+ blackhole("-54-8400", "" + aDouble);
+ blackhole("-54C(82)", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54true", "" + aDouble);
+ blackhole("-543900", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-5494000000", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54true", "" + aDouble);
+ blackhole("-545500", "" + aDouble);
+ blackhole("-54-2900", "" + aDouble);
+ blackhole("-54-194313216", "" + aDouble);
+ blackhole("-5412", "" + aDouble);
+ blackhole("-54C(87)", "" + aDouble);
+ blackhole("-5491", "" + aDouble);
+ blackhole("-5421", "" + aDouble);
+ blackhole("-5418", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54\u045180", "" + aDouble);
+ blackhole("-54C", "" + aDouble);
+ blackhole("-5475", "" + aDouble);
+ blackhole("-54-43", "" + aDouble);
+ blackhole("-5480", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54-52.0", "" + aDouble);
+ blackhole("-5475000000", "" + aDouble);
+ blackhole("-5444", "" + aDouble);
+ blackhole("-54-1705032704", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-5483.0", "" + aDouble);
+ blackhole("-54I", "" + aDouble);
+ blackhole("-5494.0", "" + aDouble);
+ blackhole("-5412.0", "" + aDouble);
+ blackhole("-54-99.0", "" + aDouble);
+ blackhole("-5417.0", "" + aDouble);
+ blackhole("-54-84.0", "" + aDouble);
+ blackhole("-5458000000", "" + aDouble);
+ blackhole("-54-55000000", "" + aDouble);
+ blackhole("-541460392448", "" + aDouble);
+ blackhole("-54C(70)", "" + aDouble);
+ blackhole("-54\u04511", "" + aDouble);
+ blackhole("-548000", "" + aDouble);
+ blackhole("-5418", "" + aDouble);
+ blackhole("-54-1000000", "" + aDouble);
+ blackhole("-541000000", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54false", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-54-2000000", "" + aDouble);
+ blackhole("-54-820130816", "" + aDouble);
+ blackhole("-54null", "" + aDouble);
+ blackhole("-5425000000", "" + aDouble);
+ blackhole("-87.0-96.0", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0\u045176", "" + aDouble);
+ blackhole("-87.092", "" + aDouble);
+ blackhole("-87.051", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0-54", "" + aDouble);
+ blackhole("-87.0-87.0", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.019", "" + aDouble);
+ blackhole("-87.0-41", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0T", "" + aDouble);
+ blackhole("-87.0-42.0", "" + aDouble);
+ blackhole("-87.025", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0-1410065408", "" + aDouble);
+ blackhole("-87.08.0", "" + aDouble);
+ blackhole("-87.055.0", "" + aDouble);
+ blackhole("-87.097000000", "" + aDouble);
+ blackhole("-87.0-9900", "" + aDouble);
+ blackhole("-87.0935228928", "" + aDouble);
+ blackhole("-87.0-8400", "" + aDouble);
+ blackhole("-87.0C(82)", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0true", "" + aDouble);
+ blackhole("-87.03900", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.094000000", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0true", "" + aDouble);
+ blackhole("-87.05500", "" + aDouble);
+ blackhole("-87.0-2900", "" + aDouble);
+ blackhole("-87.0-194313216", "" + aDouble);
+ blackhole("-87.012", "" + aDouble);
+ blackhole("-87.0C(87)", "" + aDouble);
+ blackhole("-87.091", "" + aDouble);
+ blackhole("-87.021", "" + aDouble);
+ blackhole("-87.018", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0\u045180", "" + aDouble);
+ blackhole("-87.0C", "" + aDouble);
+ blackhole("-87.075", "" + aDouble);
+ blackhole("-87.0-43", "" + aDouble);
+ blackhole("-87.080", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0-52.0", "" + aDouble);
+ blackhole("-87.075000000", "" + aDouble);
+ blackhole("-87.044", "" + aDouble);
+ blackhole("-87.0-1705032704", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.083.0", "" + aDouble);
+ blackhole("-87.0I", "" + aDouble);
+ blackhole("-87.094.0", "" + aDouble);
+ blackhole("-87.012.0", "" + aDouble);
+ blackhole("-87.0-99.0", "" + aDouble);
+ blackhole("-87.017.0", "" + aDouble);
+ blackhole("-87.0-84.0", "" + aDouble);
+ blackhole("-87.058000000", "" + aDouble);
+ blackhole("-87.0-55000000", "" + aDouble);
+ blackhole("-87.01460392448", "" + aDouble);
+ blackhole("-87.0C(70)", "" + aDouble);
+ blackhole("-87.0\u04511", "" + aDouble);
+ blackhole("-87.08000", "" + aDouble);
+ blackhole("-87.018", "" + aDouble);
+ blackhole("-87.0-1000000", "" + aDouble);
+ blackhole("-87.01000000", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0false", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.0-2000000", "" + aDouble);
+ blackhole("-87.0-820130816", "" + aDouble);
+ blackhole("-87.0null", "" + aDouble);
+ blackhole("-87.025000000", "" + aDouble);
+ blackhole("null-96.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045176", "" + aDouble);
+ blackhole("null92", "" + aDouble);
+ blackhole("null51", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-54", "" + aDouble);
+ blackhole("null-87.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null19", "" + aDouble);
+ blackhole("null-41", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullT", "" + aDouble);
+ blackhole("null-42.0", "" + aDouble);
+ blackhole("null25", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-1410065408", "" + aDouble);
+ blackhole("null8.0", "" + aDouble);
+ blackhole("null55.0", "" + aDouble);
+ blackhole("null97000000", "" + aDouble);
+ blackhole("null-9900", "" + aDouble);
+ blackhole("null935228928", "" + aDouble);
+ blackhole("null-8400", "" + aDouble);
+ blackhole("nullC(82)", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null3900", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null94000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null5500", "" + aDouble);
+ blackhole("null-2900", "" + aDouble);
+ blackhole("null-194313216", "" + aDouble);
+ blackhole("null12", "" + aDouble);
+ blackhole("nullC(87)", "" + aDouble);
+ blackhole("null91", "" + aDouble);
+ blackhole("null21", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045180", "" + aDouble);
+ blackhole("nullC", "" + aDouble);
+ blackhole("null75", "" + aDouble);
+ blackhole("null-43", "" + aDouble);
+ blackhole("null80", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-52.0", "" + aDouble);
+ blackhole("null75000000", "" + aDouble);
+ blackhole("null44", "" + aDouble);
+ blackhole("null-1705032704", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null83.0", "" + aDouble);
+ blackhole("nullI", "" + aDouble);
+ blackhole("null94.0", "" + aDouble);
+ blackhole("null12.0", "" + aDouble);
+ blackhole("null-99.0", "" + aDouble);
+ blackhole("null17.0", "" + aDouble);
+ blackhole("null-84.0", "" + aDouble);
+ blackhole("null58000000", "" + aDouble);
+ blackhole("null-55000000", "" + aDouble);
+ blackhole("null1460392448", "" + aDouble);
+ blackhole("nullC(70)", "" + aDouble);
+ blackhole("null\u04511", "" + aDouble);
+ blackhole("null8000", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("null-1000000", "" + aDouble);
+ blackhole("null1000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullfalse", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-2000000", "" + aDouble);
+ blackhole("null-820130816", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null25000000", "" + aDouble);
+ blackhole("19-96.0", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19\u045176", "" + aDouble);
+ blackhole("1992", "" + aDouble);
+ blackhole("1951", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19-54", "" + aDouble);
+ blackhole("19-87.0", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("1919", "" + aDouble);
+ blackhole("19-41", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19T", "" + aDouble);
+ blackhole("19-42.0", "" + aDouble);
+ blackhole("1925", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19-1410065408", "" + aDouble);
+ blackhole("198.0", "" + aDouble);
+ blackhole("1955.0", "" + aDouble);
+ blackhole("1997000000", "" + aDouble);
+ blackhole("19-9900", "" + aDouble);
+ blackhole("19935228928", "" + aDouble);
+ blackhole("19-8400", "" + aDouble);
+ blackhole("19C(82)", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19true", "" + aDouble);
+ blackhole("193900", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("1994000000", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19true", "" + aDouble);
+ blackhole("195500", "" + aDouble);
+ blackhole("19-2900", "" + aDouble);
+ blackhole("19-194313216", "" + aDouble);
+ blackhole("1912", "" + aDouble);
+ blackhole("19C(87)", "" + aDouble);
+ blackhole("1991", "" + aDouble);
+ blackhole("1921", "" + aDouble);
+ blackhole("1918", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19\u045180", "" + aDouble);
+ blackhole("19C", "" + aDouble);
+ blackhole("1975", "" + aDouble);
+ blackhole("19-43", "" + aDouble);
+ blackhole("1980", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19-52.0", "" + aDouble);
+ blackhole("1975000000", "" + aDouble);
+ blackhole("1944", "" + aDouble);
+ blackhole("19-1705032704", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("1983.0", "" + aDouble);
+ blackhole("19I", "" + aDouble);
+ blackhole("1994.0", "" + aDouble);
+ blackhole("1912.0", "" + aDouble);
+ blackhole("19-99.0", "" + aDouble);
+ blackhole("1917.0", "" + aDouble);
+ blackhole("19-84.0", "" + aDouble);
+ blackhole("1958000000", "" + aDouble);
+ blackhole("19-55000000", "" + aDouble);
+ blackhole("191460392448", "" + aDouble);
+ blackhole("19C(70)", "" + aDouble);
+ blackhole("19\u04511", "" + aDouble);
+ blackhole("198000", "" + aDouble);
+ blackhole("1918", "" + aDouble);
+ blackhole("19-1000000", "" + aDouble);
+ blackhole("191000000", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19false", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("19-2000000", "" + aDouble);
+ blackhole("19-820130816", "" + aDouble);
+ blackhole("19null", "" + aDouble);
+ blackhole("1925000000", "" + aDouble);
+ blackhole("-41-96.0", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41\u045176", "" + aDouble);
+ blackhole("-4192", "" + aDouble);
+ blackhole("-4151", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41-54", "" + aDouble);
+ blackhole("-41-87.0", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-4119", "" + aDouble);
+ blackhole("-41-41", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41T", "" + aDouble);
+ blackhole("-41-42.0", "" + aDouble);
+ blackhole("-4125", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41-1410065408", "" + aDouble);
+ blackhole("-418.0", "" + aDouble);
+ blackhole("-4155.0", "" + aDouble);
+ blackhole("-4197000000", "" + aDouble);
+ blackhole("-41-9900", "" + aDouble);
+ blackhole("-41935228928", "" + aDouble);
+ blackhole("-41-8400", "" + aDouble);
+ blackhole("-41C(82)", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41true", "" + aDouble);
+ blackhole("-413900", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-4194000000", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41true", "" + aDouble);
+ blackhole("-415500", "" + aDouble);
+ blackhole("-41-2900", "" + aDouble);
+ blackhole("-41-194313216", "" + aDouble);
+ blackhole("-4112", "" + aDouble);
+ blackhole("-41C(87)", "" + aDouble);
+ blackhole("-4191", "" + aDouble);
+ blackhole("-4121", "" + aDouble);
+ blackhole("-4118", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41\u045180", "" + aDouble);
+ blackhole("-41C", "" + aDouble);
+ blackhole("-4175", "" + aDouble);
+ blackhole("-41-43", "" + aDouble);
+ blackhole("-4180", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41-52.0", "" + aDouble);
+ blackhole("-4175000000", "" + aDouble);
+ blackhole("-4144", "" + aDouble);
+ blackhole("-41-1705032704", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-4183.0", "" + aDouble);
+ blackhole("-41I", "" + aDouble);
+ blackhole("-4194.0", "" + aDouble);
+ blackhole("-4112.0", "" + aDouble);
+ blackhole("-41-99.0", "" + aDouble);
+ blackhole("-4117.0", "" + aDouble);
+ blackhole("-41-84.0", "" + aDouble);
+ blackhole("-4158000000", "" + aDouble);
+ blackhole("-41-55000000", "" + aDouble);
+ blackhole("-411460392448", "" + aDouble);
+ blackhole("-41C(70)", "" + aDouble);
+ blackhole("-41\u04511", "" + aDouble);
+ blackhole("-418000", "" + aDouble);
+ blackhole("-4118", "" + aDouble);
+ blackhole("-41-1000000", "" + aDouble);
+ blackhole("-411000000", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41false", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-41-2000000", "" + aDouble);
+ blackhole("-41-820130816", "" + aDouble);
+ blackhole("-41null", "" + aDouble);
+ blackhole("-4125000000", "" + aDouble);
+ blackhole("null-96.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045176", "" + aDouble);
+ blackhole("null92", "" + aDouble);
+ blackhole("null51", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-54", "" + aDouble);
+ blackhole("null-87.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null19", "" + aDouble);
+ blackhole("null-41", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullT", "" + aDouble);
+ blackhole("null-42.0", "" + aDouble);
+ blackhole("null25", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-1410065408", "" + aDouble);
+ blackhole("null8.0", "" + aDouble);
+ blackhole("null55.0", "" + aDouble);
+ blackhole("null97000000", "" + aDouble);
+ blackhole("null-9900", "" + aDouble);
+ blackhole("null935228928", "" + aDouble);
+ blackhole("null-8400", "" + aDouble);
+ blackhole("nullC(82)", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null3900", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null94000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null5500", "" + aDouble);
+ blackhole("null-2900", "" + aDouble);
+ blackhole("null-194313216", "" + aDouble);
+ blackhole("null12", "" + aDouble);
+ blackhole("nullC(87)", "" + aDouble);
+ blackhole("null91", "" + aDouble);
+ blackhole("null21", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045180", "" + aDouble);
+ blackhole("nullC", "" + aDouble);
+ blackhole("null75", "" + aDouble);
+ blackhole("null-43", "" + aDouble);
+ blackhole("null80", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-52.0", "" + aDouble);
+ blackhole("null75000000", "" + aDouble);
+ blackhole("null44", "" + aDouble);
+ blackhole("null-1705032704", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null83.0", "" + aDouble);
+ blackhole("nullI", "" + aDouble);
+ blackhole("null94.0", "" + aDouble);
+ blackhole("null12.0", "" + aDouble);
+ blackhole("null-99.0", "" + aDouble);
+ blackhole("null17.0", "" + aDouble);
+ blackhole("null-84.0", "" + aDouble);
+ blackhole("null58000000", "" + aDouble);
+ blackhole("null-55000000", "" + aDouble);
+ blackhole("null1460392448", "" + aDouble);
+ blackhole("nullC(70)", "" + aDouble);
+ blackhole("null\u04511", "" + aDouble);
+ blackhole("null8000", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("null-1000000", "" + aDouble);
+ blackhole("null1000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullfalse", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-2000000", "" + aDouble);
+ blackhole("null-820130816", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null25000000", "" + aDouble);
+ blackhole("T-96.0", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T\u045176", "" + aDouble);
+ blackhole("T92", "" + aDouble);
+ blackhole("T51", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T-54", "" + aDouble);
+ blackhole("T-87.0", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T19", "" + aDouble);
+ blackhole("T-41", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("TT", "" + aDouble);
+ blackhole("T-42.0", "" + aDouble);
+ blackhole("T25", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T-1410065408", "" + aDouble);
+ blackhole("T8.0", "" + aDouble);
+ blackhole("T55.0", "" + aDouble);
+ blackhole("T97000000", "" + aDouble);
+ blackhole("T-9900", "" + aDouble);
+ blackhole("T935228928", "" + aDouble);
+ blackhole("T-8400", "" + aDouble);
+ blackhole("TC(82)", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("Ttrue", "" + aDouble);
+ blackhole("T3900", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T94000000", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("Ttrue", "" + aDouble);
+ blackhole("T5500", "" + aDouble);
+ blackhole("T-2900", "" + aDouble);
+ blackhole("T-194313216", "" + aDouble);
+ blackhole("T12", "" + aDouble);
+ blackhole("TC(87)", "" + aDouble);
+ blackhole("T91", "" + aDouble);
+ blackhole("T21", "" + aDouble);
+ blackhole("T18", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T\u045180", "" + aDouble);
+ blackhole("TC", "" + aDouble);
+ blackhole("T75", "" + aDouble);
+ blackhole("T-43", "" + aDouble);
+ blackhole("T80", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T-52.0", "" + aDouble);
+ blackhole("T75000000", "" + aDouble);
+ blackhole("T44", "" + aDouble);
+ blackhole("T-1705032704", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T83.0", "" + aDouble);
+ blackhole("TI", "" + aDouble);
+ blackhole("T94.0", "" + aDouble);
+ blackhole("T12.0", "" + aDouble);
+ blackhole("T-99.0", "" + aDouble);
+ blackhole("T17.0", "" + aDouble);
+ blackhole("T-84.0", "" + aDouble);
+ blackhole("T58000000", "" + aDouble);
+ blackhole("T-55000000", "" + aDouble);
+ blackhole("T1460392448", "" + aDouble);
+ blackhole("TC(70)", "" + aDouble);
+ blackhole("T\u04511", "" + aDouble);
+ blackhole("T8000", "" + aDouble);
+ blackhole("T18", "" + aDouble);
+ blackhole("T-1000000", "" + aDouble);
+ blackhole("T1000000", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("Tfalse", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T-2000000", "" + aDouble);
+ blackhole("T-820130816", "" + aDouble);
+ blackhole("Tnull", "" + aDouble);
+ blackhole("T25000000", "" + aDouble);
+ blackhole("-42.0-96.0", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0\u045176", "" + aDouble);
+ blackhole("-42.092", "" + aDouble);
+ blackhole("-42.051", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0-54", "" + aDouble);
+ blackhole("-42.0-87.0", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.019", "" + aDouble);
+ blackhole("-42.0-41", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0T", "" + aDouble);
+ blackhole("-42.0-42.0", "" + aDouble);
+ blackhole("-42.025", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0-1410065408", "" + aDouble);
+ blackhole("-42.08.0", "" + aDouble);
+ blackhole("-42.055.0", "" + aDouble);
+ blackhole("-42.097000000", "" + aDouble);
+ blackhole("-42.0-9900", "" + aDouble);
+ blackhole("-42.0935228928", "" + aDouble);
+ blackhole("-42.0-8400", "" + aDouble);
+ blackhole("-42.0C(82)", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0true", "" + aDouble);
+ blackhole("-42.03900", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.094000000", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0true", "" + aDouble);
+ blackhole("-42.05500", "" + aDouble);
+ blackhole("-42.0-2900", "" + aDouble);
+ blackhole("-42.0-194313216", "" + aDouble);
+ blackhole("-42.012", "" + aDouble);
+ blackhole("-42.0C(87)", "" + aDouble);
+ blackhole("-42.091", "" + aDouble);
+ blackhole("-42.021", "" + aDouble);
+ blackhole("-42.018", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0\u045180", "" + aDouble);
+ blackhole("-42.0C", "" + aDouble);
+ blackhole("-42.075", "" + aDouble);
+ blackhole("-42.0-43", "" + aDouble);
+ blackhole("-42.080", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0-52.0", "" + aDouble);
+ blackhole("-42.075000000", "" + aDouble);
+ blackhole("-42.044", "" + aDouble);
+ blackhole("-42.0-1705032704", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.083.0", "" + aDouble);
+ blackhole("-42.0I", "" + aDouble);
+ blackhole("-42.094.0", "" + aDouble);
+ blackhole("-42.012.0", "" + aDouble);
+ blackhole("-42.0-99.0", "" + aDouble);
+ blackhole("-42.017.0", "" + aDouble);
+ blackhole("-42.0-84.0", "" + aDouble);
+ blackhole("-42.058000000", "" + aDouble);
+ blackhole("-42.0-55000000", "" + aDouble);
+ blackhole("-42.01460392448", "" + aDouble);
+ blackhole("-42.0C(70)", "" + aDouble);
+ blackhole("-42.0\u04511", "" + aDouble);
+ blackhole("-42.08000", "" + aDouble);
+ blackhole("-42.018", "" + aDouble);
+ blackhole("-42.0-1000000", "" + aDouble);
+ blackhole("-42.01000000", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0false", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.0-2000000", "" + aDouble);
+ blackhole("-42.0-820130816", "" + aDouble);
+ blackhole("-42.0null", "" + aDouble);
+ blackhole("-42.025000000", "" + aDouble);
+ blackhole("25-96.0", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25\u045176", "" + aDouble);
+ blackhole("2592", "" + aDouble);
+ blackhole("2551", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25-54", "" + aDouble);
+ blackhole("25-87.0", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("2519", "" + aDouble);
+ blackhole("25-41", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25T", "" + aDouble);
+ blackhole("25-42.0", "" + aDouble);
+ blackhole("2525", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25-1410065408", "" + aDouble);
+ blackhole("258.0", "" + aDouble);
+ blackhole("2555.0", "" + aDouble);
+ blackhole("2597000000", "" + aDouble);
+ blackhole("25-9900", "" + aDouble);
+ blackhole("25935228928", "" + aDouble);
+ blackhole("25-8400", "" + aDouble);
+ blackhole("25C(82)", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25true", "" + aDouble);
+ blackhole("253900", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("2594000000", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25true", "" + aDouble);
+ blackhole("255500", "" + aDouble);
+ blackhole("25-2900", "" + aDouble);
+ blackhole("25-194313216", "" + aDouble);
+ blackhole("2512", "" + aDouble);
+ blackhole("25C(87)", "" + aDouble);
+ blackhole("2591", "" + aDouble);
+ blackhole("2521", "" + aDouble);
+ blackhole("2518", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25\u045180", "" + aDouble);
+ blackhole("25C", "" + aDouble);
+ blackhole("2575", "" + aDouble);
+ blackhole("25-43", "" + aDouble);
+ blackhole("2580", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25-52.0", "" + aDouble);
+ blackhole("2575000000", "" + aDouble);
+ blackhole("2544", "" + aDouble);
+ blackhole("25-1705032704", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("2583.0", "" + aDouble);
+ blackhole("25I", "" + aDouble);
+ blackhole("2594.0", "" + aDouble);
+ blackhole("2512.0", "" + aDouble);
+ blackhole("25-99.0", "" + aDouble);
+ blackhole("2517.0", "" + aDouble);
+ blackhole("25-84.0", "" + aDouble);
+ blackhole("2558000000", "" + aDouble);
+ blackhole("25-55000000", "" + aDouble);
+ blackhole("251460392448", "" + aDouble);
+ blackhole("25C(70)", "" + aDouble);
+ blackhole("25\u04511", "" + aDouble);
+ blackhole("258000", "" + aDouble);
+ blackhole("2518", "" + aDouble);
+ blackhole("25-1000000", "" + aDouble);
+ blackhole("251000000", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25false", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("25-2000000", "" + aDouble);
+ blackhole("25-820130816", "" + aDouble);
+ blackhole("25null", "" + aDouble);
+ blackhole("2525000000", "" + aDouble);
+ blackhole("null-96.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045176", "" + aDouble);
+ blackhole("null92", "" + aDouble);
+ blackhole("null51", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-54", "" + aDouble);
+ blackhole("null-87.0", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null19", "" + aDouble);
+ blackhole("null-41", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullT", "" + aDouble);
+ blackhole("null-42.0", "" + aDouble);
+ blackhole("null25", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-1410065408", "" + aDouble);
+ blackhole("null8.0", "" + aDouble);
+ blackhole("null55.0", "" + aDouble);
+ blackhole("null97000000", "" + aDouble);
+ blackhole("null-9900", "" + aDouble);
+ blackhole("null935228928", "" + aDouble);
+ blackhole("null-8400", "" + aDouble);
+ blackhole("nullC(82)", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null3900", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null94000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nulltrue", "" + aDouble);
+ blackhole("null5500", "" + aDouble);
+ blackhole("null-2900", "" + aDouble);
+ blackhole("null-194313216", "" + aDouble);
+ blackhole("null12", "" + aDouble);
+ blackhole("nullC(87)", "" + aDouble);
+ blackhole("null91", "" + aDouble);
+ blackhole("null21", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null\u045180", "" + aDouble);
+ blackhole("nullC", "" + aDouble);
+ blackhole("null75", "" + aDouble);
+ blackhole("null-43", "" + aDouble);
+ blackhole("null80", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-52.0", "" + aDouble);
+ blackhole("null75000000", "" + aDouble);
+ blackhole("null44", "" + aDouble);
+ blackhole("null-1705032704", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null83.0", "" + aDouble);
+ blackhole("nullI", "" + aDouble);
+ blackhole("null94.0", "" + aDouble);
+ blackhole("null12.0", "" + aDouble);
+ blackhole("null-99.0", "" + aDouble);
+ blackhole("null17.0", "" + aDouble);
+ blackhole("null-84.0", "" + aDouble);
+ blackhole("null58000000", "" + aDouble);
+ blackhole("null-55000000", "" + aDouble);
+ blackhole("null1460392448", "" + aDouble);
+ blackhole("nullC(70)", "" + aDouble);
+ blackhole("null\u04511", "" + aDouble);
+ blackhole("null8000", "" + aDouble);
+ blackhole("null18", "" + aDouble);
+ blackhole("null-1000000", "" + aDouble);
+ blackhole("null1000000", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("nullfalse", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null-2000000", "" + aDouble);
+ blackhole("null-820130816", "" + aDouble);
+ blackhole("nullnull", "" + aDouble);
+ blackhole("null25000000", "" + aDouble);
+ blackhole("-1410065408-96.0", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408\u045176", "" + aDouble);
+ blackhole("-141006540892", "" + aDouble);
+ blackhole("-141006540851", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408-54", "" + aDouble);
+ blackhole("-1410065408-87.0", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-141006540819", "" + aDouble);
+ blackhole("-1410065408-41", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408T", "" + aDouble);
+ blackhole("-1410065408-42.0", "" + aDouble);
+ blackhole("-141006540825", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408-1410065408", "" + aDouble);
+ blackhole("-14100654088.0", "" + aDouble);
+ blackhole("-141006540855.0", "" + aDouble);
+ blackhole("-141006540897000000", "" + aDouble);
+ blackhole("-1410065408-9900", "" + aDouble);
+ blackhole("-1410065408935228928", "" + aDouble);
+ blackhole("-1410065408-8400", "" + aDouble);
+ blackhole("-1410065408C(82)", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408true", "" + aDouble);
+ blackhole("-14100654083900", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-141006540894000000", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408true", "" + aDouble);
+ blackhole("-14100654085500", "" + aDouble);
+ blackhole("-1410065408-2900", "" + aDouble);
+ blackhole("-1410065408-194313216", "" + aDouble);
+ blackhole("-141006540812", "" + aDouble);
+ blackhole("-1410065408C(87)", "" + aDouble);
+ blackhole("-141006540891", "" + aDouble);
+ blackhole("-141006540821", "" + aDouble);
+ blackhole("-141006540818", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408\u045180", "" + aDouble);
+ blackhole("-1410065408C", "" + aDouble);
+ blackhole("-141006540875", "" + aDouble);
+ blackhole("-1410065408-43", "" + aDouble);
+ blackhole("-141006540880", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408-52.0", "" + aDouble);
+ blackhole("-141006540875000000", "" + aDouble);
+ blackhole("-141006540844", "" + aDouble);
+ blackhole("-1410065408-1705032704", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-141006540883.0", "" + aDouble);
+ blackhole("-1410065408I", "" + aDouble);
+ blackhole("-141006540894.0", "" + aDouble);
+ blackhole("-141006540812.0", "" + aDouble);
+ blackhole("-1410065408-99.0", "" + aDouble);
+ blackhole("-141006540817.0", "" + aDouble);
+ blackhole("-1410065408-84.0", "" + aDouble);
+ blackhole("-141006540858000000", "" + aDouble);
+ blackhole("-1410065408-55000000", "" + aDouble);
+ blackhole("-14100654081460392448", "" + aDouble);
+ blackhole("-1410065408C(70)", "" + aDouble);
+ blackhole("-1410065408\u04511", "" + aDouble);
+ blackhole("-14100654088000", "" + aDouble);
+ blackhole("-141006540818", "" + aDouble);
+ blackhole("-1410065408-1000000", "" + aDouble);
+ blackhole("-14100654081000000", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408false", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-1410065408-2000000", "" + aDouble);
+ blackhole("-1410065408-820130816", "" + aDouble);
+ blackhole("-1410065408null", "" + aDouble);
+ blackhole("-141006540825000000", "" + aDouble);
+ blackhole("8.0-96.0", "" + aDouble);
+ blackhole("8.0null", "" + aDouble);
+ blackhole("8.0\u045176", "" + aDouble);
+ blackhole("8.092", "" + aDouble);
+ blackhole("8.051", "" + aDouble);
+ blackhole("8.0null", "" + aDouble);
+ blackhole("8.0-54", "" + aDouble);
+ blackhole("8.0-87.0", "" + aDouble);
+ blackhole("8.0null", "" + aDouble);
+ blackhole("8.019", "" + aDouble);
+ blackhole("8.0-41", "" + aDouble);
+ blackhole("8.0null", "" + aDouble);
+ blackhole("8.0T", "" + aDouble);
+ blackhole("8.0-42.0", "" + aDouble);
+ blackhole("8.025", "" + aDouble);
+ blackhole("C(87)-96.0", "" + aDouble);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationPiTest.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import org.junit.Test;
+
+public class ConditionalEliminationPiTest extends ConditionalEliminationTestBase {
+
+ static int SideEffect;
+
+ static double oracleValue1 = -0.0;
+ static double oracleValue2;
+
+ public static double testSnippet1(int a) {
+ double phi;
+ if (a > 0) {
+ double oracle = oracleValue1;
+ if (oracle == 0.0) {
+ SideEffect = 1;
+ } else {
+ return 123;
+ }
+ phi = oracle;
+ } else {
+ double oracle = oracleValue2;
+ if (oracle == 0.0) {
+ SideEffect = 1;
+ phi = oracle;
+ } else {
+ return 0;
+ }
+ }
+ if (Double.doubleToRawLongBits(phi) == Double.doubleToRawLongBits(-0.0)) {
+ return 12;
+ }
+ return 2;
+ }
+
+ @Test
+ public void test1() {
+ test("testSnippet1", 1);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/ConditionalEliminationTest16.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.core.test;
+
+import org.graalvm.compiler.api.directives.GraalDirectives;
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.core.common.type.StampPair;
+import org.graalvm.compiler.core.common.type.TypeReference;
+import org.graalvm.compiler.nodes.ParameterNode;
+import org.graalvm.compiler.nodes.PiNode;
+import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.phases.common.CanonicalizerPhase;
+import org.junit.Test;
+
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Check that multiple bounds checks are correctly grouped together.
+ */
+public class ConditionalEliminationTest16 extends ConditionalEliminationTestBase {
+
+ public static int testCastExactInstance(Object object) {
+ if (object.getClass() == Integer.class) {
+ return ((Integer) object).intValue();
+ }
+ GraalDirectives.deoptimizeAndInvalidate();
+ return -1;
+ }
+
+ @Override
+ protected boolean checkHighTierGraph(StructuredGraph graph) {
+ for (ParameterNode param : graph.getNodes().filter(ParameterNode.class)) {
+ if (param.index() == 0) {
+ ParameterNode newParam = new ParameterNode(0, StampPair.createSingle(StampFactory.object(TypeReference.createExactTrusted(getMetaAccess().lookupJavaType(Integer.class)))));
+ graph.addWithoutUnique(newParam);
+ param.replaceAtUsages(newParam);
+ param.safeDelete();
+ break;
+ }
+ }
+ new CanonicalizerPhase().apply(graph, getDefaultHighTierContext());
+ return super.checkHighTierGraph(graph);
+ }
+
+ @Override
+ protected boolean checkMidTierGraph(StructuredGraph graph) {
+ int count = 0;
+ for (PiNode node : graph.getNodes().filter(PiNode.class)) {
+ assertTrue(node.getGuard() != null, "must have guarding node");
+ count++;
+ }
+ assertTrue(count > 0, "expected at least one Pi");
+ return super.checkMidTierGraph(graph);
+ }
+
+ @Test
+ public void test1() {
+ ResolvedJavaMethod method = getResolvedJavaMethod("testCastExactInstance");
+ StructuredGraph graph = parseForCompile(method);
+ compile(method, graph);
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -129,4 +129,9 @@
public Integer smallestCompareWidth() {
return 8;
}
+
+ @Override
+ public boolean supportBulkZeroing() {
+ return true;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java Tue May 07 17:30:14 2019 -0400
@@ -398,6 +398,9 @@
if (isJDK13OrHigher()) {
add(toBeInvestigated,
+ "java/lang/Math.abs(F)F",
+ "java/lang/Math.abs(I)I",
+ "java/lang/Math.abs(J)J",
"java/lang/Math.max(DD)D",
"java/lang/Math.max(FF)F",
"java/lang/Math.min(DD)D",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/JVMCIVersionCheckTest.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.hotspot.test;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.hotspot.JVMCIVersionCheck;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class JVMCIVersionCheckTest extends GraalCompilerTest {
+
+ @Test
+ public void test01() {
+ Properties sprops = System.getProperties();
+ Map<String, String> props = new HashMap<>(sprops.size());
+ for (String name : sprops.stringPropertyNames()) {
+ props.put(name, sprops.getProperty(name));
+ }
+
+ for (int i = 0; i < 100; i++) {
+ int minMajor = i;
+ int minMinor = 100 - i;
+ for (int j = 0; j < 100; j++) {
+ int major = j;
+ int minor = 100 - j;
+
+ boolean ok = (major > minMajor) || (major == minMajor && minor >= minMinor);
+ for (String sep : new String[]{".", "-b"}) {
+ String javaVmVersion = String.format("prefix-jvmci-%03d%s%03d-suffix", major, sep, minor);
+ if (ok) {
+ JVMCIVersionCheck.check(props, minMajor, minMinor, "1.8", javaVmVersion, false);
+ } else {
+ try {
+ JVMCIVersionCheck.check(props, minMajor, minMinor, "1.8", javaVmVersion, false);
+ Assert.fail("expected to fail checking " + javaVmVersion + " against " + minMajor + "." + minMinor);
+ } catch (InternalError e) {
+ // pass
+ }
+ }
+ }
+ }
+ }
+
+ // Test handling of version components bigger than Integer.MAX_VALUE
+ for (String sep : new String[]{".", "-b"}) {
+ for (String version : new String[]{"0" + sep + Long.MAX_VALUE, Long.MAX_VALUE + sep + 0}) {
+ String javaVmVersion = String.format("prefix-jvmci-%s-suffix", version);
+ try {
+ JVMCIVersionCheck.check(props, 0, 59, "1.8", javaVmVersion, false);
+ Assert.fail("expected to fail checking " + javaVmVersion + " against 0.59");
+ } catch (InternalError e) {
+ // pass
+ }
+ }
+ }
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/CompilationTask.java Tue May 07 17:30:14 2019 -0400
@@ -32,7 +32,6 @@
import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
import java.io.PrintStream;
-import java.util.List;
import jdk.internal.vm.compiler.collections.EconomicMap;
import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
@@ -44,7 +43,6 @@
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugDumpScope;
-import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TimerKey;
import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues;
@@ -52,7 +50,6 @@
import jdk.vm.ci.code.BailoutException;
import jdk.vm.ci.code.CodeCacheProvider;
-import jdk.vm.ci.hotspot.EventProvider;
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult;
import jdk.vm.ci.hotspot.HotSpotInstalledCode;
@@ -60,23 +57,9 @@
import jdk.vm.ci.hotspot.HotSpotNmethod;
import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
import jdk.vm.ci.runtime.JVMCICompiler;
-import jdk.vm.ci.services.JVMCIServiceLocator;
public class CompilationTask {
- private static final EventProvider eventProvider;
-
- static {
- List<EventProvider> providers = JVMCIServiceLocator.getProviders(EventProvider.class);
- if (providers.size() > 1) {
- throw new GraalError("Multiple %s providers found: %s", EventProvider.class.getName(), providers);
- } else if (providers.isEmpty()) {
- eventProvider = EventProvider.createEmptyEventProvider();
- } else {
- eventProvider = providers.get(0);
- }
- }
-
private final HotSpotJVMCIRuntime jvmciRuntime;
private final HotSpotGraalCompiler compiler;
@@ -94,12 +77,10 @@
private final boolean shouldRetainLocalVariables;
final class HotSpotCompilationWrapper extends CompilationWrapper<HotSpotCompilationRequestResult> {
- private final EventProvider.CompilationEvent compilationEvent;
CompilationResult result;
- HotSpotCompilationWrapper(EventProvider.CompilationEvent compilationEvent) {
+ HotSpotCompilationWrapper() {
super(compiler.getGraalRuntime().getOutputDirectory(), compiler.getGraalRuntime().getCompilationProblemsPerAction());
- this.compilationEvent = compilationEvent;
}
@Override
@@ -125,13 +106,6 @@
*/
return HotSpotCompilationRequestResult.failure(bailout.getMessage(), !bailout.isPermanent());
}
- // Log a failure event.
- EventProvider.CompilerFailureEvent event = eventProvider.newCompilerFailureEvent();
- if (event.shouldWrite()) {
- event.setCompileId(getId());
- event.setMessage(t.getMessage());
- event.commit();
- }
/*
* Treat random exceptions from the compiler as indicating a problem compiling this
@@ -181,14 +155,9 @@
final CompilationPrinter printer = CompilationPrinter.begin(debug.getOptions(), compilationId, method, entryBCI);
try (DebugContext.Scope s = debug.scope("Compiling", new DebugDumpScope(getIdString(), true))) {
- // Begin the compilation event.
- compilationEvent.begin();
result = compiler.compile(method, entryBCI, useProfilingInfo, shouldRetainLocalVariables, compilationId, debug);
} catch (Throwable e) {
throw debug.handle(e);
- } finally {
- // End the compilation event.
- compilationEvent.end();
}
if (result != null) {
@@ -322,9 +291,6 @@
boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
HotSpotResolvedJavaMethod method = getMethod();
- // Log a compilation event.
- EventProvider.CompilationEvent compilationEvent = eventProvider.newCompilationEvent();
-
if (installAsDefault || isOSR) {
// If there is already compiled code for this method on our level we simply return.
// JVMCI compiles are always at the highest compile level, even in non-tiered mode so we
@@ -337,7 +303,7 @@
}
}
- HotSpotCompilationWrapper compilation = new HotSpotCompilationWrapper(compilationEvent);
+ HotSpotCompilationWrapper compilation = new HotSpotCompilationWrapper();
try (DebugCloseable a = CompilationTime.start(debug)) {
return compilation.run(debug);
} finally {
@@ -354,18 +320,6 @@
InstalledCodeSize.add(debug, codeSize);
}
}
-
- // Log a compilation event.
- if (compilationEvent.shouldWrite()) {
- compilationEvent.setMethod(method.format("%H.%n(%p)"));
- compilationEvent.setCompileId(getId());
- compilationEvent.setCompileLevel(config.compilationLevelFullOptimization);
- compilationEvent.setSucceeded(compilation.result != null && installedCode != null);
- compilationEvent.setIsOsr(isOSR);
- compilationEvent.setCodeSize(codeSize);
- compilationEvent.setInlinedBytes(compiledBytecodes);
- compilationEvent.commit();
- }
} catch (Throwable t) {
return compilation.handleException(t);
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java Tue May 07 17:30:14 2019 -0400
@@ -460,6 +460,7 @@
public final int objectMonitorRecursions = getFieldOffset("ObjectMonitor::_recursions", Integer.class, "intptr_t", -1);
public final int objectMonitorCxq = getFieldOffset("ObjectMonitor::_cxq", Integer.class, "ObjectWaiter*", -1);
public final int objectMonitorEntryList = getFieldOffset("ObjectMonitor::_EntryList", Integer.class, "ObjectWaiter*", -1);
+ public final int objectMonitorSucc = getFieldOffset("ObjectMonitor::_succ", Integer.class, "Thread*", -1);
public final int markWordNoHashInPlace = getConstant("markOopDesc::no_hash_in_place", Integer.class);
public final int markWordNoLockInPlace = getConstant("markOopDesc::no_lock_in_place", Integer.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java Tue May 07 17:30:14 2019 -0400
@@ -39,7 +39,7 @@
*
* This class only depends on the JDK so that it can be used without building Graal.
*/
-class JVMCIVersionCheck {
+public final class JVMCIVersionCheck {
// 0.57 introduces HotSpotJVMCIRuntime.excludeFromJVMCICompilation
private static final int JVMCI8_MIN_MAJOR_VERSION = 0;
@@ -73,42 +73,115 @@
}
}
+ private final String javaSpecVersion;
+ private final String vmVersion;
+ private int cursor;
+ private final Map<String, String> props;
+
+ private JVMCIVersionCheck(Map<String, String> props, String javaSpecVersion, String vmVersion) {
+ this.props = props;
+ this.javaSpecVersion = javaSpecVersion;
+ this.vmVersion = vmVersion;
+ }
+
static void check(Map<String, String> props, boolean exitOnFailure) {
+ JVMCIVersionCheck checker = new JVMCIVersionCheck(props, props.get("java.specification.version"), props.get("java.vm.version"));
+ checker.run(exitOnFailure, JVMCI8_MIN_MAJOR_VERSION, JVMCI8_MIN_MINOR_VERSION);
+ }
+
+ /**
+ * Entry point for testing.
+ */
+ public static void check(Map<String, String> props,
+ int jvmci8MinMajorVersion,
+ int jvmci8MinMinorVersion,
+ String javaSpecVersion,
+ String javaVmVersion,
+ boolean exitOnFailure) {
+ JVMCIVersionCheck checker = new JVMCIVersionCheck(props, javaSpecVersion, javaVmVersion);
+ checker.run(exitOnFailure, jvmci8MinMajorVersion, jvmci8MinMinorVersion);
+ }
+
+ /**
+ * Parses a positive decimal number at {@link #cursor}.
+ *
+ * @return -1 if there is no positive decimal number at {@link #cursor}
+ */
+ private int parseNumber() {
+ int result = -1;
+ while (cursor < vmVersion.length()) {
+ int digit = vmVersion.charAt(cursor) - '0';
+ if (digit >= 0 && digit <= 9) {
+ if (result == -1) {
+ result = digit;
+ } else {
+ long r = (long) result * (long) 10;
+ if ((int) r != r) {
+ // Overflow
+ return -1;
+ }
+ result = (int) r + digit;
+ }
+ cursor++;
+ } else {
+ break;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Parse {@code "."} or {@code "-b"} at {@link #cursor}.
+ *
+ * @return {@code true} iff there was an expected separator at {@link #cursor}
+ */
+ private boolean parseSeparator() {
+ if (cursor < vmVersion.length()) {
+ char ch = vmVersion.charAt(cursor);
+ if (ch == '.') {
+ cursor++;
+ return true;
+ }
+ if (ch == '-') {
+ cursor++;
+ if (cursor < vmVersion.length()) {
+ if (vmVersion.charAt(cursor) == 'b') {
+ cursor++;
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+ return false;
+ }
+
+ private void run(boolean exitOnFailure, int jvmci8MinMajorVersion, int jvmci8MinMinorVersion) {
// Don't use regular expressions to minimize Graal startup time
- String javaSpecVersion = props.get("java.specification.version");
- String vmVersion = props.get("java.vm.version");
if (javaSpecVersion.compareTo("1.9") < 0) {
- int start = vmVersion.indexOf("-jvmci-");
- if (start >= 0) {
- start += "-jvmci-".length();
- int end = vmVersion.indexOf('.', start);
- if (end > 0) {
- int major;
- try {
- major = Integer.parseInt(vmVersion.substring(start, end));
- } catch (NumberFormatException e) {
- failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
- "Cannot read JVMCI major version from java.vm.version property: %s.%n", vmVersion);
- return;
- }
- start = end + 1;
- end = start;
- while (end < vmVersion.length() && Character.isDigit(vmVersion.charAt(end))) {
- end++;
- }
- int minor;
- try {
- minor = Integer.parseInt(vmVersion.substring(start, end));
- } catch (NumberFormatException e) {
+ cursor = vmVersion.indexOf("-jvmci-");
+ if (cursor >= 0) {
+ cursor += "-jvmci-".length();
+ int major = parseNumber();
+ if (major == -1) {
+ failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
+ "Cannot read JVMCI major version from java.vm.version property: %s.%n", vmVersion);
+ return;
+ }
+
+ if (parseSeparator()) {
+ int minor = parseNumber();
+ if (minor == -1) {
failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal.%n" +
"Cannot read JVMCI minor version from java.vm.version property: %s.%n", vmVersion);
return;
}
- if (major >= JVMCI8_MIN_MAJOR_VERSION && minor >= JVMCI8_MIN_MINOR_VERSION) {
+
+ if (major > jvmci8MinMajorVersion || (major >= jvmci8MinMajorVersion && minor >= jvmci8MinMinorVersion)) {
return;
}
failVersionCheck(props, exitOnFailure, "The VM does not support the minimum JVMCI API version required by Graal: %d.%d < %d.%d.%n",
- major, minor, JVMCI8_MIN_MAJOR_VERSION, JVMCI8_MIN_MINOR_VERSION);
+ major, minor, jvmci8MinMajorVersion, jvmci8MinMinorVersion);
return;
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/SymbolicSnippetEncoder.java Tue May 07 17:30:14 2019 -0400
@@ -571,7 +571,7 @@
try {
replacement = ((SymbolicJVMCIReference<?>) o).resolve(type);
break;
- } catch (NoClassDefFoundError | AssertionError e) {
+ } catch (NoClassDefFoundError e) {
}
}
} else if (o instanceof UnresolvedJavaType) {
@@ -579,7 +579,7 @@
try {
replacement = ((UnresolvedJavaType) o).resolve(type);
break;
- } catch (NoClassDefFoundError | AssertionError e) {
+ } catch (NoClassDefFoundError e) {
}
}
} else if (o instanceof UnresolvedJavaMethod) {
@@ -589,7 +589,7 @@
try {
replacement = ((UnresolvedJavaField) o).resolve(type);
break;
- } catch (NoClassDefFoundError | AssertionError e) {
+ } catch (NoClassDefFoundError e) {
}
}
} else if (o instanceof GraalCapability) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/LoadConstantIndirectlyNode.java Tue May 07 17:30:14 2019 -0400
@@ -43,6 +43,7 @@
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.nodes.util.GraphUtil;
+import jdk.vm.ci.hotspot.HotSpotConstantPoolObject;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
import jdk.vm.ci.meta.Constant;
@@ -83,7 +84,7 @@
public void generate(NodeLIRBuilderTool gen) {
assert constant != null : "Expected the value to fold: " + value;
Value result;
- if (constant instanceof HotSpotObjectConstant) {
+ if (constant instanceof HotSpotObjectConstant || constant instanceof HotSpotConstantPoolObject) {
result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLoadObjectAddress(constant);
} else if (constant instanceof HotSpotMetaspaceConstant) {
result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitLoadMetaspaceAddress(constant, action);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/nodes/aot/ResolveConstantStubCall.java Tue May 07 17:30:14 2019 -0400
@@ -45,6 +45,7 @@
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.word.Word;
+import jdk.vm.ci.hotspot.HotSpotConstantPoolObject;
import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant;
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
import jdk.vm.ci.meta.Constant;
@@ -100,7 +101,7 @@
Value result;
LIRFrameState fs = gen.state(this);
assert fs != null : "The stateAfter is null";
- if (constant instanceof HotSpotObjectConstant) {
+ if (constant instanceof HotSpotObjectConstant || constant instanceof HotSpotConstantPoolObject) {
result = ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitObjectConstantRetrieval(constant, stringValue, fs);
} else if (constant instanceof HotSpotMetaspaceConstant) {
if (action == HotSpotConstantLoadAction.RESOLVE) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/HotSpotReplacementsUtil.java Tue May 07 17:30:14 2019 -0400
@@ -516,6 +516,11 @@
return config.objectMonitorEntryList;
}
+ @Fold
+ public static int objectMonitorSuccOffset(@InjectedParameter GraalHotSpotVMConfig config) {
+ return config.objectMonitorSucc;
+ }
+
/**
* Mask for a biasable, locked or unlocked mark word.
*
@@ -685,6 +690,8 @@
public static final LocationIdentity OBJECT_MONITOR_ENTRY_LIST_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_EntryList");
+ public static final LocationIdentity OBJECT_MONITOR_SUCC_LOCATION = NamedLocationIdentity.mutable("ObjectMonitor::_succ");
+
@Fold
public static int lockDisplacedMarkOffset(@InjectedParameter GraalHotSpotVMConfig config) {
return config.basicLockDisplacedHeaderOffset;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java Tue May 07 17:30:14 2019 -0400
@@ -25,6 +25,7 @@
package org.graalvm.compiler.hotspot.replacements;
import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
+import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_OPTIONVALUES;
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
@@ -38,6 +39,7 @@
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_ENTRY_LIST_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_OWNER_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_RECURSION_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_SUCC_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.ageMaskInPlace;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.biasedLockMaskInPlace;
@@ -51,6 +53,7 @@
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorEntryListOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorOwnerOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorRecursionsOffset;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorSuccOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.pageSize;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.prototypeMarkWordOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
@@ -574,6 +577,32 @@
traceObject(trace, "-lock{inflated:simple}", object, false);
counters.unlockInflatedSimple.inc();
return true;
+ } else {
+ int succOffset = objectMonitorSuccOffset(INJECTED_VMCONFIG);
+ Word succ = monitor.readWord(succOffset, OBJECT_MONITOR_SUCC_LOCATION);
+ if (probability(FREQUENT_PROBABILITY, succ.isNonNull())) {
+ // There may be a thread spinning on this monitor. Temporarily setting
+ // the monitor owner to null, and hope that the other thread will grab it.
+ monitor.writeWord(ownerOffset, zero());
+ memoryBarrier(STORE_STORE | STORE_LOAD);
+ succ = monitor.readWord(succOffset, OBJECT_MONITOR_SUCC_LOCATION);
+ if (probability(NOT_FREQUENT_PROBABILITY, succ.isNonNull())) {
+ // We manage to release the monitor before the other running thread even
+ // notices.
+ traceObject(trace, "-lock{inflated:transfer}", object, false);
+ counters.unlockInflatedTransfer.inc();
+ return true;
+ } else {
+ // Either the monitor is grabbed by a spinning thread, or the spinning
+ // thread parks. Now we attempt to reset the owner of the monitor.
+ if (probability(FREQUENT_PROBABILITY, !monitor.logicCompareAndSwapWord(ownerOffset, zero(), thread, OBJECT_MONITOR_OWNER_LOCATION))) {
+ // The monitor is stolen.
+ traceObject(trace, "-lock{inflated:transfer}", object, false);
+ counters.unlockInflatedTransfer.inc();
+ return true;
+ }
+ }
+ }
}
}
counters.unlockStubInflated.inc();
@@ -692,6 +721,7 @@
public final SnippetCounter unlockStub;
public final SnippetCounter unlockStubInflated;
public final SnippetCounter unlockInflatedSimple;
+ public final SnippetCounter unlockInflatedTransfer;
public Counters(SnippetCounter.Group.Factory factory) {
SnippetCounter.Group enter = factory.createSnippetCounterGroup("MonitorEnters");
@@ -716,6 +746,7 @@
unlockStub = new SnippetCounter(exit, "unlock{stub}", "stub-unlocked an object");
unlockStubInflated = new SnippetCounter(exit, "unlock{stub:inflated}", "stub-unlocked an object with inflated monitor");
unlockInflatedSimple = new SnippetCounter(exit, "unlock{inflated}", "unlocked an object monitor");
+ unlockInflatedTransfer = new SnippetCounter(exit, "unlock{inflated:transfer}", "unlocked an object monitor in the presence of ObjectMonitor::_succ");
}
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
import static jdk.vm.ci.meta.DeoptimizationAction.None;
import static jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
+import static org.graalvm.compiler.core.common.GraalOptions.MinimalBulkZeroingSize;
import static org.graalvm.compiler.core.common.calc.UnsignedMath.belowThan;
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_OPTIONVALUES;
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase.INJECTED_VMCONFIG;
@@ -130,6 +131,7 @@
import org.graalvm.compiler.replacements.SnippetTemplate.SnippetInfo;
import org.graalvm.compiler.replacements.Snippets;
import org.graalvm.compiler.replacements.nodes.ExplodeLoopNode;
+import org.graalvm.compiler.replacements.nodes.ZeroMemoryNode;
import org.graalvm.compiler.word.Word;
import jdk.internal.vm.compiler.word.LocationIdentity;
import jdk.internal.vm.compiler.word.WordFactory;
@@ -311,21 +313,39 @@
public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
@Snippet
- public static Object allocatePrimitiveArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
- @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
+ public static Object allocatePrimitiveArrayPIC(KlassPointer hub,
+ int length,
+ Word prototypeMarkWord,
+ @ConstantParameter int headerSize,
+ @ConstantParameter int log2ElementSize,
+ @ConstantParameter boolean fillContents,
+ @ConstantParameter Register threadRegister,
+ @ConstantParameter boolean maybeUnroll,
+ @ConstantParameter String typeContext,
+ @ConstantParameter boolean useBulkZeroing,
@ConstantParameter Counters counters) {
// Primitive array types are eagerly pre-resolved. We can use a floating load.
KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub);
- return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, counters);
+ return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
+ threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters);
}
@Snippet
- public static Object allocateArrayPIC(KlassPointer hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
- @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter boolean maybeUnroll, @ConstantParameter String typeContext,
+ public static Object allocateArrayPIC(KlassPointer hub,
+ int length,
+ Word prototypeMarkWord,
+ @ConstantParameter int headerSize,
+ @ConstantParameter int log2ElementSize,
+ @ConstantParameter boolean fillContents,
+ @ConstantParameter Register threadRegister,
+ @ConstantParameter boolean maybeUnroll,
+ @ConstantParameter String typeContext,
+ @ConstantParameter boolean useBulkZeroing,
@ConstantParameter Counters counters) {
// Array type would be resolved by dominating resolution.
KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
- return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, maybeUnroll, typeContext, counters);
+ return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
+ threadRegister, maybeUnroll, typeContext, useBulkZeroing, counters);
}
@Snippet
@@ -338,6 +358,7 @@
@ConstantParameter Register threadRegister,
@ConstantParameter boolean maybeUnroll,
@ConstantParameter String typeContext,
+ @ConstantParameter boolean useBulkZeroing,
@ConstantParameter Counters counters) {
Object result = allocateArrayImpl(hub,
length,
@@ -348,7 +369,7 @@
threadRegister,
maybeUnroll,
typeContext,
-
+ useBulkZeroing,
counters);
return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
}
@@ -363,7 +384,7 @@
}
private static Object allocateArrayImpl(KlassPointer hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, Register threadRegister,
- boolean maybeUnroll, String typeContext, Counters counters) {
+ boolean maybeUnroll, String typeContext, boolean useBulkZeroing, Counters counters) {
Object result;
long allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize);
Word thread = registerAsWord(threadRegister);
@@ -378,7 +399,7 @@
if (theCounters != null && theCounters.arrayLoopInit != null) {
theCounters.arrayLoopInit.inc();
}
- result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, counters);
+ result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, maybeUnroll, useBulkZeroing, counters);
} else {
result = newArrayStub(hub, length);
}
@@ -435,15 +456,23 @@
public static native Object dynamicNewInstanceOrNull(@ConstantNodeParameter ForeignCallDescriptor descriptor, Class<?> elementType);
@Snippet
- public static Object allocateArrayDynamic(Class<?> elementType, Class<?> voidClass, int length, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister,
- @ConstantParameter JavaKind knownElementKind, @ConstantParameter int knownLayoutHelper, Word prototypeMarkWord,
+ public static Object allocateArrayDynamic(Class<?> elementType,
+ Class<?> voidClass,
+ int length,
+ @ConstantParameter boolean fillContents,
+ @ConstantParameter Register threadRegister,
+ @ConstantParameter JavaKind knownElementKind,
+ @ConstantParameter int knownLayoutHelper,
+ @ConstantParameter boolean useBulkZeroing,
+ Word prototypeMarkWord,
@ConstantParameter Counters counters) {
- Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind, knownLayoutHelper, prototypeMarkWord, counters);
+ Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, threadRegister, knownElementKind,
+ knownLayoutHelper, useBulkZeroing, prototypeMarkWord, counters);
return result;
}
private static Object allocateArrayDynamicImpl(Class<?> elementType, Class<?> voidClass, int length, boolean fillContents, Register threadRegister, JavaKind knownElementKind,
- int knownLayoutHelper, Word prototypeMarkWord, Counters counters) {
+ int knownLayoutHelper, boolean useBulkZeroing, Word prototypeMarkWord, Counters counters) {
/*
* We only need the dynamic check for void when we have no static information from
* knownElementKind.
@@ -485,7 +514,8 @@
int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift(INJECTED_VMCONFIG)) & layoutHelperHeaderSizeMask(INJECTED_VMCONFIG);
int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
- Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, threadRegister, false, "dynamic type", counters);
+ Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
+ threadRegister, false, "dynamic type", useBulkZeroing, counters);
return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
}
@@ -538,12 +568,15 @@
* @param constantSize is {@code size} known to be constant in the snippet
* @param startOffset offset to begin zeroing. May not be word aligned.
* @param manualUnroll maximally unroll zeroing
+ * @param useBulkZeroing apply bulk zeroing
*/
- private static void zeroMemory(long size, Word memory, boolean constantSize, int startOffset, boolean manualUnroll, Counters counters) {
- fillMemory(0, size, memory, constantSize, startOffset, manualUnroll, counters);
+ private static void zeroMemory(long size, Word memory, boolean constantSize, int startOffset, boolean manualUnroll,
+ boolean useBulkZeroing, Counters counters) {
+ fillMemory(0, size, memory, constantSize, startOffset, manualUnroll, useBulkZeroing, counters);
}
- private static void fillMemory(long value, long size, Word memory, boolean constantSize, int startOffset, boolean manualUnroll, Counters counters) {
+ private static void fillMemory(long value, long size, Word memory, boolean constantSize, int startOffset, boolean manualUnroll,
+ boolean useBulkZeroing, Counters counters) {
ReplacementsUtil.runtimeAssert((size & 0x7) == 0, "unaligned object size");
int offset = startOffset;
if ((offset & 0x7) != 0) {
@@ -571,22 +604,35 @@
} else {
// Use Word instead of int to avoid extension to long in generated code
Word off = WordFactory.signed(offset);
- if (constantSize && ((size - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
- if (theCounters != null && theCounters.instanceSeqInit != null) {
- theCounters.instanceSeqInit.inc();
+ if (useBulkZeroing && probability(SLOW_PATH_PROBABILITY, size >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) {
+ if (theCounters != null && theCounters.instanceBulkInit != null) {
+ theCounters.instanceBulkInit.inc();
}
- explodeLoop();
+ ZeroMemoryNode.zero(memory.add(off), size - offset, LocationIdentity.init());
} else {
- if (theCounters != null && theCounters.instanceLoopInit != null) {
- theCounters.instanceLoopInit.inc();
+ if (constantSize && ((size - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
+ if (theCounters != null && theCounters.instanceSeqInit != null) {
+ theCounters.instanceSeqInit.inc();
+ }
+ explodeLoop();
+ } else {
+ if (theCounters != null && theCounters.instanceLoopInit != null) {
+ theCounters.instanceLoopInit.inc();
+ }
}
- }
- for (; off.rawValue() < size; off = off.add(8)) {
- memory.initializeLong(off, value, LocationIdentity.init());
+ for (; off.rawValue() < size; off = off.add(8)) {
+ memory.initializeLong(off, value, LocationIdentity.init());
+ }
+
}
}
}
+ @Fold
+ static int getMinimalBulkZeroingSize(@InjectedParameter OptionValues optionValues) {
+ return MinimalBulkZeroingSize.getValue(optionValues);
+ }
+
/**
* Fill uninitialized memory with garbage value in a newly allocated object, unrolling as
* necessary and ensuring that stores are aligned.
@@ -598,7 +644,7 @@
* @param manualUnroll maximally unroll zeroing
*/
private static void fillWithGarbage(long size, Word memory, boolean constantSize, int startOffset, boolean manualUnroll, Counters counters) {
- fillMemory(0xfefefefefefefefeL, size, memory, constantSize, startOffset, manualUnroll, counters);
+ fillMemory(0xfefefefefefefefeL, size, memory, constantSize, startOffset, manualUnroll, false, counters);
}
/**
@@ -608,7 +654,7 @@
Word prototypeMarkWord = useBiasedLocking(INJECTED_VMCONFIG) ? hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord;
initializeObjectHeader(memory, prototypeMarkWord, hub);
if (fillContents) {
- zeroMemory(size, memory, constantSize, instanceHeaderSize(INJECTED_VMCONFIG), false, counters);
+ zeroMemory(size, memory, constantSize, instanceHeaderSize(INJECTED_VMCONFIG), false, false, counters);
} else if (REPLACEMENTS_ASSERTIONS_ENABLED) {
fillWithGarbage(size, memory, constantSize, instanceHeaderSize(INJECTED_VMCONFIG), false, counters);
}
@@ -632,7 +678,7 @@
* Formats some allocated memory with an object header and zeroes out the rest.
*/
private static Object formatArray(KlassPointer hub, long allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents, boolean maybeUnroll,
- Counters counters) {
+ boolean useBulkZeroing, Counters counters) {
memory.writeInt(arrayLengthOffset(INJECTED_VMCONFIG), length, LocationIdentity.init());
/*
* store hub last as the concurrent garbage collectors assume length is valid if hub field
@@ -640,7 +686,7 @@
*/
initializeObjectHeader(memory, prototypeMarkWord, hub);
if (fillContents) {
- zeroMemory(allocationSize, memory, false, headerSize, maybeUnroll, counters);
+ zeroMemory(allocationSize, memory, false, headerSize, maybeUnroll, useBulkZeroing, counters);
} else if (REPLACEMENTS_ASSERTIONS_ENABLED) {
fillWithGarbage(allocationSize, memory, false, headerSize, maybeUnroll, counters);
}
@@ -654,12 +700,14 @@
Group newArray = factory.createSnippetCounterGroup("NewArray");
instanceSeqInit = new SnippetCounter(newInstance, "tlabSeqInit", "TLAB alloc with unrolled zeroing");
instanceLoopInit = new SnippetCounter(newInstance, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
+ instanceBulkInit = new SnippetCounter(newArray, "tlabBulkInit", "TLAB alloc with bulk zeroing");
arrayLoopInit = new SnippetCounter(newArray, "tlabLoopInit", "TLAB alloc with zeroing in a loop");
stub = new SnippetCounter(newInstance, "stub", "alloc and zeroing via stub");
}
final SnippetCounter instanceSeqInit;
final SnippetCounter instanceLoopInit;
+ final SnippetCounter instanceBulkInit;
final SnippetCounter arrayLoopInit;
final SnippetCounter stub;
}
@@ -753,6 +801,7 @@
args.addConst("threadRegister", registers.getThreadRegister());
args.addConst("maybeUnroll", length.isConstant());
args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : "");
+ args.addConst("useBulkZeroing", tool.getLowerer().supportBulkZeroing());
args.addConst("counters", counters);
SnippetTemplate template = template(newArrayNode, args);
graph.getDebug().log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args);
@@ -775,7 +824,7 @@
public void lower(DynamicNewArrayNode newArrayNode, HotSpotRegistersProvider registers, LoweringTool tool) {
StructuredGraph graph = newArrayNode.graph();
- Arguments args = new Arguments(allocateArrayDynamic, newArrayNode.graph().getGuardsStage(), tool.getLoweringStage());
+ Arguments args = new Arguments(allocateArrayDynamic, graph.getGuardsStage(), tool.getLoweringStage());
args.add("elementType", newArrayNode.getElementType());
ValueNode voidClass = newArrayNode.getVoidClass();
assert voidClass != null;
@@ -794,6 +843,7 @@
} else {
args.addConst("knownLayoutHelper", 0);
}
+ args.addConst("useBulkZeroing", tool.getLowerer().supportBulkZeroing());
args.add("prototypeMarkWord", lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord());
args.addConst("counters", counters);
SnippetTemplate template = template(newArrayNode, args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java Tue May 07 17:30:14 2019 -0400
@@ -93,6 +93,7 @@
import static org.graalvm.compiler.bytecode.Bytecodes.TABLESWITCH;
import static org.graalvm.compiler.core.common.GraalOptions.SupportJsrBytecodes;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -117,7 +118,7 @@
/**
* Builds a mapping between bytecodes and basic blocks and builds a conservative control flow graph
- * (CFG). It makes one linear passes over the bytecodes to build the CFG where it detects block
+ * (CFG). It makes one linear pass over the bytecodes to build the CFG where it detects block
* headers and connects them.
* <p>
* It also creates exception dispatch blocks for exception handling. These blocks are between a
@@ -477,6 +478,18 @@
}
}
+ private static final class TraversalStep {
+ private BciBlock block;
+ private int currentSuccessorIndex;
+ private long loops;
+
+ private TraversalStep(BciBlock block) {
+ this.block = block;
+ this.currentSuccessorIndex = 0;
+ this.loops = 0;
+ }
+ }
+
/**
* The blocks found in this method, in reverse postorder.
*/
@@ -857,7 +870,7 @@
b.visited = false;
}
- long loop = fixLoopBits(blockMap, blockMap[0]);
+ long loop = fixLoopBits(blockMap[0]);
if (loop != 0) {
// There is a path from a loop end to the method entry that does not pass the loop
@@ -1029,78 +1042,107 @@
}
/**
- * Depth-first traversal of the control flow graph. The flag {@linkplain BciBlock#visited} is
- * used to visit every block only once. The flag {@linkplain BciBlock#active} is used to detect
- * cycles (backward edges).
+ * Non-recursive depth-first traversal of the control flow graph. The flag
+ * {@linkplain BciBlock#visited} is used to visit every block only once. The flag
+ * {@linkplain BciBlock#active} is used to detect cycles (backward edges)
*/
- private long computeBlockOrder(BciBlock block) {
- if (block.visited) {
- if (block.active) {
- // Reached block via backward branch.
- makeLoopHeader(block);
- // Return cached loop information for this block.
- return block.loops;
- } else if (block.isLoopHeader) {
- return block.loops & ~(1L << block.loopId);
+ private long computeBlockOrder(BciBlock initialBlock) {
+ ArrayDeque<TraversalStep> workStack = new ArrayDeque<>();
+ workStack.push(new TraversalStep(initialBlock));
+ while (true) {
+ TraversalStep step = workStack.peek();
+ BciBlock block = step.block;
+ if (step.currentSuccessorIndex == 0) {
+ block.visited = true;
+ block.active = true;
} else {
- return block.loops;
+ BciBlock successor = block.getSuccessor(step.currentSuccessorIndex - 1);
+ if (successor.active) {
+ // Reached block via backward branch.
+ step.loops |= (1L << successor.loopId);
+ }
}
- }
-
- block.visited = true;
- block.active = true;
+ if (step.currentSuccessorIndex < block.successors.size()) {
+ BciBlock successor = block.getSuccessors().get(step.currentSuccessorIndex);
+ if (successor.visited) {
+ if (successor.active) {
+ // Reached block via backward branch.
+ makeLoopHeader(successor);
+ step.loops |= successor.loops;
+ } else if (successor.isLoopHeader) {
+ step.loops |= successor.loops & ~(1L << successor.loopId);
+ } else {
+ step.loops |= successor.loops;
+ }
+ } else {
+ workStack.push(new TraversalStep(successor));
+ }
+ step.currentSuccessorIndex++;
+ } else {
+ // We processed all the successors of this block.
+ block.loops = step.loops;
+ debug.log("computeBlockOrder(%s) -> %x", block, block.loops);
- long loops = 0;
- for (BciBlock successor : block.getSuccessors()) {
- // Recursively process successors.
- loops |= computeBlockOrder(successor);
- if (successor.active) {
- // Reached block via backward branch.
- loops |= (1L << successor.loopId);
+ if (block.isLoopHeader) {
+ step.loops &= ~(1L << block.loopId);
+ }
+
+ block.active = false;
+ blocksNotYetAssignedId--;
+ blocks[blocksNotYetAssignedId] = block;
+
+ workStack.pop();
+ if (!workStack.isEmpty()) {
+ workStack.peek().loops |= step.loops;
+ } else {
+ return step.loops;
+ }
}
}
-
- block.loops = loops;
- debug.log("computeBlockOrder(%s) -> %x", block, block.loops);
-
- if (block.isLoopHeader) {
- loops &= ~(1L << block.loopId);
- }
-
- block.active = false;
- blocksNotYetAssignedId--;
- blocks[blocksNotYetAssignedId] = block;
-
- return loops;
}
- private long fixLoopBits(BciBlock[] blockMap, BciBlock block) {
- if (block.visited) {
- // Return cached loop information for this block.
- if (block.isLoopHeader) {
- return block.loops & ~(1L << block.loopId);
+ private long fixLoopBits(BciBlock initialBlock) {
+ ArrayDeque<TraversalStep> workStack = new ArrayDeque<>();
+ workStack.push(new TraversalStep(initialBlock));
+ while (true) {
+ TraversalStep step = workStack.peek();
+ BciBlock block = step.block;
+ if (step.currentSuccessorIndex == 0) {
+ block.visited = true;
+ step.loops = block.loops;
+ }
+ if (step.currentSuccessorIndex < block.getSuccessors().size()) {
+ BciBlock successor = block.getSuccessors().get(step.currentSuccessorIndex);
+ if (successor.visited) {
+ // Return cached loop information for this block.
+ if (successor.isLoopHeader) {
+ step.loops |= successor.loops & ~(1L << successor.loopId);
+ } else {
+ step.loops |= successor.loops;
+ }
+ } else {
+ workStack.push(new TraversalStep(successor));
+ }
+ step.currentSuccessorIndex++;
} else {
- return block.loops;
+ if (block.loops != step.loops) {
+ loopChanges = true;
+ block.loops = step.loops;
+ debug.log("fixLoopBits0(%s) -> %x", block, block.loops);
+ }
+
+ if (block.isLoopHeader) {
+ step.loops &= ~(1L << block.loopId);
+ }
+
+ workStack.pop();
+ if (!workStack.isEmpty()) {
+ workStack.peek().loops |= step.loops;
+ } else {
+ return step.loops;
+ }
}
}
-
- block.visited = true;
- long loops = block.loops;
- for (BciBlock successor : block.getSuccessors()) {
- // Recursively process successors.
- loops |= fixLoopBits(blockMap, successor);
- }
- if (block.loops != loops) {
- loopChanges = true;
- block.loops = loops;
- debug.log("fixLoopBits0(%s) -> %x", block, block.loops);
- }
-
- if (block.isLoopHeader) {
- loops &= ~(1L << block.loopId);
- }
-
- return loops;
}
public static BciBlockMapping create(BytecodeStream stream, Bytecode code, OptionValues options, DebugContext debug) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64Move.java Tue May 07 17:30:14 2019 -0400
@@ -710,4 +710,71 @@
}
}
+ private abstract static class ZeroNullConversionOp extends AArch64LIRInstruction {
+ @Def({REG, HINT}) protected AllocatableValue result;
+ @Use({REG}) protected AllocatableValue input;
+
+ protected ZeroNullConversionOp(LIRInstructionClass<? extends ZeroNullConversionOp> type, AllocatableValue result, AllocatableValue input) {
+ super(type);
+ this.result = result;
+ this.input = input;
+ }
+
+ @Override
+ public void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
+ Register nullRegister = crb.nullRegister;
+ if (!nullRegister.equals(Register.None)) {
+ emitConversion(asRegister(result), asRegister(input), nullRegister, masm);
+ }
+ }
+
+ protected abstract void emitConversion(Register resultRegister, Register inputRegister, Register nullRegister, AArch64MacroAssembler masm);
+ }
+
+ public static class ConvertNullToZeroOp extends ZeroNullConversionOp {
+ public static final LIRInstructionClass<ConvertNullToZeroOp> TYPE = LIRInstructionClass.create(ConvertNullToZeroOp.class);
+
+ public ConvertNullToZeroOp(AllocatableValue result, AllocatableValue input) {
+ super(TYPE, result, input);
+ }
+
+ @Override
+ protected final void emitConversion(Register resultRegister, Register inputRegister, Register nullRegister, AArch64MacroAssembler masm) {
+ if (inputRegister.equals(resultRegister)) {
+ masm.subs(64, inputRegister, inputRegister, nullRegister);
+ Label done = new Label();
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.EQ, done);
+ masm.add(64, inputRegister, inputRegister, nullRegister);
+ masm.bind(done);
+ } else {
+ masm.subs(64, resultRegister, resultRegister, resultRegister);
+ masm.cmp(64, inputRegister, nullRegister);
+ Label done = new Label();
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.EQ, done);
+ masm.movx(resultRegister, inputRegister);
+ masm.bind(done);
+ }
+ }
+ }
+
+ public static class ConvertZeroToNullOp extends ZeroNullConversionOp {
+ public static final LIRInstructionClass<ConvertZeroToNullOp> TYPE = LIRInstructionClass.create(ConvertZeroToNullOp.class);
+
+ public ConvertZeroToNullOp(AllocatableValue result, AllocatableValue input) {
+ super(TYPE, result, input);
+ }
+
+ @Override
+ protected final void emitConversion(Register resultRegister, Register inputRegister, Register nullRegister, AArch64MacroAssembler masm) {
+ if (!inputRegister.equals(resultRegister)) {
+ masm.movx(resultRegister, inputRegister);
+ }
+ Label done = new Label();
+ masm.ands(64, zr, inputRegister, inputRegister);
+ masm.branchConditionally(AArch64Assembler.ConditionFlag.NE, done);
+ masm.movx(resultRegister, nullRegister);
+ masm.bind(done);
+ }
+ }
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ZeroMemoryOp.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.lir.amd64;
+
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.COMPOSITE;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+
+import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
+import org.graalvm.compiler.core.common.LIRKind;
+import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.Opcode;
+import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
+
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.RegisterValue;
+import jdk.vm.ci.meta.Value;
+
+/**
+ * Zeros a chunk of memory using rep stosb.
+ */
+@Opcode("ZERO_MEMORY")
+public final class AMD64ZeroMemoryOp extends AMD64LIRInstruction {
+
+ public static final LIRInstructionClass<AMD64ZeroMemoryOp> TYPE = LIRInstructionClass.create(AMD64ZeroMemoryOp.class);
+
+ @Use({COMPOSITE}) protected AMD64AddressValue pointer;
+ @Use({REG}) protected RegisterValue length;
+
+ @Temp protected Value pointerTemp;
+ @Temp protected Value valueTemp;
+ @Temp protected Value lengthTemp;
+
+ public AMD64ZeroMemoryOp(AMD64AddressValue pointer, RegisterValue length) {
+ super(TYPE);
+ this.pointer = pointer;
+ this.length = length;
+
+ this.pointerTemp = AMD64.rdi.asValue(LIRKind.value(AMD64Kind.QWORD));
+ this.valueTemp = AMD64.rax.asValue(LIRKind.value(AMD64Kind.QWORD));
+ this.lengthTemp = AMD64.rcx.asValue(LIRKind.value(AMD64Kind.QWORD));
+ }
+
+ @Override
+ public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
+ assert AMD64.rcx.equals(length.getRegister());
+ masm.leaq(AMD64.rdi, pointer.toAddress());
+ masm.xorq(AMD64.rax, AMD64.rax);
+ masm.repStosb();
+ }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/ArithmeticLIRGeneratorTool.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/ArithmeticLIRGeneratorTool.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -132,4 +132,8 @@
throw GraalError.unimplemented("No specialized implementation available");
}
+ @SuppressWarnings("unused")
+ default void emitZeroMemory(Value address, Value length) {
+ throw GraalError.unimplemented("Bulk zeroing is not supported on this platform");
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/PrimitiveStampBoundaryTest.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/PrimitiveStampBoundaryTest.java Tue May 07 17:30:14 2019 -0400
@@ -83,7 +83,7 @@
}
static double[] doubleBoundaryValues = {Double.NEGATIVE_INFINITY, Double.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.MIN_VALUE,
- Long.MIN_VALUE, Long.MIN_VALUE + 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, 0, 1,
+ Long.MIN_VALUE, Long.MIN_VALUE + 1, Integer.MIN_VALUE, Integer.MIN_VALUE + 1, -1, -0.0, +0.0, 1,
Integer.MAX_VALUE - 1, Integer.MAX_VALUE, Long.MAX_VALUE - 1, Long.MAX_VALUE,
Float.MAX_VALUE, Float.POSITIVE_INFINITY, Double.MAX_VALUE, Double.POSITIVE_INFINITY};
@@ -171,11 +171,24 @@
checkConvertOperation(op, op.foldStamp(stamp), upper);
}
}
+
+ }
+
+ static void shouldConstantFold(boolean b, Stamp folded, Object o, Stamp s1) {
+ assertTrue(b || (folded instanceof FloatStamp && ((FloatStamp) folded).contains(0.0)), "should constant fold %s %s %s", o, s1, folded);
+ }
+
+ private static boolean constantFloatStampMayIncludeNegativeZero(Stamp s) {
+ if (s instanceof FloatStamp) {
+ FloatStamp f = (FloatStamp) s;
+ return Double.compare(f.lowerBound(), f.upperBound()) == 0 && f.isNonNaN();
+ }
+ return false;
}
private static void checkConvertOperation(ArithmeticOpTable.FloatConvertOp op, Stamp result, Stamp v1stamp) {
Stamp folded = op.foldStamp(v1stamp);
- assertTrue(folded.isEmpty() || folded.asConstant() != null, "should constant fold %s %s %s", op, v1stamp, folded);
+ shouldConstantFold(folded.isEmpty() || folded.asConstant() != null, folded, op, v1stamp);
assertTrue(result.meet(folded).equals(result), "result out of range %s %s %s %s %s", op, v1stamp, folded, result, result.meet(folded));
}
@@ -216,6 +229,9 @@
}
private static void checkBinaryOperation(ArithmeticOpTable.BinaryOp<?> op, Stamp result, Stamp v1stamp, Stamp v2stamp) {
+ if (constantFloatStampMayIncludeNegativeZero(v1stamp) || constantFloatStampMayIncludeNegativeZero(v2stamp)) {
+ return;
+ }
Stamp folded = op.foldStamp(v1stamp, v2stamp);
if (v1stamp.isEmpty() || v2stamp.isEmpty()) {
assertTrue(folded.isEmpty());
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java Tue May 07 17:30:14 2019 -0400
@@ -84,7 +84,7 @@
IntegerStamp yStamp = (IntegerStamp) forY.stamp(view);
if (constY < 0 && constY != CodeUtil.minValue(yStamp.getBits())) {
Stamp newStamp = IntegerStamp.OPS.getRem().foldStamp(forX.stamp(view), forY.stamp(view));
- return canonical(null, forX, ConstantNode.forIntegerStamp(yStamp, -constY), zeroCheck, newStamp, view, tool);
+ return canonical(self, forX, ConstantNode.forIntegerStamp(yStamp, -constY), zeroCheck, newStamp, view, tool);
}
if (constY == 1) {
@@ -104,10 +104,19 @@
}
}
}
- return self != null ? self : new SignedRemNode(forX, forY, zeroCheck);
+ if (self != null && self.x == forX && self.y == forY) {
+ return self;
+ } else {
+ return new SignedRemNode(forX, forY, zeroCheck);
+ }
}
private static boolean allUsagesCompareAgainstZero(SignedRemNode self) {
+ if (self == null) {
+ // If the node was not yet created, then we do not know its usages yet.
+ return false;
+ }
+
int compareAgainstZero = 0;
int usageCount = self.getUsageCount();
for (int i = 0; i < usageCount; i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ArrayLengthNode.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/ArrayLengthNode.java Tue May 07 17:30:14 2019 -0400
@@ -33,6 +33,7 @@
import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.spi.ArrayLengthProvider;
@@ -44,6 +45,8 @@
import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
import jdk.vm.ci.meta.ConstantReflectionProvider;
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
/**
* The {@code ArrayLength} instruction gets the length of an array.
@@ -83,6 +86,9 @@
@Override
public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
+ if (forValue.isNullConstant()) {
+ return new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
+ }
ValueNode length = readArrayLength(forValue, tool.getConstantReflection());
if (length != null) {
return length;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/LoadIndexedNode.java Tue May 07 17:30:14 2019 -0400
@@ -40,6 +40,7 @@
import org.graalvm.compiler.graph.spi.SimplifierTool;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.ConstantNode;
+import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.FixedGuardNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.LogicNode;
@@ -140,6 +141,9 @@
@Override
public Node canonical(CanonicalizerTool tool) {
+ if (array().isNullConstant()) {
+ return new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
+ }
ValueNode constant = tryConstantFold(array(), index(), tool.getMetaAccess(), tool.getConstantReflection());
if (constant != null) {
return constant;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewInstanceNode.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/NewInstanceNode.java Tue May 07 17:30:14 2019 -0400
@@ -60,7 +60,7 @@
protected NewInstanceNode(NodeClass<? extends NewInstanceNode> c, ResolvedJavaType type, boolean fillContents, FrameState stateBefore) {
super(c, StampFactory.objectNonNull(TypeReference.createExactTrusted(type)), fillContents, stateBefore);
- assert !type.isArray() && !type.isInterface() && !type.isPrimitive() && !type.isAbstract();
+ assert !type.isArray() && !type.isInterface() && !type.isPrimitive() && !type.isAbstract() : type;
this.instanceClass = type;
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreFieldNode.java Tue May 07 17:30:14 2019 -0400
@@ -27,10 +27,14 @@
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.Canonicalizable;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.StateSplit;
import org.graalvm.compiler.nodes.ValueNode;
@@ -39,13 +43,15 @@
import org.graalvm.compiler.nodes.virtual.VirtualInstanceNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
import jdk.vm.ci.meta.ResolvedJavaField;
/**
* The {@code StoreFieldNode} represents a write to a static or instance field.
*/
@NodeInfo(nameTemplate = "StoreField#{p#field/s}")
-public final class StoreFieldNode extends AccessFieldNode implements StateSplit, Virtualizable {
+public final class StoreFieldNode extends AccessFieldNode implements StateSplit, Virtualizable, Canonicalizable {
public static final NodeClass<StoreFieldNode> TYPE = NodeClass.create(StoreFieldNode.class);
@Input ValueNode value;
@@ -111,4 +117,12 @@
}
return super.estimatedNodeCycles();
}
+
+ @Override
+ public Node canonical(CanonicalizerTool tool) {
+ if (!field.isStatic() && object.isNullConstant()) {
+ return new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
+ }
+ return this;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/java/StoreIndexedNode.java Tue May 07 17:30:14 2019 -0400
@@ -29,9 +29,13 @@
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8;
import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.spi.Canonicalizable;
+import org.graalvm.compiler.graph.spi.CanonicalizerTool;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.StateSplit;
import org.graalvm.compiler.nodes.ValueNode;
@@ -43,6 +47,8 @@
import org.graalvm.compiler.nodes.virtual.VirtualArrayNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -50,7 +56,7 @@
* The {@code StoreIndexedNode} represents a write to an array element.
*/
@NodeInfo(cycles = CYCLES_8, size = SIZE_8)
-public final class StoreIndexedNode extends AccessIndexedNode implements StateSplit, Lowerable, Virtualizable {
+public final class StoreIndexedNode extends AccessIndexedNode implements StateSplit, Lowerable, Virtualizable, Canonicalizable {
public static final NodeClass<StoreIndexedNode> TYPE = NodeClass.create(StoreIndexedNode.class);
@@ -110,4 +116,12 @@
public FrameState getState() {
return stateAfter;
}
+
+ @Override
+ public Node canonical(CanonicalizerTool tool) {
+ if (array().isNullConstant()) {
+ return new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
+ }
+ return this;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,4 +54,11 @@
// most platforms only support 32 and 64 bit compares
return 32;
}
+
+ /**
+ * Indicates whether the target platform supports bulk zeroing instruction.
+ */
+ default boolean supportBulkZeroing() {
+ return false;
+ }
}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java Tue May 07 17:30:14 2019 -0400
@@ -88,6 +88,7 @@
import org.graalvm.compiler.nodes.extended.IntegerSwitchNode;
import org.graalvm.compiler.nodes.extended.LoadHubNode;
import org.graalvm.compiler.nodes.extended.ValueAnchorNode;
+import org.graalvm.compiler.nodes.java.InstanceOfNode;
import org.graalvm.compiler.nodes.java.TypeSwitchNode;
import org.graalvm.compiler.nodes.spi.NodeWithState;
import org.graalvm.compiler.nodes.spi.StampInverter;
@@ -364,7 +365,38 @@
node.setCondition(LogicConstantNode.forBoolean(result, node.graph()), node.isNegated());
// Don't kill this branch immediately, see `processGuard`.
}
- debug.log("Kill fixed guard guard");
+
+ if (guard instanceof DeoptimizingGuard && !node.isNegated() && !((DeoptimizingGuard) guard).isNegated()) {
+ LogicNode newCondition = ((DeoptimizingGuard) guard.asNode()).getCondition();
+ if (newCondition instanceof InstanceOfNode) {
+ InstanceOfNode inst = (InstanceOfNode) newCondition;
+ ValueNode originalValue = GraphUtil.skipPi(inst.getValue());
+ PiNode pi = null;
+ // Ensure that any Pi that's weaker than what the instanceof proves is
+ // replaced by one derived from the instanceof itself.
+ for (PiNode existing : guard.asNode().usages().filter(PiNode.class).snapshot()) {
+ if (!existing.isAlive()) {
+ continue;
+ }
+ if (originalValue != GraphUtil.skipPi(existing.object())) {
+ // Somehow these are unrelated values so leave it alone
+ continue;
+ }
+ // If the pi has a weaker stamp or the same stamp but a different input
+ // then replace it.
+ boolean strongerStamp = !existing.piStamp().join(inst.getCheckedStamp()).equals(inst.getCheckedStamp());
+ boolean differentStamp = !existing.piStamp().equals(inst.getCheckedStamp());
+ boolean differentObject = existing.object() != inst.getValue();
+ if (!strongerStamp && (differentStamp || differentObject)) {
+ if (pi == null) {
+ pi = graph.unique(new PiNode(inst.getValue(), inst.getCheckedStamp(), (ValueNode) guard));
+ }
+ existing.replaceAndDelete(pi);
+ }
+ }
+ }
+ }
+ debug.log("Kill fixed guard %s", node);
return true;
})) {
registerNewCondition(node.condition(), node.isNegated(), node);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.printer/src/org/graalvm/compiler/printer/BinaryGraphPrinter.java Tue May 07 17:30:14 2019 -0400
@@ -91,7 +91,7 @@
public BinaryGraphPrinter(DebugContext ctx, SnippetReflectionProvider snippetReflection) throws IOException {
// @formatter:off
this.output = ctx.buildOutput(GraphOutput.newBuilder(this).
- protocolVersion(6, 0).
+ protocolVersion(6, 1).
blocks(this).
elementsAndLocations(this, this).
types(this)
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java Tue May 07 17:30:14 2019 -0400
@@ -59,7 +59,13 @@
public class AArch64GraphBuilderPlugins {
- public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks, boolean registerMathPlugins) {
+ public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
+ boolean registerMathPlugins) {
+ register(plugins, bytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, true);
+ }
+
+ public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
+ boolean registerMathPlugins, boolean emitJDK9StringSubstitutions) {
InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
invocationPlugins.defer(new Runnable() {
@Override
@@ -69,8 +75,10 @@
if (registerMathPlugins) {
registerMathPlugins(invocationPlugins);
}
- registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
- registerStringUTF16Plugins(invocationPlugins, bytecodeProvider);
+ if (emitJDK9StringSubstitutions) {
+ registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
+ registerStringUTF16Plugins(invocationPlugins, bytecodeProvider);
+ }
registerUnsafePlugins(invocationPlugins, bytecodeProvider);
// This is temporarily disabled until we implement correct emitting of the CAS
// instructions of the proper width.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ZeroMemoryNode.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package org.graalvm.compiler.replacements.nodes;
+
+import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
+import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_8;
+
+import org.graalvm.compiler.core.common.type.StampFactory;
+import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.nodeinfo.InputType;
+import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.memory.FixedAccessNode;
+import org.graalvm.compiler.nodes.memory.address.AddressNode;
+import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
+import org.graalvm.compiler.nodes.spi.LIRLowerable;
+import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
+import org.graalvm.compiler.word.Word;
+import jdk.internal.vm.compiler.word.LocationIdentity;
+
+/**
+ * Zeros a chunk of memory.
+ */
+@NodeInfo(nameTemplate = "ZeroMemory#{p#location/s}", allowedUsageTypes = {InputType.Memory}, cycles = CYCLES_8, size = SIZE_8)
+public class ZeroMemoryNode extends FixedAccessNode implements LIRLowerable {
+ public static final NodeClass<ZeroMemoryNode> TYPE = NodeClass.create(ZeroMemoryNode.class);
+
+ @Input ValueNode length;
+
+ public ZeroMemoryNode(ValueNode address, ValueNode length, LocationIdentity locationIdentity) {
+ this(OffsetAddressNode.create(address), length, locationIdentity, BarrierType.NONE);
+ }
+
+ public ZeroMemoryNode(AddressNode address, ValueNode length, LocationIdentity locationIdentity, BarrierType type) {
+ super(TYPE, address, locationIdentity, StampFactory.forVoid(), type);
+ this.length = length;
+ }
+
+ @Override
+ public void generate(NodeLIRBuilderTool gen) {
+ gen.getLIRGeneratorTool().getArithmetic().emitZeroMemory(gen.operand(getAddress()), gen.operand(length));
+ }
+
+ @Override
+ public boolean canNullCheck() {
+ return false;
+ }
+
+ @NodeIntrinsic
+ public static native void zero(Word address, long length, @ConstantNodeParameter LocationIdentity locationIdentity);
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/GraphEffectList.java Tue May 07 17:30:14 2019 -0400
@@ -223,7 +223,7 @@
*/
public void replaceAtUsages(ValueNode node, ValueNode replacement, FixedNode insertBefore) {
assert node != null && replacement != null : node + " " + replacement;
- assert node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " +
+ assert !node.hasUsages() || node.stamp(NodeView.DEFAULT).isCompatible(replacement.stamp(NodeView.DEFAULT)) : "Replacement node stamp not compatible " + node.stamp(NodeView.DEFAULT) + " vs " +
replacement.stamp(NodeView.DEFAULT);
add("replace at usages", (graph, obsoleteNodes) -> {
assert node.isAlive();
@@ -240,7 +240,7 @@
* to improve the stamp information of the read. Such a read might later be replaced
* with a read with a less precise stamp.
*/
- if (!node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) {
+ if (node.hasUsages() && !node.stamp(NodeView.DEFAULT).equals(replacementNode.stamp(NodeView.DEFAULT))) {
replacementNode = graph.unique(new PiNode(replacementNode, node.stamp(NodeView.DEFAULT)));
}
node.replaceAtUsages(replacementNode);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java Fri May 03 14:59:32 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/GraphProtocol.java Tue May 07 17:30:14 2019 -0400
@@ -75,6 +75,9 @@
private static final byte[] MAGIC_BYTES = {'B', 'I', 'G', 'V'};
+ private static final int MAJOR_VERSION = 6;
+ private static final int MINOR_VERSION = 1;
+
private final ConstantPool constantPool;
private final ByteBuffer buffer;
private final WritableByteChannel channel;
@@ -84,7 +87,7 @@
private boolean printing;
GraphProtocol(WritableByteChannel channel, int major, int minor, boolean embedded) throws IOException {
- if (major > 6 || (major == 6 && minor > 0)) {
+ if (major > MAJOR_VERSION || (major == MAJOR_VERSION && minor > MINOR_VERSION)) {
throw new IllegalArgumentException("Unrecognized version " + major + "." + minor);
}
this.versionMajor = major;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.micro.benchmarks/src/micro/benchmarks/ArrayAllocationBenchmark.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package micro.benchmarks;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+
+/**
+ * Benchmarks cost of ArrayList.
+ */
+public class ArrayAllocationBenchmark extends BenchmarkBase {
+
+ @State(Scope.Benchmark)
+ public static class ThreadState {
+ @Param({"128", "256", "512", "1024", "2048", "4096", "8192", "16384", "32768", "65536", "131072"}) int size;
+ byte[] result;
+ }
+
+ @Benchmark
+ @Threads(8)
+ @Warmup(iterations = 10)
+ public void arrayAllocate(ThreadState state) {
+ state.result = new byte[state.size];
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/oops/test_markOop.cpp Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "memory/resourceArea.hpp"
+#include "memory/universe.hpp"
+#include "oops/oop.inline.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
+#include "runtime/synchronizer.hpp"
+#include "threadHelper.inline.hpp"
+#include "unittest.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+
+// The test doesn't work for PRODUCT because it needs WizardMode
+#ifndef PRODUCT
+static bool test_pattern(stringStream* st, const char* pattern) {
+ return (strstr(st->as_string(), pattern) != NULL);
+}
+
+static void assert_test_pattern(Handle object, const char* pattern) {
+ stringStream st;
+ object->print_on(&st);
+ ASSERT_TRUE(test_pattern(&st, pattern)) << pattern << " not in " << st.as_string();
+}
+
+static void assert_not_test_pattern(Handle object, const char* pattern) {
+ stringStream st;
+ object->print_on(&st);
+ ASSERT_FALSE(test_pattern(&st, pattern)) << pattern << " found in " << st.as_string();
+}
+
+class LockerThread : public JavaTestThread {
+ oop _obj;
+ public:
+ LockerThread(Semaphore* post, oop obj) : JavaTestThread(post), _obj(obj) {}
+ virtual ~LockerThread() {}
+
+ void main_run() {
+ Thread* THREAD = Thread::current();
+ HandleMark hm(THREAD);
+ Handle h_obj(THREAD, _obj);
+ ResourceMark rm(THREAD);
+
+ // Wait gets the lock inflated.
+ // The object will stay locked for the context of 'ol' so the lock will
+ // still be inflated after the notify_all() call. Deflation can't happen
+ // while an ObjectMonitor is "busy" and being locked is the most "busy"
+ // state we have...
+ ObjectLocker ol(h_obj, THREAD);
+ ol.notify_all(THREAD);
+ assert_test_pattern(h_obj, "monitor");
+ }
+};
+
+
+TEST_VM(markOopDesc, printing) {
+ JavaThread* THREAD = JavaThread::current();
+ ThreadInVMfromNative invm(THREAD);
+ ResourceMark rm(THREAD);
+
+ oop obj = SystemDictionary::Byte_klass()->allocate_instance(THREAD);
+
+ FlagSetting fs(WizardMode, true);
+ FlagSetting bf(UseBiasedLocking, true);
+
+ HandleMark hm(THREAD);
+ Handle h_obj(THREAD, obj);
+
+ // Biased locking is initially enabled for this java.lang.Byte object.
+ assert_test_pattern(h_obj, "is_biased");
+
+ // Lock using biased locking.
+ BasicObjectLock lock;
+ lock.set_obj(obj);
+ markOop mark = obj->mark()->incr_bias_epoch();
+ obj->set_mark(mark);
+ ObjectSynchronizer::fast_enter(h_obj, lock.lock(), true, THREAD);
+#ifdef _LP64
+ // Look for the biased_locker in markOop, not prototype_header.
+ assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");
+#endif
+
+ // Same thread tries to lock it again.
+ {
+ ObjectLocker ol(h_obj, THREAD);
+ assert_test_pattern(h_obj, "locked");
+ }
+
+ // This is no longer biased, because ObjectLocker revokes the bias.
+ assert_test_pattern(h_obj, "is_neutral no_hash");
+
+ // Wait gets the lock inflated.
+ {
+ ObjectLocker ol(h_obj, THREAD);
+
+ Semaphore done(0);
+ LockerThread* st;
+ st = new LockerThread(&done, h_obj());
+ st->doit();
+
+ ol.wait(THREAD);
+ assert_test_pattern(h_obj, "monitor");
+ }
+
+ // Make the object older. Not all GCs use this field.
+ Universe::heap()->collect(GCCause::_java_lang_system_gc);
+ if (UseParallelGC) {
+ assert_test_pattern(h_obj, "is_neutral no_hash age 1");
+ }
+
+ // Hash the object then print it.
+ intx hash = h_obj->identity_hash();
+ assert_test_pattern(h_obj, "is_neutral hash=0x");
+}
+#endif // PRODUCT
--- a/test/hotspot/jtreg/ProblemList-graal.txt Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/ProblemList-graal.txt Tue May 07 17:30:14 2019 -0400
@@ -210,8 +210,6 @@
serviceability/tmtools/jstat/GcCapacityTest.java 8196611 generic-all
serviceability/jvmti/HeapMonitor/MyPackage/HeapMonitorMultiArrayTest.java 8196611 generic-all
-vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TestDescription.java 8218700 generic-all
-
vmTestbase/nsk/jdb/unmonitor/unmonitor001/unmonitor001.java 8218701 generic-all
vmTestbase/nsk/jdb/clear/clear003/clear003.java 8218701 generic-all
--- a/test/hotspot/jtreg/compiler/c2/cr6340864/TestDoubleVect.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/compiler/c2/cr6340864/TestDoubleVect.java Tue May 07 17:30:14 2019 -0400
@@ -86,6 +86,7 @@
test_divc_n(a0, a1);
test_divv(a0, a1, -VALUE);
test_diva(a0, a1, a3);
+ test_negc(a0, a1);
}
// Test and verify results
System.out.println("Verification");
@@ -339,6 +340,16 @@
for (int i=12; i<ARRLEN; i++) {
errn += verify("test_diva_n: ", i, a0[i], ((ADD_INIT+i)/(-VALUE)));
}
+ test_negc(a0, a1);
+ errn += verify("test_negc: ", 0, a0[0], (Double.NaN));
+ errn += verify("test_negc: ", 1, a0[1], (Double.NEGATIVE_INFINITY));
+ errn += verify("test_negc: ", 2, a0[2], (Double.POSITIVE_INFINITY));
+ errn += verify("test_negc: ", 3, a0[3], (double)(-Double.MAX_VALUE));
+ errn += verify("test_negc: ", 4, a0[4], (double)(-Double.MIN_VALUE));
+ errn += verify("test_negc: ", 5, a0[5], (double)(-Double.MIN_NORMAL));
+ for (int i=6; i<ARRLEN; i++) {
+ errn += verify("test_negc: ", i, a0[i], (double)(-((double)(ADD_INIT+i))));
+ }
}
@@ -469,6 +480,13 @@
end = System.currentTimeMillis();
System.out.println("test_diva_n: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_negc(a0, a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_negc_n: " + (end - start));
+
return errn;
}
@@ -553,6 +571,11 @@
a0[i] = (a1[i]/a2[i]);
}
}
+ static void test_negc(double[] a0, double[] a1) {
+ for (int i = 0; i < a0.length; i+=1) {
+ a0[i] = (double)(-((double)a1[i]));
+ }
+ }
static int verify(String text, int i, double elem, double val) {
if (elem != val && !(Double.isNaN(elem) && Double.isNaN(val))) {
--- a/test/hotspot/jtreg/compiler/c2/cr6340864/TestFloatVect.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/compiler/c2/cr6340864/TestFloatVect.java Tue May 07 17:30:14 2019 -0400
@@ -86,6 +86,7 @@
test_divc_n(a0, a1);
test_divv(a0, a1, -VALUE);
test_diva(a0, a1, a3);
+ test_negc(a0, a1);
}
// Test and verify results
System.out.println("Verification");
@@ -340,6 +341,17 @@
errn += verify("test_diva_n: ", i, a0[i], ((ADD_INIT+i)/(-VALUE)));
}
+ test_negc(a0, a1);
+ errn += verify("test_negc: ", 0, a0[0], (Float.NaN));
+ errn += verify("test_negc: ", 1, a0[1], (Float.NEGATIVE_INFINITY));
+ errn += verify("test_negc: ", 2, a0[2], (Float.POSITIVE_INFINITY));
+ errn += verify("test_negc: ", 3, a0[3], (float)(-Float.MAX_VALUE));
+ errn += verify("test_negc: ", 4, a0[4], (float)(-Float.MIN_VALUE));
+ errn += verify("test_negc: ", 5, a0[5], (float)(-Float.MIN_NORMAL));
+ for (int i=6; i<ARRLEN; i++) {
+ errn += verify("test_negc: ", i, a0[i], (float)(-((float)(ADD_INIT+i))));
+ }
+
}
if (errn > 0)
@@ -469,6 +481,13 @@
end = System.currentTimeMillis();
System.out.println("test_diva_n: " + (end - start));
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_negc(a0, a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_negc_n: " + (end - start));
+
return errn;
}
@@ -554,6 +573,12 @@
}
}
+ static void test_negc(float[] a0, float[] a1) {
+ for (int i = 0; i < a0.length; i+=1) {
+ a0[i] = (float)(-((float)a1[i]));
+ }
+ }
+
static int verify(String text, int i, float elem, float val) {
if (elem != val && !(Float.isNaN(elem) && Float.isNaN(val))) {
System.err.println(text + "[" + i + "] = " + elem + " != " + val);
--- a/test/hotspot/jtreg/compiler/c2/cr6340864/TestIntVect.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/compiler/c2/cr6340864/TestIntVect.java Tue May 07 17:30:14 2019 -0400
@@ -102,6 +102,10 @@
test_xorv(a0, a1, (int)BIT_MASK);
test_xora(a0, a1, a4);
+ test_absc(a0, a1);
+ test_negc(a0, a1);
+ test_notc(a0, a1);
+
test_sllc(a0, a1);
test_sllv(a0, a1, VALUE);
test_srlc(a0, a1);
@@ -276,6 +280,21 @@
errn += verify("test_xora: ", i, a0[i], (int)((int)(ADD_INIT+i)^BIT_MASK));
}
+ test_absc(a0, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_absc: ", i, a0[i], (int)(Math.abs((int)(ADD_INIT+i))));
+ }
+
+ test_negc(a0, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_negc: ", i, a0[i], (int)(-(int)(ADD_INIT+i)));
+ }
+
+ test_notc(a0, a1);
+ for (int i=0; i<ARRLEN; i++) {
+ errn += verify("test_notc: ", i, a0[i], (int)(~(int)(ADD_INIT+i)));
+ }
+
test_sllc(a0, a1);
for (int i=0; i<ARRLEN; i++) {
errn += verify("test_sllc: ", i, a0[i], (int)((int)(ADD_INIT+i)<<VALUE));
@@ -650,6 +669,27 @@
start = System.currentTimeMillis();
for (int i=0; i<ITERS; i++) {
+ test_absc(a0, a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_absc: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_negc(a0, a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_negc: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
+ test_notc(a0, a1);
+ }
+ end = System.currentTimeMillis();
+ System.out.println("test_notc: " + (end - start));
+
+ start = System.currentTimeMillis();
+ for (int i=0; i<ITERS; i++) {
test_sllc(a0, a1);
}
end = System.currentTimeMillis();
@@ -1040,6 +1080,24 @@
}
}
+ static void test_absc(int[] a0, int[] a1) {
+ for (int i = 0; i < a0.length; i+=1) {
+ a0[i] = (int)(Math.abs(a1[i]));
+ }
+ }
+
+ static void test_negc(int[] a0, int[] a1) {
+ for (int i = 0; i < a0.length; i+=1) {
+ a0[i] = (int)(-a1[i]);
+ }
+ }
+
+ static void test_notc(int[] a0, int[] a1) {
+ for (int i = 0; i < a0.length; i+=1) {
+ a0[i] = (int)(~a1[i]);
+ }
+ }
+
static void test_sllc(int[] a0, int[] a1) {
for (int i = 0; i < a0.length; i+=1) {
a0[i] = (int)(a1[i]<<VALUE);
--- a/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java Tue May 07 17:30:14 2019 -0400
@@ -254,7 +254,11 @@
.collect(Collectors.joining(File.pathSeparator));
javaFlags.add("-cp");
- javaFlags.add(String.join(File.pathSeparator, System.getProperty("java.class.path"), graalJarsCP));
+ // Existing classpath returned by System.getProperty("java.class.path") may contain another
+ // version of junit with which the jtreg tool is built. It may be incompatible with required
+ // junit version. So we put graalJarsCP before existing classpath when generating a new one
+ // to avoid incompatibility issues.
+ javaFlags.add(String.join(File.pathSeparator, graalJarsCP, System.getProperty("java.class.path")));
//
javaFlags.add("com.oracle.mxtool.junit.MxJUnitWrapper");
--- a/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java Tue May 07 17:30:14 2019 -0400
@@ -301,7 +301,7 @@
}
public static void writeDebugOutput(byte[] bytes, int offset, int length) {
- CTVM.writeDebugOutput(bytes, offset, length);
+ CTVM.writeDebugOutput(bytes, offset, length, true, true);
}
public static void flushDebugOutput() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotJVMCIRuntime.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot.test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaType;
+
+public class TestHotSpotJVMCIRuntime {
+
+ @Test
+ public void writeDebugOutputTest() {
+ HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
+
+ expectWriteDebugOutputFailure(runtime, null, 0, 0, true, true, NullPointerException.class);
+ expectWriteDebugOutputFailure(runtime, null, 0, 0, true, false, -1);
+
+ byte[] emptyOutput = {};
+ byte[] nonEmptyOutput = String.format("non-empty output%n").getBytes();
+
+ for (boolean canThrow : new boolean[]{true, false}) {
+ for (byte[] output : new byte[][]{emptyOutput, nonEmptyOutput}) {
+ for (int offset = 0; offset < output.length; offset++) {
+ int length = output.length - offset;
+ runtime.writeDebugOutput(output, offset, length, true, canThrow);
+ }
+
+ Object expect = canThrow ? IndexOutOfBoundsException.class : -2;
+ expectWriteDebugOutputFailure(runtime, output, output.length + 1, 0, true, canThrow, expect);
+ expectWriteDebugOutputFailure(runtime, output, 0, output.length + 1, true, canThrow, expect);
+ expectWriteDebugOutputFailure(runtime, output, -1, 0, true, canThrow, expect);
+ expectWriteDebugOutputFailure(runtime, output, 0, -1, true, canThrow, expect);
+ }
+ }
+ }
+
+ private static void expectWriteDebugOutputFailure(HotSpotJVMCIRuntime runtime, byte[] bytes, int offset, int length, boolean flush, boolean canThrow, Object expect) {
+ try {
+ int result = runtime.writeDebugOutput(bytes, offset, length, flush, canThrow);
+ if (expect instanceof Integer) {
+ Assert.assertEquals((int) expect, result);
+ } else {
+ Assert.fail("expected " + expect + ", got " + result + " for bytes == " + Arrays.toString(bytes));
+ }
+ } catch (Exception e) {
+ if (expect instanceof Integer) {
+ Assert.fail("expected " + expect + ", got " + e + " for bytes == " + Arrays.toString(bytes));
+ } else {
+ Assert.assertTrue(e.toString(), ((Class<?>) expect).isInstance(e));
+ }
+ }
+ }
+
+ @Test
+ public void getIntrinsificationTrustPredicateTest() throws Exception {
+ HotSpotJVMCIRuntime runtime = HotSpotJVMCIRuntime.runtime();
+ MetaAccessProvider metaAccess = runtime.getHostJVMCIBackend().getMetaAccess();
+ Predicate<ResolvedJavaType> predicate = runtime.getIntrinsificationTrustPredicate(HotSpotJVMCIRuntime.class);
+ List<Class<?>> classes = new ArrayList<>(Arrays.asList(
+ Object.class,
+ String.class,
+ Class.class,
+ HotSpotJVMCIRuntime.class,
+ VirtualObjectLayoutTest.class,
+ TestHotSpotJVMCIRuntime.class));
+ try {
+ classes.add(Class.forName("com.sun.crypto.provider.AESCrypt"));
+ classes.add(Class.forName("com.sun.crypto.provider.CipherBlockChaining"));
+ } catch (ClassNotFoundException e) {
+ // Extension classes not available
+ }
+ ClassLoader jvmciLoader = HotSpotJVMCIRuntime.class.getClassLoader();
+ ClassLoader extLoader = getExtensionLoader();
+ for (Class<?> c : classes) {
+ ClassLoader cl = c.getClassLoader();
+ boolean expected = cl == null || cl == jvmciLoader || cl == extLoader;
+ boolean actual = predicate.test(metaAccess.lookupJavaType(c));
+ Assert.assertEquals(c + ": cl=" + cl, expected, actual);
+ }
+ }
+
+ private static ClassLoader getExtensionLoader() throws Exception {
+ Object launcher = Class.forName("sun.misc.Launcher").getMethod("getLauncher").invoke(null);
+ ClassLoader appLoader = (ClassLoader) launcher.getClass().getMethod("getClassLoader").invoke(launcher);
+ ClassLoader extLoader = appLoader.getParent();
+ assert extLoader.getClass().getName().equals("sun.misc.Launcher$ExtClassLoader") : extLoader;
+ return extLoader;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestServices.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot.test;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import jdk.vm.ci.services.Services;
+
+public class TestServices {
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void serializeSavedPropertiesTest() throws Exception {
+
+ Field f = Services.class.getDeclaredField("MAX_UTF8_PROPERTY_STRING_LENGTH");
+ f.setAccessible(true);
+ int maxUtf8PropertyStringLength = (int) f.get(null);
+
+ Method serializeProperties = Services.class.getDeclaredMethod("serializeProperties", Map.class);
+ Method deserializeProperties = Services.class.getDeclaredMethod("deserializeProperties", byte[].class);
+ serializeProperties.setAccessible(true);
+ deserializeProperties.setAccessible(true);
+
+ Map<String, String> props = new HashMap<>(Services.getSavedProperties());
+ String[] names = {
+ new String(new char[maxUtf8PropertyStringLength - 100]).replace('\0', 'x'),
+ new String(new char[maxUtf8PropertyStringLength - 1]).replace('\0', 'x'),
+ new String(new char[maxUtf8PropertyStringLength]).replace('\0', 'y'),
+ new String(new char[maxUtf8PropertyStringLength + 1]).replace('\0', 'z'),
+ new String(new char[maxUtf8PropertyStringLength + 100]).replace('\0', 'z')
+ };
+ String[] values = {
+ new String(new char[maxUtf8PropertyStringLength - 100]).replace('\0', '1'),
+ new String(new char[maxUtf8PropertyStringLength - 1]).replace('\0', '1'),
+ new String(new char[maxUtf8PropertyStringLength]).replace('\0', '2'),
+ new String(new char[maxUtf8PropertyStringLength + 1]).replace('\0', '1'),
+ new String(new char[maxUtf8PropertyStringLength + 100]).replace('\0', '3')
+ };
+ for (String name : names) {
+ for (String value : values) {
+ props.put(name, value);
+ }
+ }
+
+ byte[] data = (byte[]) serializeProperties.invoke(null, props);
+
+ Map<String, String> newProps = (Map<String, String>) deserializeProperties.invoke(null, data);
+
+ Assert.assertEquals(props.size(), newProps.size());
+ for (String name : props.keySet()) {
+ String expect = props.get(name);
+ String actual = newProps.get(name);
+ Assert.assertEquals(expect, actual);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/tiered/Level2RecompilationTest.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test Level2RecompilationTest
+ * @summary Test downgrading mechanism from level 3 to level 2 for those profiled methods.
+ * @library /test/lib /
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ *
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ * @run main/othervm -Xbootclasspath/a:. -XX:+TieredCompilation
+ * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-UseCounterDecay
+ * -XX:CompileCommand=compileonly,compiler.whitebox.SimpleTestCaseHelper::*
+ * -XX:CompileCommand=print,compiler.whitebox.SimpleTestCaseHelper::*
+ * compiler.tiered.Level2RecompilationTest
+ */
+
+package compiler.tiered;
+
+import compiler.whitebox.CompilerWhiteBoxTest;
+import jtreg.SkippedException;
+
+public class Level2RecompilationTest extends CompLevelsTest {
+ public static void main(String[] args) throws Throwable {
+ if (CompilerWhiteBoxTest.skipOnTieredCompilation(false)) {
+ throw new SkippedException("Test isn't applicable for non-tiered mode");
+ }
+ String[] testcases = {"METHOD_TEST", "OSR_STATIC_TEST"};
+ CompilerWhiteBoxTest.main(Level2RecompilationTest::new, testcases);
+ }
+
+ protected Level2RecompilationTest(TestCase testCase) {
+ super(testCase);
+ // to prevent inlining of #method
+ WHITE_BOX.testSetDontInlineMethod(method, true);
+ }
+
+ @Override
+ protected void test() throws Exception {
+ if (skipXcompOSR()) {
+ return;
+ }
+
+ checkNotCompiled();
+ int bci = WHITE_BOX.getMethodEntryBci(method);
+ WHITE_BOX.markMethodProfiled(method);
+ if (testCase.isOsr()) {
+ // for OSR compilation, it must be the begin of a BB.
+ // c1_GraphBulider.cpp:153 assert(method()->bci_block_start().at(cur_bci), ...
+ bci = 0;
+ }
+
+ WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_FULL_PROFILE, bci);
+ checkCompiled();
+ checkLevel(COMP_LEVEL_LIMITED_PROFILE, getCompLevel());
+
+ for (int i=0; i<1_000; ++i) {
+ WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_FULL_PROFILE, bci);
+ waitBackgroundCompilation();
+ checkLevel(COMP_LEVEL_LIMITED_PROFILE, getCompLevel());
+ }
+ }
+
+ @Override
+ protected void checkLevel(int expected, int actual) {
+ if (expected == COMP_LEVEL_FULL_PROFILE
+ && actual == COMP_LEVEL_LIMITED_PROFILE) {
+ // for simple method full_profile may be replaced by limited_profile
+ if (IS_VERBOSE) {
+ System.out.printf("Level check: full profiling was replaced "
+ + "by limited profiling. Expected: %d, actual:%d\n",
+ expected, actual);
+ }
+ return;
+ }
+ super.checkLevel(expected, actual);
+ }
+}
+
--- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java Tue May 07 17:30:14 2019 -0400
@@ -119,7 +119,6 @@
new LogMessageWithLevel("SystemDictionary Roots", Level.TRACE),
new LogMessageWithLevel("CLDG Roots", Level.TRACE),
new LogMessageWithLevel("JVMTI Roots", Level.TRACE),
- new LogMessageWithLevel("SATB Filtering", Level.TRACE),
new LogMessageWithLevel("CM RefProcessor Roots", Level.TRACE),
new LogMessageWithLevel("Wait For Strong CLD", Level.TRACE),
new LogMessageWithLevel("Weak CLD Roots", Level.TRACE),
--- a/test/hotspot/jtreg/gc/shenandoah/TestHumongousThreshold.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/gc/shenandoah/TestHumongousThreshold.java Tue May 07 17:30:14 2019 -0400
@@ -26,13 +26,76 @@
* @key gc
* @requires vm.gc.Shenandoah
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:+ShenandoahVerify TestHumongousThreshold
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:ShenandoahHumongousThreshold=50 -XX:+ShenandoahVerify TestHumongousThreshold
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:ShenandoahHumongousThreshold=90 -XX:+ShenandoahVerify TestHumongousThreshold
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:ShenandoahHumongousThreshold=99 -XX:+ShenandoahVerify TestHumongousThreshold
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:ShenandoahHumongousThreshold=100 -XX:+ShenandoahVerify TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:+ShenandoahVerify
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=50
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=90
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=99
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=100
+ * TestHumongousThreshold
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:+ShenandoahVerify
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=50
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=90
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=99
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=100
+ * TestHumongousThreshold
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g -XX:ShenandoahHumongousThreshold=90 -XX:ShenandoahGCHeuristics=aggressive TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=50
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=90
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=99
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=100
+ * TestHumongousThreshold
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=50
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=90
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=99
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:ObjectAlignmentInBytes=16 -XX:+ShenandoahVerify -XX:ShenandoahHumongousThreshold=100
+ * TestHumongousThreshold
+ *
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:ShenandoahHumongousThreshold=90 -XX:ShenandoahGCHeuristics=aggressive
+ * TestHumongousThreshold
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -Xmx1g
+ * -XX:-UseTLAB -XX:ShenandoahHumongousThreshold=90 -XX:ShenandoahGCHeuristics=aggressive
+ * TestHumongousThreshold
*/
import java.util.Random;
--- a/test/hotspot/jtreg/gc/shenandoah/TestStringDedupStress.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/gc/shenandoah/TestStringDedupStress.java Tue May 07 17:30:14 2019 -0400
@@ -30,60 +30,74 @@
* @modules java.base/jdk.internal.misc:open
* @modules java.base/java.lang:open
* java.management
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -DtargetStrings=3000000
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=aggressive -DtargetStrings=2000000
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=aggressive -XX:+ShenandoahOOMDuringEvacALot -DtargetStrings=2000000
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=static -DtargetStrings=4000000
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=compact
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC -DtargetOverwrites=40000000
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
+ * -XX:ShenandoahGCHeuristics=passive -XX:+ShenandoahDegeneratedGC
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC -DtargetOverwrites=40000000
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
+ * -XX:ShenandoahGCHeuristics=passive -XX:-ShenandoahDegeneratedGC
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=traversal
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahUpdateRefsEarly=off -DtargetStrings=3000000
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=compact -XX:ShenandoahUpdateRefsEarly=off -DtargetStrings=2000000
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=aggressive -XX:ShenandoahUpdateRefsEarly=off -DtargetStrings=2000000
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
- * -XX:ShenandoahGCHeuristics=static -XX:ShenandoahUpdateRefsEarly=off -DtargetOverwrites=4000000
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
+ * -XX:ShenandoahGCHeuristics=static -XX:ShenandoahUpdateRefsEarly=off
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=aggressive -XX:ShenandoahUpdateRefsEarly=off -XX:+ShenandoahOOMDuringEvacALot -DtargetStrings=2000000
+ * -Xlog:gc
* TestStringDedupStress
*
- * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx512M -Xlog:gc+stats
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:+UseStringDeduplication -Xmx1g -Xlog:gc+stats
* -XX:ShenandoahGCHeuristics=traversal -XX:+ShenandoahOOMDuringEvacALot -DtargetStrings=2000000
+ * -Xlog:gc
* TestStringDedupStress
*/
@@ -97,9 +111,9 @@
private static Field valueField;
private static Unsafe unsafe;
- private static long TARGET_STRINGS = Long.getLong("targetStrings", 2_500_000);
- private static long TARGET_OVERWRITES = Long.getLong("targetOverwrites", 600_000);
+ private static final int TARGET_STRINGS = Integer.getInteger("targetStrings", 2_500_000);
private static final long MAX_REWRITE_GC_CYCLES = 6;
+ private static final long MAX_REWRITE_TIME = 30*1000; // ms
private static final int UNIQUE_STRINGS = 20;
@@ -151,8 +165,8 @@
}
}
- private static int verifyDedepString(ArrayList<StringAndId> strs) {
- HashMap<Object, StringAndId> seen = new HashMap<>();
+ private static int verifyDedupString(ArrayList<StringAndId> strs) {
+ Map<Object, StringAndId> seen = new HashMap<>(TARGET_STRINGS*2);
int total = 0;
int dedup = 0;
@@ -195,14 +209,16 @@
}
// Generate roughly TARGET_STRINGS strings, only UNIQUE_STRINGS are unique
- long genIters = TARGET_STRINGS / UNIQUE_STRINGS;
- for (long index = 0; index < genIters; index++) {
+ int genIters = TARGET_STRINGS / UNIQUE_STRINGS;
+ for (int index = 0; index < genIters; index++) {
generateStrings(astrs, UNIQUE_STRINGS);
}
long cycleBeforeRewrite = gcCycleMBean.getCollectionCount();
+ long timeBeforeRewrite = System.currentTimeMillis();
- for (long loop = 1; loop < TARGET_OVERWRITES; loop++) {
+ long loop = 1;
+ while (true) {
int arrSize = astrs.size();
int index = rn.nextInt(arrSize);
StringAndId item = astrs.get(index);
@@ -210,13 +226,18 @@
item.str = "Unique String " + n;
item.id = n;
- if (loop % 1000 == 0) {
+ if (loop++ % 1000 == 0) {
// enough GC cycles for rewritten strings to be deduplicated
if (gcCycleMBean.getCollectionCount() - cycleBeforeRewrite >= MAX_REWRITE_GC_CYCLES) {
break;
}
+
+ // enough time is spent waiting for GC to happen
+ if (System.currentTimeMillis() - timeBeforeRewrite >= MAX_REWRITE_TIME) {
+ break;
+ }
}
}
- verifyDedepString(astrs);
+ verifyDedupString(astrs);
}
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter002.java Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadStartRequest/addThreadFilter/addthreadfilter002.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -479,12 +479,25 @@
throws JDITestRuntimeException {
log2("breakpointForCommunication");
- getEventSet();
-
- if (eventIterator.nextEvent() instanceof BreakpointEvent)
- return;
-
- throw new JDITestRuntimeException("** event IS NOT a breakpoint **");
+ while (true) {
+ getEventSet();
+ while (eventIterator.hasNext()) {
+ Event event = eventIterator.nextEvent();
+ if (event instanceof BreakpointEvent) {
+ return;
+ } else if (event instanceof ThreadStartEvent) {
+ // It might be the case that while the thread start request was enabled
+ // some threads not related to the test ( e.g. JVMCI threads) were started
+ // and generated thread start events. We ignore these thread start events
+ // and keep waiting for a breakpoint event.
+ ThreadStartEvent tse = (ThreadStartEvent) event;
+ log2("ThreadStartEvent is received while waiting for a breakpoint" +
+ " event, thread: : " + tse.thread().name());
+ continue;
+ }
+ throw new JDITestRuntimeException("** event IS NOT a breakpoint or a thread start **");
+ }
+ }
}
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach002/attach002Agent00.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach002/attach002Agent00.cpp Tue May 07 17:30:14 2019 -0400
@@ -69,14 +69,14 @@
#define ATTACH002_TARGET_APP_CLASS_NAME "nsk/jvmti/AttachOnDemand/attach002/attach002Target"
void registerNativeMethods(JNIEnv* jni_env) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jclass appClass;
JNINativeMethod nativeMethods[] = {
{ (char*) "agentGotCapabilities", (char*) "()Z", (void*) Java_nsk_jvmti_AttachOnDemand_attach002_attach002Target_agentGotCapabilities } };
jint nativeMethodsNumber = 1;
- appClass = jni->FindClass(ATTACH002_TARGET_APP_CLASS_NAME, TRACE_JNI_CALL);
- jni->RegisterNatives(appClass, nativeMethods, nativeMethodsNumber, TRACE_JNI_CALL);
+ appClass = ec_jni->FindClass(ATTACH002_TARGET_APP_CLASS_NAME, TRACE_JNI_CALL);
+ ec_jni->RegisterNatives(appClass, nativeMethods, nativeMethodsNumber, TRACE_JNI_CALL);
}
void JNICALL classLoadHandler(
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach021/attach021Agent00.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach021/attach021Agent00.cpp Tue May 07 17:30:14 2019 -0400
@@ -89,15 +89,15 @@
}
void registerNativeMethods(JNIEnv* jni_env) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jclass appClass;
JNINativeMethod nativeMethods[] = {
{ (char*) "setTagFor", (char*) "(Ljava/lang/Object;)Z", (void*) Java_nsk_jvmti_AttachOnDemand_attach021_attach021Target_setTagFor },
{ (char*) "shutdownAgent", (char*) "()V", (void*) Java_nsk_jvmti_AttachOnDemand_attach021_attach021Target_shutdownAgent } };
jint nativeMethodsNumber = 2;
- appClass = jni->FindClass(ATTACH021_TARGET_APP_CLASS_NAME, TRACE_JNI_CALL);
- jni->RegisterNatives(appClass, nativeMethods, nativeMethodsNumber, TRACE_JNI_CALL);
+ appClass = ec_jni->FindClass(ATTACH021_TARGET_APP_CLASS_NAME, TRACE_JNI_CALL);
+ ec_jni->RegisterNatives(appClass, nativeMethods, nativeMethodsNumber, TRACE_JNI_CALL);
}
#ifdef STATIC_BUILD
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach022/attach022Agent00.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/AttachOnDemand/attach022/attach022Agent00.cpp Tue May 07 17:30:14 2019 -0400
@@ -98,15 +98,15 @@
#define ATTACH022_TARGET_APP_CLASS_NAME "nsk/jvmti/AttachOnDemand/attach022/attach022Target"
void registerNativeMethods(JNIEnv* jni_env) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jclass appClass;
JNINativeMethod nativeMethods[] = {
{ (char*)"shutdownAgent", (char*)"(I)Z",
(void*) Java_nsk_jvmti_AttachOnDemand_attach022_attach022Target_shutdownAgent } };
jint nativeMethodsNumber = 1;
- appClass = jni->FindClass(ATTACH022_TARGET_APP_CLASS_NAME, TRACE_JNI_CALL);
- jni->RegisterNatives(appClass, nativeMethods, nativeMethodsNumber, TRACE_JNI_CALL);
+ appClass = ec_jni->FindClass(ATTACH022_TARGET_APP_CLASS_NAME, TRACE_JNI_CALL);
+ ec_jni->RegisterNatives(appClass, nativeMethods, nativeMethodsNumber, TRACE_JNI_CALL);
}
void JNICALL vmObjectAllocHandler(jvmtiEnv * jvmti,
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/allocation/AP04/ap04t003/ap04t003.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/allocation/AP04/ap04t003/ap04t003.cpp Tue May 07 17:30:14 2019 -0400
@@ -335,13 +335,13 @@
/** Create thread object for new agent thread. */
static jthread newThreadObj(JNIEnv* jni_env) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jclass thrClass;
jmethodID cid;
- thrClass = jni->FindClass("java/lang/Thread", TRACE_JNI_CALL);
- cid = jni->GetMethodID(thrClass, "<init>", "()V", TRACE_JNI_CALL);
- return jni->NewObject(thrClass, cid, TRACE_JNI_CALL);
+ thrClass = ec_jni->FindClass("java/lang/Thread", TRACE_JNI_CALL);
+ cid = ec_jni->GetMethodID(thrClass, "<init>", "()V", TRACE_JNI_CALL);
+ return ec_jni->NewObject(thrClass, cid, TRACE_JNI_CALL);
}
/***********************************************************************/
@@ -491,12 +491,12 @@
JNIEXPORT void JNICALL
Java_nsk_jvmti_scenarios_allocation_AP04_ap04t003_runIterateOverObjectsReachableFromObject(JNIEnv* jni_env,
jclass klass) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jobject root = NULL;
int modified = 0;
int found = 0;
- root = jni->GetStaticObjectField(debugeeClass, rootFieldID, TRACE_JNI_CALL);
+ root = ec_jni->GetStaticObjectField(debugeeClass, rootFieldID, TRACE_JNI_CALL);
if (!prepareToIteration(jni_env))
return;
@@ -524,7 +524,7 @@
static void JNICALL
agentProc(jvmtiEnv* jvmti, JNIEnv* jni_env, void* arg) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
NSK_DISPLAY0("Wait for debugee start\n\n");
if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
return;
@@ -536,10 +536,10 @@
return;
}
- debugeeClass = (jclass) jni->NewGlobalRef(debugeeClass, TRACE_JNI_CALL);
+ debugeeClass = (jclass) ec_jni->NewGlobalRef(debugeeClass, TRACE_JNI_CALL);
NSK_DISPLAY1("Find ID of 'root' field: %s\n", ROOT_SIGNATURE);
- rootFieldID = jni->GetStaticFieldID(debugeeClass, "root",
+ rootFieldID = ec_jni->GetStaticFieldID(debugeeClass, "root",
ROOT_SIGNATURE, TRACE_JNI_CALL);
NSK_DISPLAY0("Let debugee to run test cases\n");
@@ -550,7 +550,7 @@
if (!NSK_VERIFY(nsk_jvmti_waitForSync(timeout)))
return;
- jni->DeleteGlobalRef(debugeeClass, TRACE_JNI_CALL);
+ ec_jni->DeleteGlobalRef(debugeeClass, TRACE_JNI_CALL);
NSK_TRACE(jvmti->DestroyRawMonitor(counterMonitor_ptr));
NSK_TRACE(jvmti->DestroyRawMonitor(startLock));
NSK_TRACE(jvmti->DestroyRawMonitor(runLock));
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI01/bi01t001/bi01t001.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI01/bi01t001/bi01t001.cpp Tue May 07 17:30:14 2019 -0400
@@ -50,18 +50,18 @@
Java_nsk_jvmti_scenarios_bcinstr_BI01_bi01t001_setNewByteCode(JNIEnv *jni_env,
jobject o,
jbyteArray byteCode) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jbyte* elements;
jboolean isCopy;
- newClassSize = jni->GetArrayLength(byteCode, TRACE_JNI_CALL);
+ newClassSize = ec_jni->GetArrayLength(byteCode, TRACE_JNI_CALL);
if (newClassSize <= 0) {
nsk_jvmti_setFailStatus();
return NSK_FALSE;
}
NSK_DISPLAY1("\t... got array size: %d\n", newClassSize);
- elements = jni->GetByteArrayElements(byteCode, &isCopy, TRACE_JNI_CALL);
+ elements = ec_jni->GetByteArrayElements(byteCode, &isCopy, TRACE_JNI_CALL);
NSK_DISPLAY1("\t... got elements list: 0x%p\n", (void*)elements);
if (!NSK_JVMTI_VERIFY(jvmti->Allocate(newClassSize, &newClassBytes))) {
@@ -78,7 +78,7 @@
NSK_DISPLAY1("\t... copied bytecode: %d bytes\n", (int)newClassSize);
NSK_DISPLAY1("\t... release elements list: 0x%p\n", (void*)elements);
- jni->ReleaseByteArrayElements(byteCode, elements, JNI_ABORT, TRACE_JNI_CALL);
+ ec_jni->ReleaseByteArrayElements(byteCode, elements, JNI_ABORT, TRACE_JNI_CALL);
NSK_DISPLAY0("\t... released\n");
return NSK_TRUE;
}
@@ -92,8 +92,8 @@
JNIEXPORT void JNICALL
Java_nsk_jvmti_scenarios_bcinstr_BI01_bi01t001_setClass(JNIEnv *jni_env,
jobject o, jclass cls) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
- oldClassDef.klass = (jclass) jni->NewGlobalRef(cls, TRACE_JNI_CALL);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
+ oldClassDef.klass = (jclass) ec_jni->NewGlobalRef(cls, TRACE_JNI_CALL);
}
/* ============================================================================= */
@@ -149,7 +149,7 @@
/** Agent algorithm. */
static void JNICALL
agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
- ExceptionCheckingJniEnvPtr jni(agentJNI);
+ ExceptionCheckingJniEnvPtr ec_jni(agentJNI);
/*Wait for debuggee to read new byte codes nsk_jvmti_waitForSync#1*/
NSK_DISPLAY0("Wait for debuggee to read new byte codes nsk_jvmti_waitForSync#1\n");
@@ -210,7 +210,7 @@
if (!nsk_jvmti_waitForSync(timeout))
return;
- jni->DeleteGlobalRef(oldClassDef.klass, TRACE_JNI_CALL);
+ ec_jni->DeleteGlobalRef(oldClassDef.klass, TRACE_JNI_CALL);
NSK_DISPLAY0("Let debuggee to finish\n");
if (!nsk_jvmti_resumeSync())
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI01/bi01t002/bi01t002.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI01/bi01t002/bi01t002.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <string.h>
#include "jvmti.h"
#include "agent_common.h"
+#include "ExceptionCheckingJniEnv.hpp"
#include "jni_tools.h"
#include "jvmti_tools.h"
@@ -51,21 +52,18 @@
Java_nsk_jvmti_scenarios_bcinstr_BI01_bi01t002_setNewByteCode(JNIEnv *jni_env,
jobject o, jint ind, jbyteArray byteCode) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jbyte* elements;
jboolean isCopy;
- newClassSize[ind] = jni_env->GetArrayLength(byteCode);
- if (!NSK_JNI_VERIFY(jni_env, newClassSize[ind] > 0)) {
+ newClassSize[ind] = ec_jni->GetArrayLength(byteCode, TRACE_JNI_CALL);
+ if (!NSK_VERIFY(newClassSize[ind] > 0)) {
nsk_jvmti_setFailStatus();
return NSK_FALSE;
}
NSK_DISPLAY1("\t... got array size: %d\n", newClassSize[ind]);
- elements = jni_env->GetByteArrayElements(byteCode, &isCopy);
- if (!NSK_JNI_VERIFY(jni_env, elements != NULL)) {
- nsk_jvmti_setFailStatus();
- return NSK_FALSE;
- }
+ elements = ec_jni->GetByteArrayElements(byteCode, &isCopy, TRACE_JNI_CALL);
NSK_DISPLAY1("\t... got elements list: 0x%p\n", (void*)elements);
if (!NSK_JVMTI_VERIFY(jvmti->Allocate(newClassSize[ind], &newClassBytes[ind]))) {
@@ -82,7 +80,7 @@
NSK_DISPLAY1("\t... copied bytecode: %d bytes\n", (int)newClassSize[ind]);
NSK_DISPLAY1("\t... release elements list: 0x%p\n", (void*)elements);
- NSK_TRACE(jni_env->ReleaseByteArrayElements(byteCode, elements, JNI_ABORT));
+ NSK_TRACE(ec_jni->ReleaseByteArrayElements(byteCode, elements, JNI_ABORT, TRACE_JNI_CALL));
NSK_DISPLAY0("\t... released\n");
return NSK_TRUE;
}
@@ -97,10 +95,8 @@
Java_nsk_jvmti_scenarios_bcinstr_BI01_bi01t002_setClass(JNIEnv *jni_env,
jobject o, jint ind, jclass cls) {
- oldClassDef[ind].klass = (jclass) jni_env->NewGlobalRef(cls);
- if (!NSK_JNI_VERIFY(jni_env, oldClassDef[ind].klass != NULL)) {
- nsk_jvmti_setFailStatus();
- }
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
+ oldClassDef[ind].klass = (jclass) ec_jni->NewGlobalRef(cls, TRACE_JNI_CALL);
}
/* ============================================================================= */
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI01/bi01t002/libbi01t002.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI01/bi01t002/libbi01t002.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*/
+#include "ExceptionCheckingJniEnv.cpp"
#include "native_thread.cpp"
#include "nsk_tools.cpp"
#include "jni_tools.cpp"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI04/bi04t002/bi04t002.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI04/bi04t002/bi04t002.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <string.h>
#include "jvmti.h"
#include "agent_common.h"
+#include "ExceptionCheckingJniEnv.hpp"
#include "jni_tools.h"
#include "jvmti_tools.h"
@@ -91,23 +92,15 @@
static void JNICALL
agentProc(jvmtiEnv* jvmti, JNIEnv* jni, void* arg) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni);
/*Wait for debuggee to set classes to be redefined nsk_jvmti_waitForSync#4*/
NSK_DISPLAY0("Wait for debuggee to set classes to be redefined nsk_jvmti_waitForSync#4\n");
if (!nsk_jvmti_waitForSync(timeout))
return;
NSK_DISPLAY1("Find class: %s\n", TESTED_CLASS_NAME);
- classDef.klass = jni->FindClass(TESTED_CLASS_NAME);
- if (!NSK_JNI_VERIFY(jni, classDef.klass != NULL)) {
- nsk_jvmti_setFailStatus();
- return;
- }
-
- classDef.klass = (jclass) jni->NewGlobalRef(classDef.klass);
- if (!NSK_JNI_VERIFY(jni, classDef.klass != NULL)) {
- nsk_jvmti_setFailStatus();
- return;
- }
+ classDef.klass = ec_jni->FindClass(TESTED_CLASS_NAME, TRACE_JNI_CALL);
+ classDef.klass = (jclass) ec_jni->NewGlobalRef(classDef.klass, TRACE_JNI_CALL);
NSK_DISPLAY0("Redfine class with new byte code\n");
NSK_DISPLAY3("class definition:\n\t0x%p, 0x%p:%d\n",
@@ -123,7 +116,7 @@
return;
}
- jni->DeleteGlobalRef(classDef.klass);
+ ec_jni->DeleteGlobalRef(classDef.klass, TRACE_JNI_CALL);
if (!nsk_jvmti_resumeSync())
return;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI04/bi04t002/libbi04t002.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/bcinstr/BI04/bi04t002/libbi04t002.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*/
+#include "ExceptionCheckingJniEnv.cpp"
#include "native_thread.cpp"
#include "nsk_tools.cpp"
#include "jni_tools.cpp"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM01/em01t001/em01t001.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM01/em01t001/em01t001.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <string.h>
#include "jvmti.h"
#include "agent_common.h"
+#include "ExceptionCheckingJniEnv.hpp"
#include "jni_tools.h"
#include "jvmti_tools.h"
#include "JVMTITools.h"
@@ -135,17 +136,13 @@
void
threadEventHandler(jvmtiEvent event, jvmtiEnv* jvmti_env, JNIEnv* jni_env,
jthread thread) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jclass classObject;
char *className;
char *generic;
jvmtiPhase phase;
-
- classObject = jni_env->GetObjectClass(thread);
- if (!NSK_JNI_VERIFY(jni_env, classObject != NULL)) {
- nsk_jvmti_setFailStatus();
- return;
- }
+ classObject = ec_jni->GetObjectClass(thread, TRACE_JNI_CALL);
if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(classObject, &className, &generic))) {
nsk_jvmti_setFailStatus();
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM01/em01t001/libem01t001.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM01/em01t001/libem01t001.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*/
+#include "ExceptionCheckingJniEnv.cpp"
#include "native_thread.cpp"
#include "nsk_tools.cpp"
#include "jni_tools.cpp"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM01/em01t002/em01t002.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM01/em01t002/em01t002.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <string.h>
#include "jvmti.h"
#include "agent_common.h"
+#include "ExceptionCheckingJniEnv.hpp"
#include "jni_tools.h"
#include "jvmti_tools.h"
#include "JVMTITools.h"
@@ -61,28 +62,16 @@
JNIEXPORT jclass JNICALL
Java_nsk_jvmti_scenarios_events_EM01_em01t002_loadClass(JNIEnv *jni_env,
jobject o, jobject loader, jstring className) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jclass klass;
jmethodID methodID;
jclass loadedClass;
- klass = jni_env->GetObjectClass(loader);
- if (!NSK_JNI_VERIFY(jni_env, klass != NULL)) {
- nsk_jvmti_setFailStatus();
- return NULL;
- }
-
- methodID = jni_env->GetMethodID(
- klass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
- if (!NSK_JNI_VERIFY(jni_env, methodID != NULL)) {
- nsk_jvmti_setFailStatus();
- return NULL;
- }
-
- loadedClass = (jclass) jni_env->CallObjectMethod(loader, methodID, className);
- if (!NSK_JNI_VERIFY(jni_env, loadedClass != NULL)) {
- nsk_jvmti_setFailStatus();
- return NULL;
- }
+ klass = ec_jni->GetObjectClass(loader, TRACE_JNI_CALL);
+ methodID = ec_jni->GetMethodID(
+ klass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", TRACE_JNI_CALL);
+ loadedClass = (jclass) ec_jni->CallObjectMethod(loader, methodID,
+ TRACE_JNI_CALL_VARARGS(className));
return loadedClass;
}
@@ -93,16 +82,12 @@
* Signature: (Ljava/lang/Class;)Z
*/
JNIEXPORT jboolean JNICALL
-Java_nsk_jvmti_scenarios_events_EM01_em01t002_prepareClass(JNIEnv *jni_env,
+Java_nsk_jvmti_scenarios_events_EM01_em01t002_prepareClass(JNIEnv *jni,
jobject o, jclass klass) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni);
jfieldID fieldID;
- fieldID = jni_env->GetStaticFieldID(klass, "toProvokePreparation", "I");
- if (!NSK_JNI_VERIFY(jni_env, fieldID != NULL)) {
- nsk_jvmti_setFailStatus();
- return NSK_FALSE;
- }
-
+ fieldID = ec_jni->GetStaticFieldID(klass, "toProvokePreparation", "I", TRACE_JNI_CALL);
return NSK_TRUE;
}
@@ -114,26 +99,13 @@
JNIEXPORT jboolean JNICALL
Java_nsk_jvmti_scenarios_events_EM01_em01t002_startThread(JNIEnv *jni_env,
jobject o, jobject thread) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jclass klass;
jmethodID methodID;
- klass = jni_env->GetObjectClass(thread);
- if (!NSK_JNI_VERIFY(jni_env, klass != NULL)) {
- nsk_jvmti_setFailStatus();
- return NSK_FALSE;
- }
-
- methodID = jni_env->GetMethodID(klass, "start", "()V");
- if (!NSK_JNI_VERIFY(jni_env, methodID != NULL)) {
- nsk_jvmti_setFailStatus();
- return NSK_FALSE;
- }
-
- if (!NSK_JNI_VERIFY_VOID(jni_env,jni_env->CallVoidMethod(thread, methodID))) {
- nsk_jvmti_setFailStatus();
- return NSK_FALSE;
- }
-
+ klass = ec_jni->GetObjectClass(thread, TRACE_JNI_CALL);
+ methodID = ec_jni->GetMethodID(klass, "start", "()V", TRACE_JNI_CALL);
+ ec_jni->CallVoidMethod(thread, methodID, TRACE_JNI_CALL);
return NSK_TRUE;
}
@@ -224,17 +196,14 @@
void
threadEventHandler(jvmtiEvent event, jvmtiEnv* jvmti_env, JNIEnv* jni_env,
jthread thread) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jclass classObject;
char *className;
char *generic;
jvmtiPhase phase;
- classObject = jni_env->GetObjectClass(thread);
- if (!NSK_JNI_VERIFY(jni_env, classObject != NULL)) {
- nsk_jvmti_setFailStatus();
- return;
- }
+ classObject = ec_jni->GetObjectClass(thread, TRACE_JNI_CALL);
if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(classObject, &className, &generic))) {
nsk_jvmti_setFailStatus();
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM01/em01t002/libem01t002.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM01/em01t002/libem01t002.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*/
+#include "ExceptionCheckingJniEnv.cpp"
#include "native_thread.cpp"
#include "nsk_tools.cpp"
#include "jni_tools.cpp"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t001/em02t001.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t001/em02t001.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <string.h>
#include "jvmti.h"
#include "agent_common.h"
+#include "ExceptionCheckingJniEnv.hpp"
#include "jni_tools.h"
#include "jvmti_tools.h"
#include "JVMTITools.h"
@@ -102,24 +103,20 @@
getStaticObjField(const char* className, const char* objFieldName,
const char* signature) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni);
jfieldID fieldID;
jclass klass = NULL;
- klass = jni->FindClass(className);
- if (!NSK_JNI_VERIFY(jni, klass != NULL))
- return NULL;
-
- fieldID = jni->GetStaticFieldID(klass, objFieldName, signature);
- if (!NSK_JNI_VERIFY(jni, fieldID != NULL))
- return NULL;
-
- return jni->GetStaticObjectField(klass, fieldID);
+ klass = ec_jni->FindClass(className, TRACE_JNI_CALL);
+ fieldID = ec_jni->GetStaticFieldID(klass, objFieldName, signature, TRACE_JNI_CALL);
+ return ec_jni->GetStaticObjectField(klass, fieldID, TRACE_JNI_CALL);
}
/* ============================================================================= */
static int prepare() {
+ ExceptionCheckingJniEnvPtr ec_jni(jni);
mainThread = findThread(MAIN_THREAD_NAME);
if (!NSK_VERIFY(mainThread != NULL)) {
NSK_COMPLAIN1("<%s> thread not found\n", MAIN_THREAD_NAME);
@@ -127,29 +124,20 @@
}
/* make thread accessable for a long time */
- mainThread = jni->NewGlobalRef(mainThread);
- if (!NSK_JNI_VERIFY(jni, mainThread != NULL))
- return NSK_FALSE;
-
+ mainThread = ec_jni->NewGlobalRef(mainThread, TRACE_JNI_CALL);
startObject = getStaticObjField(DEBUGEE_CLASS_NAME, START_FIELD_NAME, OBJECT_FIELD_SIG);
if (!NSK_VERIFY(startObject != NULL))
return NSK_FALSE;
/*make object accessable for a long time*/
- startObject = jni->NewGlobalRef(startObject);
- if (!NSK_JNI_VERIFY(jni, startObject != NULL))
- return NSK_FALSE;
-
+ startObject = ec_jni->NewGlobalRef(startObject, TRACE_JNI_CALL);
endObject = getStaticObjField(DEBUGEE_CLASS_NAME, END_FIELD_NAME, OBJECT_FIELD_SIG);
if (!NSK_VERIFY(endObject != NULL))
return NSK_FALSE;
/*make object accessable for a long time*/
- endObject = jni->NewGlobalRef(endObject);
- if (!NSK_JNI_VERIFY(jni, endObject != NULL))
- return NSK_FALSE;
-
+ endObject = ec_jni->NewGlobalRef(endObject, TRACE_JNI_CALL);
debuggeeThread = (jthread) getStaticObjField(DEBUGEE_CLASS_NAME,
THREAD_FIELD_NAME,
@@ -158,10 +146,7 @@
return NSK_FALSE;
/* make thread accessable for a long time */
- debuggeeThread = jni->NewGlobalRef(debuggeeThread);
- if (!NSK_JNI_VERIFY(jni, debuggeeThread != NULL))
- return NSK_FALSE;
-
+ debuggeeThread = ec_jni->NewGlobalRef(debuggeeThread, TRACE_JNI_CALL);
return NSK_TRUE;
}
@@ -170,6 +155,7 @@
static int
clean() {
+ ExceptionCheckingJniEnvPtr ec_jni(jni);
/* disable MonitorContendedEnter event */
if (!NSK_JVMTI_VERIFY(
jvmti->SetEventNotificationMode(
@@ -177,10 +163,10 @@
nsk_jvmti_setFailStatus();
/* dispose global references */
- jni->DeleteGlobalRef(startObject);
- jni->DeleteGlobalRef(endObject);
- jni->DeleteGlobalRef(debuggeeThread);
- jni->DeleteGlobalRef(mainThread);
+ ec_jni->DeleteGlobalRef(startObject, TRACE_JNI_CALL);
+ ec_jni->DeleteGlobalRef(endObject, TRACE_JNI_CALL);
+ ec_jni->DeleteGlobalRef(debuggeeThread, TRACE_JNI_CALL);
+ ec_jni->DeleteGlobalRef(mainThread, TRACE_JNI_CALL);
startObject = NULL;
endObject = NULL;
@@ -409,18 +395,19 @@
handlerMC1(jvmtiEvent event, jvmtiEnv* jvmti, JNIEnv* jni_env,
jthread thread, jobject object,
jthread expectedThread, jobject expectedObject) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
if (expectedThread == NULL || expectedObject == NULL)
return;
/* check if event is for tested thread and for tested object */
- if (jni_env->IsSameObject(expectedThread, thread) &&
- jni_env->IsSameObject(expectedObject, object)) {
+ if (ec_jni->IsSameObject(expectedThread, thread, TRACE_JNI_CALL) &&
+ ec_jni->IsSameObject(expectedObject, object, TRACE_JNI_CALL)) {
NSK_DISPLAY1("--->%-40s is received\n", TranslateEvent(event));
showThreadInfo(thread);
- if (jni_env->IsSameObject(expectedObject, endObject))
+ if (ec_jni->IsSameObject(expectedObject, endObject, TRACE_JNI_CALL))
NSK_DISPLAY0("\tobject: 'endingMonitor'\n");
else
NSK_DISPLAY0("\tobject: 'startingMonitor'\n");
@@ -495,18 +482,19 @@
handlerMC2(jvmtiEvent event, jvmtiEnv* jvmti, JNIEnv* jni_env,
jthread thread, jobject object,
jthread expectedThread, jobject expectedObject) {
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
if (expectedThread == NULL || expectedObject == NULL)
return;
/* check if event is for tested thread and for tested object */
- if (jni_env->IsSameObject(expectedThread, thread) &&
- jni_env->IsSameObject(expectedObject, object)) {
+ if (ec_jni->IsSameObject(expectedThread, thread, TRACE_JNI_CALL) &&
+ ec_jni->IsSameObject(expectedObject, object, TRACE_JNI_CALL)) {
NSK_DISPLAY1("--->%-40s is received (new callbacks)\n", TranslateEvent(event));
showThreadInfo(thread);
- if (jni_env->IsSameObject(expectedObject, endObject))
+ if (ec_jni->IsSameObject(expectedObject, endObject, TRACE_JNI_CALL))
NSK_DISPLAY0("\tobject: 'endingMonitor'\n");
else
NSK_DISPLAY0("\tobject: 'startingMonitor'\n");
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t001/libem02t001.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t001/libem02t001.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*/
+#include "ExceptionCheckingJniEnv.cpp"
#include "native_thread.cpp"
#include "nsk_tools.cpp"
#include "jni_tools.cpp"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t010/em02t010.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t010/em02t010.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <string.h>
#include "jvmti.h"
#include "agent_common.h"
+#include "ExceptionCheckingJniEnv.hpp"
#include "jni_tools.h"
#include "jvmti_tools.h"
#include "JVMTITools.h"
@@ -451,6 +452,7 @@
static void JNICALL
agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
+ ExceptionCheckingJniEnvPtr ec_jni(agentJNI);
int i;
jfieldID field_accID, field_modID;
jclass cls;
@@ -459,17 +461,9 @@
if (!nsk_jvmti_waitForSync(timeout))
return;
- cls = agentJNI->FindClass(CLASS_NAME);
- if (!NSK_JNI_VERIFY(agentJNI, cls != NULL))
- return;
-
- field_accID = agentJNI->GetStaticFieldID(cls, FIELD_ACC_NAME, "I");
- if (!NSK_JNI_VERIFY(agentJNI, field_accID != NULL))
- return;
-
- field_modID = agentJNI->GetStaticFieldID(cls, FIELD_MOD_NAME, "I");
- if (!NSK_JNI_VERIFY(agentJNI, field_modID != NULL))
- return;
+ cls = ec_jni->FindClass(CLASS_NAME, TRACE_JNI_CALL);
+ field_accID = ec_jni->GetStaticFieldID(cls, FIELD_ACC_NAME, "I", TRACE_JNI_CALL);
+ field_modID = ec_jni->GetStaticFieldID(cls, FIELD_MOD_NAME, "I", TRACE_JNI_CALL);
if (!NSK_JVMTI_VERIFY(jvmti->SetFieldModificationWatch(cls, field_modID)))
return;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t010/libem02t010.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t010/libem02t010.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*/
+#include "ExceptionCheckingJniEnv.cpp"
#include "native_thread.cpp"
#include "nsk_tools.cpp"
#include "jni_tools.cpp"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t011/em02t011.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t011/em02t011.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <string.h>
#include "jvmti.h"
#include "agent_common.h"
+#include "ExceptionCheckingJniEnv.hpp"
#include "jni_tools.h"
#include "jvmti_tools.h"
#include "JVMTITools.h"
@@ -436,6 +437,7 @@
static void JNICALL
agentProc(jvmtiEnv* jvmti, JNIEnv* agentJNI, void* arg) {
+ ExceptionCheckingJniEnvPtr ec_jni(agentJNI);
int i;
jmethodID methodID;
jclass cls;
@@ -444,13 +446,8 @@
if (!nsk_jvmti_waitForSync(timeout))
return;
- cls = agentJNI->FindClass(CLASS_NAME);
- if (!NSK_JNI_VERIFY(agentJNI, cls != NULL))
- return;
-
- methodID = agentJNI->GetStaticMethodID(cls, METHOD_NAME, "()I");
- if (!NSK_JNI_VERIFY(agentJNI, methodID != NULL))
- return;
+ cls = ec_jni->FindClass(CLASS_NAME, TRACE_JNI_CALL);
+ methodID = ec_jni->GetStaticMethodID(cls, METHOD_NAME, "()I", TRACE_JNI_CALL);
if (!NSK_JVMTI_VERIFY(jvmti->SetBreakpoint(methodID, 0)))
return;
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t011/libem02t011.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t011/libem02t011.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*/
+#include "ExceptionCheckingJniEnv.cpp"
#include "native_thread.cpp"
#include "nsk_tools.cpp"
#include "jni_tools.cpp"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t012/em02t012.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t012/em02t012.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <string.h>
#include "jvmti.h"
#include "agent_common.h"
+#include "ExceptionCheckingJniEnv.hpp"
#include "jni_tools.h"
#include "jvmti_tools.h"
#include "JVMTITools.h"
@@ -48,12 +49,11 @@
/* ============================================================================= */
JNIEXPORT void JNICALL
-Java_nsk_jvmti_scenarios_events_EM02_em02t012_setThread(JNIEnv *jni_env,
+Java_nsk_jvmti_scenarios_events_EM02_em02t012_setThread(JNIEnv *jni,
jobject o, jthread thrd) {
-
+ ExceptionCheckingJniEnvPtr ec_jni(jni);
/* make thread accessable for a long time */
- testedThread = jni_env->NewGlobalRef(thrd);
- NSK_JNI_VERIFY(jni_env, testedThread != NULL);
+ testedThread = ec_jni->NewGlobalRef(thrd, TRACE_JNI_CALL);
}
static void
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t012/libem02t012.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t012/libem02t012.cpp Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
* questions.
*/
+#include "ExceptionCheckingJniEnv.cpp"
#include "native_thread.cpp"
#include "nsk_tools.cpp"
#include "jni_tools.cpp"
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/ExceptionCheckingJniEnv/exceptionjni001/exceptionjni001.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/ExceptionCheckingJniEnv/exceptionjni001/exceptionjni001.cpp Tue May 07 17:30:14 2019 -0400
@@ -79,69 +79,69 @@
}
static bool checkSuccess(JNIEnv* env, jclass cls) {
- ExceptionCheckingJniEnvPtr jni(env, ErrorCheckerMessage);
+ ExceptionCheckingJniEnvPtr ec_jni(env, ErrorCheckerMessage);
is_error_called = false;
- jni->GetFieldID(cls, "anInteger", "I", TRACE_JNI_CALL);
+ ec_jni->GetFieldID(cls, "anInteger", "I", TRACE_JNI_CALL);
return !is_error_called;
}
static bool checkFailureMessageReturnNull(JNIEnv* env, jclass cls) {
- ExceptionCheckingJniEnvPtr jni(env, ErrorCheckerMessage);
+ ExceptionCheckingJniEnvPtr ec_jni(env, ErrorCheckerMessage);
expected_message_start = null_return_expected_message_start;
expected_line_number = __LINE__ + 1;
- jni->GetFieldID(cls, "whatever", "does not matter", TRACE_JNI_CALL);
+ ec_jni->GetFieldID(cls, "whatever", "does not matter", TRACE_JNI_CALL);
return is_error_called && error_message_ok;
}
static bool checkFailureMessageEmptyFile(JNIEnv* env, jclass cls) {
- ExceptionCheckingJniEnvPtr jni(env, ErrorCheckerMessage);
+ ExceptionCheckingJniEnvPtr ec_jni(env, ErrorCheckerMessage);
expected_message_start = null_file_expected_message_start;
expected_line_number = __LINE__ + 1;
- jni->GetFieldID(cls, "whatever", "does not matter", __LINE__, NULL);
+ ec_jni->GetFieldID(cls, "whatever", "does not matter", __LINE__, NULL);
return is_error_called && error_message_ok;
}
static bool checkFailureMessageNilLine(JNIEnv* env, jclass cls) {
- ExceptionCheckingJniEnvPtr jni(env, ErrorCheckerMessage);
+ ExceptionCheckingJniEnvPtr ec_jni(env, ErrorCheckerMessage);
expected_message_start = null_return_expected_message_start;
expected_line_number = 0;
- jni->GetFieldID(cls, "whatever", "does not matter", 0, __FILE__);
+ ec_jni->GetFieldID(cls, "whatever", "does not matter", 0, __FILE__);
return is_error_called && error_message_ok;
}
static bool checkFailureMessageNegativeLine(JNIEnv* env, jclass cls) {
- ExceptionCheckingJniEnvPtr jni(env, ErrorCheckerMessage);
+ ExceptionCheckingJniEnvPtr ec_jni(env, ErrorCheckerMessage);
expected_message_start = null_return_expected_message_start;
expected_line_number = -1;
- jni->GetFieldID(cls, "whatever", "does not matter", -1, __FILE__);
+ ec_jni->GetFieldID(cls, "whatever", "does not matter", -1, __FILE__);
return is_error_called && error_message_ok;
}
static bool checkFailureMessageMinLine(JNIEnv* env, jclass cls) {
- ExceptionCheckingJniEnvPtr jni(env, ErrorCheckerMessage);
+ ExceptionCheckingJniEnvPtr ec_jni(env, ErrorCheckerMessage);
expected_message_start = null_return_expected_message_start;
expected_line_number = INT32_MIN;
- jni->GetFieldID(cls, "whatever", "does not matter", INT32_MIN, __FILE__);
+ ec_jni->GetFieldID(cls, "whatever", "does not matter", INT32_MIN, __FILE__);
return is_error_called && error_message_ok;
}
static bool checkFailureMessageMaxLine(JNIEnv* env, jclass cls) {
- ExceptionCheckingJniEnvPtr jni(env, ErrorCheckerMessage);
+ ExceptionCheckingJniEnvPtr ec_jni(env, ErrorCheckerMessage);
expected_message_start = null_return_expected_message_start;
expected_line_number = INT32_MAX;
- jni->GetFieldID(cls, "whatever", "does not matter", INT32_MAX, __FILE__);
+ ec_jni->GetFieldID(cls, "whatever", "does not matter", INT32_MAX, __FILE__);
return is_error_called && error_message_ok;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/BooleanArrayCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/BooleanArrayCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,7 +37,7 @@
*/
JNIEXPORT jboolean JNICALL Java_nsk_share_gc_lock_jni_BooleanArrayCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jbooleanArray arr;
@@ -46,18 +46,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- arr = (jbooleanArray) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ arr = (jbooleanArray) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetArrayLength(arr, TRACE_JNI_CALL);
+ size = ec_jni->GetArrayLength(arr, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- pa = (jboolean*) jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
+ pa = (jboolean*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash ^= pa[i];
@@ -65,11 +65,11 @@
hash = JNI_FALSE;
}
mssleep((long) sleepTime);
- jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
+ ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/ByteArrayCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/ByteArrayCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -36,7 +36,7 @@
*/
JNIEXPORT jbyte JNICALL Java_nsk_share_gc_lock_jni_ByteArrayCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jbyteArray arr;
@@ -45,18 +45,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- arr = (jbyteArray) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ arr = (jbyteArray) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetArrayLength(arr, TRACE_JNI_CALL);
+ size = ec_jni->GetArrayLength(arr, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- pa = (jbyte*) jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
+ pa = (jbyte*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash ^= pa[i];
@@ -64,11 +64,11 @@
hash = 0;
}
mssleep((long) sleepTime);
- jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
+ ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/CharArrayCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/CharArrayCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,7 +37,7 @@
*/
JNIEXPORT jchar JNICALL Java_nsk_share_gc_lock_jni_CharArrayCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jcharArray arr;
@@ -46,18 +46,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- arr = (jcharArray) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ arr = (jcharArray) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetArrayLength(arr, TRACE_JNI_CALL);
+ size = ec_jni->GetArrayLength(arr, TRACE_JNI_CALL);
start_time = time(NULL);
current_time = 0;
enterTime /= 1000;
while (current_time - start_time < enterTime) {
- pa = (jchar*) jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
+ pa = (jchar*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash ^= pa[i];
@@ -65,11 +65,11 @@
hash = 0;
}
mssleep((long) sleepTime);
- jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
+ ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/DoubleArrayCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/DoubleArrayCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,7 +37,7 @@
*/
JNIEXPORT jdouble JNICALL Java_nsk_share_gc_lock_jni_DoubleArrayCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jdoubleArray arr;
@@ -46,18 +46,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- arr = (jdoubleArray) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ arr = (jdoubleArray) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetArrayLength(arr, TRACE_JNI_CALL);
+ size = ec_jni->GetArrayLength(arr, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- pa = (jdouble*) jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
+ pa = (jdouble*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash += pa[i];
@@ -65,11 +65,11 @@
hash = 0;
}
mssleep((long) sleepTime);
- jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
+ ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/FloatArrayCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/FloatArrayCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,7 +37,7 @@
*/
JNIEXPORT jfloat JNICALL Java_nsk_share_gc_lock_jni_FloatArrayCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jfloatArray arr;
@@ -46,18 +46,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- arr = (jfloatArray) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ arr = (jfloatArray) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetArrayLength(arr, TRACE_JNI_CALL);
+ size = ec_jni->GetArrayLength(arr, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- pa = (jfloat*) jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
+ pa = (jfloat*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash += pa[i];
@@ -65,11 +65,11 @@
hash = 0;
}
mssleep((long) sleepTime);
- jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
+ ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/IntArrayCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/IntArrayCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,7 +37,7 @@
*/
JNIEXPORT jint JNICALL Java_nsk_share_gc_lock_jni_IntArrayCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jintArray arr;
@@ -46,18 +46,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- arr = (jintArray) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ arr = (jintArray) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetArrayLength(arr, TRACE_JNI_CALL);
+ size = ec_jni->GetArrayLength(arr, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- pa = (jint*) jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
+ pa = (jint*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash ^= pa[i];
@@ -65,11 +65,11 @@
hash = 0;
}
mssleep((long) sleepTime);
- jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
+ ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/LongArrayCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/LongArrayCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,7 +37,7 @@
*/
JNIEXPORT jlong JNICALL Java_nsk_share_gc_lock_jni_LongArrayCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jlongArray arr;
@@ -46,18 +46,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- arr = (jlongArray) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ arr = (jlongArray) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetArrayLength(arr, TRACE_JNI_CALL);
+ size = ec_jni->GetArrayLength(arr, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- pa = (jlong*) jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
+ pa = (jlong*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash ^= pa[i];
@@ -65,11 +65,11 @@
hash = 0;
}
mssleep((long) sleepTime);
- jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
+ ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/ShortArrayCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/ShortArrayCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,7 +37,7 @@
*/
JNIEXPORT jshort JNICALL Java_nsk_share_gc_lock_jni_ShortArrayCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jshortArray arr;
@@ -46,18 +46,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- arr = (jshortArray) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ arr = (jshortArray) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetArrayLength(arr, TRACE_JNI_CALL);
+ size = ec_jni->GetArrayLength(arr, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- pa = (jshort*) jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
+ pa = (jshort*) ec_jni->GetPrimitiveArrayCritical(arr, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash ^= pa[i];
@@ -65,11 +65,11 @@
hash = 0;
}
mssleep((long) sleepTime);
- jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
+ ec_jni->ReleasePrimitiveArrayCritical(arr, pa, 0, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, arr, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/StringCriticalLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jni/StringCriticalLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,7 +37,7 @@
*/
JNIEXPORT jchar JNICALL Java_nsk_share_gc_lock_jni_StringCriticalLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jsize size, i;
jstring str;
@@ -46,18 +46,18 @@
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- str = (jstring) jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ str = (jstring) ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
- size = jni->GetStringLength(str, TRACE_JNI_CALL);
+ size = ec_jni->GetStringLength(str, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- pa = jni->GetStringCritical(str, NULL, TRACE_JNI_CALL);
+ pa = ec_jni->GetStringCritical(str, NULL, TRACE_JNI_CALL);
if (pa != NULL) {
for (i = 0; i < size; ++i)
hash ^= pa[i];
@@ -65,11 +65,11 @@
hash = JNI_FALSE;
}
mssleep((long) sleepTime);
- jni->ReleaseStringCritical(str, pa, TRACE_JNI_CALL);
+ ec_jni->ReleaseStringCritical(str, pa, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, str, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, str, TRACE_JNI_CALL);
return hash;
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jniref/JNIGlobalRefLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jniref/JNIGlobalRefLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -38,29 +38,29 @@
*/
JNIEXPORT void JNICALL Java_nsk_share_gc_lock_jniref_JNIGlobalRefLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jobject obj;
jobject gref;
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- obj = jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ obj = ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- gref = jni->NewGlobalRef(obj, TRACE_JNI_CALL);
+ gref = ec_jni->NewGlobalRef(obj, TRACE_JNI_CALL);
mssleep((long) sleepTime);
- jni->DeleteGlobalRef(gref, TRACE_JNI_CALL);
+ ec_jni->DeleteGlobalRef(gref, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, obj, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, obj, TRACE_JNI_CALL);
}
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jniref/JNILocalRefLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jniref/JNILocalRefLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,29 +37,29 @@
*/
JNIEXPORT void JNICALL Java_nsk_share_gc_lock_jniref_JNILocalRefLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jobject obj;
jobject gref;
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- obj = jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ obj = ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- gref = jni->NewLocalRef(obj, TRACE_JNI_CALL);
+ gref = ec_jni->NewLocalRef(obj, TRACE_JNI_CALL);
mssleep((long) sleepTime);
- jni->DeleteLocalRef(gref, TRACE_JNI_CALL);
+ ec_jni->DeleteLocalRef(gref, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, obj, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, obj, TRACE_JNI_CALL);
}
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jniref/JNIRefLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jniref/JNIRefLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,35 +37,35 @@
*/
JNIEXPORT void JNICALL Java_nsk_share_gc_lock_jniref_JNIRefLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jobject obj;
jobject gref, lref, gwref;
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- obj = jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ obj = ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- gref = jni->NewGlobalRef(obj, TRACE_JNI_CALL);
- lref = jni->NewLocalRef(obj, TRACE_JNI_CALL);
- gwref = jni->NewWeakGlobalRef(obj, TRACE_JNI_CALL);
+ gref = ec_jni->NewGlobalRef(obj, TRACE_JNI_CALL);
+ lref = ec_jni->NewLocalRef(obj, TRACE_JNI_CALL);
+ gwref = ec_jni->NewWeakGlobalRef(obj, TRACE_JNI_CALL);
mssleep((long) sleepTime);
- jni->DeleteGlobalRef(gref, TRACE_JNI_CALL);
- jni->DeleteLocalRef(lref, TRACE_JNI_CALL);
- jni->DeleteWeakGlobalRef(gwref, TRACE_JNI_CALL);
+ ec_jni->DeleteGlobalRef(gref, TRACE_JNI_CALL);
+ ec_jni->DeleteLocalRef(lref, TRACE_JNI_CALL);
+ ec_jni->DeleteWeakGlobalRef(gwref, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, obj, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, obj, TRACE_JNI_CALL);
}
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jniref/JNIWeakGlobalRefLocker.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/lock/jniref/JNIWeakGlobalRefLocker.cpp Tue May 07 17:30:14 2019 -0400
@@ -37,30 +37,30 @@
*/
JNIEXPORT void JNICALL Java_nsk_share_gc_lock_jniref_JNIWeakGlobalRefLocker_criticalNative
(JNIEnv *jni_env, jobject o, jlong enterTime, jlong sleepTime) {
- ExceptionCheckingJniEnvPtr jni(jni_env);
+ ExceptionCheckingJniEnvPtr ec_jni(jni_env);
jobject obj;
jobject gref;
time_t start_time, current_time;
if (objFieldId == NULL) {
- jclass klass = jni->GetObjectClass(o, TRACE_JNI_CALL);
- objFieldId = jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
+ jclass klass = ec_jni->GetObjectClass(o, TRACE_JNI_CALL);
+ objFieldId = ec_jni->GetFieldID(klass, "obj", "Ljava/lang/Object;", TRACE_JNI_CALL);
}
- obj = jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
- jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
+ obj = ec_jni->GetObjectField(o, objFieldId, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, NULL, TRACE_JNI_CALL);
start_time = time(NULL);
enterTime /= 1000;
current_time = 0;
while (current_time - start_time < enterTime) {
- gref = jni->NewWeakGlobalRef(obj, TRACE_JNI_CALL);
+ gref = ec_jni->NewWeakGlobalRef(obj, TRACE_JNI_CALL);
mssleep((long) sleepTime);
- jni->DeleteWeakGlobalRef(gref, TRACE_JNI_CALL);
+ ec_jni->DeleteWeakGlobalRef(gref, TRACE_JNI_CALL);
mssleep((long) sleepTime);
current_time = time(NULL);
}
- jni->SetObjectField(o, objFieldId, obj, TRACE_JNI_CALL);
+ ec_jni->SetObjectField(o, objFieldId, obj, TRACE_JNI_CALL);
}
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jni/ExceptionCheckingJniEnv.cpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jni/ExceptionCheckingJniEnv.cpp Tue May 07 17:30:14 2019 -0400
@@ -426,6 +426,17 @@
return marker.ResultNotNull(_jni_env->GetMethodID(klass, name, sig));
}
+jmethodID ExceptionCheckingJniEnv::GetStaticMethodID(jclass klass, const char* name, const char* sig,
+ int line, const char* file_name) {
+ JNIVerifier<jmethodID> marker(this, "GetStaticMethodID", klass, name, sig, line, file_name);
+ return marker.ResultNotNull(_jni_env->GetStaticMethodID(klass, name, sig));
+}
+
+jboolean ExceptionCheckingJniEnv::IsSameObject(jobject ref1, jobject ref2, int line, const char* file_name) {
+ JNIVerifier<> marker(this, "IsSameObject", ref1, ref2, line, file_name);
+ return _jni_env->IsSameObject(ref1, ref2);
+}
+
jobject ExceptionCheckingJniEnv::NewObject(jclass klass, jmethodID methodID,
int line, const char* file_name, ...) {
// In the case of NewObject, we miss the extra arguments passed to NewObject sadly.
@@ -437,3 +448,24 @@
va_end(args);
return result;
}
+
+jobject ExceptionCheckingJniEnv::CallObjectMethod(jobject obj, jmethodID methodID, int line,
+ const char* file_name, ...) {
+ JNIVerifier<> marker(this, "CallObjectMethod", obj, methodID, line, file_name);
+
+ va_list args;
+ va_start(args, file_name);
+ jobject result = _jni_env->CallObjectMethodV(obj, methodID, args);
+ va_end(args);
+ return result;
+}
+
+void ExceptionCheckingJniEnv::CallVoidMethod(jobject obj, jmethodID methodID, int line,
+ const char* file_name, ...) {
+ JNIVerifier<> marker(this, "CallVoidMethod", obj, methodID, line, file_name);
+
+ va_list args;
+ va_start(args, file_name);
+ _jni_env->CallVoidMethodV(obj, methodID, args);
+ va_end(args);
+}
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jni/ExceptionCheckingJniEnv.hpp Fri May 03 14:59:32 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jni/ExceptionCheckingJniEnv.hpp Tue May 07 17:30:14 2019 -0400
@@ -59,6 +59,7 @@
*/
#define TRACE_JNI_CALL __LINE__, __FILE__
+#define TRACE_JNI_CALL_VARARGS(...) __LINE__, __FILE__, __VA_ARGS__
class ExceptionCheckingJniEnv {
public:
@@ -69,6 +70,8 @@
int line, const char* file_name);
jfieldID GetFieldID(jclass klass, const char* name, const char* type,
int line, const char* file_name);
+ jmethodID GetStaticMethodID(jclass klass, const char* name, const char* sig,
+ int line, const char* file_name);
jmethodID GetMethodID(jclass klass, const char* name, const char* sig,
int line, const char* file_name);
@@ -106,6 +109,14 @@
jweak NewWeakGlobalRef(jobject obj, int line, const char* file_name);
void DeleteWeakGlobalRef(jweak obj, int line, const char* file_name);
+ jboolean IsSameObject(jobject ref1, jobject ref2, int line,
+ const char* file_name);
+
+ jobject CallObjectMethod(jobject obj, jmethodID methodID, int line,
+ const char* file_name, ...);
+ void CallVoidMethod(jobject obj, jmethodID methodID, int line,
+ const char* file_name, ...);
+
// ExceptionCheckingJniEnv methods.
JNIEnv* GetJNIEnv() {
return _jni_env;
--- a/test/jdk/java/lang/String/LiteralReplace.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/java/lang/String/LiteralReplace.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 8058779 8054307
+ * @bug 8058779 8054307 8222955
* @library /test/lib
* @build jdk.test.lib.RandomFactory
* @run testng LiteralReplace
@@ -79,6 +79,10 @@
source.replace(target, replacement);
}
+ @Test(expectedExceptions = {OutOfMemoryError.class})
+ public void testOOM() {
+ "1".repeat(65537).replace("1", "2".repeat(65537));
+ }
@DataProvider
public static Object[][] sourceTargetReplacementExpected() {
@@ -104,6 +108,14 @@
{"abcdefgh", "[a-h]", "X", "abcdefgh"},
{"aa+", "a+", "", "a"},
{"^abc$", "abc", "x", "^x$"},
+ {"abc", "b", "_", "a_c"},
+ {"abc", "bc", "_", "a_"},
+ {"abc".repeat(65537) + "end", "b", "_XYZ_", "a_XYZ_c".repeat(65537) + "end"},
+ {"abc".repeat(65537) + "end", "a", "_", "_bc".repeat(65537) + "end"},
+ {"a".repeat(65537), "a", "", ""},
+ {"ab".repeat(65537), "a", "", "b".repeat(65537)},
+ {"ab".repeat(65537), "ab", "", ""},
+ {"b" + "ab".repeat(65537), "ab", "", "b"},
// more with non-latin1 characters
{"\u4e00\u4e00\u4e00",
@@ -207,6 +219,42 @@
"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05",
"",
""},
+
+ {"\u4e01\u4e02\u4e03", "\u4e02", "\u4e02", "\u4e01\u4e02\u4e03"},
+ {"\u4e01\u4e02\u4e03", "\u4e02", "\u4e04", "\u4e01\u4e04\u4e03"},
+ {"\u4e01\u4e02\u4e03", "\u4e02", "_", "\u4e01_\u4e03"},
+ {"a\u4e02c", "\u4e02", "_", "a_c"},
+ {"\u4e01@\u4e03", "@", "_", "\u4e01_\u4e03"},
+ {"\u4e01@\u4e03", "@", "\u4e02", "\u4e01\u4e02\u4e03"},
+ {"\u4e01\u4e02\u4e03", "\u4e02\u4e03", "\u4e02\u4e03", "\u4e01\u4e02\u4e03"},
+ {"\u4e01\u4e02\u4e03", "\u4e02\u4e03", "\u4e04\u4e05", "\u4e01\u4e04\u4e05"},
+ {"\u4e01\u4e02\u4e03", "\u4e02\u4e03", "\u4e06", "\u4e01\u4e06"},
+ {"\u4e01\u4e02\u4e03", "\u4e02\u4e03", "<>", "\u4e01<>"},
+ {"@\u4e02\u4e03", "\u4e02\u4e03", "<>", "@<>"},
+ {"\u4e01@@", "\u4e01@", "", "@"},
+ {"\u4e01@@", "\u4e01@", "#", "#@"},
+ {"\u4e01@@", "\u4e01@", "\u4e09", "\u4e09@"},
+ {"\u4e01@@", "\u4e01@", "#\u4e09", "#\u4e09@"},
+ {"\u4e01\u4e02\u4e03".repeat(32771) + "end", "\u4e02", "\u4e02", "\u4e01\u4e02\u4e03".repeat(32771) + "end"},
+ {"\u4e01\u4e02\u4e03".repeat(32771) + "end", "\u4e02", "\u4e04", "\u4e01\u4e04\u4e03".repeat(32771) + "end"},
+ {"\u4e01\u4e02\u4e03".repeat(32771) + "end", "\u4e02", "\u4e04\u4e05", "\u4e01\u4e04\u4e05\u4e03".repeat(32771) + "end"},
+ {"\u4e01\u4e02\u4e03".repeat(32771) + "end", "\u4e02", "_", "\u4e01_\u4e03".repeat(32771) + "end"},
+ {"\u4e01_\u4e03".repeat(32771) + "end", "_", "_", "\u4e01_\u4e03".repeat(32771) + "end"},
+ {"\u4e01_\u4e03".repeat(32771) + "end", "_", "\u4e06", "\u4e01\u4e06\u4e03".repeat(32771) + "end"},
+ {"\u4e01_\u4e03".repeat(32771) + "end", "_", "\u4e06\u4e06", "\u4e01\u4e06\u4e06\u4e03".repeat(32771) + "end"},
+ {"X_Y".repeat(32771) + "end", "_", "\u4e07", "X\u4e07Y".repeat(32771) + "end"},
+ {"X_Y".repeat(32771) + "end", "_", "\u4e07\u4e08", "X\u4e07\u4e08Y".repeat(32771) + "end"},
+ {"X_Y".repeat(32771) + "end", "_", ".\u4e08.", "X.\u4e08.Y".repeat(32771) + "end"},
+ {"\u4e0a".repeat(32771), "\u4e0a", "", ""},
+ {"\u4e0a\u4e0b".repeat(32771), "\u4e0a", "", "\u4e0b".repeat(32771)},
+ {"\u4e0a\u4e0b".repeat(32771), "\u4e0b", "", "\u4e0a".repeat(32771)},
+ {"\u4e0a\u4e0b".repeat(32771), "\u4e0a\u4e0b", "", ""},
+ {"\u4e0b" + "\u4e0a\u4e0b".repeat(32771), "\u4e0a\u4e0b", "", "\u4e0b"},
+ {"\u4e0a\u4e0b".repeat(32771) + "\u4e0a", "\u4e0a\u4e0b", "", "\u4e0a"},
+ {"\u4e0b" + "\u4e0a\u4e0b".repeat(32771) + "\u4e0a", "\u4e0a\u4e0b", "", "\u4e0b\u4e0a"},
+ {"b" + "\u4e0a\u4e0b".repeat(32771), "\u4e0a\u4e0b", "", "b"},
+ {"\u4e0a\u4e0b".repeat(32771) + "a", "\u4e0a\u4e0b", "", "a"},
+ {"b" + "\u4e0a\u4e0b".repeat(32771) + "a", "\u4e0a\u4e0b", "", "ba"},
};
}
--- a/test/jdk/java/lang/constant/ClassDescTest.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/java/lang/constant/ClassDescTest.java Tue May 07 17:30:14 2019 -0400
@@ -306,4 +306,28 @@
assertEquals(s.resolveConstantDesc(LOOKUP), s);
assertEquals(s.describeConstable().get(), s);
}
+
+ public void testNullNestedClasses() {
+ ClassDesc cd = ClassDesc.of("Bar");
+ try {
+ cd.nested(null);
+ fail("");
+ } catch (NullPointerException e) {
+ // good
+ }
+
+ try {
+ cd.nested("good", null);
+ fail("");
+ } catch (NullPointerException e) {
+ // good
+ }
+
+ try {
+ cd.nested("good", "goodToo", null);
+ fail("");
+ } catch (NullPointerException e) {
+ // good
+ }
+ }
}
--- a/test/jdk/java/net/ServerSocket/AcceptInheritHandle.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/java/net/ServerSocket/AcceptInheritHandle.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
import java.net.*;
import java.nio.channels.ServerSocketChannel;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
@@ -41,8 +42,8 @@
enum ServerSocketProducer {
JAVA_NET(() -> {
try {
- return new ServerSocket(); }
- catch(IOException x) {
+ return new ServerSocket();
+ } catch(IOException x) {
throw new UncheckedIOException(x);
}
}),
@@ -86,13 +87,13 @@
test(ServerSocketProducer.NIO_CHANNELS);
}
- static void test(ServerSocketProducer ssp, String... sysProps) throws Exception {
+ static void test(ServerSocketProducer ssp, String... jvmArgs) throws Exception {
System.out.println("\nStarting test for " + ssp.name());
List<String> commands = new ArrayList<>();
commands.add(JAVA);
- for (String prop : sysProps)
- commands.add(prop);
+ for (String arg : jvmArgs)
+ commands.add(arg);
commands.add("-cp");
commands.add(CLASSPATH);
commands.add("AcceptInheritHandle");
@@ -107,7 +108,14 @@
int port = dis.readInt();
System.out.println("Server process listening on " + port + ", connecting...");
- Socket socket = new Socket("localhost", port);
+ String address;
+ if (Arrays.stream(jvmArgs).anyMatch("-Djava.net.preferIPv4Stack=true"::equals)) {
+ address = "127.0.0.1";
+ } else {
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ address = loopback.getHostAddress();
+ }
+ Socket socket = new Socket(address, port);
String s = dis.readUTF();
System.out.println("Server process said " + s);
@@ -128,7 +136,8 @@
static void server(ServerSocketProducer producer) throws Exception {
try (ServerSocket ss = producer.supplier().get()) {
- ss.bind(new InetSocketAddress(0));
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ ss.bind(new InetSocketAddress(loopback, 0));
int port = ss.getLocalPort();
DataOutputStream dos = new DataOutputStream(System.out);
dos.writeInt(port);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/ServerSocket/NullConstructor.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8223457
+ * @run main NullConstructor
+ * @summary java.net.ServerSocket protected constructor should throw NPE if impl null
+ */
+
+import java.net.ServerSocket;
+import java.net.SocketImpl;
+
+public class NullConstructor {
+
+ public static void main(String args[]) throws Exception {
+ try {
+ ServerSocket server = new ServerSocket((SocketImpl)null) {};
+ throw new RuntimeException("Test failed");
+ } catch (NullPointerException ee) {}
+ }
+}
--- a/test/jdk/java/net/URLConnection/Responses.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/java/net/URLConnection/Responses.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,9 @@
public HttpServer() {
try {
- ss = new ServerSocket(0);
+ InetAddress loopback = InetAddress.getLoopbackAddress();
+ ss = new ServerSocket();
+ ss.bind(new InetSocketAddress(loopback, 0));
} catch (IOException ioe) {
throw new Error("Unable to create ServerSocket: " + ioe);
}
@@ -70,6 +72,16 @@
return ss.getLocalPort();
}
+ public String authority() {
+ InetAddress address = ss.getInetAddress();
+ String hostaddr = address.isAnyLocalAddress()
+ ? "localhost" : address.getHostAddress();
+ if (hostaddr.indexOf(':') > -1) {
+ hostaddr = "[" + hostaddr + "]";
+ }
+ return hostaddr + ":" + port();
+ }
+
public void shutdown() throws IOException {
ss.close();
}
@@ -116,7 +128,8 @@
HttpServer svr = new HttpServer();
(new Thread(svr)).start();
- int port = svr.port();
+ String authority = svr.authority();
+ System.out.println("Server listening on: " + authority);
/*
* Iterate through each test case and check that getResponseCode
@@ -129,7 +142,7 @@
System.out.println("******************");
System.out.println("Test with response: >" + tests[i][0] + "<");
- URL url = new URL("http://localhost:" + port + "/" + i);
+ URL url = new URL("http://" + authority + "/" + i);
HttpURLConnection http = (HttpURLConnection)url.openConnection();
try {
--- a/test/jdk/java/net/ipv6tests/TcpTest.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/java/net/ipv6tests/TcpTest.java Tue May 07 17:30:14 2019 -0400
@@ -25,7 +25,9 @@
* @test
* @bug 4868820
* @key intermittent
- * @summary IPv6 support for Windows XP and 2003 server
+ * @summary IPv6 support for Windows XP and 2003 server. This test requires
+ * binding to the wildcard address, and as such is susceptible
+ * of intermittent failures caused by port reuse policy.
* @library /test/lib
* @build jdk.test.lib.NetworkConfiguration
* jdk.test.lib.Platform
@@ -216,4 +218,3 @@
System.out.println ("Test4: OK");
}
}
-
--- a/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/java/util/TimeZone/CLDRDisplayNamesTest.java Tue May 07 17:30:14 2019 -0400
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8005471 8008577 8129881 8130845 8136518 8181157 8210490
+ * @bug 8005471 8008577 8129881 8130845 8136518 8181157 8210490 8220037
* @modules jdk.localedata
* @run main/othervm -Djava.locale.providers=CLDR CLDRDisplayNamesTest
* @summary Make sure that localized time zone names of CLDR are used
@@ -130,13 +130,10 @@
System.err.printf("Wrong display name for timezone Etc/GMT-5 : expected GMT+05:00, Actual " + displayName);
errors++;
}
- if (errors > 0) {
- throw new RuntimeException("test failed");
- }
// 8217366: No "no inheritance marker" should be left in the returned array
// from DateFormatSymbols.getZoneStrings()
- List.of(Locale.ROOT,
+ errors += List.of(Locale.ROOT,
Locale.CHINA,
Locale.GERMANY,
Locale.JAPAN,
@@ -149,11 +146,26 @@
.flatMap(zoneStrings -> Arrays.stream(zoneStrings))
.filter(namesArray -> Arrays.stream(namesArray)
.anyMatch(aName -> aName.equals(NO_INHERITANCE_MARKER)))
- .findAny()
- .ifPresentOrElse(marker -> {
- throw new RuntimeException("No inheritance marker detected with tzid: "
+ .peek(marker -> {
+ System.err.println("No-inheritance-marker is detected with tzid: "
+ marker[0]);
- },
- () -> System.out.println("Success: No \"no inheritance marker\" detected."));
+ })
+ .count();
+
+ // 8220037: Make sure CLDRConverter uniquely produces bundles, regardless of the
+ // source file enumeration order.
+ tz = TimeZone.getTimeZone("America/Argentina/La_Rioja");
+ if (!"ARST".equals(tz.getDisplayName(true, TimeZone.SHORT,
+ new Locale.Builder()
+ .setLanguage("en")
+ .setRegion("CA")
+ .build()))) {
+ System.err.println("Short display name of \"" + tz.getID() + "\" was not \"ARST\"");
+ errors++;
+ }
+
+ if (errors > 0) {
+ throw new RuntimeException("test failed");
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/regex/NegativeArraySize.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8223174
+ * @summary Pattern.compile() can throw confusing NegativeArraySizeException
+ * @requires os.maxMemory >= 5g
+ * @run main/othervm NegativeArraySize -Xms5G -Xmx5G
+ */
+
+import java.util.regex.Pattern;
+
+public class NegativeArraySize {
+ public static void main(String[] args) {
+ try {
+ Pattern.compile("\\Q" + "a".repeat(42 + Integer.MAX_VALUE / 3));
+ throw new AssertionError("expected to throw");
+ } catch (OutOfMemoryError expected) {
+ }
+ }
+}
--- a/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/jdk/jfr/event/gc/collection/TestG1ParallelPhases.java Tue May 07 17:30:14 2019 -0400
@@ -100,7 +100,6 @@
"CMRefRoots",
"WaitForStrongCLD",
"WeakCLDRoots",
- "SATBFiltering",
"UpdateRS",
"ScanHCC",
"ScanRS",
--- a/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/jdk/modules/etc/JdkQualifiedExportTest.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -71,6 +71,9 @@
static Set<String> KNOWN_EXCEPTIONS =
Set.of("jdk.internal.vm.ci/jdk.vm.ci.services",
"jdk.internal.vm.ci/jdk.vm.ci.runtime",
+ "jdk.internal.vm.ci/jdk.vm.ci.hotspot",
+ "jdk.internal.vm.ci/jdk.vm.ci.meta",
+ "jdk.internal.vm.ci/jdk.vm.ci.code",
"jdk.jsobject/jdk.internal.netscape.javascript.spi");
static void checkExports(ModuleDescriptor md) {
--- a/test/jdk/sun/net/ftp/FtpURL.java Fri May 03 14:59:32 2019 -0400
+++ b/test/jdk/sun/net/ftp/FtpURL.java Tue May 07 17:30:14 2019 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,8 +36,8 @@
*/
private class FtpServer extends Thread {
- private ServerSocket server;
- private int port;
+ private final ServerSocket server;
+ private final int port;
private boolean done = false;
private boolean portEnabled = true;
private boolean pasvEnabled = true;
@@ -253,8 +253,12 @@
continue;
}
try {
- if (pasv == null)
- pasv = new ServerSocket(0);
+ if (pasv == null) {
+ // Not sure how to support PASV mode over
+ // IPv6
+ pasv = new ServerSocket();
+ pasv.bind(new InetSocketAddress("127.0.0.1", 0));
+ }
int port = pasv.getLocalPort();
out.println("227 Entering Passive Mode (127,0,0,1," +
(port >> 8) + "," + (port & 0xff) +")");
@@ -369,21 +373,39 @@
}
public FtpServer(int port) {
+ this(InetAddress.getLoopbackAddress(), port);
+ }
+
+ public FtpServer(InetAddress address, int port) {
this.port = port;
try {
- server = new ServerSocket(port);
+ if (address == null) {
+ server = new ServerSocket(port);
+ } else {
+ server = new ServerSocket();
+ server.bind(new InetSocketAddress(address, port));
+ }
} catch (IOException e) {
+ throw new UncheckedIOException(e);
}
}
public FtpServer() {
- this(21);
+ this(null, 21);
}
public int getPort() {
- if (server != null)
- return server.getLocalPort();
- return 0;
+ return server.getLocalPort();
+ }
+
+ public String getAuthority() {
+ InetAddress address = server.getInetAddress();
+ String hostaddr = address.isAnyLocalAddress()
+ ? "localhost" : address.getHostAddress();
+ if (hostaddr.indexOf(':') > -1) {
+ hostaddr = "[" + hostaddr +"]";
+ }
+ return hostaddr + ":" + getPort();
}
/**
@@ -449,15 +471,17 @@
}
public FtpURL() throws Exception {
- FtpServer server = new FtpServer(0);
+ FtpServer server = new FtpServer(InetAddress.getLoopbackAddress(), 0);
BufferedReader in = null;
try {
server.start();
- int port = server.getPort();
+ String authority = server.getAuthority();
+ System.out.println("FTP server waiting for connections at: " + authority);
+ assert authority != null;
// Now let's check the URL handler
- URL url = new URL("ftp://user:password@localhost:" + port + "/%2Fetc/motd;type=a");
+ URL url = new URL("ftp://user:password@" + authority + "/%2Fetc/motd;type=a");
URLConnection con = url.openConnection();
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String s;
@@ -479,11 +503,10 @@
// We're done!
// Second URL test
- port = server.getPort();
// Now let's check the URL handler
- url = new URL("ftp://user2@localhost:" + port + "/%2Fusr/bin;type=d");
+ url = new URL("ftp://user2@" + authority + "/%2Fusr/bin;type=d");
con = url.openConnection();
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
do {
--- a/test/lib/sun/hotspot/WhiteBox.java Fri May 03 14:59:32 2019 -0400
+++ b/test/lib/sun/hotspot/WhiteBox.java Tue May 07 17:30:14 2019 -0400
@@ -330,6 +330,7 @@
return enqueueInitializerForCompilation0(aClass, compLevel);
}
private native void clearMethodState0(Executable method);
+ public native void markMethodProfiled(Executable method);
public void clearMethodState(Executable method) {
Objects.requireNonNull(method);
clearMethodState0(method);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/StringReplace.java Tue May 07 17:30:14 2019 -0400
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.*;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Benchmark)
+public class StringReplace {
+
+ public String slat1 = new String("java.lang.String");
+ public String sutf16 = new String("\u1D36\u1D43\u1D5B\u1D43 \uFF11\uFF13");
+
+ @Benchmark
+ public String replace0x1_1_Latin1() {
+ return slat1.replace("Z", "z");
+ }
+
+ @Benchmark
+ public String replace1x1_0_Latin1() {
+ return slat1.replace("g", "");
+ }
+
+ @Benchmark
+ public String replace1x1_1_Latin1() {
+ return slat1.replace("g", "k");
+ }
+
+ @Benchmark
+ public String replace1x1_2_Latin1() {
+ return slat1.replace("g", "th");
+ }
+
+ @Benchmark
+ public String replace2x1_0_Latin1() {
+ return slat1.replace(".", "");
+ }
+
+ @Benchmark
+ public String replace2x1_1_Latin1() {
+ return slat1.replace(".", "/");
+ }
+
+ @Benchmark
+ public String replace2x1_2_Latin1() {
+ return slat1.replace(".", "::");
+ }
+
+ @Benchmark
+ public String replace0x1_1_UTF16() {
+ return sutf16.replace("\u1D36", "\u1D38\u1D3A");
+ }
+
+ @Benchmark
+ public String replace1x1_0_UTF16() {
+ return sutf16.replace("\uFF11", "");
+ }
+
+ @Benchmark
+ public String replace1x1_1_UTF16() {
+ return sutf16.replace("\u1D36", "\u24BF");
+ }
+
+ @Benchmark
+ public String replace1x1_2_UTF16() {
+ return sutf16.replace("\uFF11", "\uFF11\uFF12");
+ }
+
+ @Benchmark
+ public String replace2x1_0_UTF16() {
+ return sutf16.replace("\u1D43", "");
+ }
+
+ @Benchmark
+ public String replace2x1_1_UTF16() {
+ return sutf16.replace("\u1D43", "\u1D2C");
+ }
+
+ @Benchmark
+ public String replace2x1_2_UTF16() {
+ return sutf16.replace("\u1D43", "\u21DB\u21DB");
+ }
+}