--- a/.hgtags Sun Feb 03 08:16:08 2019 -0500
+++ b/.hgtags Mon Feb 04 15:00:29 2019 -0500
@@ -538,3 +538,5 @@
659b004b6a1bd8c31e766cbdf328d8f8473fd4d7 jdk-12+28
e3ed960609927b5fdfd0a797159835cd83a81a31 jdk-13+5
44f41693631f9b5ac78ff4d2bfabd6734fe46df2 jdk-12+29
+b5f05fe4a6f8b3996a000c20078b356d991ca8ec jdk-13+6
+6c377af36a5c4203f16aed8a5e4c2ecc08fcd8bd jdk-12+30
--- a/make/GenerateLinkOptData.gmk Sun Feb 03 08:16:08 2019 -0500
+++ b/make/GenerateLinkOptData.gmk Mon Feb 04 15:00:29 2019 -0500
@@ -59,6 +59,8 @@
INTERIM_IMAGE_DIR := $(BUILD_JDK)
endif
+# Save the stderr output of the command and print it along with stdout in case
+# something goes wrong.
$(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/bin/java$(EXE_SUFFIX) $(CLASSLIST_JAR)
$(call MakeDir, $(LINK_OPT_DIR))
$(call LogInfo, Generating $(patsubst $(OUTPUTDIR)/%, %, $@))
@@ -67,7 +69,14 @@
-Djava.lang.invoke.MethodHandle.TRACE_RESOLVE=true \
-cp $(SUPPORT_OUTPUTDIR)/classlist.jar \
build.tools.classlist.HelloClasslist \
- $(LOG_DEBUG) 2>&1 > $(JLI_TRACE_FILE)
+ 2> $(LINK_OPT_DIR)/stderr > $(JLI_TRACE_FILE) \
+ || ( \
+ exitcode=$$? ; \
+ $(ECHO) "ERROR: Failed to generate link optimization data." \
+ "This is likely a problem with the newly built JVM/JDK." ; \
+ $(CAT) $(LINK_OPT_DIR)/stderr $(JLI_TRACE_FILE) ; \
+ exit $$exitcode \
+ )
$(GREP) -v HelloClasslist $@.raw > $@
# The jli trace is created by the same recipe as classlist. By declaring these
--- a/make/autoconf/build-performance.m4 Sun Feb 03 08:16:08 2019 -0500
+++ b/make/autoconf/build-performance.m4 Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2016, 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
@@ -42,8 +42,11 @@
NUM_CORES=`/usr/sbin/sysctl -n hw.ncpu`
FOUND_CORES=yes
elif test "x$OPENJDK_BUILD_OS" = xaix ; then
- NUM_CORES=`/usr/sbin/prtconf | grep "^Number Of Processors" | awk '{ print [$]4 }'`
- FOUND_CORES=yes
+ NUM_LCPU=`lparstat -m 2> /dev/null | $GREP -o "lcpu=[[0-9]]*" | $CUT -d "=" -f 2`
+ if test -n "$NUM_LCPU"; then
+ NUM_CORES=$NUM_LCPU
+ FOUND_CORES=yes
+ fi
elif test -n "$NUMBER_OF_PROCESSORS"; then
# On windows, look in the env
NUM_CORES=$NUMBER_OF_PROCESSORS
--- a/make/autoconf/lib-freetype.m4 Sun Feb 03 08:16:08 2019 -0500
+++ b/make/autoconf/lib-freetype.m4 Mon Feb 04 15:00:29 2019 -0500
@@ -92,7 +92,7 @@
# This setup is to verify access to system installed freetype header and libraries.
# On Windows and MacOS this does not apply and using these options will report an error.
- # On other platforms (Linux, Solaris, and perhaps AIX), they will default to using
+ # On other platforms (Linux, Solaris), they will default to using
# the system libraries. If they are found automatically, nothing need be done.
# If they are not found, the configure "--with-freetype-*" options may be used to fix that.
# If the preference is to bundle on these platforms then use --with-freetype=bundled
@@ -106,7 +106,8 @@
fi
FREETYPE_TO_USE=bundled
- if (test "x$OPENJDK_TARGET_OS" != "xwindows" && test "x$OPENJDK_TARGET_OS" != "xmacosx"); then
+ if (test "x$OPENJDK_TARGET_OS" != "xwindows" && test "x$OPENJDK_TARGET_OS" != "xmacosx" \
+ && test "x$OPENJDK_TARGET_OS" != "xaix"); then
FREETYPE_TO_USE=system
fi
if (test "x$with_freetype" != "x"); then
--- a/make/conf/jib-profiles.js Sun Feb 03 08:16:08 2019 -0500
+++ b/make/conf/jib-profiles.js Mon Feb 04 15:00:29 2019 -0500
@@ -861,7 +861,7 @@
var getJibProfilesDependencies = function (input, common) {
var devkit_platform_revisions = {
- linux_x64: "gcc7.3.0-OEL6.4+1.2",
+ linux_x64: "gcc7.3.0-OEL6.4+1.1",
macosx_x64: "Xcode9.4-MacOSX10.13+1.0",
solaris_x64: "SS12u4-Solaris11u1+1.0",
solaris_sparcv9: "SS12u6-Solaris11u3+1.0",
--- a/make/data/lsrdata/language-subtag-registry.txt Sun Feb 03 08:16:08 2019 -0500
+++ b/make/data/lsrdata/language-subtag-registry.txt Mon Feb 04 15:00:29 2019 -0500
@@ -1,4 +1,4 @@
-File-Date: 2018-10-31
+File-Date: 2018-11-30
%%
Type: language
Subtag: aa
@@ -593,6 +593,7 @@
Type: language
Subtag: lg
Description: Ganda
+Description: Luganda
Added: 2005-10-16
%%
Type: language
--- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -34,7 +34,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/monitorChunk.hpp"
-#include "runtime/os.hpp"
+#include "runtime/os.inline.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
--- a/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/cpu/aarch64/templateTable_aarch64.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -2720,7 +2720,7 @@
{
Label notVolatile;
__ tbz(r5, ConstantPoolCacheEntry::is_volatile_shift, notVolatile);
- __ membar(MacroAssembler::StoreStore);
+ __ membar(MacroAssembler::StoreStore | MacroAssembler::LoadStore);
__ bind(notVolatile);
}
--- a/src/hotspot/cpu/arm/frame_arm.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/cpu/arm/frame_arm.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -32,6 +32,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/monitorChunk.hpp"
+#include "runtime/os.inline.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
--- a/src/hotspot/cpu/ppc/frame_ppc.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/cpu/ppc/frame_ppc.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -34,6 +34,7 @@
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/monitorChunk.hpp"
+#include "runtime/os.inline.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
--- a/src/hotspot/cpu/s390/frame_s390.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/cpu/s390/frame_s390.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -32,6 +32,7 @@
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/monitorChunk.hpp"
+#include "runtime/os.inline.hpp"
#include "runtime/signature.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -4219,7 +4219,7 @@
// save F48:F54 in temp registers
__ movdtox(F54,G2);
__ movdtox(F52,G3);
- __ movdtox(F50,G6);
+ __ movdtox(F50,L6);
__ movdtox(F48,G1);
for ( int i = 46; i >= 14; i -= 8 ) {
__ aes_dround23(as_FloatRegister(i), F0, F2, F4);
@@ -4247,7 +4247,7 @@
// re-init F48:F54 with their original values
__ movxtod(G2,F54);
__ movxtod(G3,F52);
- __ movxtod(G6,F50);
+ __ movxtod(L6,F50);
__ movxtod(G1,F48);
__ movxtod(L0,F6);
--- a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -41,6 +41,7 @@
#include "runtime/atomic.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.hpp"
--- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -561,8 +561,7 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Aix::ucontext_get_pc(uc);
- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
- print_hex_dump(st, pc - 64, pc + 64, /*instrsize=*/4);
+ print_instructions(st, pc, /*instrsize=*/4);
st->cr();
// Try to decode the instructions.
--- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1021,8 +1021,8 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Bsd::ucontext_get_pc(uc);
- st->print_cr("Instructions: (pc=" INTPTR_FORMAT ")", (intptr_t)pc);
- print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+ print_instructions(st, pc, sizeof(char));
+ st->cr();
}
void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -606,8 +606,8 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Linux::ucontext_get_pc(uc);
- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
- print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+ print_instructions(st, pc, sizeof(char));
+ st->cr();
}
void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -543,8 +543,8 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Linux::ucontext_get_pc(uc);
- st->print_cr("Instructions: (pc=" INTPTR_FORMAT ")", p2i(pc));
- print_hex_dump(st, pc - 32, pc + 32, Assembler::InstructionSize);
+ print_instructions(st, pc, Assembler::InstructionSize);
+ st->cr();
}
void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -574,8 +574,7 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Linux::ucontext_get_pc(uc);
- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
- print_hex_dump(st, pc - 64, pc + 64, /*instrsize=*/4);
+ print_instructions(st, pc, /*instrsize=*/4);
st->cr();
}
--- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -605,9 +605,7 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Linux::ucontext_get_pc(uc);
- if (Verbose) { st->print_cr("pc at " PTR_FORMAT, p2i(pc)); }
- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
- print_hex_dump(st, pc-64, pc+64, /*intrsize=*/4);
+ print_instructions(st, pc, /*intrsize=*/4);
st->cr();
}
--- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -232,8 +232,8 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Linux::ucontext_get_pc(uc);
- st->print_cr("Instructions: (pc=" INTPTR_FORMAT ")", p2i(pc));
- print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+ print_instructions(st, pc, sizeof(char));
+ st->cr();
}
--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -755,8 +755,8 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = os::Linux::ucontext_get_pc(uc);
- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
- print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+ print_instructions(st, pc, sizeof(char));
+ st->cr();
}
void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/solaris_sparc/os_solaris_sparc.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -655,8 +655,8 @@
// this at the end, and hope for the best.
ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc);
address pc = epc.pc();
- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
- print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+ print_instructions(st, pc, sizeof(char));
+ st->cr();
}
void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -779,8 +779,8 @@
// this at the end, and hope for the best.
ExtendedPC epc = os::Solaris::ucontext_get_ExtendedPC(uc);
address pc = epc.pc();
- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
- print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+ print_instructions(st, pc, sizeof(char));
+ st->cr();
}
void os::print_register_info(outputStream *st, const void *context) {
--- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -585,8 +585,7 @@
// point to garbage if entry point in an nmethod is corrupted. Leave
// this at the end, and hope for the best.
address pc = (address)uc->REG_PC;
- st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
- print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+ print_instructions(st, pc, sizeof(char));
st->cr();
}
--- a/src/hotspot/share/aot/aotLoader.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/aot/aotLoader.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
#include "memory/allocation.inline.hpp"
#include "oops/method.hpp"
#include "runtime/handles.inline.hpp"
-#include "runtime/os.hpp"
+#include "runtime/os.inline.hpp"
#include "runtime/timerTrace.hpp"
GrowableArray<AOTCodeHeap*>* AOTLoader::_heaps = new(ResourceObj::C_HEAP, mtCode) GrowableArray<AOTCodeHeap*> (2, true);
--- a/src/hotspot/share/c1/c1_GraphBuilder.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/c1/c1_GraphBuilder.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1942,7 +1942,8 @@
// Use CHA on the receiver to select a more precise method.
cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
} else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) {
- // if there is only one implementor of this interface then we
+ assert(callee_holder->is_interface(), "invokeinterface to non interface?");
+ // If there is only one implementor of this interface then we
// may be able bind this invoke directly to the implementing
// klass but we need both a dependence on the single interface
// and on the method we bind to. Additionally since all we know
@@ -1950,53 +1951,44 @@
// interface we have to insert a check that it's the class we
// expect. Interface types are not checked by the verifier so
// they are roughly equivalent to Object.
+ // The number of implementors for declared_interface is less or
+ // equal to the number of implementors for target->holder() so
+ // if number of implementors of target->holder() == 1 then
+ // number of implementors for decl_interface is 0 or 1. If
+ // it's 0 then no class implements decl_interface and there's
+ // no point in inlining.
ciInstanceKlass* singleton = NULL;
- if (target->holder()->nof_implementors() == 1) {
- singleton = target->holder()->implementor();
- assert(singleton != NULL && singleton != target->holder(),
- "just checking");
-
- assert(holder->is_interface(), "invokeinterface to non interface?");
- ciInstanceKlass* decl_interface = (ciInstanceKlass*)holder;
- // the number of implementors for decl_interface is less or
- // equal to the number of implementors for target->holder() so
- // if number of implementors of target->holder() == 1 then
- // number of implementors for decl_interface is 0 or 1. If
- // it's 0 then no class implements decl_interface and there's
- // no point in inlining.
- if (!holder->is_loaded() || decl_interface->nof_implementors() != 1 || decl_interface->has_nonstatic_concrete_methods()) {
- singleton = NULL;
- }
- }
- if (singleton) {
- cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton);
+ ciInstanceKlass* declared_interface = callee_holder;
+ if (declared_interface->nof_implementors() == 1 &&
+ (!target->is_default_method() || target->is_overpass()) /* CHA doesn't support default methods yet. */) {
+ singleton = declared_interface->implementor();
+ assert(singleton != NULL && singleton != declared_interface, "");
+ cha_monomorphic_target = target->find_monomorphic_target(calling_klass, declared_interface, singleton);
if (cha_monomorphic_target != NULL) {
- // If CHA is able to bind this invoke then update the class
- // to match that class, otherwise klass will refer to the
- // interface.
- klass = cha_monomorphic_target->holder();
- actual_recv = target->holder();
-
- // insert a check it's really the expected class.
- CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
- c->set_incompatible_class_change_check();
- c->set_direct_compare(klass->is_final());
- // pass the result of the checkcast so that the compiler has
- // more accurate type info in the inlinee
- better_receiver = append_split(c);
+ if (cha_monomorphic_target->holder() != compilation()->env()->Object_klass()) {
+ // If CHA is able to bind this invoke then update the class
+ // to match that class, otherwise klass will refer to the
+ // interface.
+ klass = cha_monomorphic_target->holder();
+ actual_recv = declared_interface;
+
+ // insert a check it's really the expected class.
+ CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
+ c->set_incompatible_class_change_check();
+ c->set_direct_compare(klass->is_final());
+ // pass the result of the checkcast so that the compiler has
+ // more accurate type info in the inlinee
+ better_receiver = append_split(c);
+ } else {
+ cha_monomorphic_target = NULL; // subtype check against Object is useless
+ }
}
}
}
}
if (cha_monomorphic_target != NULL) {
- if (cha_monomorphic_target->is_abstract()) {
- // Do not optimize for abstract methods
- cha_monomorphic_target = NULL;
- }
- }
-
- if (cha_monomorphic_target != NULL) {
+ assert(!cha_monomorphic_target->is_abstract(), "");
if (!(target->is_final_method())) {
// If we inlined because CHA revealed only a single target method,
// then we are dependent on that target method not getting overridden
--- a/src/hotspot/share/c1/c1_Runtime1.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -57,6 +57,7 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
--- a/src/hotspot/share/ci/ciEnv.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/ci/ciEnv.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -55,6 +55,7 @@
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/reflection.hpp"
#include "runtime/jniHandles.inline.hpp"
--- a/src/hotspot/share/ci/ciInstanceKlass.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/ci/ciInstanceKlass.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -72,7 +72,7 @@
// The possible values of the _implementor fall into following three cases:
// NULL: no implementor.
// A ciInstanceKlass that's not itself: one implementor.
- // Itsef: more than one implementors.
+ // Itself: more than one implementor.
ciInstanceKlass* _implementor;
void compute_injected_fields();
--- a/src/hotspot/share/ci/ciMethod.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/ci/ciMethod.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -46,6 +46,7 @@
#include "oops/oop.inline.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/deoptimization.hpp"
+#include "runtime/handles.inline.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/xmlstream.hpp"
#ifdef COMPILER2
@@ -89,6 +90,7 @@
_is_c2_compilable = !h_m()->is_not_c2_compilable();
_can_be_parsed = true;
_has_reserved_stack_access = h_m()->has_reserved_stack_access();
+ _is_overpass = h_m()->is_overpass();
// Lazy fields, filled in on demand. Require allocation.
_code = NULL;
_exception_handlers = NULL;
@@ -718,7 +720,7 @@
VM_ENTRY_MARK;
// Disable CHA for default methods for now
- if (root_m->get_Method()->is_default_method()) {
+ if (root_m->is_default_method()) {
return NULL;
}
@@ -758,6 +760,7 @@
// with the same name but different vtable indexes.
return NULL;
}
+ assert(!target()->is_abstract(), "not allowed");
return CURRENT_THREAD_ENV->get_method(target());
}
@@ -874,6 +877,14 @@
}
// ------------------------------------------------------------------
+ciKlass* ciMethod::get_declared_method_holder_at_bci(int bci) {
+ ciBytecodeStream iter(this);
+ iter.reset_to_bci(bci);
+ iter.next();
+ return iter.get_declared_method_holder();
+}
+
+// ------------------------------------------------------------------
// Adjust a CounterData count to be commensurate with
// interpreter_invocation_count. If the MDO exists for
// only 25% of the time the method exists, then the
--- a/src/hotspot/share/ci/ciMethod.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/ci/ciMethod.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -89,6 +89,7 @@
bool _can_be_parsed;
bool _can_be_statically_bound;
bool _has_reserved_stack_access;
+ bool _is_overpass;
// Lazy fields, filled in on demand
address _code;
@@ -265,6 +266,8 @@
return get_method_at_bci(bci, ignored_will_link, &ignored_declared_signature);
}
+ ciKlass* get_declared_method_holder_at_bci(int bci);
+
ciSignature* get_declared_signature_at_bci(int bci) {
bool ignored_will_link;
ciSignature* declared_signature;
@@ -333,6 +336,9 @@
bool is_empty_method() const;
bool is_vanilla_constructor() const;
bool is_final_method() const { return is_final() || holder()->is_final(); }
+ bool is_default_method() const { return !is_abstract() && !is_private() &&
+ holder()->is_interface(); }
+ bool is_overpass () const { check_is_loaded(); return _is_overpass; }
bool has_loops () const;
bool has_jsrs () const;
bool is_getter () const;
--- a/src/hotspot/share/ci/ciReplay.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/ci/ciReplay.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -36,6 +36,7 @@
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "utilities/copy.hpp"
#include "utilities/macros.hpp"
--- a/src/hotspot/share/ci/ciStreams.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/ci/ciStreams.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -315,18 +315,7 @@
// If this is a method invocation bytecode, get the constant pool
// index of the invoked method.
int ciBytecodeStream::get_method_index() {
-#ifdef ASSERT
- switch (cur_bc()) {
- case Bytecodes::_invokeinterface:
- case Bytecodes::_invokevirtual:
- case Bytecodes::_invokespecial:
- case Bytecodes::_invokestatic:
- case Bytecodes::_invokedynamic:
- break;
- default:
- ShouldNotReachHere();
- }
-#endif
+ assert(Bytecodes::is_invoke(cur_bc()), "invalid bytecode: %s", Bytecodes::name(cur_bc()));
if (has_index_u4())
return get_index_u4(); // invokedynamic
return get_index_u2_cpcache();
--- a/src/hotspot/share/classfile/classLoader.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/classfile/classLoader.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -56,7 +56,6 @@
#include "prims/jvm_misc.hpp"
#include "runtime/arguments.hpp"
#include "runtime/compilationPolicy.hpp"
-#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.inline.hpp"
--- a/src/hotspot/share/classfile/dictionary.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/classfile/dictionary.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -198,41 +198,6 @@
}
}
-// During class loading we may have cached a protection domain that has
-// since been unreferenced, so this entry should be cleared.
-void Dictionary::clean_cached_protection_domains(DictionaryEntry* probe) {
- assert_locked_or_safepoint(SystemDictionary_lock);
-
- ProtectionDomainEntry* current = probe->pd_set();
- ProtectionDomainEntry* prev = NULL;
- while (current != NULL) {
- if (current->object_no_keepalive() == NULL) {
- LogTarget(Debug, protectiondomain) lt;
- if (lt.is_enabled()) {
- ResourceMark rm;
- // Print out trace information
- LogStream ls(lt);
- ls.print_cr("PD in set is not alive:");
- ls.print("class loader: "); loader_data()->class_loader()->print_value_on(&ls);
- ls.print(" loading: "); probe->instance_klass()->print_value_on(&ls);
- ls.cr();
- }
- if (probe->pd_set() == current) {
- probe->set_pd_set(current->next());
- } else {
- assert(prev != NULL, "should be set by alive entry");
- prev->set_next(current->next());
- }
- ProtectionDomainEntry* to_delete = current;
- current = current->next();
- delete to_delete;
- } else {
- prev = current;
- current = current->next();
- }
- }
-}
-
// Just the classes from defining class loaders
void Dictionary::classes_do(void f(InstanceKlass*)) {
for (int index = 0; index < table_size(); index++) {
--- a/src/hotspot/share/classfile/dictionary.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/classfile/dictionary.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -51,8 +51,6 @@
DictionaryEntry* get_entry(int index, unsigned int hash, Symbol* name);
- void clean_cached_protection_domains(DictionaryEntry* probe);
-
public:
Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable = false);
Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket<mtClass>* t, int number_of_entries, bool resizable = false);
--- a/src/hotspot/share/classfile/stringTable.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/classfile/stringTable.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -468,7 +468,7 @@
if ((dead_factor > load_factor) ||
(load_factor > PREF_AVG_LIST_LEN) ||
(dead_factor > CLEAN_DEAD_HIGH_WATER_MARK)) {
- log_debug(stringtable)("Concurrent work triggered, live factor:%g dead factor:%g",
+ log_debug(stringtable)("Concurrent work triggered, live factor: %g dead factor: %g",
load_factor, dead_factor);
trigger_concurrent_work();
}
--- a/src/hotspot/share/classfile/symbolTable.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/classfile/symbolTable.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,10 +49,6 @@
const size_t END_SIZE = 17;
// If a chain gets to 100 something might be wrong
const size_t REHASH_LEN = 100;
-// We only get a chance to check whether we need
-// to clean infrequently (on class unloading),
-// so if we have even one dead entry then mark table for cleaning
-const double CLEAN_DEAD_HIGH_WATER_MARK = 0.0;
const size_t ON_STACK_BUFFER_LENGTH = 128;
@@ -142,7 +138,7 @@
SymbolTable::SymbolTable() :
_symbols_removed(0), _symbols_counted(0), _local_table(NULL),
_current_size(0), _has_work(0), _needs_rehashing(false),
- _items_count(0), _uncleaned_items_count(0) {
+ _items_count(0), _has_items_to_clean(false) {
size_t start_size_log_2 = ceil_log2(SymbolTableSize);
_current_size = ((size_t)1) << start_size_log_2;
@@ -171,22 +167,14 @@
}
}
+void SymbolTable::reset_has_items_to_clean() { Atomic::store(false, &_has_items_to_clean); }
+void SymbolTable::mark_has_items_to_clean() { Atomic::store(true, &_has_items_to_clean); }
+bool SymbolTable::has_items_to_clean() const { return Atomic::load(&_has_items_to_clean); }
+
void SymbolTable::item_added() {
Atomic::inc(&(SymbolTable::the_table()->_items_count));
}
-void SymbolTable::set_item_clean_count(size_t ncl) {
- Atomic::store(ncl, &(SymbolTable::the_table()->_uncleaned_items_count));
- log_trace(symboltable)("Set uncleaned items:" SIZE_FORMAT, SymbolTable::the_table()->_uncleaned_items_count);
-}
-
-// Mark one item as needing to be cleaned, but only if no other items are marked yet
-void SymbolTable::mark_item_clean_count() {
- if (Atomic::cmpxchg((size_t)1, &(SymbolTable::the_table()->_uncleaned_items_count), (size_t)0) == 0) {
- log_trace(symboltable)("Marked uncleaned items:" SIZE_FORMAT, SymbolTable::the_table()->_uncleaned_items_count);
- }
-}
-
void SymbolTable::item_removed() {
Atomic::inc(&(SymbolTable::the_table()->_symbols_removed));
Atomic::dec(&(SymbolTable::the_table()->_items_count));
@@ -196,15 +184,11 @@
return (double)_items_count/_current_size;
}
-double SymbolTable::get_dead_factor() const {
- return (double)_uncleaned_items_count/_current_size;
-}
-
size_t SymbolTable::table_size() {
return ((size_t)1) << _local_table->get_size_log2(Thread::current());
}
-void SymbolTable::trigger_concurrent_work() {
+void SymbolTable::trigger_cleanup() {
MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
SymbolTable::the_table()->_has_work = true;
Service_lock->notify_all();
@@ -490,12 +474,7 @@
update_needs_rehash(rehash_warning);
if (clean_hint) {
- // we just found out that there is a dead item,
- // which we were unable to clean right now,
- // but we have no way of telling whether it's
- // been previously counted or not, so mark
- // it only if no other items were found yet
- mark_item_clean_count();
+ mark_has_items_to_clean();
check_concurrent_work();
}
@@ -697,7 +676,7 @@
}
bdt.cont(jt);
}
- SymbolTable::the_table()->set_item_clean_count(0);
+ SymbolTable::the_table()->reset_has_items_to_clean();
bdt.done(jt);
}
@@ -711,17 +690,13 @@
if (_has_work) {
return;
}
- double load_factor = SymbolTable::get_load_factor();
- double dead_factor = SymbolTable::get_dead_factor();
- // We should clean/resize if we have more dead than alive,
+ // We should clean/resize if we have
// more items than preferred load factor or
// more dead items than water mark.
- if ((dead_factor > load_factor) ||
- (load_factor > PREF_AVG_LIST_LEN) ||
- (dead_factor > CLEAN_DEAD_HIGH_WATER_MARK)) {
- log_debug(symboltable)("Concurrent work triggered, live factor:%f dead factor:%f",
- load_factor, dead_factor);
- trigger_concurrent_work();
+ if (has_items_to_clean() || (get_load_factor() > PREF_AVG_LIST_LEN)) {
+ log_debug(symboltable)("Concurrent work triggered, load factor: %f, items to clean: %s",
+ get_load_factor(), has_items_to_clean() ? "true" : "false");
+ trigger_cleanup();
}
}
@@ -737,34 +712,6 @@
_has_work = false;
}
-class CountDead : StackObj {
- size_t _count;
-public:
- CountDead() : _count(0) {}
- bool operator()(Symbol** value) {
- assert(value != NULL, "expected valid value");
- assert(*value != NULL, "value should point to a symbol");
- Symbol* sym = *value;
- if (sym->refcount() == 0) {
- _count++;
- }
- return true;
- };
- size_t get_dead_count() const {
- return _count;
- }
-};
-
-void SymbolTable::do_check_concurrent_work() {
- CountDead counter;
- if (!SymbolTable::the_table()->_local_table->try_scan(Thread::current(), counter)) {
- log_info(symboltable)("count dead unavailable at this moment");
- } else {
- SymbolTable::the_table()->set_item_clean_count(counter.get_dead_count());
- SymbolTable::the_table()->check_concurrent_work();
- }
-}
-
void SymbolTable::do_concurrent_work(JavaThread* jt) {
SymbolTable::the_table()->concurrent_work(jt);
}
@@ -800,7 +747,7 @@
if (get_load_factor() > PREF_AVG_LIST_LEN &&
!_local_table->is_max_size_reached()) {
log_debug(symboltable)("Choosing growing over rehashing.");
- trigger_concurrent_work();
+ trigger_cleanup();
_needs_rehashing = false;
return;
}
@@ -808,7 +755,7 @@
// Already rehashed.
if (rehashed) {
log_warning(symboltable)("Rehashing already done, still long lists.");
- trigger_concurrent_work();
+ trigger_cleanup();
_needs_rehashing = false;
return;
}
--- a/src/hotspot/share/classfile/symbolTable.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/classfile/symbolTable.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -123,18 +123,19 @@
volatile bool _needs_rehashing;
volatile size_t _items_count;
- volatile size_t _uncleaned_items_count;
+ volatile bool _has_items_to_clean;
double get_load_factor() const;
- double get_dead_factor() const;
void check_concurrent_work();
- void trigger_concurrent_work();
static void item_added();
static void item_removed();
- static void set_item_clean_count(size_t ncl);
- static void mark_item_clean_count();
+
+ // For cleaning
+ void reset_has_items_to_clean();
+ void mark_has_items_to_clean();
+ bool has_items_to_clean() const;
SymbolTable();
@@ -190,12 +191,9 @@
initialize_symbols(symbol_alloc_arena_size);
}
- static void unlink() {
- do_check_concurrent_work();
- }
- static void do_check_concurrent_work();
static void do_concurrent_work(JavaThread* jt);
static bool has_work() { return the_table()->_has_work; }
+ static void trigger_cleanup();
// Probing
static Symbol* lookup(const char* name, int len, TRAPS);
--- a/src/hotspot/share/classfile/systemDictionary.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/classfile/systemDictionary.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1825,40 +1825,27 @@
if (unloading_occurred) {
MutexLockerEx ml2(is_concurrent ? Module_lock : NULL);
JFR_ONLY(Jfr::on_unloading_classes();)
+
MutexLockerEx ml1(is_concurrent ? SystemDictionary_lock : NULL);
ClassLoaderDataGraph::clean_module_and_package_info();
- }
- }
-
- // Cleanup ResolvedMethodTable even if no unloading occurred.
- {
- GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer);
- ResolvedMethodTable::trigger_cleanup();
- }
-
- if (unloading_occurred) {
- {
- GCTraceTime(Debug, gc, phases) t("SymbolTable", gc_timer);
- // Check if there's work to do in the SymbolTable
- SymbolTable::do_check_concurrent_work();
- }
-
- {
- MutexLockerEx ml(is_concurrent ? SystemDictionary_lock : NULL);
- GCTraceTime(Debug, gc, phases) t("Dictionary", gc_timer);
constraints()->purge_loader_constraints();
resolution_errors()->purge_resolution_errors();
}
-
- {
- GCTraceTime(Debug, gc, phases) t("ResolvedMethodTable", gc_timer);
- // Oops referenced by the protection domain cache table may get unreachable independently
- // of the class loader (eg. cached protection domain oops). So we need to
- // explicitly unlink them here.
- // All protection domain oops are linked to the caller class, so if nothing
- // unloads, this is not needed.
- _pd_cache_table->trigger_cleanup();
- }
+ }
+
+ GCTraceTime(Debug, gc, phases) t("Trigger cleanups", gc_timer);
+ // Trigger cleaning the ResolvedMethodTable even if no unloading occurred.
+ ResolvedMethodTable::trigger_cleanup();
+
+ if (unloading_occurred) {
+ SymbolTable::trigger_cleanup();
+
+ // Oops referenced by the protection domain cache table may get unreachable independently
+ // of the class loader (eg. cached protection domain oops). So we need to
+ // explicitly unlink them here.
+ // All protection domain oops are linked to the caller class, so if nothing
+ // unloads, this is not needed.
+ _pd_cache_table->trigger_cleanup();
}
return unloading_occurred;
--- a/src/hotspot/share/compiler/compileBroker.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/compiler/compileBroker.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -48,6 +48,7 @@
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
#include "runtime/compilationPolicy.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -148,7 +148,7 @@
FLAG_SET_ERGO(uintx, CodeCacheExpansionSize, 32*K);
}
if (FLAG_IS_DEFAULT(MetaspaceSize)) {
- FLAG_SET_ERGO(size_t, MetaspaceSize, 12*M);
+ FLAG_SET_ERGO(size_t, MetaspaceSize, MIN2(12*M, MaxMetaspaceSize));
}
if (FLAG_IS_DEFAULT(MaxRAM)) {
// Do not use FLAG_SET_ERGO to update MaxRAM, as this will impact
@@ -264,7 +264,7 @@
FLAG_SET_DEFAULT(InitialCodeCacheSize, MAX2(16*M, InitialCodeCacheSize));
}
if (FLAG_IS_DEFAULT(MetaspaceSize)) {
- FLAG_SET_DEFAULT(MetaspaceSize, MAX2(12*M, MetaspaceSize));
+ FLAG_SET_DEFAULT(MetaspaceSize, MIN2(MAX2(12*M, MetaspaceSize), MaxMetaspaceSize));
}
if (FLAG_IS_DEFAULT(NewSizeThreadIncrease)) {
FLAG_SET_DEFAULT(NewSizeThreadIncrease, MAX2(4*K, NewSizeThreadIncrease));
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -5269,12 +5269,6 @@
// Prune dead klasses from subklass/sibling/implementor lists.
Klass::clean_weak_klass_links(purged_class);
}
-
- {
- GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", _gc_timer_cm);
- // Clean up unreferenced symbols in symbol table.
- SymbolTable::unlink();
- }
}
// Restore any preserved marks as a result of mark stack or
--- a/src/hotspot/share/gc/cms/parNewGeneration.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/cms/parNewGeneration.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -59,7 +59,6 @@
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/thread.inline.hpp"
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -588,7 +588,7 @@
_num_active_tasks = active_tasks;
// Need to update the three data structures below according to the
// number of active threads for this phase.
- _terminator = TaskTerminator((int) active_tasks, _task_queues);
+ _terminator.terminator()->reset_for_reuse((int) active_tasks);
_first_overflow_barrier_sync.set_n_workers((int) active_tasks);
_second_overflow_barrier_sync.set_n_workers((int) active_tasks);
}
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -566,12 +566,6 @@
Klass::clean_weak_klass_links(purged_class);
}
- {
- GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", _gc_timer);
- // Clean up unreferenced symbols in symbol table.
- SymbolTable::unlink();
- }
-
_gc_tracer->report_object_count_after_gc(is_alive_closure());
}
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -2184,12 +2184,6 @@
Klass::clean_weak_klass_links(purged_class);
}
- {
- GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", &_gc_timer);
- // Clean up unreferenced symbols in symbol table.
- SymbolTable::unlink();
- }
-
_gc_tracer.report_object_count_after_gc(is_alive_closure());
}
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -239,12 +239,6 @@
Klass::clean_weak_klass_links(purged_class);
}
- {
- GCTraceTime(Debug, gc, phases) t("Scrub Symbol Table", gc_timer());
- // Clean up unreferenced symbols in symbol table.
- SymbolTable::unlink();
- }
-
gc_tracer()->report_object_count_after_gc(&is_alive);
}
--- a/src/hotspot/share/gc/shared/taskqueue.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/shared/taskqueue.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -281,13 +281,3 @@
}
}
-// Move assignment
-TaskTerminator& TaskTerminator::operator=(const TaskTerminator& o) {
- if (_terminator != NULL) {
- delete _terminator;
- }
- _terminator = o.terminator();
- const_cast<TaskTerminator&>(o)._terminator = NULL;
- return *this;
-}
-
--- a/src/hotspot/share/gc/shared/taskqueue.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/shared/taskqueue.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -510,37 +510,21 @@
#endif
};
-#ifdef _MSC_VER
-#pragma warning(push)
-// warning C4521: multiple copy constructors specified
-#pragma warning(disable:4521)
-// warning C4522: multiple assignment operators specified
-#pragma warning(disable:4522)
-#endif
-
class TaskTerminator : public StackObj {
private:
ParallelTaskTerminator* _terminator;
- // Disable following copy constructors and assignment operator
- TaskTerminator(TaskTerminator& o) { }
- TaskTerminator(const TaskTerminator& o) { }
- TaskTerminator& operator=(TaskTerminator& o) { return *this; }
+ // Noncopyable.
+ TaskTerminator(const TaskTerminator&);
+ TaskTerminator& operator=(const TaskTerminator&);
public:
TaskTerminator(uint n_threads, TaskQueueSetSuper* queue_set);
~TaskTerminator();
- // Move assignment
- TaskTerminator& operator=(const TaskTerminator& o);
-
ParallelTaskTerminator* terminator() const {
return _terminator;
}
};
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
typedef GenericTaskQueue<oop, mtGC> OopTaskQueue;
typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet;
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -46,6 +46,7 @@
#include "memory/metaspace.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
template<UpdateRefsMode UPDATE_REFS, StringDedupMode STRING_DEDUP>
class ShenandoahInitMarkRootsClosure : public OopClosure {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -65,6 +65,8 @@
#include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
#include "memory/metaspace.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/safepointMechanism.hpp"
#include "runtime/vmThread.hpp"
#include "services/mallocTracker.hpp"
@@ -1863,6 +1865,22 @@
return _free_set->used();
}
+bool ShenandoahHeap::try_cancel_gc() {
+ while (true) {
+ jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE);
+ if (prev == CANCELLABLE) return true;
+ else if (prev == CANCELLED) return false;
+ assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers");
+ assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED");
+ {
+ // We need to provide a safepoint here, otherwise we might
+ // spin forever if a SP is pending.
+ ThreadBlockInVM sp(JavaThread::current());
+ SpinPause();
+ }
+ }
+}
+
void ShenandoahHeap::cancel_gc(GCCause::Cause cause) {
if (try_cancel_gc()) {
FormatBuffer<> msg("Cancelling GC: %s", GCCause::to_string(cause));
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
*
* 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
@@ -380,7 +380,7 @@
};
ShenandoahSharedEnumFlag<CancelState> _cancelled_gc;
- inline bool try_cancel_gc();
+ bool try_cancel_gc();
public:
static address cancelled_gc_addr();
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
*
* 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
@@ -31,7 +31,6 @@
#include "gc/shenandoah/shenandoahAsserts.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.inline.hpp"
#include "gc/shenandoah/shenandoahBrooksPointer.inline.hpp"
-#include "gc/shenandoah/shenandoahCollectionSet.hpp"
#include "gc/shenandoah/shenandoahCollectionSet.inline.hpp"
#include "gc/shenandoah/shenandoahWorkGroup.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp"
@@ -42,8 +41,6 @@
#include "gc/shenandoah/shenandoahThreadLocalData.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/interfaceSupport.inline.hpp"
-#include "runtime/prefetch.hpp"
#include "runtime/prefetch.inline.hpp"
#include "runtime/thread.hpp"
#include "utilities/copy.hpp"
@@ -216,22 +213,6 @@
}
}
-inline bool ShenandoahHeap::try_cancel_gc() {
- while (true) {
- jbyte prev = _cancelled_gc.cmpxchg(CANCELLED, CANCELLABLE);
- if (prev == CANCELLABLE) return true;
- else if (prev == CANCELLED) return false;
- assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers");
- assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED");
- {
- // We need to provide a safepoint here, otherwise we might
- // spin forever if a SP is pending.
- ThreadBlockInVM sp(JavaThread::current());
- SpinPause();
- }
- }
-}
-
inline void ShenandoahHeap::clear_cancelled_gc() {
_cancelled_gc.set(CANCELLABLE);
_oom_evac_handler.clear();
--- a/src/hotspot/share/gc/z/zFuture.inline.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/gc/z/zFuture.inline.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -25,7 +25,6 @@
#define SHARE_GC_Z_ZFUTURE_INLINE_HPP
#include "gc/z/zFuture.hpp"
-#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/semaphore.inline.hpp"
#include "runtime/thread.hpp"
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -26,6 +26,7 @@
#include "jfr/jni/jfrJavaSupport.hpp"
#include "jfr/recorder/repository/jfrChunkRotation.hpp"
#include "jfr/recorder/repository/jfrChunkWriter.hpp"
+#include "runtime/handles.inline.hpp"
static jobject chunk_monitor = NULL;
static intptr_t threshold = 0;
--- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -31,7 +31,7 @@
#include "jfr/utilities/jfrTypes.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/atomic.hpp"
-#include "runtime/handles.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/globals.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/thread.hpp"
--- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* 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 @@
#include "oops/instanceKlass.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
-#include "runtime/handles.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/thread.inline.hpp"
--- a/src/hotspot/share/jvmci/compilerRuntime.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/jvmci/compilerRuntime.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -22,6 +22,7 @@
*/
#include "precompiled.hpp"
+#include "aot/aotLoader.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "interpreter/linkResolver.hpp"
@@ -29,12 +30,12 @@
#include "oops/cpCache.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/compilationPolicy.hpp"
+#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
-#include "runtime/deoptimization.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/vframe.inline.hpp"
#include "utilities/sizes.hpp"
-#include "aot/aotLoader.hpp"
// Resolve and allocate String
JRT_BLOCK_ENTRY(void, CompilerRuntime::resolve_string_by_symbol(JavaThread *thread, void* string_result, const char* name))
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -39,6 +39,7 @@
#include "oops/oop.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/typeArrayOop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -40,6 +40,7 @@
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/timerTrace.hpp"
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -42,6 +42,7 @@
#include "oops/objArrayOop.inline.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/reflection.hpp"
--- a/src/hotspot/share/memory/metaspace.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/memory/metaspace.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -132,7 +132,15 @@
return value;
}
-bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC) {
+// Try to increase the _capacity_until_GC limit counter by v bytes.
+// Returns true if it succeeded. It may fail if either another thread
+// concurrently increased the limit or the new limit would be larger
+// than MaxMetaspaceSize.
+// On success, optionally returns new and old metaspace capacity in
+// new_cap_until_GC and old_cap_until_GC respectively.
+// On error, optionally sets can_retry to indicate whether if there is
+// actually enough space remaining to satisfy the request.
+bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC, bool* can_retry) {
assert_is_aligned(v, Metaspace::commit_alignment());
size_t old_capacity_until_GC = _capacity_until_GC;
@@ -143,6 +151,16 @@
new_value = align_down(max_uintx, Metaspace::commit_alignment());
}
+ if (new_value > MaxMetaspaceSize) {
+ if (can_retry != NULL) {
+ *can_retry = false;
+ }
+ return false;
+ }
+
+ if (can_retry != NULL) {
+ *can_retry = true;
+ }
size_t prev_value = Atomic::cmpxchg(new_value, &_capacity_until_GC, old_capacity_until_GC);
if (old_capacity_until_GC != prev_value) {
@@ -236,7 +254,7 @@
const double min_tmp = used_after_gc / maximum_used_percentage;
size_t minimum_desired_capacity =
- (size_t)MIN2(min_tmp, double(max_uintx));
+ (size_t)MIN2(min_tmp, double(MaxMetaspaceSize));
// Don't shrink less than the initial generation size
minimum_desired_capacity = MAX2(minimum_desired_capacity,
MetaspaceSize);
@@ -283,7 +301,7 @@
const double maximum_free_percentage = MaxMetaspaceFreeRatio / 100.0;
const double minimum_used_percentage = 1.0 - maximum_free_percentage;
const double max_tmp = used_after_gc / minimum_used_percentage;
- size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
+ size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(MaxMetaspaceSize));
maximum_desired_capacity = MAX2(maximum_desired_capacity,
MetaspaceSize);
log_trace(gc, metaspace)(" maximum_free_percentage: %6.2f minimum_used_percentage: %6.2f",
@@ -586,15 +604,15 @@
if (Metaspace::using_class_space()) {
out->print(" Non-Class: ");
}
- print_human_readable_size(out, Metaspace::chunk_manager_metadata()->free_chunks_total_words(), scale);
+ print_human_readable_size(out, Metaspace::chunk_manager_metadata()->free_chunks_total_bytes(), scale);
out->cr();
if (Metaspace::using_class_space()) {
out->print(" Class: ");
- print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_words(), scale);
+ print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_bytes(), scale);
out->cr();
out->print(" Both: ");
- print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_words() +
- Metaspace::chunk_manager_metadata()->free_chunks_total_words(), scale);
+ print_human_readable_size(out, Metaspace::chunk_manager_class()->free_chunks_total_bytes() +
+ Metaspace::chunk_manager_metadata()->free_chunks_total_bytes(), scale);
out->cr();
}
out->cr();
@@ -1470,6 +1488,7 @@
size_t before = 0;
size_t after = 0;
+ bool can_retry = true;
MetaWord* res;
bool incremented;
@@ -1477,9 +1496,9 @@
// the HWM, an allocation is still attempted. This is because another thread must then
// have incremented the HWM and therefore the allocation might still succeed.
do {
- incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before);
+ incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before, &can_retry);
res = allocate(word_size, mdtype);
- } while (!incremented && res == NULL);
+ } while (!incremented && res == NULL && can_retry);
if (incremented) {
Metaspace::tracer()->report_gc_threshold(before, after,
--- a/src/hotspot/share/memory/metaspace.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/memory/metaspace.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -457,7 +457,8 @@
static size_t capacity_until_GC();
static bool inc_capacity_until_GC(size_t v,
size_t* new_cap_until_GC = NULL,
- size_t* old_cap_until_GC = NULL);
+ size_t* old_cap_until_GC = NULL,
+ bool* can_retry = NULL);
static size_t dec_capacity_until_GC(size_t v);
static bool should_concurrent_collect() { return _should_concurrent_collect; }
--- a/src/hotspot/share/oops/constMethod.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/oops/constMethod.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -426,7 +426,6 @@
void ConstMethod::print_on(outputStream* st) const {
ResourceMark rm;
- assert(is_constMethod(), "must be constMethod");
st->print_cr("%s", internal_name());
Method* m = method();
st->print(" - method: " INTPTR_FORMAT " ", p2i((address)m));
@@ -444,7 +443,6 @@
// Short version of printing ConstMethod* - just print the name of the
// method it belongs to.
void ConstMethod::print_value_on(outputStream* st) const {
- assert(is_constMethod(), "must be constMethod");
st->print(" const part of method " );
Method* m = method();
if (m != NULL) {
@@ -487,8 +485,6 @@
// Verification
void ConstMethod::verify_on(outputStream* st) {
- guarantee(is_constMethod(), "object must be constMethod");
-
// Verification can occur during oop construction before the method or
// other fields have been initialized.
guarantee(method() != NULL && method()->is_method(), "should be method");
--- a/src/hotspot/share/oops/constMethod.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/oops/constMethod.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -241,8 +241,6 @@
MethodType mt,
TRAPS);
- bool is_constMethod() const { return true; }
-
// Inlined tables
void set_inlined_tables_length(InlineTableSizes* sizes);
--- a/src/hotspot/share/oops/constantPool.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/oops/constantPool.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -52,6 +52,7 @@
#include "runtime/init.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.inline.hpp"
#include "utilities/copy.hpp"
@@ -2523,11 +2524,6 @@
guarantee(entry.get_symbol()->refcount() != 0, "should have nonzero reference count");
}
}
- if (cache() != NULL) {
- // Note: cache() can be NULL before a class is completely setup or
- // in temporary constant pools used during constant pool merging
- guarantee(cache()->is_constantPoolCache(), "should be constant pool cache");
- }
if (pool_holder() != NULL) {
// Note: pool_holder() can be NULL in temporary constant pools
// used during constant pool merging
--- a/src/hotspot/share/oops/cpCache.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/oops/cpCache.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -851,14 +851,12 @@
// Printing
void ConstantPoolCache::print_on(outputStream* st) const {
- assert(is_constantPoolCache(), "obj must be constant pool cache");
st->print_cr("%s", internal_name());
// print constant pool cache entries
for (int i = 0; i < length(); i++) entry_at(i)->print(st, i);
}
void ConstantPoolCache::print_value_on(outputStream* st) const {
- assert(is_constantPoolCache(), "obj must be constant pool cache");
st->print("cache [%d]", length());
print_address_on(st);
st->print(" for ");
@@ -869,7 +867,6 @@
// Verification
void ConstantPoolCache::verify_on(outputStream* st) {
- guarantee(is_constantPoolCache(), "obj must be constant pool cache");
// print constant pool cache entries
for (int i = 0; i < length(); i++) entry_at(i)->verify(st);
}
--- a/src/hotspot/share/oops/cpCache.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/oops/cpCache.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -444,7 +444,6 @@
const intStack& cp_cache_map,
const intStack& invokedynamic_cp_cache_map,
const intStack& invokedynamic_references_map, TRAPS);
- bool is_constantPoolCache() const { return true; }
int length() const { return _length; }
void metaspace_pointers_do(MetaspaceClosure* it);
--- a/src/hotspot/share/oops/method.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/oops/method.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -2403,7 +2403,6 @@
void Method::verify_on(outputStream* st) {
guarantee(is_method(), "object must be method");
guarantee(constants()->is_constantPool(), "should be constant pool");
- guarantee(constMethod()->is_constMethod(), "should be ConstMethod*");
MethodData* md = method_data();
guarantee(md == NULL ||
md->is_methodData(), "should be method data");
--- a/src/hotspot/share/opto/c2_globals.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/c2_globals.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -516,7 +516,7 @@
"Sets max value cached by the java.lang.Integer autobox cache") \
range(0, max_jint) \
\
- experimental(bool, AggressiveUnboxing, false, \
+ experimental(bool, AggressiveUnboxing, true, \
"Control optimizations for aggressive boxing elimination") \
\
develop(bool, TracePostallocExpand, false, "Trace expanding nodes after" \
--- a/src/hotspot/share/opto/c2compiler.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/c2compiler.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
+#include "runtime/handles.inline.hpp"
#include "jfr/support/jfrIntrinsics.hpp"
#include "opto/c2compiler.hpp"
#include "opto/compile.hpp"
--- a/src/hotspot/share/opto/callGenerator.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/callGenerator.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -459,7 +459,7 @@
C->set_has_loops(C->has_loops() || _inline_cg->method()->has_loops());
C->env()->notice_inlined_method(_inline_cg->method());
C->set_inlining_progress(true);
-
+ C->set_do_cleanup(kit.stopped()); // path is dead; needs cleanup
kit.replace_call(call, result, true);
}
@@ -652,11 +652,13 @@
CallGenerator* _if_missed;
CallGenerator* _if_hit;
float _hit_prob;
+ bool _exact_check;
public:
PredictedCallGenerator(ciKlass* predicted_receiver,
CallGenerator* if_missed,
- CallGenerator* if_hit, float hit_prob)
+ CallGenerator* if_hit, bool exact_check,
+ float hit_prob)
: CallGenerator(if_missed->method())
{
// The call profile data may predict the hit_prob as extreme as 0 or 1.
@@ -668,6 +670,7 @@
_if_missed = if_missed;
_if_hit = if_hit;
_hit_prob = hit_prob;
+ _exact_check = exact_check;
}
virtual bool is_virtual() const { return true; }
@@ -682,9 +685,16 @@
CallGenerator* if_missed,
CallGenerator* if_hit,
float hit_prob) {
- return new PredictedCallGenerator(predicted_receiver, if_missed, if_hit, hit_prob);
+ return new PredictedCallGenerator(predicted_receiver, if_missed, if_hit,
+ /*exact_check=*/true, hit_prob);
}
+CallGenerator* CallGenerator::for_guarded_call(ciKlass* guarded_receiver,
+ CallGenerator* if_missed,
+ CallGenerator* if_hit) {
+ return new PredictedCallGenerator(guarded_receiver, if_missed, if_hit,
+ /*exact_check=*/false, PROB_ALWAYS);
+}
JVMState* PredictedCallGenerator::generate(JVMState* jvms) {
GraphKit kit(jvms);
@@ -695,8 +705,8 @@
Node* receiver = kit.argument(0);
CompileLog* log = kit.C->log();
if (log != NULL) {
- log->elem("predicted_call bci='%d' klass='%d'",
- jvms->bci(), log->identify(_predicted_receiver));
+ log->elem("predicted_call bci='%d' exact='%d' klass='%d'",
+ jvms->bci(), (_exact_check ? 1 : 0), log->identify(_predicted_receiver));
}
receiver = kit.null_check_receiver_before_call(method());
@@ -708,10 +718,15 @@
ReplacedNodes replaced_nodes = kit.map()->replaced_nodes();
replaced_nodes.clone();
- Node* exact_receiver = receiver; // will get updated in place...
- Node* slow_ctl = kit.type_check_receiver(receiver,
- _predicted_receiver, _hit_prob,
- &exact_receiver);
+ Node* casted_receiver = receiver; // will get updated in place...
+ Node* slow_ctl = NULL;
+ if (_exact_check) {
+ slow_ctl = kit.type_check_receiver(receiver, _predicted_receiver, _hit_prob,
+ &casted_receiver);
+ } else {
+ slow_ctl = kit.subtype_check_receiver(receiver, _predicted_receiver,
+ &casted_receiver);
+ }
SafePointNode* slow_map = NULL;
JVMState* slow_jvms = NULL;
@@ -736,7 +751,7 @@
}
// fall through if the instance exactly matches the desired type
- kit.replace_in_map(receiver, exact_receiver);
+ kit.replace_in_map(receiver, casted_receiver);
// Make the hot call:
JVMState* new_jvms = _if_hit->generate(kit.sync_jvms());
--- a/src/hotspot/share/opto/callGenerator.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/callGenerator.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -144,6 +144,10 @@
CallGenerator* if_hit,
float hit_prob);
+ static CallGenerator* for_guarded_call(ciKlass* predicted_receiver,
+ CallGenerator* if_missed,
+ CallGenerator* if_hit);
+
// How to make a call that optimistically assumes a MethodHandle target:
static CallGenerator* for_predicted_dynamic_call(ciMethodHandle* predicted_method_handle,
CallGenerator* if_missed,
--- a/src/hotspot/share/opto/castnode.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/castnode.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -410,11 +410,11 @@
Node* dispX,
bool negate = false) {
if (negate) {
- dispX = new SubXNode(phase->MakeConX(0), phase->transform(dispX));
+ dispX = phase->transform(new SubXNode(phase->MakeConX(0), dispX));
}
return new AddPNode(phase->C->top(),
phase->transform(new CastX2PNode(base)),
- phase->transform(dispX));
+ dispX);
}
Node *CastX2PNode::Ideal(PhaseGVN *phase, bool can_reshape) {
--- a/src/hotspot/share/opto/cfgnode.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/cfgnode.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -119,11 +119,13 @@
// can turn PhiNodes into copys in-place by NULL'ing out their RegionNode
// input in slot 0.
class PhiNode : public TypeNode {
+ friend class PhaseRenumberLive;
+
const TypePtr* const _adr_type; // non-null only for Type::MEMORY nodes.
// The following fields are only used for data PhiNodes to indicate
// that the PhiNode represents the value of a known instance field.
int _inst_mem_id; // Instance memory id (node index of the memory Phi)
- const int _inst_id; // Instance id of the memory slice.
+ int _inst_id; // Instance id of the memory slice.
const int _inst_index; // Alias index of the instance memory slice.
// Array elements references have the same alias_idx but different offset.
const int _inst_offset; // Offset of the instance memory slice.
--- a/src/hotspot/share/opto/compile.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/compile.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -648,6 +648,7 @@
_orig_pc_slot_offset_in_bytes(0),
_inlining_progress(false),
_inlining_incrementally(false),
+ _do_cleanup(false),
_has_reserved_stack_access(target->has_reserved_stack_access()),
#ifndef PRODUCT
_trace_opto_output(directive->TraceOptoOutputOption),
@@ -2051,52 +2052,49 @@
}
_boxing_late_inlines.trunc_to(0);
- {
- ResourceMark rm;
- PhaseRemoveUseless pru(gvn, for_igvn());
- }
-
- igvn = PhaseIterGVN(gvn);
- igvn.optimize();
-
- set_inlining_progress(false);
+ inline_incrementally_cleanup(igvn);
+
set_inlining_incrementally(false);
}
}
-void Compile::inline_incrementally_one(PhaseIterGVN& igvn) {
+bool Compile::inline_incrementally_one() {
assert(IncrementalInline, "incremental inlining should be on");
- PhaseGVN* gvn = initial_gvn();
+
+ TracePhase tp("incrementalInline_inline", &timers[_t_incrInline_inline]);
+ set_inlining_progress(false);
+ set_do_cleanup(false);
+ int i = 0;
+ for (; i <_late_inlines.length() && !inlining_progress(); i++) {
+ CallGenerator* cg = _late_inlines.at(i);
+ _late_inlines_pos = i+1;
+ cg->do_late_inline();
+ if (failing()) return false;
+ }
+ int j = 0;
+ for (; i < _late_inlines.length(); i++, j++) {
+ _late_inlines.at_put(j, _late_inlines.at(i));
+ }
+ _late_inlines.trunc_to(j);
+ assert(inlining_progress() || _late_inlines.length() == 0, "");
+
+ bool needs_cleanup = do_cleanup() || over_inlining_cutoff();
set_inlining_progress(false);
- for_igvn()->clear();
- gvn->replace_with(&igvn);
-
- {
- TracePhase tp("incrementalInline_inline", &timers[_t_incrInline_inline]);
- int i = 0;
- for (; i <_late_inlines.length() && !inlining_progress(); i++) {
- CallGenerator* cg = _late_inlines.at(i);
- _late_inlines_pos = i+1;
- cg->do_late_inline();
- if (failing()) return;
- }
- int j = 0;
- for (; i < _late_inlines.length(); i++, j++) {
- _late_inlines.at_put(j, _late_inlines.at(i));
- }
- _late_inlines.trunc_to(j);
- }
-
+ set_do_cleanup(false);
+ return (_late_inlines.length() > 0) && !needs_cleanup;
+}
+
+void Compile::inline_incrementally_cleanup(PhaseIterGVN& igvn) {
{
TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]);
ResourceMark rm;
- PhaseRemoveUseless pru(gvn, for_igvn());
+ PhaseRemoveUseless pru(initial_gvn(), for_igvn());
}
-
{
TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
- igvn = PhaseIterGVN(gvn);
+ igvn = PhaseIterGVN(initial_gvn());
+ igvn.optimize();
}
}
@@ -2104,14 +2102,10 @@
void Compile::inline_incrementally(PhaseIterGVN& igvn) {
TracePhase tp("incrementalInline", &timers[_t_incrInline]);
- PhaseGVN* gvn = initial_gvn();
-
set_inlining_incrementally(true);
- set_inlining_progress(true);
uint low_live_nodes = 0;
- while(inlining_progress() && _late_inlines.length() > 0) {
-
+ while (_late_inlines.length() > 0) {
if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
if (low_live_nodes < (uint)LiveNodeCountInliningCutoff * 8 / 10) {
TracePhase tp("incrementalInline_ideal", &timers[_t_incrInline_ideal]);
@@ -2125,22 +2119,23 @@
}
if (live_nodes() > (uint)LiveNodeCountInliningCutoff) {
- break;
+ break; // finish
}
}
- inline_incrementally_one(igvn);
-
- if (failing()) return;
-
- {
- TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
- igvn.optimize();
+ for_igvn()->clear();
+ initial_gvn()->replace_with(&igvn);
+
+ while (inline_incrementally_one()) {
+ assert(!failing(), "inconsistent");
}
if (failing()) return;
+
+ inline_incrementally_cleanup(igvn);
+
+ if (failing()) return;
}
-
assert( igvn._worklist.size() == 0, "should be done with igvn" );
if (_string_late_inlines.length() > 0) {
@@ -2152,17 +2147,7 @@
if (failing()) return;
- {
- TracePhase tp("incrementalInline_pru", &timers[_t_incrInline_pru]);
- ResourceMark rm;
- PhaseRemoveUseless pru(initial_gvn(), for_igvn());
- }
-
- {
- TracePhase tp("incrementalInline_igvn", &timers[_t_incrInline_igvn]);
- igvn = PhaseIterGVN(gvn);
- igvn.optimize();
- }
+ inline_incrementally_cleanup(igvn);
}
set_inlining_incrementally(false);
--- a/src/hotspot/share/opto/compile.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/compile.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -383,6 +383,7 @@
int _major_progress; // Count of something big happening
bool _inlining_progress; // progress doing incremental inlining?
bool _inlining_incrementally;// Are we doing incremental inlining (post parse)
+ bool _do_cleanup; // Cleanup is needed before proceeding with incremental inlining
bool _has_loops; // True if the method _may_ have some loops
bool _has_split_ifs; // True if the method _may_ have some split-if
bool _has_unsafe_access; // True if the method _may_ produce faults in unsafe loads or stores.
@@ -653,6 +654,8 @@
int inlining_progress() const { return _inlining_progress; }
void set_inlining_incrementally(bool z) { _inlining_incrementally = z; }
int inlining_incrementally() const { return _inlining_incrementally; }
+ void set_do_cleanup(bool z) { _do_cleanup = z; }
+ int do_cleanup() const { return _do_cleanup; }
void set_major_progress() { _major_progress++; }
void clear_major_progress() { _major_progress = 0; }
int max_inline_size() const { return _max_inline_size; }
@@ -1022,6 +1025,11 @@
ciMethodData* logmd = NULL);
// Report if there were too many recompiles at a method and bci.
bool too_many_recompiles(ciMethod* method, int bci, Deoptimization::DeoptReason reason);
+ // Report if there were too many traps or recompiles at a method and bci.
+ bool too_many_traps_or_recompiles(ciMethod* method, int bci, Deoptimization::DeoptReason reason) {
+ return too_many_traps(method, bci, reason) ||
+ too_many_recompiles(method, bci, reason);
+ }
// Return a bitset with the reasons where deoptimization is allowed,
// i.e., where there were not too many uncommon traps.
int _allowed_reasons;
@@ -1075,7 +1083,11 @@
if (!inlining_incrementally()) {
return unique() > (uint)NodeCountInliningCutoff;
} else {
- return live_nodes() > (uint)LiveNodeCountInliningCutoff;
+ // Give some room for incremental inlining algorithm to "breathe"
+ // and avoid thrashing when live node count is close to the limit.
+ // Keep in mind that live_nodes() isn't accurate during inlining until
+ // dead node elimination step happens (see Compile::inline_incrementally).
+ return live_nodes() > (uint)LiveNodeCountInliningCutoff * 11 / 10;
}
}
@@ -1083,7 +1095,8 @@
void dec_number_of_mh_late_inlines() { assert(_number_of_mh_late_inlines > 0, "_number_of_mh_late_inlines < 0 !"); _number_of_mh_late_inlines--; }
bool has_mh_late_inlines() const { return _number_of_mh_late_inlines > 0; }
- void inline_incrementally_one(PhaseIterGVN& igvn);
+ bool inline_incrementally_one();
+ void inline_incrementally_cleanup(PhaseIterGVN& igvn);
void inline_incrementally(PhaseIterGVN& igvn);
void inline_string_calls(bool parse_time);
void inline_boxing_calls(PhaseIterGVN& igvn);
--- a/src/hotspot/share/opto/doCall.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/doCall.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -209,7 +209,7 @@
int morphism = profile.morphism();
if (speculative_receiver_type != NULL) {
- if (!too_many_traps(caller, bci, Deoptimization::Reason_speculate_class_check)) {
+ if (!too_many_traps_or_recompiles(caller, bci, Deoptimization::Reason_speculate_class_check)) {
// We have a speculative type, we should be able to resolve
// the call. We do that before looking at the profiling at
// this invoke because it may lead to bimorphic inlining which
@@ -262,7 +262,7 @@
? Deoptimization::Reason_bimorphic
: Deoptimization::reason_class_check(speculative_receiver_type != NULL));
if ((morphism == 1 || (morphism == 2 && next_hit_cg != NULL)) &&
- !too_many_traps(caller, bci, reason)
+ !too_many_traps_or_recompiles(caller, bci, reason)
) {
// Generate uncommon trap for class check failure path
// in case of monomorphic or bimorphic virtual call site.
@@ -292,6 +292,51 @@
}
}
}
+
+ // If there is only one implementor of this interface then we
+ // may be able to bind this invoke directly to the implementing
+ // klass but we need both a dependence on the single interface
+ // and on the method we bind to. Additionally since all we know
+ // about the receiver type is that it's supposed to implement the
+ // interface we have to insert a check that it's the class we
+ // expect. Interface types are not checked by the verifier so
+ // they are roughly equivalent to Object.
+ // The number of implementors for declared_interface is less or
+ // equal to the number of implementors for target->holder() so
+ // if number of implementors of target->holder() == 1 then
+ // number of implementors for decl_interface is 0 or 1. If
+ // it's 0 then no class implements decl_interface and there's
+ // no point in inlining.
+ if (call_does_dispatch && bytecode == Bytecodes::_invokeinterface) {
+ ciInstanceKlass* declared_interface =
+ caller->get_declared_method_holder_at_bci(bci)->as_instance_klass();
+
+ if (declared_interface->nof_implementors() == 1 &&
+ (!callee->is_default_method() || callee->is_overpass()) /* CHA doesn't support default methods yet */) {
+ ciInstanceKlass* singleton = declared_interface->implementor();
+ ciMethod* cha_monomorphic_target =
+ callee->find_monomorphic_target(caller->holder(), declared_interface, singleton);
+
+ if (cha_monomorphic_target != NULL &&
+ cha_monomorphic_target->holder() != env()->Object_klass()) { // subtype check against Object is useless
+ ciKlass* holder = cha_monomorphic_target->holder();
+
+ // Try to inline the method found by CHA. Inlined method is guarded by the type check.
+ CallGenerator* hit_cg = call_generator(cha_monomorphic_target,
+ vtable_index, !call_does_dispatch, jvms, allow_inline, prof_factor);
+
+ // Deoptimize on type check fail. The interpreter will throw ICCE for us.
+ CallGenerator* miss_cg = CallGenerator::for_uncommon_trap(callee,
+ Deoptimization::Reason_class_check, Deoptimization::Action_none);
+
+ CallGenerator* cg = CallGenerator::for_guarded_call(holder, miss_cg, hit_cg);
+ if (hit_cg != NULL && cg != NULL) {
+ dependencies()->assert_unique_concrete_method(declared_interface, cha_monomorphic_target);
+ return cg;
+ }
+ }
+ }
+ }
}
// Nothing claimed the intrinsic, we go with straight-forward inlining
--- a/src/hotspot/share/opto/graphKit.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/graphKit.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -2794,6 +2794,22 @@
return fail;
}
+//------------------------------subtype_check_receiver-------------------------
+Node* GraphKit::subtype_check_receiver(Node* receiver, ciKlass* klass,
+ Node** casted_receiver) {
+ const TypeKlassPtr* tklass = TypeKlassPtr::make(klass);
+ Node* recv_klass = load_object_klass(receiver);
+ Node* want_klass = makecon(tklass);
+
+ Node* slow_ctl = gen_subtype_check(recv_klass, want_klass);
+
+ // Cast receiver after successful check
+ const TypeOopPtr* recv_type = tklass->cast_to_exactness(false)->is_klassptr()->as_instance_type();
+ Node* cast = new CheckCastPPNode(control(), receiver, recv_type);
+ (*casted_receiver) = _gvn.transform(cast);
+
+ return slow_ctl;
+}
//------------------------------seems_never_null-------------------------------
// Use null_seen information if it is available from the profile.
@@ -2836,7 +2852,7 @@
Deoptimization::DeoptReason reason = Deoptimization::reason_class_check(spec_klass != NULL);
// Make sure we haven't already deoptimized from this tactic.
- if (too_many_traps(reason) || too_many_recompiles(reason))
+ if (too_many_traps_or_recompiles(reason))
return NULL;
// (No, this isn't a call, but it's enough like a virtual call
@@ -2891,9 +2907,8 @@
Deoptimization::DeoptReason class_reason = Deoptimization::Reason_speculate_class_check;
Deoptimization::DeoptReason null_reason = Deoptimization::Reason_speculate_null_check;
- if (!too_many_traps(null_reason) && !too_many_recompiles(null_reason) &&
- !too_many_traps(class_reason) &&
- !too_many_recompiles(class_reason)) {
+ if (!too_many_traps_or_recompiles(null_reason) &&
+ !too_many_traps_or_recompiles(class_reason)) {
Node* not_null_obj = NULL;
// not_null is true if we know the object is not null and
// there's no need for a null check
@@ -2918,8 +2933,7 @@
obj = exact_obj;
}
} else {
- if (!too_many_traps(Deoptimization::Reason_null_assert) &&
- !too_many_recompiles(Deoptimization::Reason_null_assert)) {
+ if (!too_many_traps_or_recompiles(Deoptimization::Reason_null_assert)) {
Node* exact_obj = null_assert(obj);
replace_in_map(obj, exact_obj);
obj = exact_obj;
--- a/src/hotspot/share/opto/graphKit.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/graphKit.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -751,6 +751,10 @@
return C->too_many_recompiles(method(), bci(), reason);
}
+ bool too_many_traps_or_recompiles(Deoptimization::DeoptReason reason) {
+ return C->too_many_traps_or_recompiles(method(), bci(), reason);
+ }
+
// Returns the object (if any) which was created the moment before.
Node* just_allocated_object(Node* current_control);
@@ -830,6 +834,10 @@
Node* type_check_receiver(Node* receiver, ciKlass* klass, float prob,
Node* *casted_receiver);
+ // Inexact type check used for predicted calls.
+ Node* subtype_check_receiver(Node* receiver, ciKlass* klass,
+ Node** casted_receiver);
+
// implementation of object creation
Node* set_output_for_allocation(AllocateNode* alloc,
const TypeOopPtr* oop_type,
--- a/src/hotspot/share/opto/phaseX.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/phaseX.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -461,55 +461,115 @@
PhaseRenumberLive::PhaseRenumberLive(PhaseGVN* gvn,
Unique_Node_List* worklist, Unique_Node_List* new_worklist,
PhaseNumber phase_num) :
- PhaseRemoveUseless(gvn, worklist, Remove_Useless_And_Renumber_Live) {
-
+ PhaseRemoveUseless(gvn, worklist, Remove_Useless_And_Renumber_Live),
+ _new_type_array(C->comp_arena()),
+ _old2new_map(C->unique(), C->unique(), -1),
+ _delayed(Thread::current()->resource_area()),
+ _is_pass_finished(false),
+ _live_node_count(C->live_nodes())
+{
assert(RenumberLiveNodes, "RenumberLiveNodes must be set to true for node renumbering to take place");
assert(C->live_nodes() == _useful.size(), "the number of live nodes must match the number of useful nodes");
assert(gvn->nodes_size() == 0, "GVN must not contain any nodes at this point");
+ assert(_delayed.size() == 0, "should be empty");
- uint old_unique_count = C->unique();
- uint live_node_count = C->live_nodes();
uint worklist_size = worklist->size();
- // Storage for the updated type information.
- Type_Array new_type_array(C->comp_arena());
-
// Iterate over the set of live nodes.
- uint current_idx = 0; // The current new node ID. Incremented after every assignment.
- for (uint i = 0; i < _useful.size(); i++) {
- Node* n = _useful.at(i);
- // Sanity check that fails if we ever decide to execute this phase after EA
- assert(!n->is_Phi() || n->as_Phi()->inst_mem_id() == -1, "should not be linked to data Phi");
- const Type* type = gvn->type_or_null(n);
- new_type_array.map(current_idx, type);
+ for (uint current_idx = 0; current_idx < _useful.size(); current_idx++) {
+ Node* n = _useful.at(current_idx);
bool in_worklist = false;
if (worklist->member(n)) {
in_worklist = true;
}
+ const Type* type = gvn->type_or_null(n);
+ _new_type_array.map(current_idx, type);
+
+ assert(_old2new_map.at(n->_idx) == -1, "already seen");
+ _old2new_map.at_put(n->_idx, current_idx);
+
n->set_idx(current_idx); // Update node ID.
if (in_worklist) {
new_worklist->push(n);
}
- current_idx++;
+ if (update_embedded_ids(n) < 0) {
+ _delayed.push(n); // has embedded IDs; handle later
+ }
}
assert(worklist_size == new_worklist->size(), "the new worklist must have the same size as the original worklist");
- assert(live_node_count == current_idx, "all live nodes must be processed");
+ assert(_live_node_count == _useful.size(), "all live nodes must be processed");
+
+ _is_pass_finished = true; // pass finished; safe to process delayed updates
+
+ while (_delayed.size() > 0) {
+ Node* n = _delayed.pop();
+ int no_of_updates = update_embedded_ids(n);
+ assert(no_of_updates > 0, "should be updated");
+ }
// Replace the compiler's type information with the updated type information.
- gvn->replace_types(new_type_array);
+ gvn->replace_types(_new_type_array);
// Update the unique node count of the compilation to the number of currently live nodes.
- C->set_unique(live_node_count);
+ C->set_unique(_live_node_count);
// Set the dead node count to 0 and reset dead node list.
C->reset_dead_node_list();
}
+int PhaseRenumberLive::new_index(int old_idx) {
+ assert(_is_pass_finished, "not finished");
+ if (_old2new_map.at(old_idx) == -1) { // absent
+ // Allocate a placeholder to preserve uniqueness
+ _old2new_map.at_put(old_idx, _live_node_count);
+ _live_node_count++;
+ }
+ return _old2new_map.at(old_idx);
+}
+
+int PhaseRenumberLive::update_embedded_ids(Node* n) {
+ int no_of_updates = 0;
+ if (n->is_Phi()) {
+ PhiNode* phi = n->as_Phi();
+ if (phi->_inst_id != -1) {
+ if (!_is_pass_finished) {
+ return -1; // delay
+ }
+ int new_idx = new_index(phi->_inst_id);
+ assert(new_idx != -1, "");
+ phi->_inst_id = new_idx;
+ no_of_updates++;
+ }
+ if (phi->_inst_mem_id != -1) {
+ if (!_is_pass_finished) {
+ return -1; // delay
+ }
+ int new_idx = new_index(phi->_inst_mem_id);
+ assert(new_idx != -1, "");
+ phi->_inst_mem_id = new_idx;
+ no_of_updates++;
+ }
+ }
+
+ const Type* type = _new_type_array.fast_lookup(n->_idx);
+ if (type != NULL && type->isa_oopptr() && type->is_oopptr()->is_known_instance()) {
+ if (!_is_pass_finished) {
+ return -1; // delay
+ }
+ int old_idx = type->is_oopptr()->instance_id();
+ int new_idx = new_index(old_idx);
+ const Type* new_type = type->is_oopptr()->with_instance_id(new_idx);
+ _new_type_array.map(n->_idx, new_type);
+ no_of_updates++;
+ }
+
+ return no_of_updates;
+}
//=============================================================================
//------------------------------PhaseTransform---------------------------------
--- a/src/hotspot/share/opto/phaseX.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/phaseX.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -157,6 +157,16 @@
// Phase that first performs a PhaseRemoveUseless, then it renumbers compiler
// structures accordingly.
class PhaseRenumberLive : public PhaseRemoveUseless {
+protected:
+ Type_Array _new_type_array; // Storage for the updated type information.
+ GrowableArray<int> _old2new_map;
+ Node_List _delayed;
+ bool _is_pass_finished;
+ uint _live_node_count;
+
+ int update_embedded_ids(Node* n);
+ int new_index(int old_idx);
+
public:
PhaseRenumberLive(PhaseGVN* gvn,
Unique_Node_List* worklist, Unique_Node_List* new_worklist,
--- a/src/hotspot/share/opto/type.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/type.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -3436,6 +3436,12 @@
return make(_ptr, _offset, _instance_id, _speculative, depth);
}
+//------------------------------with_instance_id--------------------------------
+const TypePtr* TypeOopPtr::with_instance_id(int instance_id) const {
+ assert(_instance_id != -1, "should be known");
+ return make(_ptr, _offset, instance_id, _speculative, _inline_depth);
+}
+
//------------------------------meet_instance_id--------------------------------
int TypeOopPtr::meet_instance_id( int instance_id ) const {
// Either is 'TOP' instance? Return the other instance!
@@ -4044,6 +4050,11 @@
return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, depth);
}
+const TypePtr *TypeInstPtr::with_instance_id(int instance_id) const {
+ assert(is_known_instance(), "should be known");
+ return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, instance_id, _speculative, _inline_depth);
+}
+
//=============================================================================
// Convenience common pre-built types.
const TypeAryPtr *TypeAryPtr::RANGE;
@@ -4530,6 +4541,11 @@
return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, _speculative, depth);
}
+const TypePtr *TypeAryPtr::with_instance_id(int instance_id) const {
+ assert(is_known_instance(), "should be known");
+ return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, instance_id, _speculative, _inline_depth);
+}
+
//=============================================================================
//------------------------------hash-------------------------------------------
--- a/src/hotspot/share/opto/type.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/opto/type.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -1045,6 +1045,8 @@
virtual bool would_improve_type(ciKlass* exact_kls, int inline_depth) const;
virtual const TypePtr* with_inline_depth(int depth) const;
+ virtual const TypePtr* with_instance_id(int instance_id) const;
+
virtual const Type *xdual() const; // Compute dual right now.
// the core of the computation of the meet for TypeOopPtr and for its subclasses
virtual const Type *xmeet_helper(const Type *t) const;
@@ -1123,6 +1125,7 @@
// Speculative type helper methods.
virtual const Type* remove_speculative() const;
virtual const TypePtr* with_inline_depth(int depth) const;
+ virtual const TypePtr* with_instance_id(int instance_id) const;
// the core of the computation of the meet of 2 types
virtual const Type *xmeet_helper(const Type *t) const;
@@ -1212,6 +1215,7 @@
// Speculative type helper methods.
virtual const Type* remove_speculative() const;
virtual const TypePtr* with_inline_depth(int depth) const;
+ virtual const TypePtr* with_instance_id(int instance_id) const;
// the core of the computation of the meet of 2 types
virtual const Type *xmeet_helper(const Type *t) const;
--- a/src/hotspot/share/prims/jvm.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/jvm.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -870,10 +870,6 @@
Handle h_prot (THREAD, protection_domain);
jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
h_prot, true, thread);
- if (result != NULL) {
- oop mirror = JNIHandles::resolve_non_null(result);
- Klass* to_class = java_lang_Class::as_Klass(mirror);
- }
if (log_is_enabled(Debug, class, resolve) && result != NULL) {
// this function is generally only used for class loading during verification.
--- a/src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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,7 +32,6 @@
#include "oops/oop.inline.hpp"
#include "prims/jvmtiCodeBlobEvents.hpp"
#include "prims/jvmtiExport.hpp"
-#include "runtime/handles.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/vmThread.hpp"
--- a/src/hotspot/share/prims/jvmtiEnv.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -56,6 +56,7 @@
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -41,6 +41,7 @@
#include "runtime/biasedLocking.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jfieldIDWorkaround.hpp"
#include "runtime/jniHandles.inline.hpp"
--- a/src/hotspot/share/prims/jvmtiExport.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/jvmtiExport.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -49,7 +49,7 @@
#include "prims/jvmtiThreadState.inline.hpp"
#include "runtime/arguments.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
-#include "runtime/handles.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
--- a/src/hotspot/share/prims/jvmtiManageCapabilities.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/jvmtiManageCapabilities.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -107,6 +107,14 @@
#ifndef ZERO
jc.can_pop_frame = 1;
jc.can_force_early_return = 1;
+ // Workaround for 8195635:
+ // disable pop_frame and force_early_return capabilities with Graal
+#if INCLUDE_JVMCI
+ if (UseJVMCICompiler) {
+ jc.can_pop_frame = 0;
+ jc.can_force_early_return = 0;
+ }
+#endif // INCLUDE_JVMCI
#endif // !ZERO
jc.can_get_source_debug_extension = 1;
jc.can_access_local_variables = 1;
--- a/src/hotspot/share/prims/methodHandles.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/methodHandles.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -40,6 +40,7 @@
#include "prims/methodHandles.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
--- a/src/hotspot/share/prims/nativeLookup.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/nativeLookup.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/os.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/signature.hpp"
#include "utilities/macros.hpp"
--- a/src/hotspot/share/prims/stackwalk.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/stackwalk.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -35,6 +35,7 @@
#include "runtime/globals.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.inline.hpp"
#include "utilities/globalDefinitions.hpp"
--- a/src/hotspot/share/prims/unsafe.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/unsafe.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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,6 +38,7 @@
#include "prims/unsafe.hpp"
#include "runtime/atomic.hpp"
#include "runtime/globals.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/orderAccess.hpp"
--- a/src/hotspot/share/prims/whitebox.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/prims/whitebox.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -59,6 +59,7 @@
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/handshake.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/runtime/arguments.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/arguments.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -579,7 +579,7 @@
{ "TraceClassUnloading", LogLevel::Info, true, LOG_TAGS(class, unload) },
{ "TraceExceptions", LogLevel::Info, true, LOG_TAGS(exceptions) },
{ "TraceLoaderConstraints", LogLevel::Info, true, LOG_TAGS(class, loader, constraints) },
- { "TraceMonitorInflation", LogLevel::Debug, true, LOG_TAGS(monitorinflation) },
+ { "TraceMonitorInflation", LogLevel::Trace, true, LOG_TAGS(monitorinflation) },
{ "TraceSafepointCleanupTime", LogLevel::Info, true, LOG_TAGS(safepoint, cleanup) },
{ "TraceJVMTIObjectTagging", LogLevel::Debug, true, LOG_TAGS(jvmti, objecttagging) },
{ "TraceRedefineClasses", LogLevel::Info, false, LOG_TAGS(redefine, class) },
--- a/src/hotspot/share/runtime/deoptimization.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/deoptimization.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -47,6 +47,7 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "runtime/sharedRuntime.hpp"
--- a/src/hotspot/share/runtime/handles.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/handles.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -31,6 +31,7 @@
class InstanceKlass;
class Klass;
+class Thread;
//------------------------------------------------------------------------------------------------------------------------
// In order to preserve oops during garbage collection, they should be
--- a/src/hotspot/share/runtime/handles.inline.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/handles.inline.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -26,7 +26,9 @@
#define SHARE_RUNTIME_HANDLES_INLINE_HPP
#include "runtime/handles.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
+#include "oops/metadata.hpp"
+#include "oops/oop.hpp"
// these inline functions are in a separate file to break an include cycle
// between Thread and Handle
--- a/src/hotspot/share/runtime/init.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/init.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -166,6 +166,13 @@
static bool destructorsCalled = false;
if (!destructorsCalled) {
destructorsCalled = true;
+ if (log_is_enabled(Info, monitorinflation)) {
+ // The ObjectMonitor subsystem uses perf counters so
+ // do this before perfMemory_exit().
+ // ObjectSynchronizer::finish_deflate_idle_monitors()'s call
+ // to audit_and_print_stats() is done at the Debug level.
+ ObjectSynchronizer::audit_and_print_stats(true /* on_exit */);
+ }
perfMemory_exit();
if (log_is_enabled(Debug, safepoint, stats)) {
// Print the collected safepoint statistics.
--- a/src/hotspot/share/runtime/java.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/java.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -58,6 +58,7 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/flags/flagSetting.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
--- a/src/hotspot/share/runtime/os.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/os.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -47,6 +47,7 @@
#include "runtime/arguments.hpp"
#include "runtime/atomic.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
@@ -908,6 +909,11 @@
st->cr();
}
+void os::print_instructions(outputStream* st, address pc, int unitsize) {
+ st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
+ print_hex_dump(st, pc - 256, pc + 256, unitsize);
+}
+
void os::print_environment_variables(outputStream* st, const char** env_list) {
if (env_list) {
st->print_cr("Environment Variables:");
--- a/src/hotspot/share/runtime/os.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/os.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -640,6 +640,7 @@
static void print_siginfo(outputStream* st, const void* siginfo);
static void print_signal_handlers(outputStream* st, char* buf, size_t buflen);
static void print_date_and_time(outputStream* st, char* buf, size_t buflen);
+ static void print_instructions(outputStream* st, address pc, int unitsize);
static void print_location(outputStream* st, intptr_t x, bool verbose = false);
static size_t lasterror(char *buf, size_t len);
--- a/src/hotspot/share/runtime/reflection.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/reflection.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -49,6 +49,7 @@
#include "runtime/reflection.hpp"
#include "runtime/reflectionUtils.hpp"
#include "runtime/signature.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.inline.hpp"
static void trace_class_resolution(const Klass* to_class) {
--- a/src/hotspot/share/runtime/safepoint.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/safepoint.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -48,6 +48,7 @@
#include "runtime/compilationPolicy.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/orderAccess.hpp"
--- a/src/hotspot/share/runtime/semaphore.inline.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/semaphore.inline.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -27,7 +27,7 @@
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/semaphore.hpp"
-#include "runtime/thread.inline.hpp"
+#include "runtime/thread.hpp"
inline void Semaphore::wait_with_safepoint_check(JavaThread* thread) {
// Prepare to block and allow safepoints while blocked
--- a/src/hotspot/share/runtime/serviceThread.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/serviceThread.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -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 @@
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.hpp"
--- a/src/hotspot/share/runtime/synchronizer.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/synchronizer.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "classfile/vmSymbols.hpp"
#include "logging/log.hpp"
+#include "logging/logStream.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/metaspaceShared.hpp"
@@ -1354,6 +1355,8 @@
// before or after the CAS(INFLATING) operation.
// See the comments in omAlloc().
+ LogStreamHandle(Trace, monitorinflation) lsh;
+
if (mark->has_locker()) {
ObjectMonitor * m = omAlloc(Self);
// Optimistically prepare the objectmonitor - anticipate successful CAS
@@ -1423,14 +1426,11 @@
// Hopefully the performance counters are allocated on distinct cache lines
// to avoid false sharing on MP systems ...
OM_PERFDATA_OP(Inflations, inc());
- if (log_is_enabled(Debug, monitorinflation)) {
- if (object->is_instance()) {
- ResourceMark rm(Self);
- log_debug(monitorinflation)("inflate(has_locker): "
- "object=" INTPTR_FORMAT ", mark=" INTPTR_FORMAT ", type='%s'",
- p2i(object), p2i(object->mark()),
- object->klass()->external_name());
- }
+ if (log_is_enabled(Trace, monitorinflation)) {
+ ResourceMark rm(Self);
+ lsh.print_cr("inflate(has_locker): object=" INTPTR_FORMAT ", mark="
+ INTPTR_FORMAT ", type='%s'", p2i(object),
+ p2i(object->mark()), object->klass()->external_name());
}
if (event.should_commit()) {
post_monitor_inflate_event(&event, object, cause);
@@ -1474,14 +1474,11 @@
// Hopefully the performance counters are allocated on distinct
// cache lines to avoid false sharing on MP systems ...
OM_PERFDATA_OP(Inflations, inc());
- if (log_is_enabled(Debug, monitorinflation)) {
- if (object->is_instance()) {
- ResourceMark rm(Self);
- log_debug(monitorinflation)("inflate(neutral): "
- "object=" INTPTR_FORMAT ", mark=" INTPTR_FORMAT ", type='%s'",
- p2i(object), p2i(object->mark()),
- object->klass()->external_name());
- }
+ if (log_is_enabled(Trace, monitorinflation)) {
+ ResourceMark rm(Self);
+ lsh.print_cr("inflate(neutral): object=" INTPTR_FORMAT ", mark="
+ INTPTR_FORMAT ", type='%s'", p2i(object),
+ p2i(object->mark()), object->klass()->external_name());
}
if (event.should_commit()) {
post_monitor_inflate_event(&event, object, cause);
@@ -1529,14 +1526,12 @@
// Deflate the monitor if it is no longer being used
// It's idle - scavenge and return to the global free list
// plain old deflation ...
- if (log_is_enabled(Debug, monitorinflation)) {
- if (obj->is_instance()) {
- ResourceMark rm;
- log_debug(monitorinflation)("deflate_monitor: "
- "object=" INTPTR_FORMAT ", mark=" INTPTR_FORMAT ", type='%s'",
- p2i(obj), p2i(obj->mark()),
- obj->klass()->external_name());
- }
+ if (log_is_enabled(Trace, monitorinflation)) {
+ ResourceMark rm;
+ log_trace(monitorinflation)("deflate_monitor: "
+ "object=" INTPTR_FORMAT ", mark=" INTPTR_FORMAT ", type='%s'",
+ p2i(obj), p2i(obj->mark()),
+ obj->klass()->external_name());
}
// Restore the header back to obj
@@ -1602,10 +1597,11 @@
}
void ObjectSynchronizer::prepare_deflate_idle_monitors(DeflateMonitorCounters* counters) {
- counters->nInuse = 0; // currently associated with objects
- counters->nInCirculation = 0; // extant
- counters->nScavenged = 0; // reclaimed (global and per-thread)
- counters->perThreadTimes = 0.0; // per-thread scavenge times
+ counters->nInuse = 0; // currently associated with objects
+ counters->nInCirculation = 0; // extant
+ counters->nScavenged = 0; // reclaimed (global and per-thread)
+ counters->perThreadScavenged = 0; // per-thread scavenge total
+ counters->perThreadTimes = 0.0; // per-thread scavenge times
}
void ObjectSynchronizer::deflate_idle_monitors(DeflateMonitorCounters* counters) {
@@ -1614,6 +1610,11 @@
ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors
ObjectMonitor * freeTailp = NULL;
+ elapsedTimer timer;
+
+ if (log_is_enabled(Info, monitorinflation)) {
+ timer.start();
+ }
// Prevent omFlush from changing mids in Thread dtor's during deflation
// And in case the vm thread is acquiring a lock during a safepoint
@@ -1624,9 +1625,10 @@
// a separate pass. See deflate_thread_local_monitors().
// For moribund threads, scan gOmInUseList
+ int deflated_count = 0;
if (gOmInUseList) {
counters->nInCirculation += gOmInUseCount;
- int deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
+ deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
gOmInUseCount -= deflated_count;
counters->nScavenged += deflated_count;
counters->nInuse += gOmInUseCount;
@@ -1641,29 +1643,53 @@
gFreeList = freeHeadp;
}
Thread::muxRelease(&gListLock);
+ timer.stop();
+ LogStreamHandle(Debug, monitorinflation) lsh_debug;
+ LogStreamHandle(Info, monitorinflation) lsh_info;
+ LogStream * ls = NULL;
+ if (log_is_enabled(Debug, monitorinflation)) {
+ ls = &lsh_debug;
+ } else if (deflated_count != 0 && log_is_enabled(Info, monitorinflation)) {
+ ls = &lsh_info;
+ }
+ if (ls != NULL) {
+ ls->print_cr("deflating global idle monitors, %3.7f secs, %d monitors", timer.seconds(), deflated_count);
+ }
}
void ObjectSynchronizer::finish_deflate_idle_monitors(DeflateMonitorCounters* counters) {
- if (log_is_enabled(Info, safepoint, cleanup)) {
- // Report the cumulative time for deflating each thread's idle
- // monitors. Note: if the work is split among more than one
- // worker thread, then the reported time will likely be more
- // than a beginning to end measurement of the phase.
- log_info(safepoint, cleanup)("deflating per-thread idle monitors, %3.7f secs", counters->perThreadTimes);
+ // Report the cumulative time for deflating each thread's idle
+ // monitors. Note: if the work is split among more than one
+ // worker thread, then the reported time will likely be more
+ // than a beginning to end measurement of the phase.
+ log_info(safepoint, cleanup)("deflating per-thread idle monitors, %3.7f secs, monitors=%d", counters->perThreadTimes, counters->perThreadScavenged);
+
+ LogStreamHandle(Debug, monitorinflation) lsh_debug;
+ LogStreamHandle(Info, monitorinflation) lsh_info;
+ LogStream * ls = NULL;
+ if (log_is_enabled(Debug, monitorinflation)) {
+ ls = &lsh_debug;
+ } else if (counters->perThreadScavenged != 0 && log_is_enabled(Info, monitorinflation)) {
+ ls = &lsh_info;
+ }
+ if (ls != NULL) {
+ ls->print_cr("deflating per-thread idle monitors, %3.7f secs, %d monitors", counters->perThreadTimes, counters->perThreadScavenged);
}
gMonitorFreeCount += counters->nScavenged;
- // Consider: audit gFreeList to ensure that gMonitorFreeCount and list agree.
+ if (log_is_enabled(Debug, monitorinflation)) {
+ // exit_globals()'s call to audit_and_print_stats() is done
+ // at the Info level.
+ ObjectSynchronizer::audit_and_print_stats(false /* on_exit */);
+ }
ForceMonitorScavenge = 0; // Reset
OM_PERFDATA_OP(Deflations, inc(counters->nScavenged));
OM_PERFDATA_OP(MonExtant, set_value(counters->nInCirculation));
- // TODO: Add objectMonitor leak detection.
- // Audit/inventory the objectMonitors -- make sure they're all accounted for.
GVars.stwRandom = os::random();
GVars.stwCycle++;
}
@@ -1675,7 +1701,8 @@
ObjectMonitor * freeTailp = NULL;
elapsedTimer timer;
- if (log_is_enabled(Info, safepoint, cleanup)) {
+ if (log_is_enabled(Info, safepoint, cleanup) ||
+ log_is_enabled(Info, monitorinflation)) {
timer.start();
}
@@ -1690,6 +1717,7 @@
thread->omInUseCount -= deflated_count;
counters->nScavenged += deflated_count;
counters->nInuse += thread->omInUseCount;
+ counters->perThreadScavenged += deflated_count;
// For now, we only care about cumulative per-thread deflation time.
counters->perThreadTimes += timer.seconds();
@@ -1782,6 +1810,338 @@
return (u_char*)&GVars.stwRandom;
}
+void ObjectSynchronizer::audit_and_print_stats(bool on_exit) {
+ assert(on_exit || SafepointSynchronize::is_at_safepoint(), "invariant");
+
+ LogStreamHandle(Debug, monitorinflation) lsh_debug;
+ LogStreamHandle(Info, monitorinflation) lsh_info;
+ LogStreamHandle(Trace, monitorinflation) lsh_trace;
+ LogStream * ls = NULL;
+ if (log_is_enabled(Trace, monitorinflation)) {
+ ls = &lsh_trace;
+ } else if (log_is_enabled(Debug, monitorinflation)) {
+ ls = &lsh_debug;
+ } else if (log_is_enabled(Info, monitorinflation)) {
+ ls = &lsh_info;
+ }
+ assert(ls != NULL, "sanity check");
+
+ if (!on_exit) {
+ // Not at VM exit so grab the global list lock.
+ Thread::muxAcquire(&gListLock, "audit_and_print_stats");
+ }
+
+ // Log counts for the global and per-thread monitor lists:
+ int chkMonitorPopulation = log_monitor_list_counts(ls);
+ int error_cnt = 0;
+
+ ls->print_cr("Checking global lists:");
+
+ // Check gMonitorPopulation:
+ if (gMonitorPopulation == chkMonitorPopulation) {
+ ls->print_cr("gMonitorPopulation=%d equals chkMonitorPopulation=%d",
+ gMonitorPopulation, chkMonitorPopulation);
+ } else {
+ ls->print_cr("ERROR: gMonitorPopulation=%d is not equal to "
+ "chkMonitorPopulation=%d", gMonitorPopulation,
+ chkMonitorPopulation);
+ error_cnt++;
+ }
+
+ // Check gOmInUseList and gOmInUseCount:
+ chk_global_in_use_list_and_count(ls, &error_cnt);
+
+ // Check gFreeList and gMonitorFreeCount:
+ chk_global_free_list_and_count(ls, &error_cnt);
+
+ if (!on_exit) {
+ Thread::muxRelease(&gListLock);
+ }
+
+ ls->print_cr("Checking per-thread lists:");
+
+ for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
+ // Check omInUseList and omInUseCount:
+ chk_per_thread_in_use_list_and_count(jt, ls, &error_cnt);
+
+ // Check omFreeList and omFreeCount:
+ chk_per_thread_free_list_and_count(jt, ls, &error_cnt);
+ }
+
+ if (error_cnt == 0) {
+ ls->print_cr("No errors found in monitor list checks.");
+ } else {
+ log_error(monitorinflation)("found monitor list errors: error_cnt=%d", error_cnt);
+ }
+
+ if ((on_exit && log_is_enabled(Info, monitorinflation)) ||
+ (!on_exit && log_is_enabled(Trace, monitorinflation))) {
+ // When exiting this log output is at the Info level. When called
+ // at a safepoint, this log output is at the Trace level since
+ // there can be a lot of it.
+ log_in_use_monitor_details(ls, on_exit);
+ }
+
+ ls->flush();
+
+ guarantee(error_cnt == 0, "ERROR: found monitor list errors: error_cnt=%d", error_cnt);
+}
+
+// Check a free monitor entry; log any errors.
+void ObjectSynchronizer::chk_free_entry(JavaThread * jt, ObjectMonitor * n,
+ outputStream * out, int *error_cnt_p) {
+ if (n->is_busy()) {
+ if (jt != NULL) {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
+ ": free per-thread monitor must not be busy.", p2i(jt),
+ p2i(n));
+ } else {
+ out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": free global monitor "
+ "must not be busy.", p2i(n));
+ }
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+ if (n->header() != NULL) {
+ if (jt != NULL) {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
+ ": free per-thread monitor must have NULL _header "
+ "field: _header=" INTPTR_FORMAT, p2i(jt), p2i(n),
+ p2i(n->header()));
+ } else {
+ out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": free global monitor "
+ "must have NULL _header field: _header=" INTPTR_FORMAT,
+ p2i(n), p2i(n->header()));
+ }
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+ if (n->object() != NULL) {
+ if (jt != NULL) {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
+ ": free per-thread monitor must have NULL _object "
+ "field: _object=" INTPTR_FORMAT, p2i(jt), p2i(n),
+ p2i(n->object()));
+ } else {
+ out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": free global monitor "
+ "must have NULL _object field: _object=" INTPTR_FORMAT,
+ p2i(n), p2i(n->object()));
+ }
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+}
+
+// Check the global free list and count; log the results of the checks.
+void ObjectSynchronizer::chk_global_free_list_and_count(outputStream * out,
+ int *error_cnt_p) {
+ int chkMonitorFreeCount = 0;
+ for (ObjectMonitor * n = gFreeList; n != NULL; n = n->FreeNext) {
+ chk_free_entry(NULL /* jt */, n, out, error_cnt_p);
+ chkMonitorFreeCount++;
+ }
+ if (gMonitorFreeCount == chkMonitorFreeCount) {
+ out->print_cr("gMonitorFreeCount=%d equals chkMonitorFreeCount=%d",
+ gMonitorFreeCount, chkMonitorFreeCount);
+ } else {
+ out->print_cr("ERROR: gMonitorFreeCount=%d is not equal to "
+ "chkMonitorFreeCount=%d", gMonitorFreeCount,
+ chkMonitorFreeCount);
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+}
+
+// Check the global in-use list and count; log the results of the checks.
+void ObjectSynchronizer::chk_global_in_use_list_and_count(outputStream * out,
+ int *error_cnt_p) {
+ int chkOmInUseCount = 0;
+ for (ObjectMonitor * n = gOmInUseList; n != NULL; n = n->FreeNext) {
+ chk_in_use_entry(NULL /* jt */, n, out, error_cnt_p);
+ chkOmInUseCount++;
+ }
+ if (gOmInUseCount == chkOmInUseCount) {
+ out->print_cr("gOmInUseCount=%d equals chkOmInUseCount=%d", gOmInUseCount,
+ chkOmInUseCount);
+ } else {
+ out->print_cr("ERROR: gOmInUseCount=%d is not equal to chkOmInUseCount=%d",
+ gOmInUseCount, chkOmInUseCount);
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+}
+
+// Check an in-use monitor entry; log any errors.
+void ObjectSynchronizer::chk_in_use_entry(JavaThread * jt, ObjectMonitor * n,
+ outputStream * out, int *error_cnt_p) {
+ if (n->header() == NULL) {
+ if (jt != NULL) {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
+ ": in-use per-thread monitor must have non-NULL _header "
+ "field.", p2i(jt), p2i(n));
+ } else {
+ out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": in-use global monitor "
+ "must have non-NULL _header field.", p2i(n));
+ }
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+ if (n->object() == NULL) {
+ if (jt != NULL) {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
+ ": in-use per-thread monitor must have non-NULL _object "
+ "field.", p2i(jt), p2i(n));
+ } else {
+ out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": in-use global monitor "
+ "must have non-NULL _object field.", p2i(n));
+ }
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+ const oop obj = (oop)n->object();
+ const markOop mark = obj->mark();
+ if (!mark->has_monitor()) {
+ if (jt != NULL) {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
+ ": in-use per-thread monitor's object does not think "
+ "it has a monitor: obj=" INTPTR_FORMAT ", mark="
+ INTPTR_FORMAT, p2i(jt), p2i(n), p2i((address)obj),
+ p2i((address)mark));
+ } else {
+ out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": in-use global "
+ "monitor's object does not think it has a monitor: obj="
+ INTPTR_FORMAT ", mark=" INTPTR_FORMAT, p2i(n),
+ p2i((address)obj), p2i((address)mark));
+ }
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+ ObjectMonitor * const obj_mon = mark->monitor();
+ if (n != obj_mon) {
+ if (jt != NULL) {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
+ ": in-use per-thread monitor's object does not refer "
+ "to the same monitor: obj=" INTPTR_FORMAT ", mark="
+ INTPTR_FORMAT ", obj_mon=" INTPTR_FORMAT, p2i(jt),
+ p2i(n), p2i((address)obj), p2i((address)mark),
+ p2i((address)obj_mon));
+ } else {
+ out->print_cr("ERROR: monitor=" INTPTR_FORMAT ": in-use global "
+ "monitor's object does not refer to the same monitor: obj="
+ INTPTR_FORMAT ", mark=" INTPTR_FORMAT ", obj_mon="
+ INTPTR_FORMAT, p2i(n), p2i((address)obj),
+ p2i((address)mark), p2i((address)obj_mon));
+ }
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+}
+
+// Check the thread's free list and count; log the results of the checks.
+void ObjectSynchronizer::chk_per_thread_free_list_and_count(JavaThread *jt,
+ outputStream * out,
+ int *error_cnt_p) {
+ int chkOmFreeCount = 0;
+ for (ObjectMonitor * n = jt->omFreeList; n != NULL; n = n->FreeNext) {
+ chk_free_entry(jt, n, out, error_cnt_p);
+ chkOmFreeCount++;
+ }
+ if (jt->omFreeCount == chkOmFreeCount) {
+ out->print_cr("jt=" INTPTR_FORMAT ": omFreeCount=%d equals "
+ "chkOmFreeCount=%d", p2i(jt), jt->omFreeCount, chkOmFreeCount);
+ } else {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ": omFreeCount=%d is not "
+ "equal to chkOmFreeCount=%d", p2i(jt), jt->omFreeCount,
+ chkOmFreeCount);
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+}
+
+// Check the thread's in-use list and count; log the results of the checks.
+void ObjectSynchronizer::chk_per_thread_in_use_list_and_count(JavaThread *jt,
+ outputStream * out,
+ int *error_cnt_p) {
+ int chkOmInUseCount = 0;
+ for (ObjectMonitor * n = jt->omInUseList; n != NULL; n = n->FreeNext) {
+ chk_in_use_entry(jt, n, out, error_cnt_p);
+ chkOmInUseCount++;
+ }
+ if (jt->omInUseCount == chkOmInUseCount) {
+ out->print_cr("jt=" INTPTR_FORMAT ": omInUseCount=%d equals "
+ "chkOmInUseCount=%d", p2i(jt), jt->omInUseCount,
+ chkOmInUseCount);
+ } else {
+ out->print_cr("ERROR: jt=" INTPTR_FORMAT ": omInUseCount=%d is not "
+ "equal to chkOmInUseCount=%d", p2i(jt), jt->omInUseCount,
+ chkOmInUseCount);
+ *error_cnt_p = *error_cnt_p + 1;
+ }
+}
+
+// Log details about ObjectMonitors on the in-use lists. The 'BHL'
+// flags indicate why the entry is in-use, 'object' and 'object type'
+// indicate the associated object and its type.
+void ObjectSynchronizer::log_in_use_monitor_details(outputStream * out,
+ bool on_exit) {
+ if (!on_exit) {
+ // Not at VM exit so grab the global list lock.
+ Thread::muxAcquire(&gListLock, "log_in_use_monitor_details");
+ }
+
+ if (gOmInUseCount > 0) {
+ out->print_cr("In-use global monitor info:");
+ out->print_cr("(B -> is_busy, H -> has hashcode, L -> lock status)");
+ out->print_cr("%18s %s %18s %18s",
+ "monitor", "BHL", "object", "object type");
+ out->print_cr("================== === ================== ==================");
+ for (ObjectMonitor * n = gOmInUseList; n != NULL; n = n->FreeNext) {
+ const oop obj = (oop) n->object();
+ const markOop mark = n->header();
+ ResourceMark rm;
+ out->print_cr(INTPTR_FORMAT " %d%d%d " INTPTR_FORMAT " %s", p2i(n),
+ n->is_busy() != 0, mark->hash() != 0, n->owner() != NULL,
+ p2i(obj), obj->klass()->external_name());
+ }
+ }
+
+ if (!on_exit) {
+ Thread::muxRelease(&gListLock);
+ }
+
+ out->print_cr("In-use per-thread monitor info:");
+ out->print_cr("(B -> is_busy, H -> has hashcode, L -> lock status)");
+ out->print_cr("%18s %18s %s %18s %18s",
+ "jt", "monitor", "BHL", "object", "object type");
+ out->print_cr("================== ================== === ================== ==================");
+ for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
+ for (ObjectMonitor * n = jt->omInUseList; n != NULL; n = n->FreeNext) {
+ const oop obj = (oop) n->object();
+ const markOop mark = n->header();
+ ResourceMark rm;
+ out->print_cr(INTPTR_FORMAT " " INTPTR_FORMAT " %d%d%d " INTPTR_FORMAT
+ " %s", p2i(jt), p2i(n), n->is_busy() != 0,
+ mark->hash() != 0, n->owner() != NULL, p2i(obj),
+ obj->klass()->external_name());
+ }
+ }
+
+ out->flush();
+}
+
+// Log counts for the global and per-thread monitor lists and return
+// the population count.
+int ObjectSynchronizer::log_monitor_list_counts(outputStream * out) {
+ int popCount = 0;
+ out->print_cr("%18s %10s %10s %10s",
+ "Global Lists:", "InUse", "Free", "Total");
+ out->print_cr("================== ========== ========== ==========");
+ out->print_cr("%18s %10d %10d %10d", "",
+ gOmInUseCount, gMonitorFreeCount, gMonitorPopulation);
+ popCount += gOmInUseCount + gMonitorFreeCount;
+
+ out->print_cr("%18s %10s %10s %10s",
+ "Per-Thread Lists:", "InUse", "Free", "Provision");
+ out->print_cr("================== ========== ========== ==========");
+
+ for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
+ out->print_cr(INTPTR_FORMAT " %10d %10d %10d", p2i(jt),
+ jt->omInUseCount, jt->omFreeCount, jt->omFreeProvision);
+ popCount += jt->omInUseCount + jt->omFreeCount;
+ }
+ return popCount;
+}
+
#ifndef PRODUCT
// Check if monitor belongs to the monitor cache
--- a/src/hotspot/share/runtime/synchronizer.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/synchronizer.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -35,10 +35,11 @@
class ThreadsList;
struct DeflateMonitorCounters {
- int nInuse; // currently associated with objects
- int nInCirculation; // extant
- int nScavenged; // reclaimed (global and per-thread)
- double perThreadTimes; // per-thread scavenge times
+ int nInuse; // currently associated with objects
+ int nInCirculation; // extant
+ int nScavenged; // reclaimed (global and per-thread)
+ int perThreadScavenged; // per-thread scavenge total
+ double perThreadTimes; // per-thread scavenge times
};
class ObjectSynchronizer : AllStatic {
@@ -153,6 +154,23 @@
static void thread_local_used_oops_do(Thread* thread, OopClosure* f);
// debugging
+ static void audit_and_print_stats(bool on_exit);
+ static void chk_free_entry(JavaThread * jt, ObjectMonitor * n,
+ outputStream * out, int *error_cnt_p);
+ static void chk_global_free_list_and_count(outputStream * out,
+ int *error_cnt_p);
+ static void chk_global_in_use_list_and_count(outputStream * out,
+ int *error_cnt_p);
+ static void chk_in_use_entry(JavaThread * jt, ObjectMonitor * n,
+ outputStream * out, int *error_cnt_p);
+ static void chk_per_thread_in_use_list_and_count(JavaThread *jt,
+ outputStream * out,
+ int *error_cnt_p);
+ static void chk_per_thread_free_list_and_count(JavaThread *jt,
+ outputStream * out,
+ int *error_cnt_p);
+ static void log_in_use_monitor_details(outputStream * out, bool on_exit);
+ static int log_monitor_list_counts(outputStream * out);
static int verify_objmon_isinpool(ObjectMonitor *addr) PRODUCT_RETURN0;
private:
--- a/src/hotspot/share/runtime/thread.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/thread.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -69,6 +69,7 @@
#include "runtime/flags/jvmFlagWriteableList.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/frame.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/handshake.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.inline.hpp"
--- a/src/hotspot/share/runtime/thread.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/thread.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -1280,15 +1280,8 @@
address last_Java_pc(void) { return _anchor.last_Java_pc(); }
// Safepoint support
-#if !(defined(PPC64) || defined(AARCH64))
- JavaThreadState thread_state() const { return _thread_state; }
- void set_thread_state(JavaThreadState s) { _thread_state = s; }
-#else
- // Use membars when accessing volatile _thread_state. See
- // Threads::create_vm() for size checks.
inline JavaThreadState thread_state() const;
inline void set_thread_state(JavaThreadState s);
-#endif
inline ThreadSafepointState* safepoint_state() const;
inline void set_safepoint_state(ThreadSafepointState* state);
inline bool is_at_poll_safepoint();
--- a/src/hotspot/share/runtime/thread.inline.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/thread.inline.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -121,15 +121,25 @@
set_has_async_exception();
}
+inline JavaThreadState JavaThread::thread_state() const {
#if defined(PPC64) || defined (AARCH64)
-inline JavaThreadState JavaThread::thread_state() const {
+ // Use membars when accessing volatile _thread_state. See
+ // Threads::create_vm() for size checks.
return (JavaThreadState) OrderAccess::load_acquire((volatile jint*)&_thread_state);
+#else
+ return _thread_state;
+#endif
}
inline void JavaThread::set_thread_state(JavaThreadState s) {
+#if defined(PPC64) || defined (AARCH64)
+ // Use membars when accessing volatile _thread_state. See
+ // Threads::create_vm() for size checks.
OrderAccess::release_store((volatile jint*)&_thread_state, (jint)s);
+#else
+ _thread_state = s;
+#endif
}
-#endif
ThreadSafepointState* JavaThread::safepoint_state() const {
return _safepoint_state;
--- a/src/hotspot/share/runtime/tieredThresholdPolicy.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/tieredThresholdPolicy.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -28,6 +28,7 @@
#include "memory/resourceArea.hpp"
#include "runtime/arguments.hpp"
#include "runtime/handles.inline.hpp"
+#include "runtime/safepoint.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "runtime/tieredThresholdPolicy.hpp"
#include "code/scopeDesc.hpp"
--- a/src/hotspot/share/runtime/vframe.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/vframe.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
+#include "runtime/thread.inline.hpp"
#include "runtime/vframe.inline.hpp"
#include "runtime/vframeArray.hpp"
#include "runtime/vframe_hp.hpp"
--- a/src/hotspot/share/runtime/vmThread.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/runtime/vmThread.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -34,6 +34,7 @@
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "oops/verifyOopClosure.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/os.hpp"
--- a/src/hotspot/share/services/lowMemoryDetector.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/services/lowMemoryDetector.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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 @@
#include "classfile/vmSymbols.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
+#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
--- a/src/hotspot/share/utilities/debug.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/utilities/debug.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -92,6 +92,21 @@
# endif
#endif // PRODUCT
+#ifdef ASSERT
+// This is to test that error reporting works if we assert during dynamic
+// initialization of the hotspot. See JDK-8214975.
+struct Crasher {
+ Crasher() {
+ // Using getenv - no other mechanism would work yet.
+ const char* s = ::getenv("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");
+ if (s != NULL && ::strcmp(s, "1") == 0) {
+ fatal("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION");
+ }
+ }
+};
+static Crasher g_crasher;
+#endif // ASSERT
+
ATTRIBUTE_PRINTF(1, 2)
void warning(const char* format, ...) {
if (PrintWarnings) {
--- a/src/hotspot/share/utilities/vmError.cpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/utilities/vmError.cpp Mon Feb 04 15:00:29 2019 -0500
@@ -1189,16 +1189,6 @@
volatile intptr_t VMError::first_error_tid = -1;
-// An error could happen before tty is initialized or after it has been
-// destroyed.
-// Please note: to prevent large stack allocations, the log- and
-// output-stream use a global scratch buffer for format printing.
-// (see VmError::report_and_die(). Access to those streams is synchronized
-// in VmError::report_and_die() - there is only one reporting thread at
-// any given time.
-fdStream VMError::out(defaultStream::output_fd());
-fdStream VMError::log; // error log used by VMError::report_and_die()
-
/** Expand a pattern into a buffer starting at pos and open a file using constructed path */
static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
int fd = -1;
@@ -1303,9 +1293,25 @@
Thread* thread, address pc, void* siginfo, void* context, const char* filename,
int lineno, size_t size)
{
- // Don't allocate large buffer on stack
+ // A single scratch buffer to be used from here on.
+ // Do not rely on it being preserved across function calls.
static char buffer[O_BUFLEN];
+
+ // File descriptor to tty to print an error summary to.
+ // Hard wired to stdout; see JDK-8215004 (compatibility concerns).
+ static const int fd_out = 1; // stdout
+
+ // File descriptor to the error log file.
+ static int fd_log = -1;
+
+ // Use local fdStream objects only. Do not use global instances whose initialization
+ // relies on dynamic initialization (see JDK-8214975). Do not rely on these instances
+ // to carry over into recursions or invocations from other threads.
+ fdStream out(fd_out);
out.set_scratch_buffer(buffer, sizeof(buffer));
+
+ // Depending on the re-entrance depth at this point, fd_log may be -1 or point to an open hs-err file.
+ fdStream log(fd_log);
log.set_scratch_buffer(buffer, sizeof(buffer));
// How many errors occurred in error handler when reporting first_error.
@@ -1451,15 +1457,15 @@
// see if log file is already open
if (!log.is_open()) {
// open log file
- int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));
- if (fd != -1) {
+ fd_log = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));
+ if (fd_log != -1) {
out.print_raw("# An error report file with more information is saved as:\n# ");
out.print_raw_cr(buffer);
- log.set_fd(fd);
+ log.set_fd(fd_log);
} else {
out.print_raw_cr("# Can not save log file, dump to screen..");
- log.set_fd(defaultStream::output_fd());
+ log.set_fd(fd_out);
}
}
@@ -1468,8 +1474,9 @@
_current_step = 0;
_current_step_info = "";
- if (log.fd() != defaultStream::output_fd()) {
- close(log.fd());
+ if (fd_log != -1) {
+ close(fd_log);
+ fd_log = -1;
}
log.set_fd(-1);
--- a/src/hotspot/share/utilities/vmError.hpp Sun Feb 03 08:16:08 2019 -0500
+++ b/src/hotspot/share/utilities/vmError.hpp Mon Feb 04 15:00:29 2019 -0500
@@ -122,9 +122,6 @@
void* context, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(6, 7);
static void report_and_die(const char* message, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(2, 3);
- static fdStream out;
- static fdStream log; // error log used by VMError::report_and_die()
-
// Timeout handling.
// Hook functions for platform dependend functionality:
static void reporting_started();
--- a/src/java.base/share/classes/java/lang/Character.java Sun Feb 03 08:16:08 2019 -0500
+++ b/src/java.base/share/classes/java/lang/Character.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * 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
@@ -35,35 +35,29 @@
/**
* The {@code Character} class wraps a value of the primitive
- * type {@code char} in an object. An object of type
+ * type {@code char} in an object. An object of class
* {@code Character} contains a single field whose type is
* {@code char}.
* <p>
- * In addition, this class provides several methods for determining
- * a character's category (lowercase letter, digit, etc.) and for converting
- * characters from uppercase to lowercase and vice versa.
- * <p>
- * Character information is based on the Unicode Standard, version 11.0.0.
- * <p>
- * The methods and data of class {@code Character} are defined by
- * the information in the <i>UnicodeData</i> file that is part of the
- * Unicode Character Database maintained by the Unicode
- * Consortium. This file specifies various properties including name
- * and general category for every defined Unicode code point or
- * character range.
+ * In addition, this class provides a large number of static methods for
+ * determining a character's category (lowercase letter, digit, etc.)
+ * and for converting characters from uppercase to lowercase and vice
+ * versa.
+ *
+ * <h3><a id="conformance">Unicode Conformance</a></h3>
* <p>
- * The file and its description are available from the Unicode Consortium at:
- * <ul>
- * <li><a href="http://www.unicode.org">http://www.unicode.org</a>
- * </ul>
+ * The fields and methods of class {@code Character} are defined in terms
+ * of character information from the Unicode Standard, specifically the
+ * <i>UnicodeData</i> file that is part of the Unicode Character Database.
+ * This file specifies properties including name and category for every
+ * assigned Unicode code point or character range. The file is available
+ * from the Unicode Consortium at
+ * <a href="http://www.unicode.org">http://www.unicode.org</a>.
* <p>
- * The code point, U+32FF, is reserved by the Unicode Consortium
- * to represent the Japanese square character for the new era that begins
- * May 2019. Relevant methods in the Character class return the same
- * properties as for the existing Japanese era characters (e.g., U+337E for
- * "Meizi"). For the details of the code point, refer to
- * <a href="http://blog.unicode.org/2018/09/new-japanese-era.html">
- * http://blog.unicode.org/2018/09/new-japanese-era.html</a>.
+ * The Java SE 13 Platform uses character information from version 11.0
+ * of the Unicode Standard, plus the Japanese Era code point,
+ * {@code U+32FF}, from the first version of the Unicode Standard
+ * after 11.0 that assigns the code point.
*
* <h3><a id="unicode">Unicode Character Representations</a></h3>
*
@@ -9495,7 +9489,7 @@
* character in a Java identifier.
* <p>
* A character may start a Java identifier if and only if
- * one of the following is true:
+ * one of the following conditions is true:
* <ul>
* <li> {@link #isLetter(char) isLetter(ch)} returns {@code true}
* <li> {@link #getType(char) getType(ch)} returns {@code LETTER_NUMBER}
@@ -9524,8 +9518,8 @@
* Determines if the specified character may be part of a Java
* identifier as other than the first character.
* <p>
- * A character may be part of a Java identifier if and only if any
- * of the following are true:
+ * A character may be part of a Java identifier if and only if one
+ * of the following conditions is true:
* <ul>
* <li> it is a letter
* <li> it is a currency symbol (such as {@code '$'})
@@ -9667,7 +9661,7 @@
* identifier as other than the first character.
* <p>
* A character may be part of a Java identifier if any of the following
- * are true:
+ * conditions are true:
* <ul>
* <li> it is a letter
* <li> it is a currency symbol (such as {@code '$'})
@@ -9704,7 +9698,7 @@
* identifier as other than the first character.
* <p>
* A character may be part of a Java identifier if any of the following
- * are true:
+ * conditions are true:
* <ul>
* <li> it is a letter
* <li> it is a currency symbol (such as {@code '$'})
@@ -9715,7 +9709,7 @@
* <li> it is a non-spacing mark
* <li> {@link #isIdentifierIgnorable(int)
* isIdentifierIgnorable(codePoint)} returns {@code true} for
- * the character
+ * the code point
* </ul>
*
* @param codePoint the character (Unicode code point) to be tested.
--- a/src/java.base/share/classes/java/time/chrono/JapaneseEra.java Sun Feb 03 08:16:08 2019 -0500
+++ b/src/java.base/share/classes/java/time/chrono/JapaneseEra.java Mon Feb 04 15:00:29 2019 -0500
@@ -88,15 +88,33 @@
/**
* An era in the Japanese Imperial calendar system.
* <p>
- * This class defines the valid eras for the Japanese chronology.
- * Japan introduced the Gregorian calendar starting with Meiji 6.
- * Only Meiji and later eras are supported;
- * dates before Meiji 6, January 1 are not supported.
- * The number of the valid eras may increase, as new eras may be
- * defined by the Japanese government. Once an era is defined,
- * future versions of the platform may add a singleton instance
- * for it. The defined era is expected to have a consecutive integer
- * associated with it.
+ * The Japanese government defines the official name and start date of
+ * each era. Eras are consecutive and their date ranges do not overlap,
+ * so the end date of one era is always the day before the start date
+ * of the next era.
+ * <p>
+ * The Java SE Platform supports all eras defined by the Japanese government,
+ * beginning with the Meiji era. Each era is identified in the Platform by an
+ * integer value and a name. The {@link #of(int)} and {@link #valueOf(String)}
+ * methods may be used to obtain a singleton instance of {@code JapaneseEra}
+ * for each era. The {@link #values()} method returns the singleton instances
+ * of all supported eras.
+ * <p>
+ * For convenience, this class declares a number of public static final fields
+ * that refer to singleton instances returned by the {@link #values()} method.
+ *
+ * @apiNote
+ * The fields declared in this class may evolve over time, in line with the
+ * results of the {@link #values()} method. However, there is not necessarily
+ * a 1:1 correspondence between the fields and the singleton instances.
+ *
+ * @apiNote
+ * The Japanese government may announce a new era and define its start
+ * date but not its official name. In this scenario, the singleton instance
+ * that represents the new era may return a name that is not stable until
+ * the official name is defined. Developers should exercise caution when
+ * relying on the name returned by any singleton instance that does not
+ * correspond to a public static final field.
*
* @implSpec
* This class is immutable and thread-safe.
@@ -199,14 +217,18 @@
//-----------------------------------------------------------------------
/**
* Obtains an instance of {@code JapaneseEra} from an {@code int} value.
+ * <ul>
+ * <li>The value {@code 1} is associated with the 'Showa' era, because
+ * it contains 1970-01-01 (ISO calendar system).</li>
+ * <li>The values {@code -1} and {@code 0} are associated with two earlier
+ * eras, Meiji and Taisho, respectively.</li>
+ * <li>A value greater than {@code 1} is associated with a later era,
+ * beginning with Heisei ({@code 2}).</li>
+ * </ul>
* <p>
- * The {@link #SHOWA} era that contains 1970-01-01 (ISO calendar system) has the value 1.
- * Later era is numbered 2 ({@link #HEISEI}). Earlier eras are numbered 0 ({@link #TAISHO}),
- * -1 ({@link #MEIJI}), only Meiji and later eras are supported.
- * <p>
- * In addition to the known era singletons, values for additional
- * eras may be defined. Those values are the {@link Era#getValue()}
- * of corresponding eras from the {@link #values()} method.
+ * Every instance of {@code JapaneseEra} that is returned from the {@link #values()}
+ * method has an int value (available via {@link Era#getValue()} which is
+ * accepted by this method.
*
* @param japaneseEra the era to represent
* @return the {@code JapaneseEra} singleton, not null
--- a/src/java.base/share/classes/java/util/jar/Attributes.java Sun Feb 03 08:16:08 2019 -0500
+++ b/src/java.base/share/classes/java/util/jar/Attributes.java Mon Feb 04 15:00:29 2019 -0500
@@ -265,9 +265,10 @@
}
/**
- * Compares the specified Attributes object with this Map for equality.
- * Returns true if the given object is also an instance of Attributes
- * and the two Attributes objects represent the same mappings.
+ * Compares the specified object to the underlying
+ * {@linkplain Attributes#map map} for equality.
+ * Returns true if the given object is also a Map
+ * and the two maps represent the same mappings.
*
* @param o the Object to be compared
* @return true if the specified Object is equal to this Map
--- a/src/java.desktop/share/legal/mesa3d.md Sun Feb 03 08:16:08 2019 -0500
+++ b/src/java.desktop/share/legal/mesa3d.md Mon Feb 04 15:00:29 2019 -0500
@@ -1,10 +1,10 @@
-## Mesa 3-D Graphics Library v4.1
+## Mesa 3-D Graphics Library v5.0
### Mesa License
<pre>
Mesa 3-D graphics library
-Version: 4.1
+Version: 5.0
Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/SourceTreeManager.java Sun Feb 03 08:16:08 2019 -0500
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,391 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- */
-/*
- * 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.xpath.internal;
-
-import com.sun.org.apache.xml.internal.dtm.DTM;
-import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import javax.xml.transform.Source;
-import javax.xml.transform.SourceLocator;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.URIResolver;
-import javax.xml.transform.sax.SAXSource;
-import javax.xml.transform.stream.StreamSource;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * This class bottlenecks all management of source trees. The methods
- * in this class should allow easy garbage collection of source
- * trees (not yet!), and should centralize parsing for those source trees.
- *
- * @LastModified: Oct 2017
- */
-@SuppressWarnings("deprecation")
-public class SourceTreeManager
-{
-
- /** List of SourceTree objects that this manager manages. */
- private List<SourceTree> m_sourceTree = new ArrayList<>();
-
- /**
- * Reset the list of SourceTree objects that this manager manages.
- *
- */
- public void reset()
- {
- m_sourceTree = new ArrayList<>();
- }
-
- /** The TrAX URI resolver used to obtain source trees. */
- URIResolver m_uriResolver;
-
- /**
- * Set an object that will be used to resolve URIs used in
- * document(), etc.
- * @param resolver An object that implements the URIResolver interface,
- * or null.
- */
- public void setURIResolver(URIResolver resolver)
- {
- m_uriResolver = resolver;
- }
-
- /**
- * Get the object that will be used to resolve URIs used in
- * document(), etc.
- * @return An object that implements the URIResolver interface,
- * or null.
- */
- public URIResolver getURIResolver()
- {
- return m_uriResolver;
- }
-
- /**
- * Given a document, find the URL associated with that document.
- * @param owner Document that was previously processed by this liaison.
- *
- * @return The base URI of the owner argument.
- */
- public String findURIFromDoc(int owner)
- {
- int n = m_sourceTree.size();
-
- for (int i = 0; i < n; i++)
- {
- SourceTree sTree = m_sourceTree.get(i);
-
- if (owner == sTree.m_root)
- return sTree.m_url;
- }
-
- return null;
- }
-
- /**
- * This will be called by the processor when it encounters
- * an xsl:include, xsl:import, or document() function.
- *
- * @param base The base URI that should be used.
- * @param urlString Value from an xsl:import or xsl:include's href attribute,
- * or a URI specified in the document() function.
- *
- * @return a Source that can be used to process the resource.
- *
- * @throws IOException
- * @throws TransformerException
- */
- public Source resolveURI(
- String base, String urlString, SourceLocator locator)
- throws TransformerException, IOException
- {
-
- Source source = null;
-
- if (null != m_uriResolver)
- {
- source = m_uriResolver.resolve(urlString, base);
- }
-
- if (null == source)
- {
- String uri = SystemIDResolver.getAbsoluteURI(urlString, base);
-
- source = new StreamSource(uri);
- }
-
- return source;
- }
-
- /** JJK: Support <?xalan:doc_cache_off?> kluge in ElemForEach.
- * TODO: This function is highly dangerous. Cache management must be improved.
- *
- * @param n The node to remove.
- */
- public void removeDocumentFromCache(int n)
- {
- if(DTM.NULL ==n)
- return;
- for(int i=m_sourceTree.size()-1;i>=0;--i)
- {
- SourceTree st= m_sourceTree.get(i);
- if(st!=null && st.m_root==n)
- {
- m_sourceTree.remove(i);
- return;
- }
- }
- }
-
-
-
- /**
- * Put the source tree root node in the document cache.
- * TODO: This function needs to be a LOT more sophisticated.
- *
- * @param n The node to cache.
- * @param source The Source object to cache.
- */
- public void putDocumentInCache(int n, Source source)
- {
-
- int cachedNode = getNode(source);
-
- if (DTM.NULL != cachedNode)
- {
- if (!(cachedNode == n))
- throw new RuntimeException(
- "Programmer's Error! "
- + "putDocumentInCache found reparse of doc: "
- + source.getSystemId());
- return;
- }
- if (null != source.getSystemId())
- {
- m_sourceTree.add(new SourceTree(n, source.getSystemId()));
- }
- }
-
- /**
- * Given a Source object, find the node associated with it.
- *
- * @param source The Source object to act as the key.
- *
- * @return The node that is associated with the Source, or null if not found.
- */
- public int getNode(Source source)
- {
-
-// if (source instanceof DOMSource)
-// return ((DOMSource) source).getNode();
-
- // TODO: Not sure if the BaseID is really the same thing as the ID.
- String url = source.getSystemId();
-
- if (null == url)
- return DTM.NULL;
-
- int n = m_sourceTree.size();
-
- // System.out.println("getNode: "+n);
- for (int i = 0; i < n; i++)
- {
- SourceTree sTree = m_sourceTree.get(i);
-
- // System.out.println("getNode - url: "+url);
- // System.out.println("getNode - sTree.m_url: "+sTree.m_url);
- if (url.equals(sTree.m_url))
- return sTree.m_root;
- }
-
- // System.out.println("getNode - returning: "+node);
- return DTM.NULL;
- }
-
- /**
- * Get the source tree from the a base URL and a URL string.
- *
- * @param base The base URI to use if the urlString is relative.
- * @param urlString An absolute or relative URL string.
- * @param locator The location of the caller, for diagnostic purposes.
- *
- * @return should be a non-null reference to the node identified by the
- * base and urlString.
- *
- * @throws TransformerException If the URL can not resolve to a node.
- */
- public int getSourceTree(
- String base, String urlString, SourceLocator locator, XPathContext xctxt)
- throws TransformerException
- {
-
- // System.out.println("getSourceTree");
- try
- {
- Source source = this.resolveURI(base, urlString, locator);
-
- // System.out.println("getSourceTree - base: "+base+", urlString: "+urlString+", source: "+source.getSystemId());
- return getSourceTree(source, locator, xctxt);
- }
- catch (IOException ioe)
- {
- throw new TransformerException(ioe.getMessage(), locator, ioe);
- }
-
- /* catch (TransformerException te)
- {
- throw new TransformerException(te.getMessage(), locator, te);
- }*/
- }
-
- /**
- * Get the source tree from the input source.
- *
- * @param source The Source object that should identify the desired node.
- * @param locator The location of the caller, for diagnostic purposes.
- *
- * @return non-null reference to a node.
- *
- * @throws TransformerException if the Source argument can't be resolved to
- * a node.
- */
- public int getSourceTree(Source source, SourceLocator locator, XPathContext xctxt)
- throws TransformerException
- {
-
- int n = getNode(source);
-
- if (DTM.NULL != n)
- return n;
-
- n = parseToNode(source, locator, xctxt);
-
- if (DTM.NULL != n)
- putDocumentInCache(n, source);
-
- return n;
- }
-
- /**
- * Try to create a DOM source tree from the input source.
- *
- * @param source The Source object that identifies the source node.
- * @param locator The location of the caller, for diagnostic purposes.
- *
- * @return non-null reference to node identified by the source argument.
- *
- * @throws TransformerException if the source argument can not be resolved
- * to a source node.
- */
- public int parseToNode(Source source, SourceLocator locator, XPathContext xctxt)
- throws TransformerException
- {
-
- try
- {
- Object xowner = xctxt.getOwnerObject();
- DTM dtm;
- if(null != xowner && xowner instanceof com.sun.org.apache.xml.internal.dtm.DTMWSFilter)
- {
- dtm = xctxt.getDTM(source, false,
- (com.sun.org.apache.xml.internal.dtm.DTMWSFilter)xowner, false, true);
- }
- else
- {
- dtm = xctxt.getDTM(source, false, null, false, true);
- }
- return dtm.getDocument();
- }
- catch (Exception e)
- {
- //e.printStackTrace();
- throw new TransformerException(e.getMessage(), locator, e);
- }
-
- }
-
- /**
- * This method returns the SAX2 parser to use with the InputSource
- * obtained from this URI.
- * It may return null if any SAX2-conformant XML parser can be used,
- * or if getInputSource() will also return null. The parser must
- * be free for use (i.e.
- * not currently in use for another parse().
- *
- * @param inputSource The value returned from the URIResolver.
- * @return a SAX2 XMLReader to use to resolve the inputSource argument.
- * @param locator The location of the original caller, for diagnostic purposes.
- *
- * @throws TransformerException if the reader can not be created.
- */
- public static XMLReader getXMLReader(Source inputSource, SourceLocator locator)
- throws TransformerException
- {
-
- try
- {
- XMLReader reader = (inputSource instanceof SAXSource)
- ? ((SAXSource) inputSource).getXMLReader() : null;
-
- if (null == reader)
- {
- try {
- javax.xml.parsers.SAXParserFactory factory=
- javax.xml.parsers.SAXParserFactory.newInstance();
- factory.setNamespaceAware( true );
- javax.xml.parsers.SAXParser jaxpParser=
- factory.newSAXParser();
- reader=jaxpParser.getXMLReader();
-
- } catch( javax.xml.parsers.ParserConfigurationException ex ) {
- throw new org.xml.sax.SAXException( ex );
- } catch( javax.xml.parsers.FactoryConfigurationError ex1 ) {
- throw new org.xml.sax.SAXException( ex1.toString() );
- } catch( NoSuchMethodError ex2 ) {
- }
- catch (AbstractMethodError ame){}
- if(null == reader)
- reader = XMLReaderFactory.createXMLReader();
- }
-
- try
- {
- reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
- true);
- }
- catch (org.xml.sax.SAXException se)
- {
-
- // What can we do?
- // TODO: User diagnostics.
- }
-
- return reader;
- }
- catch (org.xml.sax.SAXException se)
- {
- throw new TransformerException(se.getMessage(), locator, se);
- }
- }
-}
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPathContext.java Sun Feb 03 08:16:08 2019 -0500
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPathContext.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -49,7 +49,6 @@
import javax.xml.transform.ErrorListener;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.URIResolver;
-import jdk.xml.internal.JdkXmlUtils;
import org.xml.sax.XMLReader;
/**
@@ -57,7 +56,7 @@
*
* <p>This class extends DTMManager but does not directly implement it.</p>
* @xsl.usage advanced
- * @LastModified: Oct 2017
+ * @LastModified: Jan 2019
*/
public class XPathContext extends DTMManager // implements ExpressionContext
{
@@ -483,33 +482,6 @@
m_variableStacks = varStack;
}
- // ================ SourceTreeManager ===================
-
- /** The source tree manager, which associates Source objects to source
- * tree nodes. */
- private SourceTreeManager m_sourceTreeManager = new SourceTreeManager();
-
- /**
- * Get the SourceTreeManager associated with this execution context.
- *
- * @return the SourceTreeManager associated with this execution context.
- */
- public final SourceTreeManager getSourceTreeManager()
- {
- return m_sourceTreeManager;
- }
-
- /**
- * Set the SourceTreeManager associated with this execution context.
- *
- * @param mgr the SourceTreeManager to be associated with this
- * execution context.
- */
- public void setSourceTreeManager(SourceTreeManager mgr)
- {
- m_sourceTreeManager = mgr;
- }
-
// =================================================
/** The ErrorListener where errors and warnings are to be reported. */
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncDoclocation.java Sun Feb 03 08:16:08 2019 -0500
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncDoclocation.java Mon Feb 04 15:00:29 2019 -0500
@@ -62,8 +62,6 @@
if (DTM.NULL != whereNode)
{
fileLocation = dtm.getDocumentBaseURI();
-// int owner = dtm.getDocument();
-// fileLocation = xctxt.getSourceTreeManager().findURIFromDoc(owner);
}
}
--- a/src/jdk.javadoc/share/legal/jquery.md Sun Feb 03 08:16:08 2019 -0500
+++ b/src/jdk.javadoc/share/legal/jquery.md Mon Feb 04 15:00:29 2019 -0500
@@ -3,8 +3,7 @@
### jQuery License
```
jQuery v 3.3.1
-Copyright 2005, 2018 jQuery Foundation, Inc. and other contributors
-http://jquery.com/
+Copyright JS Foundation and other contributors, https://js.foundation/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
--- a/src/jdk.jdwp.agent/share/native/libjdwp/eventHelper.c Sun Feb 03 08:16:08 2019 -0500
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/eventHelper.c Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -752,6 +752,7 @@
holdEvents = JNI_FALSE;
debugMonitorNotifyAll(commandQueueLock);
debugMonitorExit(commandQueueLock);
+ unblockCommandLoop();
}
/*
--- a/test/hotspot/jtreg/ProblemList-Xcomp.txt Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -27,4 +27,4 @@
#
#############################################################################
-vmTestbase/vm/mlvm/meth/stress/jni/nativeAndMH/Test.java 8208235 solaris-all
+vmTestbase/vm/mlvm/meth/stress/jni/nativeAndMH/Test.java 8058176 solaris-all
--- a/test/hotspot/jtreg/ProblemList-graal.txt Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/ProblemList-graal.txt Mon Feb 04 15:00:29 2019 -0500
@@ -60,6 +60,8 @@
gc/g1/plab/TestPLABPromotion.java 8191048 generic-all
gc/g1/plab/TestPLABResize.java 8191048 generic-all
+gc/stress/TestStressG1Humongous.java 8218176 generic-all
+
compiler/compilercontrol/directives/LogTest.java 8181753 generic-all
gc/parallel/TestPrintGCDetailsVerbose.java 8196611 macosx-all
@@ -109,8 +111,6 @@
vmTestbase/vm/mlvm/anonloader/stress/oome/metaspace/Test.java 8186299 generic-all
# jvmti tests
-vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/TestDescription.java 8195635 generic-all
-
vmTestbase/nsk/jvmti/PopFrame/popframe009/TestDescription.java 8195639 generic-all
vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn001/TestDescription.java 8195674 generic-all
@@ -127,6 +127,61 @@
serviceability/jvmti/FieldAccessWatch/FieldAccessWatch.java 8202482 generic-all
+# tests require pop_frame and force_early_return capabilities
+vmTestbase/nsk/jdb/pop/pop001/pop001.java 8195635 generic-all
+vmTestbase/nsk/jdb/pop_exception/pop_exception001/pop_exception001.java 8195635 generic-all
+vmTestbase/nsk/jdb/reenter/reenter001/reenter001.java 8195635 generic-all
+vmTestbase/nsk/jdi/BScenarios/hotswap/tc01x002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/BScenarios/hotswap/tc02x001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/BScenarios/hotswap/tc02x002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/BScenarios/hotswap/tc04x001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/BScenarios/hotswap/tc04x002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/BScenarios/hotswap/tc06x001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/BScenarios/hotswap/tc08x001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/BScenarios/hotswap/tc10x002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/MethodExitEvent/returnValue/returnValue003/returnValue003.java 8195635 generic-all
+vmTestbase/nsk/jdi/Scenarios/invokeMethod/popframes001/TestDescription.jav 8195635 generic-all
+vmTestbase/nsk/jdi/Scenarios/invokeMethod/popframes001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/ThreadReference/popFrames/popframes001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/stress/serial/forceEarlyReturn001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/stress/serial/forceEarlyReturn002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdi/stress/serial/mixed002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jdwp/ThreadReference/ForceEarlyReturn/forceEarlyReturn002/forceEarlyReturn002.java 8195635 generic-all
+vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/ForceEarlyReturn/ForceEarlyReturn002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/PopFrame/popframe001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/PopFrame/popframe003/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/PopFrame/popframe005/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/capability/CM01/cm01t007/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS102/hs102t001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS201/hs201t001/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS201/hs201t002/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS202/hs202t002/hs202t002.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS203/hs203t001/hs203t001.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS203/hs203t002/hs203t002.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS203/hs203t003/hs203t003.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS203/hs203t004/hs203t004.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS204/hs204t001/hs204t001.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS204/hs204t003/hs204t003.java 8195635 generic-all
+vmTestbase/nsk/jvmti/scenarios/hotswap/HS204/hs204t004/hs204t004.java 8195635 generic-all
+vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretfp/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretint/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretlong/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretobj/TestDescription.java 8195635 generic-all
+vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretstr/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_a/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manySame_a/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_b/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_a/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2same_b/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_a/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_none2indy_b/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/redefineClassInTarget/TestDescription.java 8195635 generic-all
+vmTestbase/vm/mlvm/indy/func/jvmti/stepBreakPopReturn/INDIFY_Test.java 8195635 generic-all
+
compiler/stable/TestStableBoolean.java 8204347 generic-all
compiler/stable/TestStableByte.java 8204347 generic-all
compiler/stable/TestStableChar.java 8204347 generic-all
--- a/test/hotspot/jtreg/ProblemList.txt Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/ProblemList.txt Mon Feb 04 15:00:29 2019 -0500
@@ -57,9 +57,9 @@
compiler/runtime/Test8168712.java 8211769,8211771 generic-ppc64,generic-ppc64le,linux-s390x
-applications/ctw/modules/java_desktop.java 8217851 windows-all
-applications/ctw/modules/java_desktop_2.java 8217851 windows-all
-applications/ctw/modules/jdk_jconsole.java 8217851 windows-all
+applications/ctw/modules/java_desktop.java 8189604 windows-all
+applications/ctw/modules/java_desktop_2.java 8189604 windows-all
+applications/ctw/modules/jdk_jconsole.java 8189604 windows-all
#############################################################################
@@ -67,12 +67,12 @@
gc/epsilon/TestMemoryMXBeans.java 8206434 generic-all
gc/g1/humongousObjects/objectGraphTest/TestObjectGraphAfterGC.java 8156755 generic-all
-gc/survivorAlignment/TestPromotionToSurvivor.java 8129886 generic-all
+gc/survivorAlignment/TestPromotionToSurvivor.java 8218049 generic-all
+gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java 8218049 generic-all
gc/g1/logging/TestG1LoggingFailure.java 8169634 generic-all
gc/g1/humongousObjects/TestHeapCounters.java 8178918 generic-all
gc/stress/gclocker/TestGCLockerWithParallel.java 8180622 generic-all
gc/stress/gclocker/TestGCLockerWithG1.java 8180622 generic-all
-gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java 8177765 generic-all
gc/stress/TestJNIBlockFullGC/TestJNIBlockFullGC.java 8192647 generic-all
gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8193639 solaris-all
@@ -171,7 +171,7 @@
vmTestbase/metaspace/gc/firstGC_default/TestDescription.java 8208250 generic-all
vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted003/TestDescription.java 6606767 generic-all
-vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted004/TestDescription.java 7013634,6606767 generic-all
+vmTestbase/nsk/jvmti/ResourceExhausted/resexhausted004/TestDescription.java 6606767 generic-all
vmTestbase/nsk/jvmti/scenarios/extension/EX03/ex03t001/TestDescription.java 8173658 generic-all
vmTestbase/nsk/jvmti/AttachOnDemand/attach045/TestDescription.java 8202971 generic-all
@@ -181,14 +181,14 @@
vmTestbase/jit/escape/LockCoarsening/LockCoarsening002/TestDescription.java 8208259 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/redefineClassInBootstrap/TestDescription.java 8013267 generic-all
-vmTestbase/vm/mlvm/meth/func/java/throwException/Test.java 8208255 generic-all
-vmTestbase/vm/mlvm/meth/func/jdi/breakpointOtherStratum/Test.java 8208257,8208255 generic-all
-vmTestbase/vm/mlvm/meth/stress/compiler/deoptimize/Test.java 8208255 generic-all
-vmTestbase/vm/mlvm/meth/stress/compiler/i2c_c2i/Test.java 8208255 generic-all
-vmTestbase/vm/mlvm/meth/stress/compiler/sequences/Test.java 8208255 generic-all
-vmTestbase/vm/mlvm/meth/stress/gc/callSequencesDuringGC/Test.java 8208255 generic-all
-vmTestbase/vm/mlvm/meth/stress/java/sequences/Test.java 8208255 generic-all
-vmTestbase/vm/mlvm/meth/stress/jdi/breakpointInCompiledCode/Test.java 8208255 generic-all
+vmTestbase/vm/mlvm/meth/func/java/throwException/Test.java 8058176 generic-all
+vmTestbase/vm/mlvm/meth/func/jdi/breakpointOtherStratum/Test.java 8208257,8058176 generic-all
+vmTestbase/vm/mlvm/meth/stress/compiler/deoptimize/Test.java 8058176 generic-all
+vmTestbase/vm/mlvm/meth/stress/compiler/i2c_c2i/Test.java 8058176 generic-all
+vmTestbase/vm/mlvm/meth/stress/compiler/sequences/Test.java 8058176 generic-all
+vmTestbase/vm/mlvm/meth/stress/gc/callSequencesDuringGC/Test.java 8058176 generic-all
+vmTestbase/vm/mlvm/meth/stress/java/sequences/Test.java 8058176 generic-all
+vmTestbase/vm/mlvm/meth/stress/jdi/breakpointInCompiledCode/Test.java 8058176 generic-all
vmTestbase/vm/mlvm/mixed/stress/java/findDeadlock/TestDescription.java 8208278 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2none_a/TestDescription.java 8013267 generic-all
vmTestbase/vm/mlvm/indy/func/jvmti/mergeCP_indy2manyDiff_b/TestDescription.java 8013267 generic-all
--- a/test/hotspot/jtreg/compiler/aot/AotCompiler.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/compiler/aot/AotCompiler.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -117,6 +117,8 @@
// Execute with asserts
args.add("-J-ea");
args.add("-J-esa");
+ // we don't want to run jaotc w/ Xcomp even if it's in extraopts
+ args.add("-J-Xmixed");
return launchJaotc(args, extraopts);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/cha/StrengthReduceInterfaceCall.java Mon Feb 04 15:00:29 2019 -0500
@@ -0,0 +1,970 @@
+/*
+ * 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
+ * @requires !vm.graal.enabled
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * java.base/jdk.internal.misc
+ * java.base/jdk.internal.vm.annotation
+ * @library /test/lib /
+ * @build sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+PrintCompilation -XX:+PrintInlining -XX:+TraceDependencies -verbose:class -XX:CompileCommand=quiet
+ * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=compileonly,*::m -XX:CompileCommand=dontinline,*::test
+ * -Xbatch -XX:+WhiteBoxAPI -Xmixed
+ * -XX:-TieredCompilation
+ * compiler.cha.StrengthReduceInterfaceCall
+ *
+ * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
+ * -XX:+PrintCompilation -XX:+PrintInlining -XX:+TraceDependencies -verbose:class -XX:CompileCommand=quiet
+ * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=compileonly,*::m -XX:CompileCommand=dontinline,*::test
+ * -Xbatch -XX:+WhiteBoxAPI -Xmixed
+ * -XX:+TieredCompilation -XX:TieredStopAtLevel=1
+ * compiler.cha.StrengthReduceInterfaceCall
+ */
+package compiler.cha;
+
+import jdk.internal.misc.Unsafe;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.vm.annotation.DontInline;
+import sun.hotspot.WhiteBox;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.concurrent.Callable;
+
+import static jdk.test.lib.Asserts.*;
+import static jdk.internal.org.objectweb.asm.ClassWriter.*;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+public class StrengthReduceInterfaceCall {
+ public static void main(String[] args) {
+ run(ObjectToString.class);
+ run(ObjectHashCode.class);
+ run(TwoLevelHierarchyLinear.class);
+ run(ThreeLevelHierarchyLinear.class);
+ run(ThreeLevelHierarchyAbstractVsDefault.class);
+ run(ThreeLevelDefaultHierarchy.class);
+ run(ThreeLevelDefaultHierarchy1.class);
+ }
+
+ public static class ObjectToString extends ATest<ObjectToString.I> {
+ public ObjectToString() { super(I.class, C.class); }
+
+ interface J { String toString(); }
+ interface I extends J {}
+
+ static class C implements I {}
+
+ interface K1 extends I {}
+ interface K2 extends I { String toString(); } // K2.tS() ABSTRACT
+ // interface K3 extends I { default String toString() { return "K3"; } // K2.tS() DEFAULT
+
+ static class D implements I { public String toString() { return "D"; }}
+
+ static class DJ1 implements J {}
+ static class DJ2 implements J { public String toString() { return "DJ2"; }}
+
+ @Override
+ public Object test(I i) { return ObjectToStringHelper.test(i); /* invokeinterface I.toString() */ }
+
+ @TestCase
+ public void testMono() {
+ // 0. Trigger compilation of a monomorphic call site
+ compile(monomophic()); // C1 <: C <: intf I <: intf J <: Object.toString()
+ assertCompiled();
+
+ // Dependency: none
+
+ call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
+ assertCompiled();
+ }
+
+ @TestCase
+ public void testBi() {
+ // 0. Trigger compilation of a bimorphic call site
+ compile(bimorphic()); // C1 <: C <: intf I <: intf J <: Object.toString()
+ assertCompiled();
+
+ // Dependency: none
+
+ call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
+ assertCompiled();
+ }
+
+ @TestCase
+ public void testMega() {
+ // 0. Trigger compilation of a megamorphic call site
+ compile(megamorphic()); // C1,C2,C3 <: C <: intf I <: intf J <: Object.toString()
+ assertCompiled();
+
+ // Dependency: none
+ // compiler.cha.StrengthReduceInterfaceCall$ObjectToString::test (5 bytes)
+ // @ 1 compiler.cha.StrengthReduceInterfaceCall$ObjectToStringHelper::test (7 bytes) inline (hot)
+ // @ 1 java.lang.Object::toString (36 bytes) virtual call
+
+ // No dependency - no invalidation
+ repeat(100, () -> call(new C(){})); // Cn <: C <: intf I
+ assertCompiled();
+
+ initialize(K1.class, // intf K1 <: intf I <: intf J
+ K2.class, // intf K2.tS ABSTRACT <: intf I <: intf J
+ DJ1.class, // DJ1 <: intf J
+ DJ2.class); // DJ2.tS <: intf J
+ assertCompiled();
+
+ initialize(D.class); // D.tS <: intf I <: intf J
+ assertCompiled();
+
+ call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
+ assertCompiled();
+ }
+
+ @Override
+ public void checkInvalidReceiver() {
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+ test(o);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
+ test(j);
+ });
+ assertCompiled();
+ }
+ }
+
+ public static class ObjectHashCode extends ATest<ObjectHashCode.I> {
+ public ObjectHashCode() { super(I.class, C.class); }
+
+ interface J {}
+ interface I extends J {}
+
+ static class C implements I {}
+
+ interface K1 extends I {}
+ interface K2 extends I { int hashCode(); } // K2.hC() ABSTRACT
+ // interface K3 extends I { default int hashCode() { return CORRECT; } // K2.hC() DEFAULT
+
+ static class D implements I { public int hashCode() { return super.hashCode(); }}
+
+ static class DJ1 implements J {}
+ static class DJ2 implements J { public int hashCode() { return super.hashCode(); }}
+
+ @Override
+ public Object test(I i) {
+ return ObjectHashCodeHelper.test(i); /* invokeinterface I.hashCode() */
+ }
+
+ @TestCase
+ public void testMono() {
+ // 0. Trigger compilation of a monomorphic call site
+ compile(monomophic()); // C1 <: C <: intf I <: intf J <: Object.hashCode()
+ assertCompiled();
+
+ // Dependency: none
+
+ call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
+ assertCompiled();
+ }
+
+ @TestCase
+ public void testBi() {
+ // 0. Trigger compilation of a bimorphic call site
+ compile(bimorphic()); // C1 <: C <: intf I <: intf J <: Object.toString()
+ assertCompiled();
+
+ // Dependency: none
+
+ call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
+ assertCompiled();
+ }
+
+ @TestCase
+ public void testMega() {
+ // 0. Trigger compilation of a megamorphic call site
+ compile(megamorphic()); // C1,C2,C3 <: C <: intf I <: intf J <: Object.hashCode()
+ assertCompiled();
+
+ // Dependency: none
+
+ // No dependency - no invalidation
+ repeat(100, () -> call(new C(){})); // Cn <: C <: intf I
+ assertCompiled();
+
+ initialize(K1.class, // intf K1 <: intf I <: intf J
+ K2.class, // intf K2.hC ABSTRACT <: intf I <: intf J
+ DJ1.class, // DJ1 <: intf J
+ DJ2.class); // DJ2.hC <: intf J
+ assertCompiled();
+
+ initialize(D.class); // D.hC <: intf I <: intf J
+ assertCompiled();
+
+ call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
+ assertCompiled();
+ }
+
+ @Override
+ public void checkInvalidReceiver() {
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+ test(o);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
+ test(j);
+ });
+ assertCompiled();
+ }
+ }
+
+ public static class TwoLevelHierarchyLinear extends ATest<TwoLevelHierarchyLinear.I> {
+ public TwoLevelHierarchyLinear() { super(I.class, C.class); }
+
+ interface J { default Object m() { return WRONG; } }
+
+ interface I extends J { Object m(); }
+ static class C implements I { public Object m() { return CORRECT; }}
+
+ interface K1 extends I {}
+ interface K2 extends I { Object m(); }
+ interface K3 extends I { default Object m() { return WRONG; }}
+
+ static class D implements I { public Object m() { return WRONG; }}
+
+ static class DJ1 implements J {}
+ static class DJ2 implements J { public Object m() { return WRONG; }}
+
+ @DontInline
+ public Object test(I i) {
+ return i.m();
+ }
+
+ @TestCase
+ public void testMega1() {
+ // 0. Trigger compilation of a megamorphic call site
+ compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m ABSTRACT <: intf J.m ABSTRACT
+ assertCompiled();
+
+ // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+ checkInvalidReceiver(); // ensure proper type check is preserved
+
+ // 1. No deoptimization/invalidation on not-yet-seen receiver
+ repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
+ assertCompiled();
+
+ // 2. No dependency invalidation on class loading of unrelated classes: different context
+ initialize(K1.class, // intf K1 <: intf I.m ABSTRACT <: intf J.m DEFAULT
+ K2.class, // intf K2.m ABSTRACT <: intf I.m ABSTRACT <: intf J.m DEFAULT
+ DJ1.class, // DJ1 <: intf J.m DEFAULT
+ DJ2.class); // DJ2.m <: intf J.m DEFAULT
+ assertCompiled();
+
+ // 3. Dependency invalidation on D <: I
+ initialize(D.class); // D.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
+ assertNotCompiled();
+
+ // 4. Recompilation: no inlining, no dependencies
+ compile(megamorphic());
+ call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
+ assertCompiled();
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+ }
+
+ @TestCase
+ public void testMega2() {
+ // 0. Trigger compilation of a megamorphic call site
+ compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
+ assertCompiled();
+
+ // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+ // 1. Dependency invalidation
+ initialize(K3.class); // intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m DEFAULT
+ assertNotCompiled();
+
+ // 2. Recompilation: still inlines
+ // FIXME: no default method support in CHA yet
+ compile(megamorphic());
+ call(new K3() { public Object m() { return CORRECT; }}); // K3n.m <: intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m ABSTRACT
+ assertNotCompiled();
+
+ // 3. Recompilation: no inlining, no dependencies
+ compile(megamorphic());
+ call(new K3() { public Object m() { return CORRECT; }}); // Kn.m <: intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m DEFAULT
+ assertCompiled();
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+ }
+
+ @Override
+ public void checkInvalidReceiver() {
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+ test(o);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
+ test(j);
+ });
+ assertCompiled();
+ }
+ }
+
+ public static class ThreeLevelHierarchyLinear extends ATest<ThreeLevelHierarchyLinear.I> {
+ public ThreeLevelHierarchyLinear() { super(I.class, C.class); }
+
+ interface J { Object m(); }
+ interface I extends J {}
+
+ interface K1 extends I {}
+ interface K2 extends I { Object m(); }
+ interface K3 extends I { default Object m() { return WRONG; }}
+
+ static class C implements I { public Object m() { return CORRECT; }}
+
+ static class DI implements I { public Object m() { return WRONG; }}
+ static class DJ implements J { public Object m() { return WRONG; }}
+
+ @DontInline
+ public Object test(I i) {
+ return i.m(); // I <: J.m ABSTRACT
+ }
+
+ @TestCase
+ public void testMega1() {
+ // 0. Trigger compilation of a megamorphic call site
+ compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
+ assertCompiled();
+
+ // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+ // 1. No deoptimization/invalidation on not-yet-seen receiver
+ repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I
+ assertCompiled(); // No deopt on not-yet-seen receiver
+
+ // 2. No dependency invalidation: different context
+ initialize(DJ.class, // DJ.m <: intf J.m ABSTRACT
+ K1.class, // intf K1 <: intf I <: intf J.m ABSTRACT
+ K2.class); // intf K2.m ABSTRACT <: intf I <: intf J.m ABSTRACT
+ assertCompiled();
+
+ // 3. Dependency invalidation: DI.m <: I
+ initialize(DI.class); // DI.m <: intf I <: intf J.m ABSTRACT
+ assertNotCompiled();
+
+ // 4. Recompilation w/o a dependency
+ compile(megamorphic());
+ call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I <: intf J.m ABSTRACT
+ assertCompiled(); // no dependency
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+ }
+
+ @TestCase
+ public void testMega2() {
+ compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
+ assertCompiled();
+
+ // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+ // Dependency invalidation
+ initialize(K3.class); // intf K3.m DEFAULT <: intf I;
+ assertNotCompiled(); // FIXME: default methods in sub-interfaces shouldn't be taken into account by CHA
+
+ // Recompilation with a dependency
+ compile(megamorphic());
+ assertCompiled();
+
+ // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+ call(new K3() { public Object m() { return CORRECT; }}); // Kn.m <: K3.m DEFAULT <: intf I <: intf J.m ABSTRACT
+ assertNotCompiled();
+
+ // Recompilation w/o a dependency
+ compile(megamorphic());
+ // Dependency: none
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+ call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I <: intf J.m ABSTRACT
+ assertCompiled();
+ }
+
+ @Override
+ public void checkInvalidReceiver() {
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+ test(o);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() { public Object m() { return WRONG; }}); // super interface
+ test(j);
+ });
+ assertCompiled();
+ }
+ }
+
+ public static class ThreeLevelHierarchyAbstractVsDefault extends ATest<ThreeLevelHierarchyAbstractVsDefault.I> {
+ public ThreeLevelHierarchyAbstractVsDefault() { super(I.class, C.class); }
+
+ interface J1 { default Object m() { return WRONG; } } // intf J1.m DEFAULT
+ interface J2 extends J1 { Object m(); } // intf J2.m ABSTRACT <: intf J1
+ interface I extends J1, J2 {} // intf I.m OVERPASS <: intf J1,J2
+
+ static class C implements I { public Object m() { return CORRECT; }}
+
+ @DontInline
+ public Object test(I i) {
+ return i.m(); // intf I.m OVERPASS
+ }
+
+ static class DI implements I { public Object m() { return WRONG; }}
+
+ static class DJ11 implements J1 {}
+ static class DJ12 implements J1 { public Object m() { return WRONG; }}
+
+ static class DJ2 implements J2 { public Object m() { return WRONG; }}
+
+ interface K11 extends J1 {}
+ interface K12 extends J1 { Object m(); }
+ interface K13 extends J1 { default Object m() { return WRONG; }}
+ interface K21 extends J2 {}
+ interface K22 extends J2 { Object m(); }
+ interface K23 extends J2 { default Object m() { return WRONG; }}
+
+
+ public void testMega1() {
+ // 0. Trigger compilation of megamorphic call site
+ compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
+ assertCompiled();
+
+ // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+ // 1. No deopt/invalidation on not-yet-seen receiver
+ repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
+ assertCompiled();
+
+ // 2. No dependency invalidation: different context
+ initialize(K11.class, K12.class, K13.class,
+ K21.class, K22.class, K23.class);
+
+ // 3. Dependency invalidation: Cn.m <: C <: I
+ call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
+ assertNotCompiled();
+
+ // 4. Recompilation w/o a dependency
+ compile(megamorphic());
+ call(new C() { public Object m() { return CORRECT; }});
+ assertCompiled(); // no inlining
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+ }
+
+ public void testMega2() {
+ // 0. Trigger compilation of a megamorphic call site
+ compile(megamorphic());
+ assertCompiled();
+
+ // Dependency: type = unique_concrete_method, context = I, method = C.m
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+ // 1. No dependency invalidation: different context
+ initialize(DJ11.class,
+ DJ12.class,
+ DJ2.class);
+ assertCompiled();
+
+ // 2. Dependency invalidation: DI.m <: I
+ initialize(DI.class);
+ assertNotCompiled();
+
+ // 3. Recompilation w/o a dependency
+ compile(megamorphic());
+ call(new C() { public Object m() { return CORRECT; }});
+ assertCompiled(); // no inlining
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+ }
+
+ @Override
+ public void checkInvalidReceiver() {
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+ test(o);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J1() {}); // super interface
+ test(j);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J2() { public Object m() { return WRONG; }}); // super interface
+ test(j);
+ });
+ assertCompiled();
+ }
+ }
+
+ public static class ThreeLevelDefaultHierarchy extends ATest<ThreeLevelDefaultHierarchy.I> {
+ public ThreeLevelDefaultHierarchy() { super(I.class, C.class); }
+
+ interface J { default Object m() { return WRONG; }}
+ interface I extends J {}
+
+ static class C implements I { public Object m() { return CORRECT; }}
+
+ interface K1 extends I {}
+ interface K2 extends I { Object m(); }
+ interface K3 extends I { default Object m() { return WRONG; }}
+
+ static class DI implements I { public Object m() { return WRONG; }}
+ static class DJ implements J { public Object m() { return WRONG; }}
+
+ @DontInline
+ public Object test(I i) {
+ return i.m(); // no inlining since J.m is a default method
+ }
+
+ @TestCase
+ public void testMega() {
+ // 0. Trigger compilation of a megamorphic call site
+ compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
+ assertCompiled();
+
+ // Dependency: none
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+ // 1. No deoptimization/invalidation on not-yet-seen receiver
+ repeat(100, () -> call(new C() {}));
+ assertCompiled();
+
+ // 2. No dependency and no inlining
+ initialize(DJ.class, // DJ.m <: intf J.m ABSTRACT
+ DI.class, // DI.m <: intf I <: intf J.m ABSTRACT
+ K1.class, // intf K1 <: intf I <: intf J.m ABSTRACT
+ K2.class); // intf K2.m ABSTRACT <: intf I <: intf J.m ABSTRACT
+ assertCompiled();
+ }
+
+ @Override
+ public void checkInvalidReceiver() {
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+ test(o);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
+ test(j);
+ });
+ assertCompiled();
+ }
+ }
+
+ public static class ThreeLevelDefaultHierarchy1 extends ATest<ThreeLevelDefaultHierarchy1.I> {
+ public ThreeLevelDefaultHierarchy1() { super(I.class, C.class); }
+
+ interface J1 { Object m();}
+ interface J2 extends J1 { default Object m() { return WRONG; } }
+ interface I extends J1, J2 {}
+
+ static class C implements I { public Object m() { return CORRECT; }}
+
+ interface K1 extends I {}
+ interface K2 extends I { Object m(); }
+ interface K3 extends I { default Object m() { return WRONG; }}
+
+ static class DI implements I { public Object m() { return WRONG; }}
+ static class DJ1 implements J1 { public Object m() { return WRONG; }}
+ static class DJ2 implements J2 { public Object m() { return WRONG; }}
+
+ @DontInline
+ public Object test(I i) {
+ return i.m(); // no inlining since J.m is a default method
+ }
+
+ @TestCase
+ public void testMega() {
+ // 0. Trigger compilation of a megamorphic call site
+ compile(megamorphic());
+ assertCompiled();
+
+ // Dependency: none
+
+ checkInvalidReceiver(); // ensure proper type check on receiver is preserved
+
+ // 1. No deoptimization/invalidation on not-yet-seen receiver
+ repeat(100, () -> call(new C() {}));
+ assertCompiled();
+
+ // 2. No dependency, no inlining
+ // CHA doesn't support default methods yet.
+ initialize(DJ1.class,
+ DJ2.class,
+ DI.class,
+ K1.class,
+ K2.class,
+ K3.class);
+ assertCompiled();
+ }
+
+ @Override
+ public void checkInvalidReceiver() {
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
+ test(o);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J1() { public Object m() { return WRONG; } }); // super interface
+ test(j);
+ });
+ assertCompiled();
+
+ shouldThrow(IncompatibleClassChangeError.class, () -> {
+ I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J2() {}); // super interface
+ test(j);
+ });
+ assertCompiled();
+ }
+ }
+
+ /* =========================================================== */
+
+ interface Action {
+ int run();
+ }
+
+ public static final Unsafe U = Unsafe.getUnsafe();
+
+ interface Test<T> {
+ boolean isCompiled();
+ void assertNotCompiled();
+ void assertCompiled();
+
+ void call(T o);
+ T receiver(int id);
+
+ default Runnable monomophic() {
+ return () -> {
+ call(receiver(0)); // 100%
+ };
+ }
+
+ default Runnable bimorphic() {
+ return () -> {
+ call(receiver(0)); // 50%
+ call(receiver(1)); // 50%
+ };
+ }
+
+ default Runnable polymorphic() {
+ return () -> {
+ for (int i = 0; i < 23; i++) {
+ call(receiver(0)); // 92%
+ }
+ call(receiver(1)); // 4%
+ call(receiver(2)); // 4%
+ };
+ }
+
+ default Runnable megamorphic() {
+ return () -> {
+ call(receiver(0)); // 33%
+ call(receiver(1)); // 33%
+ call(receiver(2)); // 33%
+ };
+ }
+
+ default void compile(Runnable r) {
+ assertNotCompiled();
+ while(!isCompiled()) {
+ r.run();
+ }
+ assertCompiled();
+ }
+
+ default void initialize(Class<?>... cs) {
+ for (Class<?> c : cs) {
+ U.ensureClassInitialized(c);
+ }
+ }
+
+ default void repeat(int cnt, Runnable r) {
+ for (int i = 0; i < cnt; i++) {
+ r.run();
+ }
+ }
+ }
+
+ public static abstract class ATest<T> implements Test<T> {
+ public static final WhiteBox WB = WhiteBox.getWhiteBox();
+
+ public static final Object CORRECT = new Object();
+ public static final Object WRONG = new Object();
+
+ final Method TEST;
+ private final Class<T> declared;
+ private final Class<?> receiver;
+
+ private final HashMap<Integer, T> receivers = new HashMap<>();
+
+ public ATest(Class<T> declared, Class<?> receiver) {
+ this.declared = declared;
+ this.receiver = receiver;
+ TEST = compute(() -> this.getClass().getDeclaredMethod("test", declared));
+ }
+
+ @DontInline
+ public abstract Object test(T i);
+
+ public abstract void checkInvalidReceiver();
+
+ public T receiver(int id) {
+ return receivers.computeIfAbsent(id, (i -> {
+ try {
+ MyClassLoader cl = (MyClassLoader) receiver.getClassLoader();
+ Class<?> sub = cl.subclass(receiver, i);
+ return (T)sub.getDeclaredConstructor().newInstance();
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }));
+ }
+
+ @Override
+ public boolean isCompiled() { return WB.isMethodCompiled(TEST); }
+
+ @Override
+ public void assertNotCompiled() { assertFalse(isCompiled()); }
+
+ @Override
+ public void assertCompiled() { assertTrue(isCompiled()); }
+
+ @Override
+ public void call(T i) {
+ assertTrue(test(i) != WRONG);
+ }
+ }
+
+ @Retention(value = RetentionPolicy.RUNTIME)
+ public @interface TestCase {}
+
+ static void run(Class<?> test) {
+ try {
+ for (Method m : test.getDeclaredMethods()) {
+ if (m.isAnnotationPresent(TestCase.class)) {
+ System.out.println(m.toString());
+ ClassLoader cl = new MyClassLoader(test);
+ Class<?> c = cl.loadClass(test.getName());
+ c.getMethod(m.getName()).invoke(c.getDeclaredConstructor().newInstance());
+ }
+ }
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ static class ObjectToStringHelper {
+ static Object test(Object o) {
+ throw new Error("not used");
+ }
+ }
+ static class ObjectHashCodeHelper {
+ static int test(Object o) {
+ throw new Error("not used");
+ }
+ }
+
+ static final class MyClassLoader extends ClassLoader {
+ private final Class<?> test;
+
+ MyClassLoader(Class<?> test) {
+ this.test = test;
+ }
+
+ static String intl(String s) {
+ return s.replace('.', '/');
+ }
+
+ Class<?> subclass(Class<?> c, int id) {
+ String name = c.getName() + id;
+ Class<?> sub = findLoadedClass(name);
+ if (sub == null) {
+ ClassWriter cw = new ClassWriter(COMPUTE_MAXS | COMPUTE_FRAMES);
+ cw.visit(52, ACC_PUBLIC | ACC_SUPER, intl(name), null, intl(c.getName()), null);
+
+ { // Default constructor: <init>()V
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, intl(c.getName()), "<init>", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
+ byte[] classFile = cw.toByteArray();
+ return defineClass(name, classFile, 0, classFile.length);
+ }
+ return sub;
+ }
+
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException
+ {
+ // First, check if the class has already been loaded
+ Class<?> c = findLoadedClass(name);
+ if (c == null) {
+ try {
+ c = getParent().loadClass(name);
+ if (name.endsWith("ObjectToStringHelper")) {
+ ClassWriter cw = new ClassWriter(COMPUTE_MAXS | COMPUTE_FRAMES);
+ cw.visit(52, ACC_PUBLIC | ACC_SUPER, intl(name), null, "java/lang/Object", null);
+
+ {
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "test", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEINTERFACE, intl(test.getName()) + "$I", "toString", "()Ljava/lang/String;", true);
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
+ byte[] classFile = cw.toByteArray();
+ return defineClass(name, classFile, 0, classFile.length);
+ } else if (name.endsWith("ObjectHashCodeHelper")) {
+ ClassWriter cw = new ClassWriter(COMPUTE_MAXS | COMPUTE_FRAMES);
+ cw.visit(52, ACC_PUBLIC | ACC_SUPER, intl(name), null, "java/lang/Object", null);
+
+ {
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "test", "(Ljava/lang/Object;)I", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEINTERFACE, intl(test.getName()) + "$I", "hashCode", "()I", true);
+ mv.visitInsn(IRETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+
+ byte[] classFile = cw.toByteArray();
+ return defineClass(name, classFile, 0, classFile.length);
+ } else if (c == test || name.startsWith(test.getName())) {
+ try {
+ String path = name.replace('.', '/') + ".class";
+ byte[] classFile = getParent().getResourceAsStream(path).readAllBytes();
+ return defineClass(name, classFile, 0, classFile.length);
+ } catch (IOException e) {
+ throw new Error(e);
+ }
+ }
+ } catch (ClassNotFoundException e) {
+ // ClassNotFoundException thrown if class not found
+ // from the non-null parent class loader
+ }
+
+ if (c == null) {
+ // If still not found, then invoke findClass in order
+ // to find the class.
+ c = findClass(name);
+ }
+ }
+ if (resolve) {
+ resolveClass(c);
+ }
+ return c;
+ }
+ }
+
+ public interface RunnableWithException {
+ void run() throws Throwable;
+ }
+
+ public static void shouldThrow(Class<? extends Throwable> expectedException, RunnableWithException r) {
+ try {
+ r.run();
+ throw new AssertionError("Exception not thrown: " + expectedException.getName());
+ } catch(Throwable e) {
+ if (expectedException == e.getClass()) {
+ // success: proper exception is thrown
+ } else {
+ throw new Error(expectedException.getName() + " is expected", e);
+ }
+ }
+ }
+
+ public static MethodHandle unsafeCastMH(Class<?> cls) {
+ try {
+ MethodHandle mh = MethodHandles.identity(Object.class);
+ return MethodHandles.explicitCastArguments(mh, mh.type().changeReturnType(cls));
+ } catch (Throwable e) {
+ throw new Error(e);
+ }
+ }
+
+ static <T> T compute(Callable<T> c) {
+ try {
+ return c.call();
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/codegen/aes/TestCipherBlockChainingEncrypt.java Mon Feb 04 15:00:29 2019 -0500
@@ -0,0 +1,136 @@
+/*
+ * 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 8209951
+ * @summary SIGBUS in com.sun.crypto.provider.CipherBlockChaining
+ * @run main/othervm/timeout=300 -Xbatch
+ * compiler.codegen.aes.TestCipherBlockChainingEncrypt
+ */
+
+package compiler.codegen.aes;
+
+import java.io.PrintStream;
+import java.security.*;
+import java.util.Random;
+import java.lang.reflect.Method;
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
+public class TestCipherBlockChainingEncrypt {
+ private static String algorithm = "PBEWithHmacSHA1AndAES_256";
+ private static final String PBEPASS = "Hush, it's supposed to be a secret!";
+
+ private static final int INPUT_LENGTH = 800;
+ private static final int[] OFFSETS = {0};
+ private static final int NUM_PAD_BYTES = 8;
+ private static final int PBKDF2_ADD_PAD_BYTES = 8;
+
+ private static SecretKey key;
+ private static Cipher ci;
+
+ public static void main(String[] args) throws Exception {
+ for(int i=0; i<5_000; i++) {
+ if (!(new TestCipherBlockChainingEncrypt().test(args))) {
+ throw new RuntimeException("TestCipherBlockChainingEncrypt test failed");
+ }
+ }
+ }
+
+ public boolean test(String[] args) throws Exception {
+ boolean result = true;
+
+ Provider p = Security.getProvider("SunJCE");
+ ci = Cipher.getInstance(algorithm, p);
+ key = SecretKeyFactory.getInstance(algorithm, p).generateSecret(
+ new PBEKeySpec(PBEPASS.toCharArray()));
+
+ // generate input data
+ byte[] inputText = new byte[INPUT_LENGTH + NUM_PAD_BYTES
+ + PBKDF2_ADD_PAD_BYTES];
+ new Random().nextBytes(inputText);
+
+ try {
+ // Encrypt
+ execute(Cipher.ENCRYPT_MODE,
+ inputText,
+ 0,
+ INPUT_LENGTH);
+
+ // PBKDF2 required 16 byte padding
+ int padLength = NUM_PAD_BYTES + PBKDF2_ADD_PAD_BYTES;
+
+ // Decrypt
+ // Note: inputText is implicitly padded by the above encrypt
+ // operation so decrypt operation can safely proceed
+ execute(Cipher.DECRYPT_MODE,
+ inputText,
+ 0,
+ INPUT_LENGTH + padLength);
+
+ } catch (Exception ex) {
+ ex.printStackTrace(System.out);
+ result = false;
+ }
+ return result;
+ }
+
+ private void execute(int edMode, byte[] inputText, int offset, int len) {
+ try {
+ // init Cipher
+ if (Cipher.ENCRYPT_MODE == edMode) {
+ ci.init(Cipher.ENCRYPT_MODE, this.key);
+ } else {
+ ci.init(Cipher.DECRYPT_MODE, this.key, ci.getParameters());
+ }
+
+ // First, generate the cipherText at an allocated buffer
+ byte[] outputText = ci.doFinal(inputText, offset, len);
+
+ // Second, generate cipherText again at the same buffer of plainText
+ int myoff = offset / 2;
+ int off = ci.update(inputText, offset, len, inputText, myoff);
+ ci.doFinal(inputText, myoff + off);
+
+ // Compare to see whether the two results are the same or not
+ boolean e = equalsBlock(inputText, myoff, outputText, 0,
+ outputText.length);
+ } catch (Exception ex) {
+ System.out.println("Got unexpected exception for " + algorithm);
+ ex.printStackTrace(System.out);
+ }
+ }
+
+ private boolean equalsBlock(byte[] b1, int off1,
+ byte[] b2, int off2, int len) {
+ for (int i = off1, j = off2, k = 0; k < len; i++, j++, k++) {
+ if (b1[i] != b2[j]) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java Mon Feb 04 15:00:29 2019 -0500
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, SAP. All rights reserved.
+ * 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 8214975
+ * @summary No hs-err file if fatal error is raised during dynamic initialization.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @requires (vm.debug == true)
+ * @requires os.family == "linux"
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.regex.Pattern;
+import java.util.Map;
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class VeryEarlyAssertTest {
+
+ public static void main(String[] args) throws Exception {
+
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ "-Xmx64M",
+ "-XX:-CreateCoredumpOnCrash",
+ "-version");
+ Map<String, String> env = pb.environment();
+ env.put("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION", "1");
+
+ OutputAnalyzer output_detail = new OutputAnalyzer(pb.start());
+
+ // we should have crashed with an assert with a specific message:
+ output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*");
+ output_detail.shouldMatch("#.*HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION.*");
+
+ // extract hs-err file
+ String hs_err_file = output_detail.firstMatch("# *(\\S*hs_err_pid\\d+\\.log)", 1);
+ if (hs_err_file == null) {
+ throw new RuntimeException("Did not find hs-err file in output.\n");
+ }
+
+ // scan hs-err file: File should contain the same assertion message. Other than that,
+ // do not expect too much: file will be littered with secondary errors. The test
+ // should test that we get a hs-err file at all.
+ File f = new File(hs_err_file);
+ if (!f.exists()) {
+ throw new RuntimeException("hs-err file missing at "
+ + f.getAbsolutePath() + ".\n");
+ }
+
+ System.out.println("Found hs_err file. Scanning...");
+
+ FileInputStream fis = new FileInputStream(f);
+ BufferedReader br = new BufferedReader(new InputStreamReader(fis));
+ String line = null;
+
+ Pattern[] pattern = new Pattern[]{
+ Pattern.compile(".*HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION.*")
+ };
+ int currentPattern = 0;
+
+ String lastLine = null;
+ while ((line = br.readLine()) != null) {
+ if (currentPattern < pattern.length) {
+ if (pattern[currentPattern].matcher(line).matches()) {
+ System.out.println("Found: " + line + ".");
+ currentPattern++;
+ }
+ }
+ lastLine = line;
+ }
+ br.close();
+
+ if (currentPattern < pattern.length) {
+ throw new RuntimeException("hs-err file incomplete (first missing pattern: " + currentPattern + ")");
+ }
+
+ if (!lastLine.equals("END.")) {
+ throw new RuntimeException("hs-err file incomplete (missing END marker.)");
+ } else {
+ System.out.println("End marker found.");
+ }
+
+ System.out.println("OK.");
+
+ }
+
+}
+
+
--- a/test/hotspot/jtreg/runtime/logging/MonitorInflationTest.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/runtime/logging/MonitorInflationTest.java Mon Feb 04 15:00:29 2019 -0500
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8133885
- * @summary monitorinflation=debug should have logging from each of the statements in the code
+ * @summary monitorinflation=trace should have logging from each of the statements in the code
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
@@ -50,7 +50,7 @@
}
public static void main(String[] args) throws Exception {
- ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:monitorinflation=debug",
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xlog:monitorinflation=trace",
InnerClass.class.getName());
analyzeOutputOn(pb);
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbAttach.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbAttach.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -26,6 +26,7 @@
import java.util.Map;
import jdk.test.lib.apps.LingeredApp;
+import jtreg.SkippedException;
/**
* @test
@@ -68,6 +69,8 @@
"longConstant markOopDesc::locked_value"));
test.run(-1, cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -25,6 +25,7 @@
import java.util.List;
import java.util.Map;
import jdk.test.lib.apps.LingeredApp;
+import jtreg.SkippedException;
/**
* @test
@@ -63,6 +64,8 @@
"field nmethod _entry_bci int",
"field Universe _collectedHeap CollectedHeap"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbFindPC.java Mon Feb 04 15:00:29 2019 -0500
@@ -27,6 +27,8 @@
import java.util.ArrayList;
import jdk.test.lib.apps.LingeredApp;
+import jtreg.SkippedException;
+
/**
* @test
* @bug 8193124
@@ -91,6 +93,8 @@
test.run(theApp.getPid(), cmds, expStrMap, null);
}
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbFlags.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbFlags.java Mon Feb 04 15:00:29 2019 -0500
@@ -29,6 +29,7 @@
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Platform;
import jdk.test.lib.Utils;
+import jtreg.SkippedException;
/**
* @test
@@ -82,6 +83,8 @@
"MaxJavaStackTraceDepth = 1024"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbInspect.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbInspect.java Mon Feb 04 15:00:29 2019 -0500
@@ -57,13 +57,6 @@
String jstackOutput = test.run(theApp.getPid(), cmds, null, null);
- if (jstackOutput == null) {
- // Output could be null due to attach permission issues
- // and if we are skipping this.
- LingeredApp.stopApp(theApp);
- throw new SkippedException("attach permission issues");
- }
-
Map<String, String> tokensMap = new HashMap<>();
tokensMap.put("(a java.lang.Class for LingeredAppWithLock)",
"instance of Oop for java/lang/Class");
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbJdis.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbJdis.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -57,11 +57,6 @@
// the 'jstack -v' command
cmds = new ArrayList<String>();
- // Output could be null if the test was skipped due to
- // attach permission issues.
- if (output == null) {
- throw new SkippedException("attach permission issues");
- }
String cmdStr = null;
String[] parts = output.split("LingeredApp.main");
String[] tokens = parts[1].split(" ");
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbJhisto.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbJhisto.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -28,6 +28,7 @@
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Utils;
+import jtreg.SkippedException;
/**
* @test
@@ -68,6 +69,8 @@
"ParselTongue"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbJstack.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbJstack.java Mon Feb 04 15:00:29 2019 -0500
@@ -27,6 +27,7 @@
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Platform;
+import jtreg.SkippedException;
/**
* @test
@@ -64,6 +65,8 @@
"LingeredApp.main"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR (with -Xcomp=" + withXcomp + ") " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java Mon Feb 04 15:00:29 2019 -0500
@@ -33,6 +33,7 @@
import jdk.test.lib.JDKToolFinder;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.SA.SATestUtils;
+import jtreg.SkippedException;
/**
@@ -177,22 +178,18 @@
List<String> commands,
Map<String, List<String>> expectedStrMap,
Map<String, List<String>> unExpectedStrMap)
- throws IOException, InterruptedException {
+ throws Exception {
if (!Platform.shouldSAAttach()) {
- if (Platform.isOSX()) {
- if (!SATestUtils.canAddPrivileges()) {
- // Skip the test if we don't have enough permissions to attach
- // and cannot add privileges.
- System.out.println("SA attach not expected to work - test skipped.");
- return null;
- } else {
- needPrivileges = true;
- }
- } else {
- System.out.println("SA attach not expected to work. Insufficient privileges.");
- throw new Error("Cannot attach.");
+ if (Platform.isOSX() && SATestUtils.canAddPrivileges()) {
+ needPrivileges = true;
}
+ else {
+ // Skip the test if we don't have enough permissions to attach
+ // and cannot add privileges.
+ throw new SkippedException(
+ "SA attach not expected to work. Insufficient privileges.");
+ }
}
attach(lingeredAppPid);
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLongConstant.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLongConstant.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -75,9 +75,6 @@
String longConstantOutput = test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap);
- if (longConstantOutput == null) {
- throw new SkippedException("attach permission issues");
- }
checkForTruncation(longConstantOutput);
} catch (SkippedException e) {
throw e;
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -27,6 +27,7 @@
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Platform;
+import jtreg.SkippedException;
/**
* @test
@@ -57,6 +58,8 @@
"jimage", "zip", "verify"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintAll.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintAll.java Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -25,6 +25,7 @@
import java.util.List;
import java.util.Map;
import jdk.test.lib.apps.LingeredApp;
+import jtreg.SkippedException;
/**
* @test
@@ -68,6 +69,8 @@
unExpStrMap.put("printall", List.of(
"cannot be cast to"));
test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintAs.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintAs.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -55,11 +55,6 @@
String jstackOutput = test.run(theApp.getPid(), cmds, null, null);
- if (jstackOutput == null) {
- LingeredApp.stopApp(theApp);
- throw new SkippedException("attach permission issues");
- }
-
String[] snippets = jstackOutput.split("LingeredApp.main");
String addressString = null;
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintStatics.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPrintStatics.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -27,6 +27,7 @@
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Platform;
+import jtreg.SkippedException;
/**
* @test
@@ -83,6 +84,8 @@
"bool JvmtiExport::_can_post_on_exceptions"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPstack.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPstack.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -27,6 +27,7 @@
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Platform;
+import jtreg.SkippedException;
/**
* @test
@@ -58,6 +59,8 @@
"Reference Handler", "Finalizer", "main"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbRegionDetailsScanOopsForG1.java Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -70,11 +70,6 @@
unExpStrMap.put("g1regiondetails", List.of("Unknown Region Type"));
String regionDetailsOutput = test.run(theApp.getPid(), cmds,
expStrMap, unExpStrMap);
- if (regionDetailsOutput == null) {
- LingeredApp.stopApp(theApp);
- throw new SkippedException("attach permission issues");
- }
-
// Test the output of 'scanoops' -- get the start and end addresses
// from the StartsHumongous region. Ensure that it contains an
// array of Strings.
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbScanOops.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -58,11 +58,6 @@
String universeOutput = test.run(theApp.getPid(), cmds, null, null);
- if (universeOutput == null) {
- LingeredApp.stopApp(theApp);
- throw new SkippedException("attach permission issues");
- }
-
cmds = new ArrayList<String>();
Map<String, List<String>> expStrMap = new HashMap<>();
Map<String, List<String>> unExpStrMap = new HashMap<>();
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbSource.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbSource.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -29,6 +29,7 @@
import java.util.Map;
import jdk.test.lib.apps.LingeredApp;
+import jtreg.SkippedException;
/**
* @test
@@ -74,6 +75,8 @@
test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap);
Files.delete(file);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbThread.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbThread.java Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -25,6 +25,7 @@
import java.util.List;
import java.util.Map;
import jdk.test.lib.apps.LingeredApp;
+import jtreg.SkippedException;
/**
* @test
@@ -76,14 +77,6 @@
expStrMap,
unExpStrMap);
- if (consolidatedOutput == null) {
- // Output could be null due to attach permission issues.
- System.out.println(
- "Output is empty. Probably due to attach permission issues.");
- LingeredApp.stopApp(theApp);
- return;
- }
-
// Test the thread <id> command now. Obtain <id> from the
// output of the previous 'threads' command. The word before
// the token 'Finalizer' should denote the thread id of the
@@ -109,6 +102,8 @@
"Last_Java_SP"));
cmds = List.of(cmd);
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -25,6 +25,7 @@
import java.util.List;
import java.util.Map;
import jdk.test.lib.apps.LingeredApp;
+import jtreg.SkippedException;
/**
* @test
@@ -63,6 +64,8 @@
"type Universe null",
"type ConstantPoolCache MetaspaceObj"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018, 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
@@ -27,6 +27,7 @@
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.Platform;
+import jtreg.SkippedException;
/**
* @test
@@ -63,6 +64,8 @@
"public static void main"));
test.run(theApp.getPid(), cmds, expStrMap, null);
+ } catch (SkippedException se) {
+ throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
--- a/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/ShrinkGrowTest/ShrinkGrowTest.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/shrink_grow/ShrinkGrowTest/ShrinkGrowTest.java Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -25,6 +25,7 @@
/*
* @test
*
+ * @bug 8217432
* @summary converted from VM Testbase metaspace/shrink_grow/ShrinkGrowTest.
*
* @requires vm.opt.final.ClassUnloading
--- a/test/hotspot/jtreg/vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/hotspot/jtreg/vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java Mon Feb 04 15:00:29 2019 -0500
@@ -397,7 +397,7 @@
// TODO: exclude GC time, compilation time (optionally) from measurements
print("Comparing invocation time orders");
- verifyTimeOrder(results[REFLECTION_CALL], results[INVOKE_EXACT]);
+ verifyTimeOrder(results[INDY], results[REFLECTION_CALL]);
verifyTimeOrder(results[INVOKE_EXACT], results[DIRECT_CALL]);
verifyTimeOrder(results[INVOKE], results[DIRECT_CALL]);
verifyTimeOrder(results[INVOKE_EXACT], results[INDY]);
--- a/test/jdk/ProblemList-Xcomp.txt Sun Feb 03 08:16:08 2019 -0500
+++ b/test/jdk/ProblemList-Xcomp.txt Mon Feb 04 15:00:29 2019 -0500
@@ -29,3 +29,4 @@
java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all
java/util/concurrent/CountDownLatch/Basic.java 8195057 generic-all
+java/util/stream/test/org/openjdk/tests/java/util/stream/StreamLinkTest.java 8216317 solaris-all
--- a/test/jdk/ProblemList-graal.txt Sun Feb 03 08:16:08 2019 -0500
+++ b/test/jdk/ProblemList-graal.txt Mon Feb 04 15:00:29 2019 -0500
@@ -69,6 +69,29 @@
java/lang/Runtime/exec/LotsOfOutput.java 8196611 generic-all
java/util/concurrent/ScheduledThreadPoolExecutor/BasicCancelTest.java 8196611 generic-all
+# tests require pop_frame and force_early_return capabilities
+com/sun/jdi/RedefineTTYLineNumber.java 8195635 generic-all
+com/sun/jdi/RedefineG.java 8195635 generic-all
+com/sun/jdi/RedefineCrossStart.java 8195635 generic-all
+com/sun/jdi/PopSynchronousTest.java 8195635 generic-all
+com/sun/jdi/RedefineTTYLineNumber.java 8195635 generic-all
+com/sun/jdi/RedefineG.java 8195635 generic-all
+com/sun/jdi/RedefineCrossStart.java 8195635 generic-all
+com/sun/jdi/PopSynchronousTest.java 8195635 generic-all
+com/sun/jdi/PopAsynchronousTest.java 8195635 generic-all
+com/sun/jdi/PopAndStepTest.java 8195635 generic-all
+com/sun/jdi/PopAsynchronousTest.java 8195635 generic-all
+com/sun/jdi/PopAndStepTest.java 8195635 generic-all
+com/sun/jdi/EarlyReturnTest.java 8195635 generic-all
+com/sun/jdi/RedefineTTYLineNumber.java 8195635 generic-all
+com/sun/jdi/RedefineG.java 8195635 generic-all
+com/sun/jdi/RedefineCrossStart.java 8195635 generic-all
+com/sun/jdi/PopSynchronousTest.java 8195635 generic-all
+com/sun/jdi/PopAsynchronousTest.java 8195635 generic-all
+com/sun/jdi/PopAndStepTest.java 8195635 generic-all
+com/sun/jdi/EarlyReturnTest.java 8195635 generic-all
+com/sun/jdi/EarlyReturnTest.java 8195635 generic-all
+
# Next JFR tests fail with Graal. Assuming 8193210.
jdk/jfr/event/compiler/TestCodeSweeper.java 8193210 generic-all
jdk/jfr/event/compiler/TestCompilerInlining.java 8193210 generic-all
--- a/test/jdk/java/beans/PropertyEditor/Test6397609.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/jdk/java/beans/PropertyEditor/Test6397609.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,31 +32,38 @@
*/
import java.beans.PropertyEditorManager;
+import java.lang.ref.WeakReference;
public class Test6397609 {
public static void main(String[] args) throws Exception {
- MemoryClassLoader loader = new MemoryClassLoader();
- PropertyEditorManager.registerEditor(
- Object.class,
- loader.compile("Editor",
- "public class Editor extends java.beans.PropertyEditorSupport {}"));
+ Class<?> targetClass = Object.class;
+ Class<?> editorClass = new MemoryClassLoader().compile("Editor",
+ "public class Editor extends java.beans.PropertyEditorSupport {}");
+ PropertyEditorManager.registerEditor(targetClass, editorClass);
- if (!isEditorExist(Object.class)) {
+ // trigger a gc
+ Object object = new Object();
+ var r = new WeakReference<Object>(object);
+ object = null;
+ while (r.get() != null) {
+ System.gc();
+ Thread.sleep(100);
+ }
+
+ if (PropertyEditorManager.findEditor(targetClass) == null) {
throw new Error("the editor is lost");
}
- loader = null; // clean the reference
- if (isEditorExist(Object.class)) {
+
+ // allow, and wait for, Editor class to be unloaded
+ var ref = new WeakReference<Class<?>>(editorClass);
+ editorClass = null;
+ while (ref.get() != null) {
+ System.gc();
+ Thread.sleep(100);
+ }
+
+ if (PropertyEditorManager.findEditor(targetClass) != null) {
throw new Error("unexpected editor is found");
}
}
-
- private static boolean isEditorExist(Class type) {
- for (int i = 0; i < 10; i++) {
- System.gc(); // clean all weak references
- if (null == PropertyEditorManager.findEditor(type)) {
- return false;
- }
- }
- return true;
- }
}
--- a/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/jdk/java/lang/System/LoggerFinder/internal/BootstrapLogger/BootstrapLoggerTest.java Mon Feb 04 15:00:29 2019 -0500
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 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,6 +22,7 @@
*/
import java.io.PrintStream;
+import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Array;
@@ -37,6 +38,7 @@
import java.security.Policy;
import java.security.ProtectionDomain;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -156,7 +158,7 @@
.collect(Collectors.toSet());
set.stream().forEach(t -> LogStream.err.println("Found: " + t));
if (set.size() > 1) {
- throw new RuntimeException("Too many bootsrap threads found");
+ throw new RuntimeException("Too many bootstrap threads found");
}
Optional<Thread> t = set.stream().findFirst();
if (t.isPresent()) {
@@ -292,46 +294,73 @@
// of the executor.
SimplePolicy.allowAll.set(Boolean.TRUE);
try {
- Stream<Thread> stream = Thread.getAllStackTraces().keySet().stream();
- stream.filter((t) -> t.getName().startsWith("BootstrapMessageLoggerTask-"))
- .forEach(t -> LogStream.err.println(t));
+ // Though unlikely, it is not impossible that the bootstrap logger
+ // executor may have released its first thread and spawned a new one.
+ // If that happened then the executor itself might have been GC'ed
+ // as well and a new one might have been created.
+ // The code below will lookup the executor threads again and
+ // join them.
+ // Only one may be active at a given time, but that might not
+ // be the one referenced by threadRef.
+ // We're just making sure all of them have stopped running
+ // before verifying that the executor is eventually GC'ed.
+ final WeakReference<Thread> previous = threadRef;
+ Stream<WeakReference<Thread>> stream = Thread.getAllStackTraces().keySet().stream()
+ .filter((t) -> t.getName().startsWith("BootstrapMessageLoggerTask-"))
+ .filter((t) -> previous == null ? true : t != previous.get())
+ .map((t) -> new WeakReference<>(t, queue));
+ List<WeakReference<Thread>> threads = stream.collect(Collectors.toList());
+ if (previous != null) threads.add(previous);
+ threads.forEach(t -> LogStream.err.println(t.get()));
stream = null;
- if (threadRef != null && test == TestCase.SECURE_AND_WAIT) {
- Thread t = threadRef.get();
- if (t != null) {
- if (!(Boolean)isAlive.invoke(null)) {
- throw new RuntimeException("Executor already terminated");
+
+ if (test == TestCase.SECURE_AND_WAIT) {
+ // First wait for all executor threads to terminate
+ for (var ref : threads) {
+ Thread t = ref.get();
+ if (t != null) {
+ if (!(Boolean)isAlive.invoke(null) && t.isAlive()) {
+ throw new RuntimeException("Executor already terminated");
+ } else {
+ LogStream.err.println("Executor still alive as expected: " + t.getName());
+ }
+ LogStream.err.println("Waiting for " + t.getName() + " to terminate (join)");
+ t.join(60_000);
+ t = null;
} else {
- LogStream.err.println("Executor still alive as expected.");
+ LogStream.err.println("WeakReference<Thread> is already cleared.");
+ long count = Thread.getAllStackTraces().keySet().stream()
+ .filter((tr) -> tr.getName().startsWith("BootstrapMessageLoggerTask-"))
+ .count();
+ if (count != 0) {
+ LogStream.err.println("There are " + count + " threads still lingering.");
+ }
}
- LogStream.err.println("Waiting for " + t.getName() + " to terminate (join)");
- t.join(60_000);
- t = null;
}
- LogStream.err.println("Calling System.gc()");
- System.gc();
- LogStream.err.println("Waiting for BootstrapMessageLoggerTask to be gc'ed");
- while (queue.remove(1000) == null) {
+ // Then wait until all the executor threads are GC'ed
+ while (!threads.isEmpty()) {
LogStream.err.println("Calling System.gc()");
System.gc();
- }
+ LogStream.err.println("Waiting for BootstrapMessageLoggerTask to be gc'ed");
+ Reference<?> tref;
+ while ((tref = queue.remove(1000)) == null) {
+ LogStream.err.println("Calling System.gc()");
+ System.gc();
+ }
- // Call the reference here to make sure threadRef will not be
- // eagerly garbage collected before the thread it references.
- // otherwise, it might not be enqueued, resulting in the
- // queue.remove() call above to always return null....
- if (threadRef.get() != null) {
- throw new RuntimeException("Reference should have been cleared");
+ threads.remove(tref);
+ LogStream.err.println("BootstrapMessageLoggerTask has been gc'ed: "
+ + threads.size() + " remaining...");
}
-
- LogStream.err.println("BootstrapMessageLoggerTask has been gc'ed");
- // Wait for the executor to be gc'ed...
+ // Then wait for the executor to be gc'ed...
+ LogStream.err.println("Waiting for the executor to be gc'ed: Calling System.gc()");
+ System.gc();
for (int i=0; i<10; i++) {
- LogStream.err.println("Calling System.gc()");
- System.gc();
if (!(Boolean)isAlive.invoke(null)) break;
// It would be unexpected that we reach here...
Thread.sleep(1000);
+ LogStream.err.println("Calling System.gc()");
+ System.gc();
}
if ((Boolean)isAlive.invoke(null)) {
--- a/test/jdk/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/jdk/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java Mon Feb 04 15:00:29 2019 -0500
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4404702
+ * @bug 4404702 8216528
* @summary When the RMI runtime (lazily) spawns system threads that could
* outlive the application context in which they were (happened to be)
* created, such threads should not inherit (thread local) data specific to
@@ -106,7 +106,10 @@
* context class loader-- by giving it a chance to pass away.
*/
Thread.sleep(2000);
- System.gc();
+ while (loaderRef.get() != null) {
+ System.gc();
+ Thread.sleep(100);
+ }
System.err.println(
"waiting to be notified of loader being weakly reachable...");
--- a/test/jdk/javax/net/ssl/sanity/ciphersuites/CheckCipherSuites.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/jdk/javax/net/ssl/sanity/ciphersuites/CheckCipherSuites.java Mon Feb 04 15:00:29 2019 -0500
@@ -117,7 +117,7 @@
"TLS_EMPTY_RENEGOTIATION_INFO_SCSV"
};
- // List of enabled cipher suites when the "crypto.policy" security
+ // List of supported cipher suites when the "crypto.policy" security
// property is set to "unlimited" (the default value).
private final static String[] SUPPORTED_DEFAULT = {
"TLS_AES_128_GCM_SHA256",
--- a/test/jdk/sun/net/www/protocol/http/ProtocolRedirect.java Sun Feb 03 08:16:08 2019 -0500
+++ b/test/jdk/sun/net/www/protocol/http/ProtocolRedirect.java Mon Feb 04 15:00:29 2019 -0500
@@ -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
@@ -31,24 +31,30 @@
public class ProtocolRedirect {
public static void main(String [] args) throws Exception {
- int localPort;
- new Thread(new Redirect()).start();
- while ((localPort = Redirect.listenPort) == -1) {
- Thread.sleep(1000);
- }
+ try (Redirect server = new Redirect(new ServerSocket())) {
+ ServerSocket ss = server.ssock;
+ ss.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+ new Thread(server).start();
- String page = "http://localhost:"+localPort+"/";
- URL url = new URL(page);
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- conn.connect();
- if (conn.getResponseCode() != 302) {
- throw new RuntimeException("Test failed. Should get RespCode: 302. Got:"+conn.getResponseCode());
+ URL url = new URL("http", ss.getInetAddress().getHostAddress(), ss.getLocalPort(), "/");
+ String page = url.toString();
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.connect();
+ if (conn.getResponseCode() != 302) {
+ System.err.println("Bad response code received from: " + page);
+ throw new RuntimeException("Test failed. Should get RespCode: 302. Got:" + conn.getResponseCode());
+ }
+ System.out.println("Received expected response code from: " + page);
}
}
}
-class Redirect implements Runnable {
- public static int listenPort = -1; // port to listen for connections on
+class Redirect implements Runnable, Closeable {
+ final ServerSocket ssock;
+ volatile boolean stopped;
+ Redirect(ServerSocket ss) {
+ ssock = ss;
+ }
// Send a header redirect to the peer telling it to go to the
// https server on the host it sent the connection request to.
@@ -61,18 +67,31 @@
out.write(reply.toString().getBytes());
}
- Socket sock;
+ volatile Socket sock;
public void run() {
try {
- ServerSocket ssock = new ServerSocket();
- ssock.bind(null);
- listenPort = ssock.getLocalPort();
- sock = ssock.accept();
- sock.setTcpNoDelay(true);
+ Socket s = sock = ssock.accept();
+ s.setTcpNoDelay(true);
sendReply();
- sock.shutdownOutput();
- } catch(IOException io) {
- throw new RuntimeException(io.getCause());
+ s.shutdownOutput();
+ } catch(Throwable t) {
+ if (!stopped) {
+ t.printStackTrace();
+ throw new RuntimeException(String.valueOf(t), t);
+ }
+ }
+ }
+
+ public void close() {
+ Socket s = sock;
+ boolean done = stopped;
+ if (done) return;
+ stopped = true;
+ try {
+ if (s != null) s.close();
+ } catch (Throwable x) {
+ } finally {
+ try { ssock.close(); } catch (Throwable x) {}
}
}