Merge
This commit is contained in:
commit
a9bfe45ca8
.hgtags
make
autoconf
common
hotspot
src
hotspot
cpu
ppc
s390
x86
zero
os
share
classfile
gc
shared/stringdedup
shenandoah
z
prims
runtime
interfaceSupport.inline.hppmutex.cppsafepoint.cppthread.cppthread.hppthread.inline.hppvm_version.cppvm_version.hpp
utilities
java.base/share/classes/java/lang
jdk.compiler/share/classes/com/sun/tools/javac/comp
test
hotspot/jtreg
serviceability/jvmti/GenerateEvents
vmTestbase/nsk/jvmti/SingleStep/singlestep001
jdk/java/lang/Math
langtools
jdk/javadoc/doclet
tools/javac/T8222035
micro/org/openjdk/bench/java/lang
1
.hgtags
1
.hgtags
@ -553,3 +553,4 @@ b67884871b5fff79c5ef3eb8ac74dd48d71ea9b1 jdk-12-ga
|
||||
83cace4142c8563b6a921787db02388e1bc48d01 jdk-13+13
|
||||
46cf212cdccaf4fb064d913b12004007d3322b67 jdk-13+14
|
||||
f855ec13aa2501ae184c8b3e0626a8cec9966116 jdk-13+15
|
||||
9d0ae9508d5337b0dc7cc4684be42888c4023755 jdk-13+16
|
||||
|
@ -883,10 +883,11 @@ AC_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
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_DEFUN_ONCE([BASIC_SETUP_OUTPUT_DIR],
|
||||
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.
|
||||
|
@ -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 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP],
|
||||
$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
|
||||
|
@ -140,7 +140,9 @@ SYSROOT_LDFLAGS := @SYSROOT_LDFLAGS@
|
||||
|
||||
# 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@
|
||||
|
@ -236,8 +236,10 @@ define SetupCompileNativeFileBody
|
||||
# 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 @@ define SetupCompileNativeFileBody
|
||||
$(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 @@ endef
|
||||
# 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 @@ define SetupNativeCompilationBody
|
||||
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 @@ define SetupNativeCompilationBody
|
||||
$(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
|
||||
|
@ -76,6 +76,7 @@ ifeq ($(call check-jvm-feature, compiler2), true)
|
||||
DEBUG_SYMBOLS := false, \
|
||||
DISABLED_WARNINGS_clang := tautological-compare, \
|
||||
DISABLED_WARNINGS_solstudio := notemsource, \
|
||||
DEFINE_THIS_FILE := false, \
|
||||
))
|
||||
|
||||
ADLC_TOOL := $(BUILD_ADLC_TARGET)
|
||||
|
@ -80,6 +80,7 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
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)
|
||||
|
@ -42,6 +42,7 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
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 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
||||
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)
|
||||
|
@ -92,6 +92,7 @@ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LIBJVM, \
|
||||
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 @@ $(eval $(call SetupNativeCompilation, BUILD_GTEST_LAUNCHER, \
|
||||
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)
|
||||
|
@ -202,6 +202,7 @@ $(eval $(call SetupNativeCompilation, BUILD_LIBJVM, \
|
||||
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
|
||||
|
@ -381,6 +381,27 @@ void VM_Version::initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -88,6 +88,9 @@ public:
|
||||
// Initialization
|
||||
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();
|
||||
|
||||
|
@ -516,6 +516,19 @@ void VM_Version::print_features_internal(const char* text, bool print_anyway) {
|
||||
}
|
||||
}
|
||||
|
||||
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:");
|
||||
}
|
||||
|
@ -346,6 +346,9 @@ class VM_Version: public Abstract_VM_Version {
|
||||
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; }
|
||||
|
@ -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 @@ void VM_Version::get_processor_features() {
|
||||
#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 @@ bool VM_Version::use_biased_locking() {
|
||||
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 @@ void VM_Version::initialize() {
|
||||
g.generate_get_cpu_info());
|
||||
|
||||
get_processor_features();
|
||||
if (cpu_family() > 4) { // it supports CPUID
|
||||
check_virtualizations();
|
||||
}
|
||||
}
|
||||
|
@ -685,6 +685,9 @@ public:
|
||||
// Initialization
|
||||
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();
|
||||
|
||||
@ -930,6 +933,11 @@ public:
|
||||
// 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
|
||||
|
@ -371,14 +371,12 @@ int CppInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
|
||||
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.
|
||||
|
@ -273,98 +273,12 @@ static int SCANF_ARGS(2, 3) read_statdata(const char* procfile, _SCANFMT_ const
|
||||
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 @@ static int read_ticks(const char* procfile, uint64_t* userTicks, uint64_t* syste
|
||||
* 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 double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters, dou
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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 @@ static bool _print_ascii_file(const char* filename, outputStream* st, const char
|
||||
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 @@ void os::print_os_info(outputStream* st) {
|
||||
|
||||
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 @@ void os::Linux::print_container_info(outputStream* st) {
|
||||
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;
|
||||
|
@ -108,7 +108,6 @@ class Linux {
|
||||
|
||||
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);
|
||||
|
@ -1601,6 +1601,10 @@ void os::print_os_info(outputStream* st) {
|
||||
#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) {
|
||||
|
@ -160,6 +160,7 @@ static void compute_offset(int& dest_offset, InstanceKlass* ik,
|
||||
|
||||
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 @@ bool java_lang_String::is_instance(oop obj) {
|
||||
#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 @@ jchar* java_lang_String::as_unicode_string(oop java_string, int& length, TRAPS)
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
return java_lang_String::hash_code(value->char_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 {
|
||||
java_string->bool_field_put(hashIsZero_offset, true);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
char* java_lang_String::as_quoted_ascii(oop java_string) {
|
||||
|
@ -94,6 +94,7 @@ class java_lang_String : AllStatic {
|
||||
private:
|
||||
static int value_offset;
|
||||
static int hash_offset;
|
||||
static int hashIsZero_offset;
|
||||
static int coder_offset;
|
||||
|
||||
static bool initialized;
|
||||
@ -132,6 +133,10 @@ class java_lang_String : AllStatic {
|
||||
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 @@ class java_lang_String : AllStatic {
|
||||
|
||||
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);
|
||||
|
@ -45,9 +45,9 @@ void java_lang_String::set_value(oop string, typeArrayOop buffer) {
|
||||
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 @@ typeArrayOop java_lang_String::value_no_keepalive(oop java_string) {
|
||||
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");
|
||||
|
@ -761,8 +761,6 @@ struct CopyToArchive : StackObj {
|
||||
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;
|
||||
|
@ -351,19 +351,14 @@ void StringDedupTable::deduplicate(oop java_string, StringDedupStat* stat) {
|
||||
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);
|
||||
|
@ -196,6 +196,10 @@ public:
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -123,7 +123,7 @@ uintptr_t ZBarrier::load_barrier_on_oop_slow_path(uintptr_t addr) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ inline oop ZBarrier::barrier(volatile oop* p, oop o) {
|
||||
retry:
|
||||
// Fast path
|
||||
if (fast_path(addr)) {
|
||||
return ZOop::to_oop(addr);
|
||||
return ZOop::from_address(addr);
|
||||
}
|
||||
|
||||
// Slow path
|
||||
@ -56,7 +56,7 @@ retry:
|
||||
}
|
||||
}
|
||||
|
||||
return ZOop::to_oop(good_addr);
|
||||
return ZOop::from_address(good_addr);
|
||||
}
|
||||
|
||||
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
|
||||
@ -67,7 +67,7 @@ inline oop ZBarrier::weak_barrier(volatile oop* p, oop o) {
|
||||
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 @@ inline oop ZBarrier::weak_barrier(volatile oop* p, oop o) {
|
||||
}
|
||||
}
|
||||
|
||||
return ZOop::to_oop(good_addr);
|
||||
return ZOop::from_address(good_addr);
|
||||
}
|
||||
|
||||
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
|
||||
@ -117,7 +117,7 @@ inline void ZBarrier::root_barrier(oop* p, oop o) {
|
||||
// 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) {
|
||||
|
@ -69,6 +69,11 @@ void ZForwarding::verify() const {
|
||||
// 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");
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ inline void ZHeap::check_out_of_memory() {
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -144,7 +144,7 @@ inline void ZLiveMap::iterate_segment(ObjectClosure* cl, BitMap::idx_t segment,
|
||||
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);
|
||||
|
@ -200,7 +200,7 @@ void ZMark::finish_work() {
|
||||
}
|
||||
|
||||
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 @@ void ZMark::mark_and_follow(ZMarkCache* cache, ZMarkStackEntry entry) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 @@ void ZVerifyOopClosure::do_oop(oop* p) {
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ inline size_t ZUtils::words_to_bytes(size_t size_in_words) {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -3971,7 +3971,7 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
|
||||
#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 @@ static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
|
||||
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 @@ static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool dae
|
||||
// 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();
|
||||
|
@ -236,7 +236,7 @@ jvmtiError JvmtiCodeBlobEvents::generate_compiled_method_load_events(JvmtiEnv* e
|
||||
// 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;
|
||||
}
|
||||
|
@ -2170,61 +2170,37 @@ void JvmtiExport::post_compiled_method_load(nmethod *nm) {
|
||||
|
||||
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)));
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
|
@ -165,9 +165,7 @@ class JvmtiExport : public AllStatic {
|
||||
// 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;
|
||||
|
||||
|
@ -66,22 +66,6 @@ class InterfaceSupport: AllStatic {
|
||||
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 @@ class ThreadStateTransition : public StackObj {
|
||||
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 @@ class ThreadStateTransition : public StackObj {
|
||||
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 @@ class ThreadStateTransition : public StackObj {
|
||||
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 @@ class ThreadInVMForHandshake : public ThreadStateTransition {
|
||||
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 ThreadInVMfromJava : public ThreadStateTransition {
|
||||
|
||||
|
||||
class ThreadInVMfromUnknown {
|
||||
private:
|
||||
JavaThread* _thread;
|
||||
public:
|
||||
ThreadInVMfromUnknown() : _thread(NULL) {
|
||||
@ -236,7 +192,7 @@ class ThreadInVMfromUnknown {
|
||||
}
|
||||
~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 @@ class ThreadInVMfromNative : public ThreadStateTransition {
|
||||
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 @@ class ThreadToNativeFromVM : public ThreadStateTransition {
|
||||
// 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 @@ class ThreadBlockInVM : public ThreadStateTransition {
|
||||
: 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 @@ class ThreadBlockInVMWithDeadlockCheck : public ThreadStateTransition {
|
||||
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 @@ class ThreadBlockInVMWithDeadlockCheck : public ThreadStateTransition {
|
||||
}
|
||||
|
||||
_thread->set_thread_state(_thread_in_vm);
|
||||
CHECK_UNHANDLED_OOPS_ONLY(_thread->clear_unhandled_oops();)
|
||||
|
||||
OrderAccess::cross_modify_fence();
|
||||
}
|
||||
};
|
||||
|
@ -159,7 +159,7 @@ bool Monitor::wait(bool no_safepoint_check, long timeout,
|
||||
// !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 @@ bool Monitor::wait(bool no_safepoint_check, long timeout,
|
||||
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
|
||||
|
@ -805,9 +805,9 @@ void SafepointSynchronize::block(JavaThread *thread) {
|
||||
|
||||
// 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");
|
||||
|
||||
|
@ -1837,7 +1837,7 @@ void JavaThread::run() {
|
||||
|
||||
// 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 @@ void JavaThread::java_suspend_self_with_safepoint_check() {
|
||||
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);
|
||||
}
|
||||
|
@ -1288,6 +1288,7 @@ class JavaThread: public Thread {
|
||||
// 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();
|
||||
|
@ -141,6 +141,11 @@ inline void JavaThread::set_thread_state(JavaThreadState s) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void JavaThread::set_thread_state_fence(JavaThreadState s) {
|
||||
set_thread_state(s);
|
||||
OrderAccess::fence();
|
||||
}
|
||||
|
||||
ThreadSafepointState* JavaThread::safepoint_state() const {
|
||||
return _safepoint_state;
|
||||
}
|
||||
|
@ -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 @@ bool Abstract_VM_Version::_supports_atomic_getadd8 = false;
|
||||
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 @@ unsigned int Abstract_VM_Version::jvm_version() {
|
||||
(Abstract_VM_Version::vm_build_number() & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
void VM_Version_init() {
|
||||
VM_Version::initialize();
|
||||
|
||||
@ -306,3 +307,27 @@ void VM_Version_init() {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 @@ class Abstract_VM_Version: AllStatic {
|
||||
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 @@ class Abstract_VM_Version: AllStatic {
|
||||
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 @@ class Abstract_VM_Version: AllStatic {
|
||||
|
||||
// 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)
|
||||
|
@ -237,11 +237,7 @@ class Exceptions {
|
||||
// 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; }
|
||||
|
@ -1274,7 +1274,12 @@ public final class Math {
|
||||
* @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 final class Math {
|
||||
*/
|
||||
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 @@ public final class Math {
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,6 +164,12 @@ public final class String
|
||||
/** 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 @@ public final class String
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
|
@ -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.EnumSet;
|
||||
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 @@ public class InferenceContext {
|
||||
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 @@ public class InferenceContext {
|
||||
|
||||
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 @@ public class InferenceContext {
|
||||
@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);
|
||||
|
48
test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/MyPackage/GenerateEventsTest.java
Normal file
48
test/hotspot/jtreg/serviceability/jvmti/GenerateEvents/MyPackage/GenerateEventsTest.java
Normal file
@ -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!");
|
||||
}
|
||||
}
|
@ -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"
|
@ -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"
|
@ -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 volatile jint result = PASSED;
|
||||
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 @@ ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {
|
||||
|
||||
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 @@ Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID method,
|
||||
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 @@ Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID method,
|
||||
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 @@ void JNICALL
|
||||
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 @@ jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
|
||||
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)))
|
||||
|
@ -91,6 +91,10 @@ public class DivModTests {
|
||||
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 @@ public class DivModTests {
|
||||
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 @@ public class DivModTests {
|
||||
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);
|
||||
}
|
||||
|
@ -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 @@ public class TestHtmlLandmarkRegions extends JavadocTester {
|
||||
|
||||
TestHtmlLandmarkRegions() {
|
||||
tb = new ToolBox();
|
||||
setAutomaticCheckLinks(false); // @ignore 8217013
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -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 @@ public class TestIndexWithModules extends JavadocTester {
|
||||
//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 @@ public class TestIndexWithModules extends JavadocTester {
|
||||
"<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
|
||||
|
53
test/langtools/tools/javac/T8222035/MinContextOpTest.java
Normal file
53
test/langtools/tools/javac/T8222035/MinContextOpTest.java
Normal file
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
4
test/langtools/tools/javac/T8222035/MinContextOpTest.out
Normal file
4
test/langtools/tools/javac/T8222035/MinContextOpTest.out
Normal file
@ -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
|
95
test/micro/org/openjdk/bench/java/lang/MathBench.java
Normal file
95
test/micro/org/openjdk/bench/java/lang/MathBench.java
Normal file
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user