--- a/.hgtags Wed Apr 10 10:46:53 2019 +0530
+++ b/.hgtags Thu Apr 11 14:20:16 2019 +0530
@@ -553,3 +553,4 @@
83cace4142c8563b6a921787db02388e1bc48d01 jdk-13+13
46cf212cdccaf4fb064d913b12004007d3322b67 jdk-13+14
f855ec13aa2501ae184c8b3e0626a8cec9966116 jdk-13+15
+9d0ae9508d5337b0dc7cc4684be42888c4023755 jdk-13+16
--- a/make/autoconf/basics.m4 Wed Apr 10 10:46:53 2019 +0530
+++ b/make/autoconf/basics.m4 Thu Apr 11 14:20:16 2019 +0530
@@ -883,10 +883,11 @@
fi
if test "x$CUSTOM_ROOT" != x; then
- OUTPUTDIR="${CUSTOM_ROOT}/build/${CONF_NAME}"
+ WORKSPACE_ROOT="${CUSTOM_ROOT}"
else
- OUTPUTDIR="${TOPDIR}/build/${CONF_NAME}"
+ WORKSPACE_ROOT="${TOPDIR}"
fi
+ OUTPUTDIR="${WORKSPACE_ROOT}/build/${CONF_NAME}"
$MKDIR -p "$OUTPUTDIR"
if test ! -d "$OUTPUTDIR"; then
AC_MSG_ERROR([Could not create build directory $OUTPUTDIR])
@@ -942,6 +943,7 @@
AC_SUBST(SPEC)
AC_SUBST(CONF_NAME)
AC_SUBST(OUTPUTDIR)
+ AC_SUBST(WORKSPACE_ROOT)
AC_SUBST(CONFIGURESUPPORT_OUTPUTDIR)
# The spec.gmk file contains all variables for the make system.
--- a/make/autoconf/flags-cflags.m4 Wed Apr 10 10:46:53 2019 +0530
+++ b/make/autoconf/flags-cflags.m4 Thu Apr 11 14:20:16 2019 +0530
@@ -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
@@ -799,15 +799,29 @@
$1_WARNING_CFLAGS_JVM="-Wno-format-zero-length -Wtype-limits -Wuninitialized"
fi
+ if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then
+ # Check if compiler supports -fmacro-prefix-map. If so, use that to make
+ # the __FILE__ macro resolve to paths relative to the workspace root.
+ workspace_root_trailing_slash="${WORKSPACE_ROOT%/}/"
+ FILE_MACRO_CFLAGS="-fmacro-prefix-map=${workspace_root_trailing_slash}="
+ FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${FILE_MACRO_CFLAGS}],
+ PREFIX: $3,
+ IF_FALSE: [
+ FILE_MACRO_CFLAGS=
+ ]
+ )
+ fi
+
# EXPORT to API
CFLAGS_JVM_COMMON="$ALWAYS_CFLAGS_JVM $ALWAYS_DEFINES_JVM \
$TOOLCHAIN_CFLAGS_JVM ${$1_TOOLCHAIN_CFLAGS_JVM} \
$OS_CFLAGS $OS_CFLAGS_JVM $CFLAGS_OS_DEF_JVM $DEBUG_CFLAGS_JVM \
- $WARNING_CFLAGS $WARNING_CFLAGS_JVM $JVM_PICFLAG"
+ $WARNING_CFLAGS $WARNING_CFLAGS_JVM $JVM_PICFLAG $FILE_MACRO_CFLAGS"
CFLAGS_JDK_COMMON="$ALWAYS_CFLAGS_JDK $ALWAYS_DEFINES_JDK $TOOLCHAIN_CFLAGS_JDK \
$OS_CFLAGS $CFLAGS_OS_DEF_JDK $DEBUG_CFLAGS_JDK $DEBUG_OPTIONS_FLAGS_JDK \
- $WARNING_CFLAGS $WARNING_CFLAGS_JDK $DEBUG_SYMBOLS_CFLAGS_JDK"
+ $WARNING_CFLAGS $WARNING_CFLAGS_JDK $DEBUG_SYMBOLS_CFLAGS_JDK \
+ $FILE_MACRO_CFLAGS"
# Use ${$2EXTRA_CFLAGS} to block EXTRA_CFLAGS to be added to build flags.
# (Currently we don't have any OPENJDK_BUILD_EXTRA_CFLAGS, but that might
--- a/make/autoconf/spec.gmk.in Wed Apr 10 10:46:53 2019 +0530
+++ b/make/autoconf/spec.gmk.in Thu Apr 11 14:20:16 2019 +0530
@@ -140,7 +140,9 @@
# The top-level directory of the source repository
TOPDIR:=@TOPDIR@
-
+# Usually the top level directory, but could be something else if a custom
+# root is defined.
+WORKSPACE_ROOT:=@WORKSPACE_ROOT@
IMPORT_MODULES_CLASSES:=@IMPORT_MODULES_CLASSES@
IMPORT_MODULES_CMDS:=@IMPORT_MODULES_CMDS@
IMPORT_MODULES_LIBS:=@IMPORT_MODULES_LIBS@
--- a/make/common/NativeCompilation.gmk Wed Apr 10 10:46:53 2019 +0530
+++ b/make/common/NativeCompilation.gmk Thu Apr 11 14:20:16 2019 +0530
@@ -236,8 +236,10 @@
# This is the definite source file to use for $1_FILENAME.
$1_SRC_FILE := $$($1_FILE)
- ifneq ($$($1_DISABLE_THIS_FILE_DEFINE), true)
- $1_THIS_FILE = -DTHIS_FILE='"$$($1_FILENAME)"'
+ ifneq ($$($1_DEFINE_THIS_FILE), false)
+ ifneq ($$($$($1_BASE)_DEFINE_THIS_FILE), false)
+ $1_THIS_FILE = -DTHIS_FILE='"$$($1_FILENAME)"'
+ endif
endif
ifeq ($$($1_OPTIMIZATION), )
@@ -370,6 +372,7 @@
$(ECHO) $$@: \\ > $$($1_DEPS_FILE) ; \
$(SED) $(WINDOWS_SHOWINCLUDE_SED_PATTERN) $$($1_OBJ).log \
| $(SORT) -u >> $$($1_DEPS_FILE) ; \
+ $(ECHO) >> $$($1_DEPS_FILE) ; \
$(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_DEPS_FILE) > $$($1_DEPS_TARGETS_FILE)
endif
endif
@@ -426,6 +429,7 @@
# STRIPFLAGS Optionally change the flags given to the strip command
# PRECOMPILED_HEADER Header file to use as precompiled header
# PRECOMPILED_HEADER_EXCLUDE List of source files that should not use PCH
+# DEFINE_THIS_FILE Set to false to not set the THIS_FILE preprocessor macro
#
# After being called, some variables are exported from this macro, all prefixed
# with parameter 1 followed by a '_':
@@ -703,7 +707,7 @@
FILE := $$($1_GENERATED_PCH_SRC), \
BASE := $1, \
EXTRA_CXXFLAGS := -Fp$$($1_PCH_FILE) -Yc$$(notdir $$($1_PRECOMPILED_HEADER)), \
- DISABLE_THIS_FILE_DEFINE := true, \
+ DEFINE_THIS_FILE := false, \
))
$1_USE_PCH_FLAGS := \
@@ -840,6 +844,7 @@
$(ECHO) $$($1_RES): \\ > $$($1_RES_DEPS_FILE) ; \
$(SED) $(WINDOWS_SHOWINCLUDE_SED_PATTERN) $$($1_RES_DEPS_FILE).obj.log \
>> $$($1_RES_DEPS_FILE) ; \
+ $(ECHO) >> $$($1_RES_DEPS_FILE) ;\
$(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_RES_DEPS_FILE) \
> $$($1_RES_DEPS_TARGETS_FILE)
endif
--- a/make/hotspot/gensrc/GensrcAdlc.gmk Wed Apr 10 10:46:53 2019 +0530
+++ b/make/hotspot/gensrc/GensrcAdlc.gmk Thu Apr 11 14:20:16 2019 +0530
@@ -76,6 +76,7 @@
DEBUG_SYMBOLS := false, \
DISABLED_WARNINGS_clang := tautological-compare, \
DISABLED_WARNINGS_solstudio := notemsource, \
+ DEFINE_THIS_FILE := false, \
))
ADLC_TOOL := $(BUILD_ADLC_TARGET)
--- a/make/hotspot/gensrc/GensrcDtrace.gmk Wed Apr 10 10:46:53 2019 +0530
+++ b/make/hotspot/gensrc/GensrcDtrace.gmk Thu Apr 11 14:20:16 2019 +0530
@@ -80,6 +80,7 @@
EXTRA_DEPS := $(JVMTI_H) $(JFR_FILES), \
OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \
OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \
+ DEFINE_THIS_FILE := false, \
))
DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET)
--- a/make/hotspot/lib/CompileDtraceLibraries.gmk Wed Apr 10 10:46:53 2019 +0530
+++ b/make/hotspot/lib/CompileDtraceLibraries.gmk Thu Apr 11 14:20:16 2019 +0530
@@ -42,6 +42,7 @@
LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
LIBS := $(LIBDL) -lthread -ldoor, \
OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \
+ DEFINE_THIS_FILE := false, \
))
# Note that libjvm_db.c has tests for COMPILER2, but this was never set by
@@ -54,6 +55,7 @@
CFLAGS := -I$(DTRACE_GENSRC_DIR) $(JNI_INCLUDE_FLAGS) -m64 -G -mt -KPIC -xldscope=hidden, \
LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \
OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \
+ DEFINE_THIS_FILE := false, \
))
TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB)
--- a/make/hotspot/lib/CompileGtest.gmk Wed Apr 10 10:46:53 2019 +0530
+++ b/make/hotspot/lib/CompileGtest.gmk Thu Apr 11 14:20:16 2019 +0530
@@ -92,6 +92,7 @@
STRIP_SYMBOLS := false, \
PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \
PRECOMPILED_HEADER_EXCLUDE := gtest-all.cc gtestMain.cpp, \
+ DEFINE_THIS_FILE := false, \
))
TARGETS += $(BUILD_GTEST_LIBJVM)
@@ -115,6 +116,7 @@
LIBS_windows := $(JVM_OUTPUTDIR)/gtest/objs/jvm.lib, \
COPY_DEBUG_SYMBOLS := $(GTEST_COPY_DEBUG_SYMBOLS), \
ZIP_EXTERNAL_DEBUG_SYMBOLS := false, \
+ DEFINE_THIS_FILE := false, \
))
$(BUILD_GTEST_LAUNCHER): $(BUILD_GTEST_LIBJVM)
--- a/make/hotspot/lib/CompileJvm.gmk Wed Apr 10 10:46:53 2019 +0530
+++ b/make/hotspot/lib/CompileJvm.gmk Thu Apr 11 14:20:16 2019 +0530
@@ -202,6 +202,7 @@
VERSIONINFO_RESOURCE := $(TOPDIR)/src/hotspot/os/windows/version.rc, \
PRECOMPILED_HEADER := $(JVM_PRECOMPILED_HEADER), \
PRECOMPILED_HEADER_EXCLUDE := $(JVM_PRECOMPILED_HEADER_EXCLUDE), \
+ DEFINE_THIS_FILE := false, \
))
# Always recompile vm_version.cpp if libjvm needs to be relinked. This ensures
--- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -381,6 +381,27 @@
}
}
+void VM_Version::print_platform_virtualization_info(outputStream* st) {
+ const char* info_file = "/proc/ppc64/lparcfg";
+ const char* kw[] = { "system_type=", // qemu indicates PowerKVM
+ "partition_entitled_capacity=", // entitled processor capacity percentage
+ "partition_max_entitled_capacity=",
+ "capacity_weight=", // partition CPU weight
+ "partition_active_processors=",
+ "partition_potential_processors=",
+ "entitled_proc_capacity_available=",
+ "capped=", // 0 - uncapped, 1 - vcpus capped at entitled processor capacity percentage
+ "shared_processor_mode=", // (non)dedicated partition
+ "system_potential_processors=",
+ "pool=", // CPU-pool number
+ "pool_capacity=",
+ "NumLpars=", // on non-KVM machines, NumLpars is not found for full partition mode machines
+ NULL };
+ if (!print_matching_lines_from_file(info_file, st, kw)) {
+ st->print_cr(" <%s Not Available>", info_file);
+ }
+}
+
bool VM_Version::use_biased_locking() {
#if INCLUDE_RTM_OPT
// RTM locking is most useful when there is high lock contention and
--- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -89,6 +89,9 @@
static void initialize();
// Override Abstract_VM_Version implementation
+ static void print_platform_virtualization_info(outputStream*);
+
+ // Override Abstract_VM_Version implementation
static bool use_biased_locking();
static bool is_determine_features_test_running() { return _is_determine_features_test_running; }
--- a/src/hotspot/cpu/s390/vm_version_s390.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/cpu/s390/vm_version_s390.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -516,6 +516,19 @@
}
}
+void VM_Version::print_platform_virtualization_info(outputStream* st) {
+ // /proc/sysinfo contains interesting information about
+ // - LPAR
+ // - whole "Box" (CPUs )
+ // - z/VM / KVM (VM<nn>); this is not available in an LPAR-only setup
+ const char* kw[] = { "LPAR", "CPUs", "VM", NULL };
+ const char* info_file = "/proc/sysinfo";
+
+ if (!print_matching_lines_from_file(info_file, st, kw)) {
+ st->print_cr(" <%s Not Available>", info_file);
+ }
+}
+
void VM_Version::print_features() {
print_features_internal("Version:");
}
--- a/src/hotspot/cpu/s390/vm_version_s390.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/cpu/s390/vm_version_s390.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -346,6 +346,9 @@
static void print_features();
static bool is_determine_features_test_running() { return _is_determine_features_test_running; }
+ // Override Abstract_VM_Version implementation
+ static void print_platform_virtualization_info(outputStream*);
+
// CPU feature query functions
static const char* get_model_string() { return _model_string; }
static bool has_StoreFacilityListExtended() { return (_features[0] & StoreFacilityListExtendedMask) == StoreFacilityListExtendedMask; }
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -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
@@ -1573,6 +1573,65 @@
#endif // !PRODUCT
}
+void VM_Version::print_platform_virtualization_info(outputStream* st) {
+ VirtualizationType vrt = VM_Version::get_detected_virtualization();
+ if (vrt == XenHVM) {
+ st->print_cr("Xen hardware-assisted virtualization detected");
+ } else if (vrt == KVM) {
+ st->print_cr("KVM virtualization detected");
+ } else if (vrt == VMWare) {
+ st->print_cr("VMWare virtualization detected");
+ } else if (vrt == HyperV) {
+ st->print_cr("HyperV virtualization detected");
+ }
+}
+
+void VM_Version::check_virt_cpuid(uint32_t idx, uint32_t *regs) {
+// TODO support 32 bit
+#if defined(_LP64)
+#if defined(_MSC_VER)
+ // Allocate space for the code
+ const int code_size = 100;
+ ResourceMark rm;
+ CodeBuffer cb("detect_virt", code_size, 0);
+ MacroAssembler* a = new MacroAssembler(&cb);
+ address code = a->pc();
+ void (*test)(uint32_t idx, uint32_t *regs) = (void(*)(uint32_t idx, uint32_t *regs))code;
+
+ a->movq(r9, rbx); // save nonvolatile register
+
+ // next line would not work on 32-bit
+ a->movq(rax, c_rarg0 /* rcx */);
+ a->movq(r8, c_rarg1 /* rdx */);
+ a->cpuid();
+ a->movl(Address(r8, 0), rax);
+ a->movl(Address(r8, 4), rbx);
+ a->movl(Address(r8, 8), rcx);
+ a->movl(Address(r8, 12), rdx);
+
+ a->movq(rbx, r9); // restore nonvolatile register
+ a->ret(0);
+
+ uint32_t *code_end = (uint32_t *)a->pc();
+ a->flush();
+
+ // execute code
+ (*test)(idx, regs);
+#elif defined(__GNUC__)
+ __asm__ volatile (
+ " cpuid;"
+ " mov %%eax,(%1);"
+ " mov %%ebx,4(%1);"
+ " mov %%ecx,8(%1);"
+ " mov %%edx,12(%1);"
+ : "+a" (idx)
+ : "S" (regs)
+ : "ebx", "ecx", "edx", "memory" );
+#endif
+#endif
+}
+
+
bool VM_Version::use_biased_locking() {
#if INCLUDE_RTM_OPT
// RTM locking is most useful when there is high lock contention and
@@ -1594,6 +1653,54 @@
return UseBiasedLocking;
}
+// On Xen, the cpuid instruction returns
+// eax / registers[0]: Version of Xen
+// ebx / registers[1]: chars 'XenV'
+// ecx / registers[2]: chars 'MMXe'
+// edx / registers[3]: chars 'nVMM'
+//
+// On KVM / VMWare / MS Hyper-V, the cpuid instruction returns
+// ebx / registers[1]: chars 'KVMK' / 'VMwa' / 'Micr'
+// ecx / registers[2]: chars 'VMKV' / 'reVM' / 'osof'
+// edx / registers[3]: chars 'M' / 'ware' / 't Hv'
+//
+// more information :
+// https://kb.vmware.com/s/article/1009458
+//
+void VM_Version::check_virtualizations() {
+#if defined(_LP64)
+ uint32_t registers[4];
+ char signature[13];
+ uint32_t base;
+ signature[12] = '\0';
+ memset((void*)registers, 0, 4*sizeof(uint32_t));
+
+ for (base = 0x40000000; base < 0x40010000; base += 0x100) {
+ check_virt_cpuid(base, registers);
+
+ *(uint32_t *)(signature + 0) = registers[1];
+ *(uint32_t *)(signature + 4) = registers[2];
+ *(uint32_t *)(signature + 8) = registers[3];
+
+ if (strncmp("VMwareVMware", signature, 12) == 0) {
+ Abstract_VM_Version::_detected_virtualization = VMWare;
+ }
+
+ if (strncmp("Microsoft Hv", signature, 12) == 0) {
+ Abstract_VM_Version::_detected_virtualization = HyperV;
+ }
+
+ if (strncmp("KVMKVMKVM", signature, 9) == 0) {
+ Abstract_VM_Version::_detected_virtualization = KVM;
+ }
+
+ if (strncmp("XenVMMXenVMM", signature, 12) == 0) {
+ Abstract_VM_Version::_detected_virtualization = XenHVM;
+ }
+ }
+#endif
+}
+
void VM_Version::initialize() {
ResourceMark rm;
// Making this stub must be FIRST use of assembler
@@ -1608,4 +1715,7 @@
g.generate_get_cpu_info());
get_processor_features();
+ if (cpu_family() > 4) { // it supports CPUID
+ check_virtualizations();
+ }
}
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/cpu/x86/vm_version_x86.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -686,6 +686,9 @@
static void initialize();
// Override Abstract_VM_Version implementation
+ static void print_platform_virtualization_info(outputStream*);
+
+ // Override Abstract_VM_Version implementation
static bool use_biased_locking();
// Asserts
@@ -930,6 +933,11 @@
// that can be used for efficient implementation of
// the intrinsic for java.lang.Thread.onSpinWait()
static bool supports_on_spin_wait() { return supports_sse2(); }
+
+ // support functions for virtualization detection
+ private:
+ static void check_virt_cpuid(uint32_t idx, uint32_t *regs);
+ static void check_virtualizations();
};
#endif // CPU_X86_VM_VERSION_X86_HPP
--- a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -371,14 +371,12 @@
intptr_t result[4 - LogBytesPerWord];
ffi_call(handler->cif(), (void (*)()) function, result, arguments);
- // Change the thread state back to _thread_in_Java.
+ // Change the thread state back to _thread_in_Java and ensure it
+ // is seen by the GC thread.
// ThreadStateTransition::transition_from_native() cannot be used
// here because it does not check for asynchronous exceptions.
// We have to manage the transition ourself.
- thread->set_thread_state(_thread_in_native_trans);
-
- // Make sure new state is visible in the GC thread
- InterfaceSupport::serialize_thread_state(thread);
+ thread->set_thread_state_fence(_thread_in_native_trans);
// Handle safepoint operations, pending suspend requests,
// and pending asynchronous exceptions.
--- a/src/hotspot/os/aix/os_perf_aix.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/os/aix/os_perf_aix.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -273,98 +273,12 @@
return n;
}
-static FILE* open_statfile(void) {
- FILE *f;
-
- if ((f = fopen("/proc/stat", "r")) == NULL) {
- static int haveWarned = 0;
- if (!haveWarned) {
- haveWarned = 1;
- }
- }
- return f;
-}
-
-static void
-next_line(FILE *f) {
- int c;
- do {
- c = fgetc(f);
- } while (c != '\n' && c != EOF);
-}
-
/**
- * Return the total number of ticks since the system was booted.
- * If the usedTicks parameter is not NULL, it will be filled with
- * the number of ticks spent on actual processes (user, system or
- * nice processes) since system boot. Note that this is the total number
- * of "executed" ticks on _all_ CPU:s, that is on a n-way system it is
- * n times the number of ticks that has passed in clock time.
- *
- * Returns a negative value if the reading of the ticks failed.
+ * on Linux we got the ticks related information from /proc/stat
+ * this does not work on AIX, libperfstat might be an alternative
*/
static OSReturn get_total_ticks(int which_logical_cpu, CPUPerfTicks* pticks) {
- FILE* fh;
- uint64_t userTicks, niceTicks, systemTicks, idleTicks;
- uint64_t iowTicks = 0, irqTicks = 0, sirqTicks= 0;
- int logical_cpu = -1;
- const int expected_assign_count = (-1 == which_logical_cpu) ? 4 : 5;
- int n;
-
- if ((fh = open_statfile()) == NULL) {
- return OS_ERR;
- }
- if (-1 == which_logical_cpu) {
- n = fscanf(fh, "cpu " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " "
- UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT,
- &userTicks, &niceTicks, &systemTicks, &idleTicks,
- &iowTicks, &irqTicks, &sirqTicks);
- } else {
- // Move to next line
- next_line(fh);
-
- // find the line for requested cpu faster to just iterate linefeeds?
- for (int i = 0; i < which_logical_cpu; i++) {
- next_line(fh);
- }
-
- n = fscanf(fh, "cpu%u " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " "
- UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT " " UINT64_FORMAT,
- &logical_cpu, &userTicks, &niceTicks,
- &systemTicks, &idleTicks, &iowTicks, &irqTicks, &sirqTicks);
- }
-
- fclose(fh);
- if (n < expected_assign_count || logical_cpu != which_logical_cpu) {
- return OS_ERR;
- }
- pticks->used = userTicks + niceTicks;
- pticks->usedKernel = systemTicks + irqTicks + sirqTicks;
- pticks->total = userTicks + niceTicks + systemTicks + idleTicks +
- iowTicks + irqTicks + sirqTicks;
-
- return OS_OK;
-}
-
-
-static int get_systemtype(void) {
- static int procEntriesType = UNDETECTED;
- DIR *taskDir;
-
- if (procEntriesType != UNDETECTED) {
- return procEntriesType;
- }
-
- // Check whether we have a task subdirectory
- if ((taskDir = opendir("/proc/self/task")) == NULL) {
- procEntriesType = UNDETECTABLE;
- } else {
- // The task subdirectory exists; we're on a Linux >= 2.6 system
- closedir(taskDir);
- procEntriesType = LINUX26_NPTL;
- }
-
- return procEntriesType;
+ return OS_ERR;
}
/** read user and system ticks from a named procfile, assumed to be in 'stat' format then. */
@@ -378,26 +292,7 @@
* to the JVM on any CPU.
*/
static OSReturn get_jvm_ticks(CPUPerfTicks* pticks) {
- uint64_t userTicks;
- uint64_t systemTicks;
-
- if (get_systemtype() != LINUX26_NPTL) {
- return OS_ERR;
- }
-
- if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) != 2) {
- return OS_ERR;
- }
-
- // get the total
- if (get_total_ticks(-1, pticks) != OS_OK) {
- return OS_ERR;
- }
-
- pticks->used = userTicks;
- pticks->usedKernel = systemTicks;
-
- return OS_OK;
+ return OS_ERR;
}
/**
@@ -461,29 +356,7 @@
}
static int SCANF_ARGS(1, 2) parse_stat(_SCANFMT_ const char* fmt, ...) {
- FILE *f;
- va_list args;
-
- va_start(args, fmt);
-
- if ((f = open_statfile()) == NULL) {
- va_end(args);
- return OS_ERR;
- }
- for (;;) {
- char line[80];
- if (fgets(line, sizeof(line), f) != NULL) {
- if (vsscanf(line, fmt, args) == 1) {
- fclose(f);
- va_end(args);
- return OS_OK;
- }
- } else {
- fclose(f);
- va_end(args);
- return OS_ERR;
- }
- }
+ return OS_ERR;
}
static int get_noof_context_switches(uint64_t* switches) {
--- a/src/hotspot/os/linux/os_linux.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/os/linux/os_linux.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -63,6 +63,7 @@
#include "runtime/threadCritical.hpp"
#include "runtime/threadSMR.hpp"
#include "runtime/timer.hpp"
+#include "runtime/vm_version.hpp"
#include "semaphore_posix.hpp"
#include "services/attachListener.hpp"
#include "services/memTracker.hpp"
@@ -1939,35 +1940,6 @@
return true;
}
-#if defined(S390) || defined(PPC64)
-// keywords_to_match - NULL terminated array of keywords
-static bool print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]) {
- char* line = NULL;
- size_t length = 0;
- FILE* fp = fopen(filename, "r");
- if (fp == NULL) {
- return false;
- }
-
- st->print_cr("Virtualization information:");
- while (getline(&line, &length, fp) != -1) {
- int i = 0;
- while (keywords_to_match[i] != NULL) {
- if (strncmp(line, keywords_to_match[i], strlen(keywords_to_match[i])) == 0) {
- st->print("%s", line);
- break;
- }
- i++;
- }
- }
-
- free(line);
- fclose(fp);
-
- return true;
-}
-#endif
-
void os::print_dll_info(outputStream *st) {
st->print_cr("Dynamic libraries:");
@@ -2052,7 +2024,7 @@
os::Linux::print_container_info(st);
- os::Linux::print_virtualization_info(st);
+ VM_Version::print_platform_virtualization_info(st);
os::Linux::print_steal_info(st);
}
@@ -2309,40 +2281,6 @@
st->cr();
}
-void os::Linux::print_virtualization_info(outputStream* st) {
-#if defined(S390)
- // /proc/sysinfo contains interesting information about
- // - LPAR
- // - whole "Box" (CPUs )
- // - z/VM / KVM (VM<nn>); this is not available in an LPAR-only setup
- const char* kw[] = { "LPAR", "CPUs", "VM", NULL };
- const char* info_file = "/proc/sysinfo";
-
- if (!print_matching_lines_from_file(info_file, st, kw)) {
- st->print_cr(" <%s Not Available>", info_file);
- }
-#elif defined(PPC64)
- const char* info_file = "/proc/ppc64/lparcfg";
- const char* kw[] = { "system_type=", // qemu indicates PowerKVM
- "partition_entitled_capacity=", // entitled processor capacity percentage
- "partition_max_entitled_capacity=",
- "capacity_weight=", // partition CPU weight
- "partition_active_processors=",
- "partition_potential_processors=",
- "entitled_proc_capacity_available=",
- "capped=", // 0 - uncapped, 1 - vcpus capped at entitled processor capacity percentage
- "shared_processor_mode=", // (non)dedicated partition
- "system_potential_processors=",
- "pool=", // CPU-pool number
- "pool_capacity=",
- "NumLpars=", // on non-KVM machines, NumLpars is not found for full partition mode machines
- NULL };
- if (!print_matching_lines_from_file(info_file, st, kw)) {
- st->print_cr(" <%s Not Available>", info_file);
- }
-#endif
-}
-
void os::Linux::print_steal_info(outputStream* st) {
if (has_initial_tick_info) {
CPUPerfTicks pticks;
--- a/src/hotspot/os/linux/os_linux.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/os/linux/os_linux.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -108,7 +108,6 @@
static void print_full_memory_info(outputStream* st);
static void print_container_info(outputStream* st);
- static void print_virtualization_info(outputStream* st);
static void print_steal_info(outputStream* st);
static void print_distro_info(outputStream* st);
static void print_libversion_info(outputStream* st);
--- a/src/hotspot/os/windows/os_windows.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/os/windows/os_windows.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -1601,6 +1601,10 @@
#endif
st->print("OS:");
os::win32::print_windows_version(st);
+
+#ifdef _LP64
+ VM_Version::print_platform_virtualization_info(st);
+#endif
}
void os::win32::print_windows_version(outputStream* st) {
--- a/src/hotspot/share/classfile/javaClasses.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/classfile/javaClasses.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -160,6 +160,7 @@
int java_lang_String::value_offset = 0;
int java_lang_String::hash_offset = 0;
+int java_lang_String::hashIsZero_offset = 0;
int java_lang_String::coder_offset = 0;
bool java_lang_String::initialized = false;
@@ -179,7 +180,8 @@
#define STRING_FIELDS_DO(macro) \
macro(value_offset, k, vmSymbols::value_name(), byte_array_signature, false); \
macro(hash_offset, k, "hash", int_signature, false); \
- macro(coder_offset, k, "coder", byte_signature, false)
+ macro(hashIsZero_offset, k, "hashIsZero", bool_signature, false); \
+ macro(coder_offset, k, "coder", byte_signature, false);
void java_lang_String::compute_offsets() {
if (initialized) {
@@ -507,18 +509,38 @@
}
unsigned int java_lang_String::hash_code(oop java_string) {
- typeArrayOop value = java_lang_String::value(java_string);
- int length = java_lang_String::length(java_string, value);
- // Zero length string will hash to zero with String.hashCode() function.
- if (length == 0) return 0;
-
- bool is_latin1 = java_lang_String::is_latin1(java_string);
-
- if (is_latin1) {
- return java_lang_String::hash_code(value->byte_at_addr(0), length);
+ // The hash and hashIsZero fields are subject to a benign data race,
+ // making it crucial to ensure that any observable result of the
+ // calculation in this method stays correct under any possible read of
+ // these fields. Necessary restrictions to allow this to be correct
+ // without explicit memory fences or similar concurrency primitives is
+ // that we can ever only write to one of these two fields for a given
+ // String instance, and that the computation is idempotent and derived
+ // from immutable state
+ assert(initialized && (hash_offset > 0) && (hashIsZero_offset > 0), "Must be initialized");
+ if (java_lang_String::hash_is_set(java_string)) {
+ return java_string->int_field(hash_offset);
+ }
+
+ typeArrayOop value = java_lang_String::value(java_string);
+ int length = java_lang_String::length(java_string, value);
+ bool is_latin1 = java_lang_String::is_latin1(java_string);
+
+ unsigned int hash = 0;
+ if (length > 0) {
+ if (is_latin1) {
+ hash = java_lang_String::hash_code(value->byte_at_addr(0), length);
+ } else {
+ hash = java_lang_String::hash_code(value->char_at_addr(0), length);
+ }
+ }
+
+ if (hash != 0) {
+ java_string->int_field_put(hash_offset, hash);
} else {
- return java_lang_String::hash_code(value->char_at_addr(0), length);
+ java_string->bool_field_put(hashIsZero_offset, true);
}
+ return hash;
}
char* java_lang_String::as_quoted_ascii(oop java_string) {
--- a/src/hotspot/share/classfile/javaClasses.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/classfile/javaClasses.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -94,6 +94,7 @@
private:
static int value_offset;
static int hash_offset;
+ static int hashIsZero_offset;
static int coder_offset;
static bool initialized;
@@ -132,6 +133,10 @@
assert(initialized && (hash_offset > 0), "Must be initialized");
return hash_offset;
}
+ static int hashIsZero_offset_in_bytes() {
+ assert(initialized && (hashIsZero_offset > 0), "Must be initialized");
+ return hashIsZero_offset;
+ }
static int coder_offset_in_bytes() {
assert(initialized && (coder_offset > 0), "Must be initialized");
return coder_offset;
@@ -139,12 +144,11 @@
static inline void set_value_raw(oop string, typeArrayOop buffer);
static inline void set_value(oop string, typeArrayOop buffer);
- static inline void set_hash(oop string, unsigned int hash);
// Accessors
static inline typeArrayOop value(oop java_string);
static inline typeArrayOop value_no_keepalive(oop java_string);
- static inline unsigned int hash(oop java_string);
+ static inline bool hash_is_set(oop string);
static inline bool is_latin1(oop java_string);
static inline int length(oop java_string);
static inline int length(oop java_string, typeArrayOop string_value);
--- a/src/hotspot/share/classfile/javaClasses.inline.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -45,9 +45,9 @@
string->obj_field_put(value_offset, (oop)buffer);
}
-void java_lang_String::set_hash(oop string, unsigned int hash) {
- assert(initialized && (hash_offset > 0), "Must be initialized");
- string->int_field_put(hash_offset, hash);
+bool java_lang_String::hash_is_set(oop java_string) {
+ assert(initialized && (hash_offset > 0) && (hashIsZero_offset > 0), "Must be initialized");
+ return java_string->int_field(hash_offset) != 0 || java_string->bool_field(hashIsZero_offset) != 0;
}
// Accessors
@@ -71,12 +71,6 @@
return (typeArrayOop) java_string->obj_field_access<AS_NO_KEEPALIVE>(value_offset);
}
-unsigned int java_lang_String::hash(oop java_string) {
- assert(initialized && (hash_offset > 0), "Must be initialized");
- assert(is_instance(java_string), "must be java_string");
- return java_string->int_field(hash_offset);
-}
-
bool java_lang_String::is_latin1(oop java_string) {
assert(initialized && (coder_offset > 0), "Must be initialized");
assert(is_instance(java_string), "must be java_string");
--- a/src/hotspot/share/classfile/stringTable.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/classfile/stringTable.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -761,8 +761,6 @@
return true;
}
unsigned int hash = java_lang_String::hash_code(s);
-
- java_lang_String::set_hash(s, hash);
oop new_s = StringTable::create_archived_string(s, Thread::current());
if (new_s == NULL) {
return true;
--- a/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -351,19 +351,14 @@
unsigned int hash = 0;
if (use_java_hash()) {
- // Get hash code from cache
- hash = java_lang_String::hash(java_string);
- }
-
- if (hash == 0) {
+ if (!java_lang_String::hash_is_set(java_string)) {
+ stat->inc_hashed();
+ }
+ hash = java_lang_String::hash_code(java_string);
+ } else {
// Compute hash
hash = hash_code(value, latin1);
stat->inc_hashed();
-
- if (use_java_hash() && hash != 0) {
- // Store hash code in cache
- java_lang_String::set_hash(java_string, hash);
- }
}
typeArrayOop existing_value = lookup_or_add(value, latin1, hash);
--- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -196,6 +196,10 @@
} else {
_rp->process_all_roots(&roots_cl, &cld_cl, &code_cl, NULL, worker_id);
}
+ if (ShenandoahStringDedup::is_enabled()) {
+ AlwaysTrueClosure is_alive;
+ ShenandoahStringDedup::parallel_oops_do(&is_alive, &roots_cl, worker_id);
+ }
}
}
};
--- a/src/hotspot/share/gc/z/zBarrier.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zBarrier.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -123,7 +123,7 @@
}
void ZBarrier::load_barrier_on_oop_fields(oop o) {
- assert(ZOop::is_good(o), "Should be good");
+ assert(ZAddress::is_good(ZOop::to_address(o)), "Should be good");
ZLoadBarrierOopClosure cl;
o->oop_iterate(&cl);
}
--- a/src/hotspot/share/gc/z/zBarrier.inline.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zBarrier.inline.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -37,7 +37,7 @@
retry:
// Fast path
if (fast_path(addr)) {
- return ZOop::to_oop(addr);
+ return ZOop::from_address(addr);
}
// Slow path
@@ -56,7 +56,7 @@
}
}
- return ZOop::to_oop(good_addr);
+ return ZOop::from_address(good_addr);
}
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
@@ -67,7 +67,7 @@
if (fast_path(addr)) {
// Return the good address instead of the weak good address
// to ensure that the currently active heap view is used.
- return ZOop::to_oop(ZAddress::good_or_null(addr));
+ return ZOop::from_address(ZAddress::good_or_null(addr));
}
// Slow path
@@ -95,7 +95,7 @@
}
}
- return ZOop::to_oop(good_addr);
+ return ZOop::from_address(good_addr);
}
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
@@ -117,7 +117,7 @@
// to heal the same root if it is aligned, since they would always heal
// the root in the same way and it does not matter in which order it
// happens. For misaligned oops, there needs to be mutual exclusion.
- *p = ZOop::to_oop(good_addr);
+ *p = ZOop::from_address(good_addr);
}
inline bool ZBarrier::is_null_fast_path(uintptr_t addr) {
--- a/src/hotspot/share/gc/z/zForwarding.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zForwarding.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -69,6 +69,11 @@
// Check for duplicates
for (ZForwardingCursor j = i + 1; j < _entries.length(); j++) {
const ZForwardingEntry other = at(&j);
+ if (!other.populated()) {
+ // Skip empty entries
+ continue;
+ }
+
guarantee(entry.from_index() != other.from_index(), "Duplicate from");
guarantee(entry.to_offset() != other.to_offset(), "Duplicate to");
}
--- a/src/hotspot/share/gc/z/zHeap.inline.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zHeap.inline.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -135,7 +135,7 @@
}
inline bool ZHeap::is_oop(oop object) const {
- return ZOop::is_good(object);
+ return ZAddress::is_good(ZOop::to_address(object));
}
#endif // SHARE_GC_Z_ZHEAP_INLINE_HPP
--- a/src/hotspot/share/gc/z/zLiveMap.inline.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zLiveMap.inline.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -144,7 +144,7 @@
const uintptr_t addr = page_start + ((index / 2) << page_object_alignment_shift);
// Apply closure
- cl->do_object(ZOop::to_oop(addr));
+ cl->do_object(ZOop::from_address(addr));
// Find next bit after this object
const size_t size = ZUtils::object_size(addr);
--- a/src/hotspot/share/gc/z/zMark.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zMark.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -200,7 +200,7 @@
}
bool ZMark::is_array(uintptr_t addr) const {
- return ZOop::to_oop(addr)->is_objArray();
+ return ZOop::from_address(addr)->is_objArray();
}
void ZMark::push_partial_array(uintptr_t addr, size_t size, bool finalizable) {
@@ -347,9 +347,9 @@
}
if (is_array(addr)) {
- follow_array_object(objArrayOop(ZOop::to_oop(addr)), finalizable);
+ follow_array_object(objArrayOop(ZOop::from_address(addr)), finalizable);
} else {
- follow_object(ZOop::to_oop(addr), finalizable);
+ follow_object(ZOop::from_address(addr), finalizable);
}
}
--- a/src/hotspot/share/gc/z/zOop.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zOop.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, 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
@@ -29,13 +29,8 @@
class ZOop : public AllStatic {
public:
- static oop to_oop(uintptr_t value);
+ static oop from_address(uintptr_t addr);
static uintptr_t to_address(oop o);
-
- static bool is_good(oop o);
- static bool is_finalizable_good(oop o);
-
- static oop good(oop);
};
#endif // SHARE_GC_Z_ZOOP_HPP
--- a/src/hotspot/share/gc/z/zOop.inline.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zOop.inline.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, 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
@@ -24,28 +24,14 @@
#ifndef SHARE_GC_Z_ZOOP_INLINE_HPP
#define SHARE_GC_Z_ZOOP_INLINE_HPP
-#include "gc/z/zAddress.inline.hpp"
#include "gc/z/zOop.hpp"
-#include "oops/oopsHierarchy.hpp"
-inline oop ZOop::to_oop(uintptr_t value) {
- return cast_to_oop(value);
+inline oop ZOop::from_address(uintptr_t addr) {
+ return cast_to_oop(addr);
}
inline uintptr_t ZOop::to_address(oop o) {
return cast_from_oop<uintptr_t>(o);
}
-inline bool ZOop::is_good(oop o) {
- return ZAddress::is_good(to_address(o));
-}
-
-inline bool ZOop::is_finalizable_good(oop o) {
- return ZAddress::is_finalizable_good(to_address(o));
-}
-
-inline oop ZOop::good(oop o) {
- return to_oop(ZAddress::good(to_address(o)));
-}
-
#endif // SHARE_GC_Z_ZOOP_INLINE_HPP
--- a/src/hotspot/share/gc/z/zOopClosures.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zOopClosures.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -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
@@ -39,12 +39,14 @@
const oop o = RawAccess<>::oop_load(p);
if (o != NULL) {
- guarantee(ZOop::is_good(o) || ZOop::is_finalizable_good(o),
+ const uintptr_t addr = ZOop::to_address(o);
+ const uintptr_t good_addr = ZAddress::good(addr);
+ guarantee(ZAddress::is_good(addr) || ZAddress::is_finalizable_good(addr),
"Bad oop " PTR_FORMAT " found at " PTR_FORMAT ", expected " PTR_FORMAT,
- p2i(o), p2i(p), p2i(ZOop::good(o)));
- guarantee(oopDesc::is_oop(ZOop::good(o)),
+ addr, p2i(p), good_addr);
+ guarantee(oopDesc::is_oop(ZOop::from_address(good_addr)),
"Bad object " PTR_FORMAT " found at " PTR_FORMAT,
- p2i(o), p2i(p));
+ addr, p2i(p));
}
}
--- a/src/hotspot/share/gc/z/zUtils.inline.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/gc/z/zUtils.inline.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -57,7 +57,7 @@
}
inline size_t ZUtils::object_size(uintptr_t addr) {
- return words_to_bytes(ZOop::to_oop(addr)->size());
+ return words_to_bytes(ZOop::from_address(addr)->size());
}
inline void ZUtils::object_copy(uintptr_t from, uintptr_t to, size_t size) {
--- a/src/hotspot/share/prims/jni.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/prims/jni.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -3971,7 +3971,7 @@
#endif
// Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
- ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
+ ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
} else {
// If create_vm exits because of a pending exception, exit with that
// exception. In the future when we figure out how to reclaim memory,
@@ -4073,7 +4073,7 @@
res = JNI_OK;
return res;
} else {
- ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
+ ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
res = JNI_ERR;
return res;
}
@@ -4195,7 +4195,7 @@
// using ThreadStateTransition::transition, we do a callback to the safepoint code if
// needed.
- ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
+ ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_native);
// Perform any platform dependent FPU setup
os::setup_fpu();
--- a/src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -236,7 +236,7 @@
// Don't hold the lock over the notify or jmethodID creation
MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
current->get_and_cache_jmethod_id();
- JvmtiExport::post_compiled_method_load(current);
+ JvmtiExport::post_compiled_method_load(env, current);
}
return JVMTI_ERROR_NONE;
}
--- a/src/hotspot/share/prims/jvmtiExport.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/prims/jvmtiExport.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -2170,61 +2170,37 @@
JvmtiEnvIterator it;
for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
- if (env->phase() == JVMTI_PHASE_PRIMORDIAL) {
- continue;
- }
- EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
- ("[%s] class compile method load event sent %s.%s ",
- JvmtiTrace::safe_get_thread_name(thread),
- (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),
- (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
- ResourceMark rm(thread);
- HandleMark hm(thread);
-
- // Add inlining information
- jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);
- // Pass inlining information through the void pointer
- JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), jem.jni_methodID(),
- jem.code_size(), jem.code_data(), jem.map_length(),
- jem.map(), jem.compile_info());
- }
- }
+ post_compiled_method_load(env, nm);
}
}
-
// post a COMPILED_METHOD_LOAD event for a given environment
-void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length,
- const void *code_begin, const jint map_length,
- const jvmtiAddrLocationMap* map)
-{
- if (env->phase() <= JVMTI_PHASE_PRIMORDIAL) {
+void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, nmethod *nm) {
+ if (env->phase() == JVMTI_PHASE_PRIMORDIAL || !env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
+ return;
+ }
+ jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
+ if (callback == NULL) {
return;
}
JavaThread* thread = JavaThread::current();
- EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
- ("[%s] method compile load event triggered (by GenerateEvents)",
- JvmtiTrace::safe_get_thread_name(thread)));
- if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
-
- EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
- ("[%s] class compile method load event sent (by GenerateEvents), jmethodID=" PTR_FORMAT,
- JvmtiTrace::safe_get_thread_name(thread), p2i(method)));
-
- JvmtiEventMark jem(thread);
- JvmtiJavaThreadEventTransition jet(thread);
- jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), method,
- length, code_begin, map_length,
- map, NULL);
- }
- }
+
+ EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
+ ("[%s] method compile load event sent %s.%s ",
+ JvmtiTrace::safe_get_thread_name(thread),
+ (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),
+ (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
+ ResourceMark rm(thread);
+ HandleMark hm(thread);
+
+ // Add inlining information
+ jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);
+ // Pass inlining information through the void pointer
+ JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);
+ JvmtiJavaThreadEventTransition jet(thread);
+ (*callback)(env->jvmti_external(), jem.jni_methodID(),
+ jem.code_size(), jem.code_data(), jem.map_length(),
+ jem.map(), jem.compile_info());
}
void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {
--- a/src/hotspot/share/prims/jvmtiExport.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/prims/jvmtiExport.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -165,9 +165,7 @@
// DynamicCodeGenerated events for a given environment.
friend class JvmtiCodeBlobEvents;
- static void post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length,
- const void *code_begin, const jint map_length,
- const jvmtiAddrLocationMap* map) NOT_JVMTI_RETURN;
+ static void post_compiled_method_load(JvmtiEnv* env, nmethod *nm) NOT_JVMTI_RETURN;
static void post_dynamic_code_generated(JvmtiEnv* env, const char *name, const void *code_begin,
const void *code_end) NOT_JVMTI_RETURN;
--- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -66,22 +66,6 @@
static void verify_stack();
static void verify_last_frame();
# endif
-
- public:
- static void serialize_thread_state_with_handler(JavaThread* thread) {
- serialize_thread_state_internal(thread, true);
- }
-
- // Should only call this if we know that we have a proper SEH set up.
- static void serialize_thread_state(JavaThread* thread) {
- serialize_thread_state_internal(thread, false);
- }
-
- private:
- static void serialize_thread_state_internal(JavaThread* thread, bool needs_exception_handler) {
- // Make sure new state is seen by VM thread
- OrderAccess::fence();
- }
};
@@ -103,28 +87,8 @@
assert(from != _thread_in_native, "use transition_from_native");
assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
assert(thread->thread_state() == from, "coming from wrong thread state");
- // Change to transition state
- thread->set_thread_state((JavaThreadState)(from + 1));
-
- InterfaceSupport::serialize_thread_state(thread);
-
- SafepointMechanism::block_if_requested(thread);
- thread->set_thread_state(to);
-
- CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
- }
-
- // transition_and_fence must be used on any thread state transition
- // where there might not be a Java call stub on the stack, in
- // particular on Windows where the Structured Exception Handler is
- // set up in the call stub.
- static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
- assert(thread->thread_state() == from, "coming from wrong thread state");
- assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
- // Change to transition state
- thread->set_thread_state((JavaThreadState)(from + 1));
-
- InterfaceSupport::serialize_thread_state_with_handler(thread);
+ // Change to transition state and ensure it is seen by the VM thread.
+ thread->set_thread_state_fence((JavaThreadState)(from + 1));
SafepointMechanism::block_if_requested(thread);
thread->set_thread_state(to);
@@ -143,19 +107,14 @@
static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
assert((to & 1) == 0, "odd numbers are transitions states");
assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
- // Change to transition state
- thread->set_thread_state(_thread_in_native_trans);
-
- InterfaceSupport::serialize_thread_state_with_handler(thread);
+ // Change to transition state and ensure it is seen by the VM thread.
+ thread->set_thread_state_fence(_thread_in_native_trans);
// We never install asynchronous exceptions when coming (back) in
// to the runtime from native code because the runtime is not set
// up to handle exceptions floating around at arbitrary points.
if (SafepointMechanism::should_block(thread) || thread->is_suspend_after_native()) {
JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
-
- // Clear unhandled oops anywhere where we could block, even if we don't.
- CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
}
thread->set_thread_state(to);
@@ -164,7 +123,6 @@
void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }
void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }
void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }
- void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
};
class ThreadInVMForHandshake : public ThreadStateTransition {
@@ -173,9 +131,8 @@
void transition_back() {
// This can be invoked from transition states and must return to the original state properly
assert(_thread->thread_state() == _thread_in_vm, "should only call when leaving VM after handshake");
- _thread->set_thread_state(_thread_in_vm_trans);
-
- InterfaceSupport::serialize_thread_state(_thread);
+ // Change to transition state and ensure it is seen by the VM thread.
+ _thread->set_thread_state_fence(_thread_in_vm_trans);
SafepointMechanism::block_if_requested(_thread);
@@ -217,7 +174,6 @@
class ThreadInVMfromUnknown {
- private:
JavaThread* _thread;
public:
ThreadInVMfromUnknown() : _thread(NULL) {
@@ -236,7 +192,7 @@
}
~ThreadInVMfromUnknown() {
if (_thread) {
- ThreadStateTransition::transition_and_fence(_thread, _thread_in_vm, _thread_in_native);
+ ThreadStateTransition::transition(_thread, _thread_in_vm, _thread_in_native);
}
}
};
@@ -248,7 +204,7 @@
trans_from_native(_thread_in_vm);
}
~ThreadInVMfromNative() {
- trans_and_fence(_thread_in_vm, _thread_in_native);
+ trans(_thread_in_vm, _thread_in_native);
}
};
@@ -260,7 +216,7 @@
// Block, if we are in the middle of a safepoint synchronization.
assert(!thread->owns_locks(), "must release all locks when leaving VM");
thread->frame_anchor()->make_walkable(thread);
- trans_and_fence(_thread_in_vm, _thread_in_native);
+ trans(_thread_in_vm, _thread_in_native);
// Check for pending. async. exceptions or suspends.
if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition(false);
}
@@ -279,10 +235,10 @@
: ThreadStateTransition(thread) {
// Once we are blocked vm expects stack to be walkable
thread->frame_anchor()->make_walkable(thread);
- trans_and_fence(_thread_in_vm, _thread_blocked);
+ trans(_thread_in_vm, _thread_blocked);
}
~ThreadBlockInVM() {
- trans_and_fence(_thread_blocked, _thread_in_vm);
+ trans(_thread_blocked, _thread_in_vm);
OrderAccess::cross_modify_fence();
// We don't need to clear_walkable because it will happen automagically when we return to java
}
@@ -322,14 +278,10 @@
OrderAccess::storestore();
thread->set_thread_state(_thread_blocked);
-
- CHECK_UNHANDLED_OOPS_ONLY(_thread->clear_unhandled_oops();)
}
~ThreadBlockInVMWithDeadlockCheck() {
- // Change to transition state
- _thread->set_thread_state((JavaThreadState)(_thread_blocked_trans));
-
- InterfaceSupport::serialize_thread_state_with_handler(_thread);
+ // Change to transition state and ensure it is seen by the VM thread.
+ _thread->set_thread_state_fence((JavaThreadState)(_thread_blocked_trans));
if (SafepointMechanism::should_block(_thread)) {
release_monitor();
@@ -337,8 +289,6 @@
}
_thread->set_thread_state(_thread_in_vm);
- CHECK_UNHANDLED_OOPS_ONLY(_thread->clear_unhandled_oops();)
-
OrderAccess::cross_modify_fence();
}
};
--- a/src/hotspot/share/runtime/mutex.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/runtime/mutex.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -159,7 +159,7 @@
// !no_safepoint_check logically implies java_thread
guarantee(no_safepoint_check || self->is_Java_thread(), "invariant");
- #ifdef ASSERT
+#ifdef ASSERT
Monitor * least = get_least_ranked_lock_besides_this(self->owned_locks());
assert(least != this, "Specification of get_least_... call above");
if (least != NULL && least->rank() <= special) {
@@ -168,7 +168,14 @@
name(), rank(), least->name(), least->rank());
assert(false, "Shouldn't block(wait) while holding a lock of rank special");
}
- #endif // ASSERT
+#endif // ASSERT
+
+#ifdef CHECK_UNHANDLED_OOPS
+ // Clear unhandled oops in JavaThreads so we get a crash right away.
+ if (self->is_Java_thread() && !no_safepoint_check) {
+ self->clear_unhandled_oops();
+ }
+#endif // CHECK_UNHANDLED_OOPS
int wait_status;
// conceptually set the owner to NULL in anticipation of
--- a/src/hotspot/share/runtime/safepoint.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/runtime/safepoint.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -805,9 +805,9 @@
// This part we can skip if we notice we miss or are in a future safepoint.
OrderAccess::storestore();
- thread->set_thread_state(_thread_blocked);
+ // Load in wait barrier should not float up
+ thread->set_thread_state_fence(_thread_blocked);
- OrderAccess::fence(); // Load in wait barrier should not float up
_wait_barrier->wait(static_cast<int>(safepoint_id));
assert(_state != _synchronized, "Can't be");
--- a/src/hotspot/share/runtime/thread.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/runtime/thread.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -1837,7 +1837,7 @@
// Thread is now sufficiently initialized to be handled by the safepoint code as being
// in the VM. Change thread state from _thread_new to _thread_in_vm
- ThreadStateTransition::transition_and_fence(this, _thread_new, _thread_in_vm);
+ ThreadStateTransition::transition(this, _thread_new, _thread_in_vm);
// Before a thread is on the threads list it is always safe, so after leaving the
// _thread_new we should emit a instruction barrier. The distance to modified code
// from here is probably far enough, but this is consistent and safe.
@@ -2475,11 +2475,10 @@
JavaThreadState state = thread_state();
set_thread_state(_thread_blocked);
java_suspend_self();
- set_thread_state(state);
+ set_thread_state_fence(state);
// Since we are not using a regular thread-state transition helper here,
// we must manually emit the instruction barrier after leaving a safe state.
OrderAccess::cross_modify_fence();
- InterfaceSupport::serialize_thread_state_with_handler(this);
if (state != _thread_in_native) {
SafepointMechanism::block_if_requested(this);
}
--- a/src/hotspot/share/runtime/thread.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/runtime/thread.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -1288,6 +1288,7 @@
// Safepoint support
inline JavaThreadState thread_state() const;
inline void set_thread_state(JavaThreadState s);
+ inline void set_thread_state_fence(JavaThreadState s); // fence after setting thread state
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 Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/runtime/thread.inline.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -141,6 +141,11 @@
#endif
}
+inline void JavaThread::set_thread_state_fence(JavaThreadState s) {
+ set_thread_state(s);
+ OrderAccess::fence();
+}
+
ThreadSafepointState* JavaThread::safepoint_state() const {
return _safepoint_state;
}
--- a/src/hotspot/share/runtime/vm_version.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/runtime/vm_version.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -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
@@ -44,6 +44,8 @@
unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U;
unsigned int Abstract_VM_Version::_L1_data_cache_line_size = 0;
+VirtualizationType Abstract_VM_Version::_detected_virtualization = NoDetectedVirtualization;
+
#ifndef HOTSPOT_VERSION_STRING
#error HOTSPOT_VERSION_STRING must be defined
#endif
@@ -295,7 +297,6 @@
(Abstract_VM_Version::vm_build_number() & 0xFF);
}
-
void VM_Version_init() {
VM_Version::initialize();
@@ -306,3 +307,27 @@
os::print_cpu_info(&ls, buf, sizeof(buf));
}
}
+
+bool Abstract_VM_Version::print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]) {
+ char line[500];
+ FILE* fp = fopen(filename, "r");
+ if (fp == NULL) {
+ return false;
+ }
+
+ st->print_cr("Virtualization information:");
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ int i = 0;
+ while (keywords_to_match[i] != NULL) {
+ if (strncmp(line, keywords_to_match[i], strlen(keywords_to_match[i])) == 0) {
+ st->print("%s", line);
+ break;
+ }
+ i++;
+ }
+ }
+ fclose(fp);
+ return true;
+}
+
+
--- a/src/hotspot/share/runtime/vm_version.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/runtime/vm_version.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -29,6 +29,14 @@
#include "utilities/ostream.hpp"
#include "utilities/macros.hpp"
+typedef enum {
+ NoDetectedVirtualization,
+ XenHVM,
+ KVM,
+ VMWare,
+ HyperV
+} VirtualizationType;
+
// VM_Version provides information about the VM.
class Abstract_VM_Version: AllStatic {
@@ -57,6 +65,8 @@
static int _vm_patch_version;
static int _vm_build_number;
+ static VirtualizationType _detected_virtualization;
+
public:
// Called as part of the runtime services initialization which is
// called from the management module initialization (via init_globals())
@@ -111,6 +121,14 @@
return _features_string;
}
+ static VirtualizationType get_detected_virtualization() {
+ return _detected_virtualization;
+ }
+
+ // platforms that need to specialize this
+ // define VM_Version::print_platform_virtualization_info()
+ static void print_platform_virtualization_info(outputStream*) { }
+
// does HW support an 8-byte compare-exchange operation?
static bool supports_cx8() {
#ifdef SUPPORTS_NATIVE_CX8
@@ -149,6 +167,8 @@
// Does this CPU support spin wait instruction?
static bool supports_on_spin_wait() { return false; }
+
+ static bool print_matching_lines_from_file(const char* filename, outputStream* st, const char* keywords_to_match[]);
};
#include CPU_HEADER(vm_version)
--- a/src/hotspot/share/utilities/exceptions.hpp Wed Apr 10 10:46:53 2019 +0530
+++ b/src/hotspot/share/utilities/exceptions.hpp Thu Apr 11 14:20:16 2019 +0530
@@ -237,11 +237,7 @@
// visible within the scope containing the THROW. Usually this is achieved by declaring the function
// with a TRAPS argument.
-#ifdef THIS_FILE
-#define THREAD_AND_LOCATION THREAD, THIS_FILE, __LINE__
-#else
#define THREAD_AND_LOCATION THREAD, __FILE__, __LINE__
-#endif
#define THROW_OOP(e) \
{ Exceptions::_throw_oop(THREAD_AND_LOCATION, e); return; }
--- a/src/java.base/share/classes/java/lang/Math.java Wed Apr 10 10:46:53 2019 +0530
+++ b/src/java.base/share/classes/java/lang/Math.java Thu Apr 11 14:20:16 2019 +0530
@@ -1274,7 +1274,12 @@
* @since 1.8
*/
public static int floorMod(int x, int y) {
- return x - floorDiv(x, y) * y;
+ int mod = x % y;
+ // if the signs are different and modulo not zero, adjust result
+ if ((mod ^ y) < 0 && mod != 0) {
+ mod += y;
+ }
+ return mod;
}
/**
@@ -1301,7 +1306,7 @@
*/
public static int floorMod(long x, int y) {
// Result cannot overflow the range of int.
- return (int)(x - floorDiv(x, y) * y);
+ return (int)floorMod(x, (long)y);
}
/**
@@ -1327,7 +1332,12 @@
* @since 1.8
*/
public static long floorMod(long x, long y) {
- return x - floorDiv(x, y) * y;
+ long mod = x % y;
+ // if the signs are different and modulo not zero, adjust result
+ if ((x ^ y) < 0 && mod != 0) {
+ mod += y;
+ }
+ return mod;
}
/**
--- a/src/java.base/share/classes/java/lang/String.java Wed Apr 10 10:46:53 2019 +0530
+++ b/src/java.base/share/classes/java/lang/String.java Thu Apr 11 14:20:16 2019 +0530
@@ -164,6 +164,12 @@
/** Cache the hash code for the string */
private int hash; // Default to 0
+ /**
+ * Cache if the hash has been calculated as actually being zero, enabling
+ * us to avoid recalculating this.
+ */
+ private boolean hashIsZero; // Default to false;
+
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
@@ -1508,14 +1514,21 @@
* @return a hash code value for this object.
*/
public int hashCode() {
+ // The hash or hashIsZero fields are subject to a benign data race,
+ // making it crucial to ensure that any observable result of the
+ // calculation in this method stays correct under any possible read of
+ // these fields. Necessary restrictions to allow this to be correct
+ // without explicit memory fences or similar concurrency primitives is
+ // that we can ever only write to one of these two fields for a given
+ // String instance, and that the computation is idempotent and derived
+ // from immutable state
int h = hash;
- if (h == 0 && value.length > 0) {
+ if (h == 0 && !hashIsZero) {
h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
- // Avoid issuing a store if the calculated value is also zero:
- // in addition to a minor performance benefit, this allows storing
- // Strings with zero hash code in read-only memory.
- if (h != 0) {
+ if (h == 0) {
+ hashIsZero = true;
+ } else {
hash = h;
}
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java Wed Apr 10 10:46:53 2019 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java Thu Apr 11 14:20:16 2019 +0530
@@ -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
@@ -30,6 +30,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@@ -366,9 +367,11 @@
for (Type t : minContext.inferencevars) {
//add listener that forwards notifications to original context
minContext.addFreeTypeListener(List.of(t), (inferenceContext) -> {
- ((UndetVar)asUndetVar(t)).setInst(inferenceContext.asInstType(t));
- infer.doIncorporation(inferenceContext, warn);
- solve(List.from(rv.minMap.get(t)), warn);
+ Type instType = inferenceContext.asInstType(t);
+ for (Type eq : rv.minMap.get(t)) {
+ ((UndetVar)asUndetVar(eq)).setInst(instType);
+ }
+ infer.doIncorporation(this, warn);
notifyChange();
});
}
@@ -385,9 +388,9 @@
class ReachabilityVisitor extends Types.UnaryVisitor<Void> {
- Set<Type> equiv = new HashSet<>();
- Set<Type> min = new HashSet<>();
- Map<Type, Set<Type>> minMap = new HashMap<>();
+ Set<Type> equiv = new LinkedHashSet<>();
+ Set<Type> min = new LinkedHashSet<>();
+ Map<Type, Set<Type>> minMap = new LinkedHashMap<>();
void scan(List<Type> roots) {
roots.stream().forEach(this::visit);
@@ -401,7 +404,7 @@
@Override
public Void visitUndetVar(UndetVar t, Void _unused) {
if (min.add(t.qtype)) {
- Set<Type> deps = minMap.getOrDefault(t.qtype, new HashSet<>(Collections.singleton(t.qtype)));
+ Set<Type> deps = minMap.getOrDefault(t.qtype, new LinkedHashSet<>(Collections.singleton(t.qtype)));
for (InferenceBound boundKind : InferenceBound.values()) {
for (Type b : t.getBounds(boundKind)) {
Type undet = asUndetVar(b);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/MyPackage/GenerateEventsTest.java Thu Apr 11 14:20:16 2019 +0530
@@ -0,0 +1,48 @@
+/*
+ * 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 8222072
+ * @summary Send CompiledMethodLoad events only to the environment requested it with GenerateEvents
+ * @compile GenerateEventsTest.java
+ * @run main/othervm/native -agentlib:GenerateEvents1 -agentlib:GenerateEvents2 MyPackage.GenerateEventsTest
+ */
+
+package MyPackage;
+
+public class GenerateEventsTest {
+ static native void agent1GenerateEvents();
+ static native void agent2SetThread(Thread thread);
+ static native boolean agent1FailStatus();
+ static native boolean agent2FailStatus();
+
+ public static void main(String[] args) {
+ agent2SetThread(Thread.currentThread());
+ agent1GenerateEvents(); // Re-generate CompiledMethodLoad events
+ if (agent1FailStatus()|| agent2FailStatus()) {
+ throw new RuntimeException("GenerateEventsTest failed!");
+ }
+ System.out.println("GenerateEventsTest passed!");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents1.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <string.h>
+#include "jvmti.h"
+
+extern "C" {
+
+#define AGENT_NAME "agent1"
+
+static JavaVM *java_vm = NULL;
+static jthread exp_thread = NULL;
+static jvmtiEnv *jvmti1 = NULL;
+static jint agent1_event_count = 0;
+static bool fail_status = false;
+
+static void
+check_jvmti_status(JNIEnv* env, jvmtiError err, const char* msg) {
+ if (err != JVMTI_ERROR_NONE) {
+ printf("check_jvmti_status: JVMTI function returned error: %d\n", err);
+ fail_status = true;
+ env->FatalError(msg);
+ }
+}
+
+static void JNICALL
+CompiledMethodLoad(jvmtiEnv* jvmti, jmethodID method,
+ jint code_size, const void* code_addr,
+ jint map_length, const jvmtiAddrLocationMap* map,
+ const void* compile_info) {
+ JNIEnv* env = NULL;
+ jthread thread = NULL;
+ char* name = NULL;
+ char* sign = NULL;
+ jvmtiError err;
+
+ // Posted on JavaThread's, so it is legal to obtain JNIEnv*
+ if (java_vm->GetEnv((void **) (&env), JNI_VERSION_9) != JNI_OK) {
+ printf("CompiledMethodLoad: failed to obtain JNIEnv*\n");
+ fail_status = true;
+ return;
+ }
+
+ jvmti->GetCurrentThread(&thread);
+ if (!env->IsSameObject(thread, exp_thread)) {
+ return; // skip events from unexpected threads
+ }
+ agent1_event_count++;
+
+ err = jvmti->GetMethodName(method, &name, &sign, NULL);
+ check_jvmti_status(env, err, "CompiledMethodLoad: Error in JVMTI GetMethodName");
+
+ printf("%s: CompiledMethodLoad: %s%s\n", AGENT_NAME, name, sign);
+ fflush(0);
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
+ jvmtiEventCallbacks callbacks;
+ jvmtiCapabilities caps;
+ jvmtiError err;
+
+ java_vm = jvm;
+ if (jvm->GetEnv((void **) (&jvmti1), JVMTI_VERSION) != JNI_OK) {
+ printf("Agent_OnLoad: Error in GetEnv in obtaining jvmtiEnv*\n");
+ fail_status = true;
+ return JNI_ERR;
+ }
+
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.CompiledMethodLoad = &CompiledMethodLoad;
+
+ err = jvmti1->SetEventCallbacks(&callbacks, sizeof(jvmtiEventCallbacks));
+ if (err != JVMTI_ERROR_NONE) {
+ printf("Agent_OnLoad: Error in JVMTI SetEventCallbacks: %d\n", err);
+ fail_status = true;
+ return JNI_ERR;
+ }
+
+ memset(&caps, 0, sizeof(caps));
+ caps.can_generate_compiled_method_load_events = 1;
+
+ err = jvmti1->AddCapabilities(&caps);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("Agent_OnLoad: Error in JVMTI AddCapabilities: %d\n", err);
+ fail_status = true;
+ return JNI_ERR;
+ }
+ return JNI_OK;
+}
+
+JNIEXPORT void JNICALL
+Java_MyPackage_GenerateEventsTest_agent1GenerateEvents(JNIEnv *env, jclass cls) {
+ jthread thread = NULL;
+ jvmtiError err;
+
+ err = jvmti1->GetCurrentThread(&thread);
+ check_jvmti_status(env, err, "generateEvents1: Error in JVMTI GetCurrentThread");
+
+ exp_thread = (jthread)env->NewGlobalRef(thread);
+
+ err = jvmti1->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL);
+ check_jvmti_status(env, err, "generateEvents1: Error in JVMTI SetEventNotificationMode: JVMTI_ENABLE");
+
+ err = jvmti1->GenerateEvents(JVMTI_EVENT_COMPILED_METHOD_LOAD);
+ check_jvmti_status(env, err, "generateEvents1: Error in JVMTI GenerateEvents");
+
+ err = jvmti1->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL);
+ check_jvmti_status(env, err, "generateEvents1: Error in JVMTI SetEventNotificationMode: JVMTI_DISABLE");
+}
+
+JNIEXPORT jboolean JNICALL
+Java_MyPackage_GenerateEventsTest_agent1FailStatus(JNIEnv *env, jclass cls) {
+ return fail_status;
+}
+
+} // extern "C"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/libGenerateEvents2.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <string.h>
+#include "jvmti.h"
+
+extern "C" {
+
+#define AGENT_NAME "agent2"
+
+static JavaVM *java_vm = NULL;
+static jthread exp_thread = NULL;
+static jvmtiEnv *jvmti2 = NULL;
+static jint agent2_event_count = 0;
+static bool fail_status = false;
+
+static void
+check_jvmti_status(JNIEnv* env, jvmtiError err, const char* msg) {
+ if (err != JVMTI_ERROR_NONE) {
+ printf("check_jvmti_status: JVMTI function returned error: %d\n", err);
+ fail_status = true;
+ env->FatalError(msg);
+ }
+}
+
+static void JNICALL
+CompiledMethodLoad(jvmtiEnv* jvmti, jmethodID method,
+ jint code_size, const void* code_addr,
+ jint map_length, const jvmtiAddrLocationMap* map,
+ const void* compile_info) {
+ JNIEnv* env = NULL;
+ jthread thread = NULL;
+ char* name = NULL;
+ char* sign = NULL;
+ jvmtiError err;
+
+ // Posted on JavaThread's, so it is legal to obtain JNIEnv*
+ if (java_vm->GetEnv((void **) (&env), JNI_VERSION_9) != JNI_OK) {
+ fail_status = true;
+ return;
+ }
+
+ err = jvmti->GetCurrentThread(&thread);
+ check_jvmti_status(env, err, "CompiledMethodLoad: Error in JVMTI GetCurrentThread");
+ if (!env->IsSameObject(thread, exp_thread)) {
+ return; // skip events from unexpected threads
+ }
+ agent2_event_count++;
+
+ err = jvmti->GetMethodName(method, &name, &sign, NULL);
+ check_jvmti_status(env, err, "CompiledMethodLoad: Error in JVMTI GetMethodName");
+
+ printf("%s: CompiledMethodLoad: %s%s\n", AGENT_NAME, name, sign);
+ fflush(0);
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
+ jvmtiEventCallbacks callbacks;
+ jvmtiCapabilities caps;
+ jvmtiError err;
+
+ java_vm = jvm;
+ if (jvm->GetEnv((void **) (&jvmti2), JVMTI_VERSION_9) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.CompiledMethodLoad = &CompiledMethodLoad;
+
+ err = jvmti2->SetEventCallbacks(&callbacks, sizeof(jvmtiEventCallbacks));
+ if (err != JVMTI_ERROR_NONE) {
+ printf("Agent_OnLoad: Error in JVMTI SetEventCallbacks: %d\n", err);
+ fail_status = true;
+ return JNI_ERR;
+ }
+
+ memset(&caps, 0, sizeof(caps));
+ caps.can_generate_compiled_method_load_events = 1;
+
+ err = jvmti2->AddCapabilities(&caps);
+ if (err != JVMTI_ERROR_NONE) {
+ printf("Agent_OnLoad: Error in JVMTI AddCapabilities: %d\n", err);
+ fail_status = true;
+ return JNI_ERR;
+ }
+ return JNI_OK;
+}
+
+JNIEXPORT void JNICALL
+Java_MyPackage_GenerateEventsTest_agent2SetThread(JNIEnv *env, jclass cls, jthread thread) {
+ jvmtiError err;
+
+ exp_thread = (jthread)env->NewGlobalRef(thread);
+
+ err = jvmti2->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL);
+ check_jvmti_status(env, err, "setThread2: Error in JVMTI SetEventNotificationMode: JVMTI_ENABLE");
+}
+
+JNIEXPORT jboolean JNICALL
+Java_MyPackage_GenerateEventsTest_agent2FailStatus(JNIEnv *env, jclass cls) {
+ jvmtiError err;
+
+ err = jvmti2->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL);
+ check_jvmti_status(env, err, "check2: Error in JVMTI SetEventNotificationMode: JVMTI_DISABLE");
+
+ printf("\n");
+ if (agent2_event_count == 0) {
+ printf("check2: Zero events in agent2 as expected\n");
+ } else {
+ fail_status = true;
+ printf("check2: Unexpected non-zero event count in agent2: %d\n", agent2_event_count);
+ }
+ printf("\n");
+ fflush(0);
+
+ return fail_status;
+}
+
+} // extern "C"
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep001/singlestep001.cpp Wed Apr 10 10:46:53 2019 +0530
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep001/singlestep001.cpp Thu Apr 11 14:20:16 2019 +0530
@@ -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
@@ -57,7 +57,7 @@
static jvmtiEnv *jvmti = NULL;
static jvmtiEventCallbacks callbacks;
-static int vm_started = 0;
+static volatile int callbacksEnabled = NSK_FALSE;
static jrawMonitorID agent_lock;
static void setBP(jvmtiEnv *jvmti_env, JNIEnv *env, jclass klass) {
@@ -77,7 +77,7 @@
jvmti->RawMonitorEnter(agent_lock);
- if (vm_started) {
+ if (callbacksEnabled) {
if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic)))
env->FatalError("failed to obtain a class signature\n");
@@ -99,6 +99,13 @@
jclass klass;
char *sig, *generic;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
+
NSK_DISPLAY0("Breakpoint event received\n");
if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &klass)))
NSK_COMPLAIN0("TEST FAILURE: unable to get method declaring class\n\n");
@@ -118,6 +125,7 @@
NSK_COMPLAIN1("TEST FAILURE: unexpected breakpoint event in method of class \"%s\"\n\n",
sig);
}
+ jvmti->RawMonitorExit(agent_lock);
}
void JNICALL
@@ -197,7 +205,16 @@
VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
jvmti->RawMonitorEnter(agent_lock);
- vm_started = 1;
+ callbacksEnabled = NSK_TRUE;
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+void JNICALL
+VMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_FALSE;
jvmti->RawMonitorExit(agent_lock);
}
@@ -261,12 +278,15 @@
callbacks.Breakpoint = &Breakpoint;
callbacks.SingleStep = &SingleStep;
callbacks.VMStart = &VMStart;
+ callbacks.VMDeath = &VMDeath;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))
return JNI_ERR;
NSK_DISPLAY0("setting event callbacks done\nenabling JVMTI events ...\n");
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
return JNI_ERR;
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
+ return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))
return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))
--- a/test/jdk/java/lang/Math/DivModTests.java Wed Apr 10 10:46:53 2019 +0530
+++ b/test/jdk/java/lang/Math/DivModTests.java Thu Apr 11 14:20:16 2019 +0530
@@ -91,6 +91,10 @@
testIntFloorDivMod(Integer.MIN_VALUE, 3, -715827883, 1);
testIntFloorDivMod(Integer.MIN_VALUE + 1, 3, -715827883, 2);
testIntFloorDivMod(Integer.MIN_VALUE + 1, -1, Integer.MAX_VALUE, 0);
+ testIntFloorDivMod(Integer.MAX_VALUE, Integer.MAX_VALUE, 1, 0);
+ testIntFloorDivMod(Integer.MAX_VALUE, Integer.MIN_VALUE, -1, -1);
+ testIntFloorDivMod(Integer.MIN_VALUE, Integer.MIN_VALUE, 1, 0);
+ testIntFloorDivMod(Integer.MIN_VALUE, Integer.MAX_VALUE, -2, 2147483646);
// Special case of integer overflow
testIntFloorDivMod(Integer.MIN_VALUE, -1, Integer.MIN_VALUE, 0);
}
@@ -179,6 +183,10 @@
testLongFloorDivMod(Long.MIN_VALUE, 3L, Long.MIN_VALUE / 3L - 1L, 1L);
testLongFloorDivMod(Long.MIN_VALUE + 1L, 3L, Long.MIN_VALUE / 3L - 1L, 2L);
testLongFloorDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0L);
+ testLongFloorDivMod(Long.MAX_VALUE, Long.MAX_VALUE, 1L, 0L);
+ testLongFloorDivMod(Long.MAX_VALUE, Long.MIN_VALUE, -1L, -1L);
+ testLongFloorDivMod(Long.MIN_VALUE, Long.MIN_VALUE, 1L, 0L);
+ testLongFloorDivMod(Long.MIN_VALUE, Long.MAX_VALUE, -2L, 9223372036854775806L);
// Special case of integer overflow
testLongFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0L);
}
@@ -283,6 +291,10 @@
testLongIntFloorDivMod(Long.MIN_VALUE, 3, Long.MIN_VALUE / 3L - 1L, 1L);
testLongIntFloorDivMod(Long.MIN_VALUE + 1L, 3, Long.MIN_VALUE / 3L - 1L, 2L);
testLongIntFloorDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0L);
+ testLongIntFloorDivMod(Long.MAX_VALUE, Integer.MAX_VALUE, 4294967298L, 1);
+ testLongIntFloorDivMod(Long.MAX_VALUE, Integer.MIN_VALUE, -4294967296L, -1);
+ testLongIntFloorDivMod(Long.MIN_VALUE, Integer.MIN_VALUE, 4294967296L, 0);
+ testLongIntFloorDivMod(Long.MIN_VALUE, Integer.MAX_VALUE, -4294967299L, 2147483645);
// Special case of integer overflow
testLongIntFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0L);
}
--- a/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java Wed Apr 10 10:46:53 2019 +0530
+++ b/test/langtools/jdk/javadoc/doclet/testHtmlLandmarkRegions/TestHtmlLandmarkRegions.java Thu Apr 11 14:20:16 2019 +0530
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8210047 8199892
+ * @bug 8210047 8199892 8215599
* @summary some pages contains content outside of landmark region
* @library /tools/lib ../../lib
* @modules
@@ -57,7 +57,6 @@
TestHtmlLandmarkRegions() {
tb = new ToolBox();
- setAutomaticCheckLinks(false); // @ignore 8217013
}
@Test
--- a/test/langtools/jdk/javadoc/doclet/testIndexWithModules/TestIndexWithModules.java Wed Apr 10 10:46:53 2019 +0530
+++ b/test/langtools/jdk/javadoc/doclet/testIndexWithModules/TestIndexWithModules.java Thu Apr 11 14:20:16 2019 +0530
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8190875
+ * @bug 8190875 8215599
* @summary modules not listed in overview/index page
* @library /tools/lib ../../lib
* @modules
@@ -83,7 +83,6 @@
//multiple modules with frames
@Test
public void testIndexWithMultipleModules1(Path base) throws Exception {
- setAutomaticCheckLinks(false); // @ignore 8217013
Path out = base.resolve("out");
javadoc("-d", out.toString(),
"--module-source-path", src.toString(),
@@ -98,7 +97,6 @@
"<a href=\"m1/module-summary.html\">m1</a>",
"<a href=\"m3/module-summary.html\">m3</a>",
"<a href=\"m4/module-summary.html\">m4</a>");
- setAutomaticCheckLinks(true); // @ignore 8217013
}
//multiple modules with out frames
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/T8222035/MinContextOpTest.java Thu Apr 11 14:20:16 2019 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2019, Google LLC. All rights reserved.
+ * 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 8222035
+ * @summary minimal inference context optimization is forcing resolution with incomplete constraints
+ * @compile/fail/ref=MinContextOpTest.out -XDrawDiagnostics MinContextOpTest.java
+ */
+
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collector;
+import java.util.stream.Stream;
+
+public class MinContextOpTest {
+ abstract class A {
+ abstract static class T<K> {
+ abstract String f();
+ }
+
+ abstract <E> Function<E, E> id();
+
+ abstract static class ImmutableMap<K, V> implements Map<K, V> {}
+
+ abstract <T, K, V> Collector<T, ?, ImmutableMap<K, V>> toImmutableMap(
+ Function<? super T, ? extends K> k, Function<? super T, ? extends V> v);
+
+ ImmutableMap<String, T<?>> test(Stream<T> stream) {
+ return stream.collect(toImmutableMap(T::f, id()));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/T8222035/MinContextOpTest.out Thu Apr 11 14:20:16 2019 +0530
@@ -0,0 +1,4 @@
+MinContextOpTest.java:38:25: compiler.err.mod.not.allowed.here: static
+MinContextOpTest.java:44:25: compiler.err.mod.not.allowed.here: static
+MinContextOpTest.java:50:34: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: T,K,V,E, (compiler.misc.inconvertible.types: java.util.function.Function<MinContextOpTest.A.T,MinContextOpTest.A.T>, java.util.function.Function<? super MinContextOpTest.A.T,? extends MinContextOpTest.A.T<?>>))
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/MathBench.java Thu Apr 11 14:20:16 2019 +0530
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class MathBench {
+
+ @Param("0")
+ public long seed;
+
+ public int dividend;
+ public int divisor;
+
+ public long longDividend;
+ public long longDivisor;
+
+ @Setup
+ public void setupValues() {
+ Random random = new Random(seed);
+ dividend = Math.abs(random.nextInt() + 4711);
+ divisor = Math.abs(random.nextInt(dividend) + 17);
+ longDividend = Math.abs(random.nextLong() + 4711L);
+ longDivisor = Math.abs(random.nextLong() + longDividend);
+ }
+
+ @Benchmark
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public int floorModIntIntPositive() {
+ return Math.floorMod(dividend, divisor);
+ }
+
+ @Benchmark
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public int floorModIntInt() {
+ return Math.floorMod( dividend, divisor) +
+ Math.floorMod( dividend, -divisor) +
+ Math.floorMod(-dividend, divisor) +
+ Math.floorMod(-dividend, -divisor);
+ }
+
+ @Benchmark
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public int floorModLongInt() {
+ return Math.floorMod( longDividend, divisor) +
+ Math.floorMod( longDividend, -divisor) +
+ Math.floorMod(-longDividend, divisor) +
+ Math.floorMod(-longDividend, -divisor);
+ }
+
+ @Benchmark
+ @CompilerControl(CompilerControl.Mode.DONT_INLINE)
+ public long floorModLongLong() {
+ return Math.floorMod( longDividend, longDivisor) +
+ Math.floorMod( longDividend, -longDivisor) +
+ Math.floorMod(-longDividend, longDivisor) +
+ Math.floorMod(-longDividend, -longDivisor);
+ }
+
+}