Merge
This commit is contained in:
commit
614e78b7fa
doc
make
autoconf
hotspot
src/hotspot/share
c1
classfile
gc
shenandoah
c1
c2
heuristics
shenandoahAdaptiveHeuristics.cppshenandoahAdaptiveHeuristics.hppshenandoahAggressiveHeuristics.cppshenandoahAggressiveHeuristics.hppshenandoahCompactHeuristics.cppshenandoahCompactHeuristics.hppshenandoahPassiveHeuristics.cppshenandoahPassiveHeuristics.hppshenandoahStaticHeuristics.cppshenandoahStaticHeuristics.hppshenandoahTraversalAggressiveHeuristics.hppshenandoahTraversalHeuristics.hpp
shenandoahAllocRequest.hppshenandoahAllocTracker.hppshenandoahArguments.hppshenandoahAsserts.hppshenandoahBarrierSet.inline.hppshenandoahBarrierSetAssembler.hppshenandoahCollectionSet.cppshenandoahCollectionSet.hppshenandoahCollectionSet.inline.hppshenandoahCollectorPolicy.cppshenandoahCollectorPolicy.hppshenandoahControlThread.cppshenandoahControlThread.hppshenandoahEvacOOMHandler.cppshenandoahEvacOOMHandler.hppshenandoahForwarding.hppshenandoahForwarding.inline.hppshenandoahFreeSet.hppshenandoahHeapRegion.inline.hppshenandoahHeapRegionCounters.cppshenandoahHeapRegionCounters.hppshenandoahHeapRegionSet.inline.hppshenandoahHeuristics.cppshenandoahHeuristics.hppshenandoahMarkCompact.hppshenandoahMarkingContext.inline.hppshenandoahMemoryPool.cppshenandoahMemoryPool.hppshenandoahMetrics.hppshenandoahMonitoringSupport.cppshenandoahMonitoringSupport.hppshenandoahNumberSeq.cppshenandoahNumberSeq.hppshenandoahOopClosures.hppshenandoahOopClosures.inline.hppshenandoahPacer.hppshenandoahPacer.inline.hppshenandoahPhaseTimings.cppshenandoahRuntime.cppshenandoahSharedVariables.hppshenandoahStrDedupQueue.hppshenandoahStrDedupQueue.inline.hppshenandoahTimingTracker.cppshenandoahTimingTracker.hppshenandoahTracer.hppshenandoahTraversalGC.hppshenandoahTraversalGC.inline.hppshenandoahVMOperations.cppshenandoahVMOperations.hppshenandoahWorkGroup.hppshenandoahWorkerPolicy.cppshenandoahWorkerPolicy.hppz
include
jfr
@ -161,6 +161,7 @@
|
||||
<p>Even for 32-bit builds, it is recommended to use a 64-bit build machine, and instead create a 32-bit target using <code>--with-target-bits=32</code>.</p>
|
||||
<h3 id="building-on-sparc">Building on sparc</h3>
|
||||
<p>At a minimum, a machine with 4 cores is advisable, as well as 4 GB of RAM. (The more cores to use, the more memory you need.) At least 8 GB of free disk space is required.</p>
|
||||
<p>Note: The sparc port is deprecated.</p>
|
||||
<h3 id="building-on-aarch64">Building on aarch64</h3>
|
||||
<p>At a minimum, a machine with 8 cores is advisable, as well as 8 GB of RAM. (The more cores to use, the more memory you need.) At least 6 GB of free disk space is required.</p>
|
||||
<p>If you do not have access to sufficiently powerful hardware, it is also possible to use <a href="#cross-compiling">cross-compiling</a>.</p>
|
||||
@ -225,6 +226,7 @@
|
||||
<h3 id="solaris">Solaris</h3>
|
||||
<p>See <code>make/devkit/solaris11.1-package-list.txt</code> for a list of recommended packages to install when building on Solaris. The versions specified in this list is the versions used by the daily builds at Oracle, and is likely to work properly.</p>
|
||||
<p>Older versions of Solaris shipped a broken version of <code>objcopy</code>. At least version 2.21.1 is needed, which is provided by Solaris 11 Update 1. Objcopy is needed if you want to have external debug symbols. Please make sure you are using at least version 2.21.1 of objcopy, or that you disable external debug symbols.</p>
|
||||
<p>Note: The Solaris port is deprecated.</p>
|
||||
<h3 id="macos">macOS</h3>
|
||||
<p>Apple is using a quite aggressive scheme of pushing OS updates, and coupling these updates with required updates of Xcode. Unfortunately, this makes it difficult for a project such as the JDK to keep pace with a continuously updated machine running macOS. See the section on <a href="#apple-xcode">Apple Xcode</a> on some strategies to deal with this.</p>
|
||||
<p>It is recommended that you use at least Mac OS X 10.13 (High Sierra). At the time of writing, the JDK has been successfully compiled on macOS 10.12 (Sierra).</p>
|
||||
|
@ -120,6 +120,8 @@ At a minimum, a machine with 4 cores is advisable, as well as 4 GB of RAM. (The
|
||||
more cores to use, the more memory you need.) At least 8 GB of free disk space
|
||||
is required.
|
||||
|
||||
Note: The sparc port is deprecated.
|
||||
|
||||
### Building on aarch64
|
||||
|
||||
At a minimum, a machine with 8 cores is advisable, as well as 8 GB of RAM.
|
||||
@ -258,6 +260,8 @@ needed if you want to have external debug symbols. Please make sure you are
|
||||
using at least version 2.21.1 of objcopy, or that you disable external debug
|
||||
symbols.
|
||||
|
||||
Note: The Solaris port is deprecated.
|
||||
|
||||
### macOS
|
||||
|
||||
Apple is using a quite aggressive scheme of pushing OS updates, and coupling
|
||||
|
@ -558,6 +558,23 @@ AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_BUILD_AND_TARGET],
|
||||
PLATFORM_SET_MODULE_TARGET_OS_VALUES
|
||||
PLATFORM_SET_RELEASE_FILE_OS_VALUES
|
||||
PLATFORM_SETUP_LEGACY_VARS
|
||||
PLATFORM_CHECK_DEPRECATION
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([PLATFORM_CHECK_DEPRECATION],
|
||||
[
|
||||
AC_ARG_ENABLE(deprecated-ports, [AS_HELP_STRING([--enable-deprecated-ports@<:@=yes/no@:>@],
|
||||
[Suppress the error when configuring for a deprecated port @<:@no@:>@])])
|
||||
|
||||
AC_REQUIRE([PLATFORM_EXTRACT_TARGET_AND_BUILD])
|
||||
if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_CPU_ARCH" = xsparc; then
|
||||
if test "x$enable_deprecated_ports" = "xyes"; then
|
||||
AC_MSG_WARN([The Solaris and SPARC ports are deprecated and may be removed in a future release.])
|
||||
else
|
||||
AC_MSG_ERROR(m4_normalize([The Solaris and SPARC ports are deprecated and may be removed in a
|
||||
future release. Use --enable-deprecated-ports=yes to suppress this error.]))
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_BUILD_OS_VERSION],
|
||||
|
@ -403,7 +403,6 @@ class CompilerInterfaceVC10 extends CompilerInterface {
|
||||
"/export:jio_snprintf /export:jio_printf "+
|
||||
"/export:jio_fprintf /export:jio_vfprintf "+
|
||||
"/export:jio_vsnprintf "+
|
||||
"/export:JVM_GetVersionInfo "+
|
||||
"/export:JVM_InitAgentProperties");
|
||||
}
|
||||
addAttr(rv, "AdditionalDependencies", "kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;Wsock32.lib;winmm.lib;psapi.lib;version.lib");
|
||||
|
@ -31,5 +31,4 @@ JNI_CreateJavaVM
|
||||
JNI_GetCreatedJavaVMs
|
||||
JNI_GetDefaultJavaVMInitArgs
|
||||
JVM_FindClassFromBootLoader
|
||||
JVM_GetVersionInfo
|
||||
JVM_InitAgentProperties
|
||||
|
@ -329,7 +329,9 @@ void InstructionPrinter::print_head() {
|
||||
void InstructionPrinter::print_line(Instruction* instr) {
|
||||
// print instruction data on one line
|
||||
if (instr->is_pinned()) output()->put('.');
|
||||
fill_to(bci_pos ); output()->print("%d", instr->printable_bci());
|
||||
if (instr->has_printable_bci()) {
|
||||
fill_to(bci_pos ); output()->print("%d", instr->printable_bci());
|
||||
}
|
||||
fill_to(use_pos ); output()->print("%d", instr->use_count());
|
||||
fill_to(temp_pos ); print_temp(instr);
|
||||
fill_to(instr_pos); print_instr(instr);
|
||||
|
@ -3477,7 +3477,7 @@ void ClassFileParser::parse_classfile_bootstrap_methods_attribute(const ClassFil
|
||||
}
|
||||
|
||||
bool ClassFileParser::supports_records() {
|
||||
return _major_version == JAVA_14_VERSION &&
|
||||
return _major_version == JVM_CLASSFILE_MAJOR_VERSION &&
|
||||
_minor_version == JAVA_PREVIEW_MINOR_VERSION &&
|
||||
Arguments::enable_preview();
|
||||
}
|
||||
@ -3722,14 +3722,19 @@ void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cf
|
||||
record_attribute_length = attribute_length;
|
||||
} else if (log_is_enabled(Info, class, record)) {
|
||||
// Log why the Record attribute was ignored. Note that if the
|
||||
// class file version is 58.65535 and --enable-preview wasn't
|
||||
// specified then a java.lang.UnsupportedClassVersionError
|
||||
// class file version is JVM_CLASSFILE_MAJOR_VERSION.65535 and
|
||||
// --enable-preview wasn't specified then a java.lang.UnsupportedClassVersionError
|
||||
// exception would have been thrown.
|
||||
ResourceMark rm(THREAD);
|
||||
log_info(class, record)("Ignoring Record attribute in class %s because %s",
|
||||
_class_name->as_C_string(),
|
||||
supports_records() ? "super type is not java.lang.Record" :
|
||||
"class file version is not 58.65535");
|
||||
if (supports_records()) {
|
||||
log_info(class, record)(
|
||||
"Ignoring Record attribute in class %s because super type is not java.lang.Record",
|
||||
_class_name->as_C_string());
|
||||
} else {
|
||||
log_info(class, record)(
|
||||
"Ignoring Record attribute in class %s because class file version is not %d.65535",
|
||||
_class_name->as_C_string(), JVM_CLASSFILE_MAJOR_VERSION);
|
||||
}
|
||||
}
|
||||
cfs->skip_u1(attribute_length, CHECK);
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2016, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2014, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2015, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2018, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, 2019, Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
static bool is_weak_good(uintptr_t value);
|
||||
static bool is_weak_good_or_null(uintptr_t value);
|
||||
static bool is_marked(uintptr_t value);
|
||||
static bool is_marked_or_null(uintptr_t value);
|
||||
static bool is_finalizable(uintptr_t value);
|
||||
static bool is_finalizable_good(uintptr_t value);
|
||||
static bool is_remapped(uintptr_t value);
|
||||
|
@ -70,6 +70,10 @@ inline bool ZAddress::is_marked(uintptr_t value) {
|
||||
return value & ZAddressMetadataMarked;
|
||||
}
|
||||
|
||||
inline bool ZAddress::is_marked_or_null(uintptr_t value) {
|
||||
return is_marked(value) || is_null(value);
|
||||
}
|
||||
|
||||
inline bool ZAddress::is_finalizable(uintptr_t value) {
|
||||
return value & ZAddressMetadataFinalizable;
|
||||
}
|
||||
|
@ -84,6 +84,17 @@ uintptr_t ZBarrier::mark(uintptr_t addr) {
|
||||
ZHeap::heap()->mark_object<follow, finalizable, publish>(good_addr);
|
||||
}
|
||||
|
||||
if (finalizable) {
|
||||
// Make the oop finalizable marked/good, instead of normal marked/good.
|
||||
// This is needed because an object might first becomes finalizable
|
||||
// marked by the GC, and then loaded by a mutator thread. In this case,
|
||||
// the mutator thread must be able to tell that the object needs to be
|
||||
// strongly marked. The finalizable bit in the oop exists to make sure
|
||||
// that a load of a finalizable marked oop will fall into the barrier
|
||||
// slow path so that we can mark the object as strongly reachable.
|
||||
return ZAddress::finalizable_good(good_addr);
|
||||
}
|
||||
|
||||
return good_addr;
|
||||
}
|
||||
|
||||
@ -166,25 +177,17 @@ uintptr_t ZBarrier::keep_alive_barrier_on_phantom_oop_slow_path(uintptr_t addr)
|
||||
// Mark barrier
|
||||
//
|
||||
uintptr_t ZBarrier::mark_barrier_on_oop_slow_path(uintptr_t addr) {
|
||||
assert(during_mark(), "Invalid phase");
|
||||
|
||||
// Mark
|
||||
return mark<Follow, Strong, Overflow>(addr);
|
||||
}
|
||||
|
||||
uintptr_t ZBarrier::mark_barrier_on_finalizable_oop_slow_path(uintptr_t addr) {
|
||||
const uintptr_t good_addr = mark<Follow, Finalizable, Overflow>(addr);
|
||||
if (ZAddress::is_good(addr)) {
|
||||
// If the oop was already strongly marked/good, then we do
|
||||
// not want to downgrade it to finalizable marked/good.
|
||||
return good_addr;
|
||||
}
|
||||
assert(during_mark(), "Invalid phase");
|
||||
|
||||
// Make the oop finalizable marked/good, instead of normal marked/good.
|
||||
// This is needed because an object might first becomes finalizable
|
||||
// marked by the GC, and then loaded by a mutator thread. In this case,
|
||||
// the mutator thread must be able to tell that the object needs to be
|
||||
// strongly marked. The finalizable bit in the oop exists to make sure
|
||||
// that a load of a finalizable marked oop will fall into the barrier
|
||||
// slow path so that we can mark the object as strongly reachable.
|
||||
return ZAddress::finalizable_good(good_addr);
|
||||
// Mark
|
||||
return mark<Follow, Finalizable, Overflow>(addr);
|
||||
}
|
||||
|
||||
uintptr_t ZBarrier::mark_barrier_on_root_oop_slow_path(uintptr_t addr) {
|
||||
|
@ -41,15 +41,15 @@ private:
|
||||
static const bool Publish = true;
|
||||
static const bool Overflow = false;
|
||||
|
||||
static void self_heal(volatile oop* p, uintptr_t addr, uintptr_t heal_addr);
|
||||
template <ZBarrierFastPath fast_path> static void self_heal(volatile oop* p, uintptr_t addr, uintptr_t heal_addr);
|
||||
|
||||
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path> static oop barrier(volatile oop* p, oop o);
|
||||
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path> static oop weak_barrier(volatile oop* p, oop o);
|
||||
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path> static void root_barrier(oop* p, oop o);
|
||||
|
||||
static bool is_null_fast_path(uintptr_t addr);
|
||||
static bool is_good_or_null_fast_path(uintptr_t addr);
|
||||
static bool is_weak_good_or_null_fast_path(uintptr_t addr);
|
||||
static bool is_marked_or_null_fast_path(uintptr_t addr);
|
||||
|
||||
static bool during_mark();
|
||||
static bool during_relocate();
|
||||
|
@ -32,6 +32,77 @@
|
||||
#include "oops/oop.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
|
||||
// A self heal must always "upgrade" the address metadata bits in
|
||||
// accordance with the metadata bits state machine, which has the
|
||||
// valid state transitions as described below (where N is the GC
|
||||
// cycle).
|
||||
//
|
||||
// Note the subtleness of overlapping GC cycles. Specifically that
|
||||
// oops are colored Remapped(N) starting at relocation N and ending
|
||||
// at marking N + 1.
|
||||
//
|
||||
// +--- Mark Start
|
||||
// | +--- Mark End
|
||||
// | | +--- Relocate Start
|
||||
// | | | +--- Relocate End
|
||||
// | | | |
|
||||
// Marked |---N---|--N+1--|--N+2--|----
|
||||
// Finalizable |---N---|--N+1--|--N+2--|----
|
||||
// Remapped ----|---N---|--N+1--|--N+2--|
|
||||
//
|
||||
// VALID STATE TRANSITIONS
|
||||
//
|
||||
// Marked(N) -> Remapped(N)
|
||||
// -> Marked(N + 1)
|
||||
// -> Finalizable(N + 1)
|
||||
//
|
||||
// Finalizable(N) -> Marked(N)
|
||||
// -> Remapped(N)
|
||||
// -> Marked(N + 1)
|
||||
// -> Finalizable(N + 1)
|
||||
//
|
||||
// Remapped(N) -> Marked(N + 1)
|
||||
// -> Finalizable(N + 1)
|
||||
//
|
||||
// PHASE VIEW
|
||||
//
|
||||
// ZPhaseMark
|
||||
// Load & Mark
|
||||
// Marked(N) <- Marked(N - 1)
|
||||
// <- Finalizable(N - 1)
|
||||
// <- Remapped(N - 1)
|
||||
// <- Finalizable(N)
|
||||
//
|
||||
// Mark(Finalizable)
|
||||
// Finalizable(N) <- Marked(N - 1)
|
||||
// <- Finalizable(N - 1)
|
||||
// <- Remapped(N - 1)
|
||||
//
|
||||
// Load(AS_NO_KEEPALIVE)
|
||||
// Remapped(N - 1) <- Marked(N - 1)
|
||||
// <- Finalizable(N - 1)
|
||||
//
|
||||
// ZPhaseMarkCompleted (Resurrection blocked)
|
||||
// Load & Load(ON_WEAK/PHANTOM_OOP_REF | AS_NO_KEEPALIVE) & KeepAlive
|
||||
// Marked(N) <- Marked(N - 1)
|
||||
// <- Finalizable(N - 1)
|
||||
// <- Remapped(N - 1)
|
||||
// <- Finalizable(N)
|
||||
//
|
||||
// Load(ON_STRONG_OOP_REF | AS_NO_KEEPALIVE)
|
||||
// Remapped(N - 1) <- Marked(N - 1)
|
||||
// <- Finalizable(N - 1)
|
||||
//
|
||||
// ZPhaseMarkCompleted (Resurrection unblocked)
|
||||
// Load
|
||||
// Marked(N) <- Finalizable(N)
|
||||
//
|
||||
// ZPhaseRelocate
|
||||
// Load & Load(AS_NO_KEEPALIVE)
|
||||
// Remapped(N) <- Marked(N)
|
||||
// <- Finalizable(N)
|
||||
|
||||
template <ZBarrierFastPath fast_path>
|
||||
inline void ZBarrier::self_heal(volatile oop* p, uintptr_t addr, uintptr_t heal_addr) {
|
||||
if (heal_addr == 0) {
|
||||
// Never heal with null since it interacts badly with reference processing.
|
||||
@ -41,12 +112,10 @@ inline void ZBarrier::self_heal(volatile oop* p, uintptr_t addr, uintptr_t heal_
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (addr == heal_addr) {
|
||||
// Already healed
|
||||
return;
|
||||
}
|
||||
assert(!fast_path(addr), "Invalid self heal");
|
||||
assert(fast_path(heal_addr), "Invalid self heal");
|
||||
|
||||
for (;;) {
|
||||
// Heal
|
||||
const uintptr_t prev_addr = Atomic::cmpxchg((volatile uintptr_t*)p, addr, heal_addr);
|
||||
if (prev_addr == addr) {
|
||||
@ -54,15 +123,14 @@ inline void ZBarrier::self_heal(volatile oop* p, uintptr_t addr, uintptr_t heal_
|
||||
return;
|
||||
}
|
||||
|
||||
if (ZAddress::is_good_or_null(prev_addr)) {
|
||||
// No need to heal
|
||||
if (fast_path(prev_addr)) {
|
||||
// Must not self heal
|
||||
return;
|
||||
}
|
||||
|
||||
// The oop location was healed by another barrier, but it is still not
|
||||
// good or null. Re-apply healing to make sure the oop is not left with
|
||||
// weaker (remapped or finalizable) metadata bits than what this barrier
|
||||
// tried to apply.
|
||||
// The oop location was healed by another barrier, but still needs upgrading.
|
||||
// Re-apply healing to make sure the oop is not left with weaker (remapped or
|
||||
// finalizable) metadata bits than what this barrier tried to apply.
|
||||
assert(ZAddress::offset(prev_addr) == ZAddress::offset(heal_addr), "Invalid offset");
|
||||
addr = prev_addr;
|
||||
}
|
||||
@ -70,7 +138,7 @@ inline void ZBarrier::self_heal(volatile oop* p, uintptr_t addr, uintptr_t heal_
|
||||
|
||||
template <ZBarrierFastPath fast_path, ZBarrierSlowPath slow_path>
|
||||
inline oop ZBarrier::barrier(volatile oop* p, oop o) {
|
||||
uintptr_t addr = ZOop::to_address(o);
|
||||
const uintptr_t addr = ZOop::to_address(o);
|
||||
|
||||
// Fast path
|
||||
if (fast_path(addr)) {
|
||||
@ -81,7 +149,7 @@ inline oop ZBarrier::barrier(volatile oop* p, oop o) {
|
||||
const uintptr_t good_addr = slow_path(addr);
|
||||
|
||||
if (p != NULL) {
|
||||
self_heal(p, addr, good_addr);
|
||||
self_heal<fast_path>(p, addr, good_addr);
|
||||
}
|
||||
|
||||
return ZOop::from_address(good_addr);
|
||||
@ -104,7 +172,7 @@ inline oop ZBarrier::weak_barrier(volatile oop* p, oop o) {
|
||||
if (p != NULL) {
|
||||
// The slow path returns a good/marked address or null, but we never mark
|
||||
// oops in a weak load barrier so we always heal with the remapped address.
|
||||
self_heal(p, addr, ZAddress::remapped_or_null(good_addr));
|
||||
self_heal<fast_path>(p, addr, ZAddress::remapped_or_null(good_addr));
|
||||
}
|
||||
|
||||
return ZOop::from_address(good_addr);
|
||||
@ -132,10 +200,6 @@ inline void ZBarrier::root_barrier(oop* p, oop o) {
|
||||
*p = ZOop::from_address(good_addr);
|
||||
}
|
||||
|
||||
inline bool ZBarrier::is_null_fast_path(uintptr_t addr) {
|
||||
return ZAddress::is_null(addr);
|
||||
}
|
||||
|
||||
inline bool ZBarrier::is_good_or_null_fast_path(uintptr_t addr) {
|
||||
return ZAddress::is_good_or_null(addr);
|
||||
}
|
||||
@ -144,6 +208,10 @@ inline bool ZBarrier::is_weak_good_or_null_fast_path(uintptr_t addr) {
|
||||
return ZAddress::is_weak_good_or_null(addr);
|
||||
}
|
||||
|
||||
inline bool ZBarrier::is_marked_or_null_fast_path(uintptr_t addr) {
|
||||
return ZAddress::is_marked_or_null(addr);
|
||||
}
|
||||
|
||||
inline bool ZBarrier::during_mark() {
|
||||
return ZGlobalPhase == ZPhaseMark;
|
||||
}
|
||||
@ -300,8 +368,11 @@ inline void ZBarrier::keep_alive_barrier_on_phantom_root_oop_field(oop* p) {
|
||||
}
|
||||
|
||||
inline void ZBarrier::keep_alive_barrier_on_oop(oop o) {
|
||||
const uintptr_t addr = ZOop::to_address(o);
|
||||
assert(ZAddress::is_good(addr), "Invalid address");
|
||||
|
||||
if (during_mark()) {
|
||||
barrier<is_null_fast_path, mark_barrier_on_oop_slow_path>(NULL, o);
|
||||
mark_barrier_on_oop_slow_path(addr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,14 +380,19 @@ inline void ZBarrier::keep_alive_barrier_on_oop(oop o) {
|
||||
// Mark barrier
|
||||
//
|
||||
inline void ZBarrier::mark_barrier_on_oop_field(volatile oop* p, bool finalizable) {
|
||||
// The fast path only checks for null since the GC worker
|
||||
// threads doing marking wants to mark through good oops.
|
||||
const oop o = *p;
|
||||
|
||||
if (finalizable) {
|
||||
barrier<is_null_fast_path, mark_barrier_on_finalizable_oop_slow_path>(p, o);
|
||||
barrier<is_marked_or_null_fast_path, mark_barrier_on_finalizable_oop_slow_path>(p, o);
|
||||
} else {
|
||||
barrier<is_null_fast_path, mark_barrier_on_oop_slow_path>(p, o);
|
||||
const uintptr_t addr = ZOop::to_address(o);
|
||||
if (ZAddress::is_good(addr)) {
|
||||
// Mark through good oop
|
||||
mark_barrier_on_oop_slow_path(addr);
|
||||
} else {
|
||||
// Mark through bad oop
|
||||
barrier<is_good_or_null_fast_path, mark_barrier_on_oop_slow_path>(p, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,6 +140,10 @@ public:
|
||||
ZThreadLocalAllocBuffer::retire(thread);
|
||||
}
|
||||
|
||||
virtual bool should_disarm_nmethods() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void do_oop(oop* p) {
|
||||
ZBarrier::mark_barrier_on_root_oop_field(p);
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ void ZNMethod::register_nmethod(nmethod* nm) {
|
||||
ZNMethodTable::register_nmethod(nm);
|
||||
|
||||
// Disarm nmethod entry barrier
|
||||
disarm_nmethod(nm);
|
||||
disarm(nm);
|
||||
}
|
||||
|
||||
void ZNMethod::unregister_nmethod(nmethod* nm) {
|
||||
@ -187,7 +187,16 @@ void ZNMethod::flush_nmethod(nmethod* nm) {
|
||||
delete gc_data(nm);
|
||||
}
|
||||
|
||||
void ZNMethod::disarm_nmethod(nmethod* nm) {
|
||||
bool ZNMethod::is_armed(nmethod* nm) {
|
||||
BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||
if (bs != NULL) {
|
||||
return bs->is_armed(nm);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ZNMethod::disarm(nmethod* nm) {
|
||||
BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||
if (bs != NULL) {
|
||||
bs->disarm(nm);
|
||||
@ -301,10 +310,12 @@ public:
|
||||
|
||||
ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
|
||||
|
||||
// Heal oops and disarm
|
||||
ZNMethodOopClosure cl;
|
||||
ZNMethod::nmethod_oops_do(nm, &cl);
|
||||
ZNMethod::disarm_nmethod(nm);
|
||||
if (ZNMethod::is_armed(nm)) {
|
||||
// Heal oops and disarm
|
||||
ZNMethodOopClosure cl;
|
||||
ZNMethod::nmethod_oops_do(nm, &cl);
|
||||
ZNMethod::disarm(nm);
|
||||
}
|
||||
|
||||
// Clear compiled ICs and exception caches
|
||||
if (!nm->unload_nmethod_caches(_unloading_occurred)) {
|
||||
|
@ -43,7 +43,8 @@ public:
|
||||
static void unregister_nmethod(nmethod* nm);
|
||||
static void flush_nmethod(nmethod* nm);
|
||||
|
||||
static void disarm_nmethod(nmethod* nm);
|
||||
static bool is_armed(nmethod* nm);
|
||||
static void disarm(nmethod* nm);
|
||||
|
||||
static void nmethod_oops_do(nmethod* nm, OopClosure* cl);
|
||||
|
||||
|
@ -56,6 +56,10 @@ public:
|
||||
ZThreadLocalAllocBuffer::remap(thread);
|
||||
}
|
||||
|
||||
virtual bool should_disarm_nmethods() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void do_oop(oop* p) {
|
||||
ZBarrier::relocate_barrier_on_root_oop_field(p);
|
||||
}
|
||||
|
@ -139,27 +139,31 @@ void ZParallelWeakOopsDo<T, F>::weak_oops_do(BoolObjectClosure* is_alive, ZRoots
|
||||
}
|
||||
}
|
||||
|
||||
class ZRootsIteratorCodeBlobClosure : public CodeBlobToOopClosure {
|
||||
class ZRootsIteratorCodeBlobClosure : public CodeBlobClosure {
|
||||
private:
|
||||
BarrierSetNMethod* _bs;
|
||||
ZRootsIteratorClosure* const _cl;
|
||||
const bool _should_disarm_nmethods;
|
||||
|
||||
public:
|
||||
ZRootsIteratorCodeBlobClosure(OopClosure* cl) :
|
||||
CodeBlobToOopClosure(cl, true /* fix_relocations */),
|
||||
_bs(BarrierSet::barrier_set()->barrier_set_nmethod()) {}
|
||||
ZRootsIteratorCodeBlobClosure(ZRootsIteratorClosure* cl) :
|
||||
_cl(cl),
|
||||
_should_disarm_nmethods(cl->should_disarm_nmethods()) {}
|
||||
|
||||
virtual void do_code_blob(CodeBlob* cb) {
|
||||
nmethod* const nm = cb->as_nmethod_or_null();
|
||||
if (nm != NULL && nm->oops_do_try_claim()) {
|
||||
CodeBlobToOopClosure::do_code_blob(cb);
|
||||
_bs->disarm(nm);
|
||||
ZNMethod::nmethod_oops_do(nm, _cl);
|
||||
assert(ZNMethod::is_armed(nm) == _should_disarm_nmethods, "Invalid state");
|
||||
if (_should_disarm_nmethods) {
|
||||
ZNMethod::disarm(nm);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ZRootsIteratorThreadClosure : public ThreadClosure {
|
||||
private:
|
||||
ZRootsIteratorClosure* _cl;
|
||||
ZRootsIteratorClosure* const _cl;
|
||||
|
||||
public:
|
||||
ZRootsIteratorThreadClosure(ZRootsIteratorClosure* cl) :
|
||||
|
@ -31,10 +31,7 @@
|
||||
#include "runtime/thread.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
class ZRootsIteratorClosure : public OopClosure {
|
||||
public:
|
||||
virtual void do_thread(Thread* thread) {}
|
||||
};
|
||||
class ZRootsIteratorClosure;
|
||||
|
||||
typedef OopStorage::ParState<true /* concurrent */, false /* is_const */> ZOopStorageIterator;
|
||||
|
||||
@ -82,9 +79,18 @@ public:
|
||||
void weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
|
||||
};
|
||||
|
||||
class ZRootsIteratorClosure : public OopClosure {
|
||||
public:
|
||||
virtual void do_thread(Thread* thread) {}
|
||||
|
||||
virtual bool should_disarm_nmethods() const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class ZRootsIterator {
|
||||
private:
|
||||
bool _visit_jvmti_weak_export;
|
||||
const bool _visit_jvmti_weak_export;
|
||||
|
||||
void do_universe(ZRootsIteratorClosure* cl);
|
||||
void do_object_synchronizer(ZRootsIteratorClosure* cl);
|
||||
|
@ -1186,76 +1186,6 @@ JVM_GetTemporaryDirectory(JNIEnv *env);
|
||||
JNIEXPORT jobjectArray JNICALL
|
||||
JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass);
|
||||
|
||||
/* =========================================================================
|
||||
* The following defines a private JVM interface that the JDK can query
|
||||
* for the JVM version and capabilities. sun.misc.Version defines
|
||||
* the methods for getting the VM version and its capabilities.
|
||||
*
|
||||
* When a new bit is added, the following should be updated to provide
|
||||
* access to the new capability:
|
||||
* HS: JVM_GetVersionInfo and Abstract_VM_Version class
|
||||
* SDK: Version class
|
||||
*
|
||||
* Similary, a private JDK interface JDK_GetVersionInfo0 is defined for
|
||||
* JVM to query for the JDK version and capabilities.
|
||||
*
|
||||
* When a new bit is added, the following should be updated to provide
|
||||
* access to the new capability:
|
||||
* HS: JDK_Version class
|
||||
* SDK: JDK_GetVersionInfo0
|
||||
*
|
||||
* ==========================================================================
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int jvm_version; /* Encoded $VNUM as specified by JEP-223 */
|
||||
unsigned int patch_version : 8; /* JEP-223 patch version */
|
||||
unsigned int reserved3 : 8;
|
||||
unsigned int reserved1 : 16;
|
||||
unsigned int reserved2;
|
||||
|
||||
/* The following bits represents JVM supports that JDK has dependency on.
|
||||
* JDK can use these bits to determine which JVM version
|
||||
* and support it has to maintain runtime compatibility.
|
||||
*
|
||||
* When a new bit is added in a minor or update release, make sure
|
||||
* the new bit is also added in the main/baseline.
|
||||
*/
|
||||
unsigned int is_attach_supported : 1;
|
||||
unsigned int : 31;
|
||||
unsigned int : 32;
|
||||
unsigned int : 32;
|
||||
} jvm_version_info;
|
||||
|
||||
#define JVM_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
|
||||
#define JVM_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
|
||||
#define JVM_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8)
|
||||
#define JVM_VERSION_BUILD(version) ((version & 0x000000FF))
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size);
|
||||
|
||||
typedef struct {
|
||||
unsigned int jdk_version; /* Encoded $VNUM as specified by JEP-223 */
|
||||
unsigned int patch_version : 8; /* JEP-223 patch version */
|
||||
unsigned int reserved3 : 8;
|
||||
unsigned int reserved1 : 16;
|
||||
unsigned int reserved2;
|
||||
unsigned int : 32;
|
||||
unsigned int : 32;
|
||||
unsigned int : 32;
|
||||
} jdk_version_info;
|
||||
|
||||
#define JDK_VERSION_MAJOR(version) ((version & 0xFF000000) >> 24)
|
||||
#define JDK_VERSION_MINOR(version) ((version & 0x00FF0000) >> 16)
|
||||
#define JDK_VERSION_SECURITY(version) ((version & 0x0000FF00) >> 8)
|
||||
#define JDK_VERSION_BUILD(version) ((version & 0x000000FF))
|
||||
|
||||
/*
|
||||
* This is the function JDK_GetVersionInfo0 defined in libjava.so
|
||||
* that is dynamically looked up by JVM.
|
||||
*/
|
||||
typedef void (*jdk_version_info_fn_t)(jdk_version_info* info, size_t info_size);
|
||||
|
||||
/*
|
||||
* This structure is used by the launcher to get the default thread
|
||||
* stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a
|
||||
|
@ -103,7 +103,7 @@ void Jfr::on_vm_shutdown(bool exception_handler) {
|
||||
|
||||
void Jfr::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
|
||||
if (LeakProfiler::is_running()) {
|
||||
LeakProfiler::oops_do(is_alive, f);
|
||||
LeakProfiler::weak_oops_do(is_alive, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "jfr/leakprofiler/chains/edgeStore.hpp"
|
||||
#include "jfr/leakprofiler/chains/edgeQueue.hpp"
|
||||
#include "jfr/leakprofiler/utilities/granularTimer.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
@ -111,12 +111,12 @@ void BFSClosure::process_root_set() {
|
||||
}
|
||||
}
|
||||
|
||||
void BFSClosure::process(const oop* reference, const oop pointee) {
|
||||
void BFSClosure::process(UnifiedOopRef reference, const oop pointee) {
|
||||
closure_impl(reference, pointee);
|
||||
}
|
||||
void BFSClosure::closure_impl(const oop* reference, const oop pointee) {
|
||||
assert(reference != NULL, "invariant");
|
||||
assert(UnifiedOop::dereference(reference) == pointee, "invariant");
|
||||
void BFSClosure::closure_impl(UnifiedOopRef reference, const oop pointee) {
|
||||
assert(!reference.is_null(), "invariant");
|
||||
assert(reference.dereference() == pointee, "invariant");
|
||||
|
||||
if (GranularTimer::is_finished()) {
|
||||
return;
|
||||
@ -146,7 +146,7 @@ void BFSClosure::closure_impl(const oop* reference, const oop pointee) {
|
||||
}
|
||||
}
|
||||
|
||||
void BFSClosure::add_chain(const oop* reference, const oop pointee) {
|
||||
void BFSClosure::add_chain(UnifiedOopRef reference, const oop pointee) {
|
||||
assert(pointee != NULL, "invariant");
|
||||
assert(NULL == pointee->mark().to_pointer(), "invariant");
|
||||
Edge leak_edge(_current_parent, reference);
|
||||
@ -213,23 +213,23 @@ void BFSClosure::iterate(const Edge* parent) {
|
||||
void BFSClosure::do_oop(oop* ref) {
|
||||
assert(ref != NULL, "invariant");
|
||||
assert(is_aligned(ref, HeapWordSize), "invariant");
|
||||
const oop pointee = *ref;
|
||||
const oop pointee = HeapAccess<AS_NO_KEEPALIVE>::oop_load(ref);
|
||||
if (pointee != NULL) {
|
||||
closure_impl(ref, pointee);
|
||||
closure_impl(UnifiedOopRef::encode_in_heap(ref), pointee);
|
||||
}
|
||||
}
|
||||
|
||||
void BFSClosure::do_oop(narrowOop* ref) {
|
||||
assert(ref != NULL, "invariant");
|
||||
assert(is_aligned(ref, sizeof(narrowOop)), "invariant");
|
||||
const oop pointee = RawAccess<>::oop_load(ref);
|
||||
const oop pointee = HeapAccess<AS_NO_KEEPALIVE>::oop_load(ref);
|
||||
if (pointee != NULL) {
|
||||
closure_impl(UnifiedOop::encode(ref), pointee);
|
||||
closure_impl(UnifiedOopRef::encode_in_heap(ref), pointee);
|
||||
}
|
||||
}
|
||||
|
||||
void BFSClosure::do_root(const oop* ref) {
|
||||
assert(ref != NULL, "invariant");
|
||||
void BFSClosure::do_root(UnifiedOopRef ref) {
|
||||
assert(!ref.is_null(), "invariant");
|
||||
if (!_edge_queue->is_full()) {
|
||||
_edge_queue->add(NULL, ref);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_JFR_LEAKPROFILER_CHAINS_BFSCLOSURE_HPP
|
||||
#define SHARE_JFR_LEAKPROFILER_CHAINS_BFSCLOSURE_HPP
|
||||
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
|
||||
class BitSet;
|
||||
@ -51,20 +52,23 @@ class BFSClosure : public BasicOopIterateClosure {
|
||||
bool is_complete() const;
|
||||
void step_frontier() const;
|
||||
|
||||
void closure_impl(const oop* reference, const oop pointee);
|
||||
void add_chain(const oop* reference, const oop pointee);
|
||||
void closure_impl(UnifiedOopRef reference, const oop pointee);
|
||||
void add_chain(UnifiedOopRef reference, const oop pointee);
|
||||
void dfs_fallback();
|
||||
|
||||
void iterate(const Edge* parent);
|
||||
void process(const oop* reference, const oop pointee);
|
||||
void process(UnifiedOopRef reference, const oop pointee);
|
||||
|
||||
void process_root_set();
|
||||
void process_queue();
|
||||
|
||||
public:
|
||||
virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS_EXCEPT_REFERENT; }
|
||||
virtual bool should_verify_oops() { return false; }
|
||||
|
||||
BFSClosure(EdgeQueue* edge_queue, EdgeStore* edge_store, BitSet* mark_bits);
|
||||
void process();
|
||||
void do_root(const oop* ref);
|
||||
void do_root(UnifiedOopRef ref);
|
||||
|
||||
virtual void do_oop(oop* ref);
|
||||
virtual void do_oop(narrowOop* ref);
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
|
||||
#include "jfr/leakprofiler/utilities/granularTimer.hpp"
|
||||
#include "jfr/leakprofiler/utilities/rootType.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
|
||||
#include "memory/iterator.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
@ -48,13 +48,13 @@ bool DFSClosure::_ignore_root_set = false;
|
||||
|
||||
DFSClosure::DFSClosure() :
|
||||
_parent(NULL),
|
||||
_reference(NULL),
|
||||
_reference(UnifiedOopRef::encode_null()),
|
||||
_depth(0) {
|
||||
}
|
||||
|
||||
DFSClosure::DFSClosure(DFSClosure* parent, size_t depth) :
|
||||
_parent(parent),
|
||||
_reference(NULL),
|
||||
_reference(UnifiedOopRef::encode_null()),
|
||||
_depth(depth) {
|
||||
}
|
||||
|
||||
@ -99,9 +99,9 @@ void DFSClosure::find_leaks_from_root_set(EdgeStore* edge_store,
|
||||
rs.process();
|
||||
}
|
||||
|
||||
void DFSClosure::closure_impl(const oop* reference, const oop pointee) {
|
||||
void DFSClosure::closure_impl(UnifiedOopRef reference, const oop pointee) {
|
||||
assert(pointee != NULL, "invariant");
|
||||
assert(reference != NULL, "invariant");
|
||||
assert(!reference.is_null(), "invariant");
|
||||
|
||||
if (GranularTimer::is_finished()) {
|
||||
return;
|
||||
@ -161,24 +161,24 @@ void DFSClosure::add_chain() {
|
||||
void DFSClosure::do_oop(oop* ref) {
|
||||
assert(ref != NULL, "invariant");
|
||||
assert(is_aligned(ref, HeapWordSize), "invariant");
|
||||
const oop pointee = *ref;
|
||||
const oop pointee = HeapAccess<AS_NO_KEEPALIVE>::oop_load(ref);
|
||||
if (pointee != NULL) {
|
||||
closure_impl(ref, pointee);
|
||||
closure_impl(UnifiedOopRef::encode_in_heap(ref), pointee);
|
||||
}
|
||||
}
|
||||
|
||||
void DFSClosure::do_oop(narrowOop* ref) {
|
||||
assert(ref != NULL, "invariant");
|
||||
assert(is_aligned(ref, sizeof(narrowOop)), "invariant");
|
||||
const oop pointee = RawAccess<>::oop_load(ref);
|
||||
const oop pointee = HeapAccess<AS_NO_KEEPALIVE>::oop_load(ref);
|
||||
if (pointee != NULL) {
|
||||
closure_impl(UnifiedOop::encode(ref), pointee);
|
||||
closure_impl(UnifiedOopRef::encode_in_heap(ref), pointee);
|
||||
}
|
||||
}
|
||||
|
||||
void DFSClosure::do_root(const oop* ref) {
|
||||
assert(ref != NULL, "invariant");
|
||||
const oop pointee = UnifiedOop::dereference(ref);
|
||||
void DFSClosure::do_root(UnifiedOopRef ref) {
|
||||
assert(!ref.is_null(), "invariant");
|
||||
const oop pointee = ref.dereference();
|
||||
assert(pointee != NULL, "invariant");
|
||||
closure_impl(ref, pointee);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_JFR_LEAKPROFILER_CHAINS_DFSCLOSURE_HPP
|
||||
#define SHARE_JFR_LEAKPROFILER_CHAINS_DFSCLOSURE_HPP
|
||||
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
|
||||
class BitSet;
|
||||
@ -41,22 +42,25 @@ class DFSClosure : public BasicOopIterateClosure {
|
||||
static size_t _max_depth;
|
||||
static bool _ignore_root_set;
|
||||
DFSClosure* _parent;
|
||||
const oop* _reference;
|
||||
UnifiedOopRef _reference;
|
||||
size_t _depth;
|
||||
|
||||
void add_chain();
|
||||
void closure_impl(const oop* reference, const oop pointee);
|
||||
void closure_impl(UnifiedOopRef reference, const oop pointee);
|
||||
|
||||
DFSClosure* parent() const { return _parent; }
|
||||
const oop* reference() const { return _reference; }
|
||||
UnifiedOopRef reference() const { return _reference; }
|
||||
|
||||
DFSClosure(DFSClosure* parent, size_t depth);
|
||||
DFSClosure();
|
||||
|
||||
public:
|
||||
virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS_EXCEPT_REFERENT; }
|
||||
virtual bool should_verify_oops() { return false; }
|
||||
|
||||
static void find_leaks_from_edge(EdgeStore* edge_store, BitSet* mark_bits, const Edge* start_edge);
|
||||
static void find_leaks_from_root_set(EdgeStore* edge_store, BitSet* mark_bits);
|
||||
void do_root(const oop* ref);
|
||||
void do_root(UnifiedOopRef ref);
|
||||
|
||||
virtual void do_oop(oop* ref);
|
||||
virtual void do_oop(narrowOop* ref);
|
||||
|
@ -24,19 +24,17 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/javaClasses.inline.hpp"
|
||||
#include "jfr/leakprofiler/chains/edge.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
|
||||
|
||||
Edge::Edge() : _parent(NULL), _reference(NULL) {}
|
||||
|
||||
Edge::Edge(const Edge* parent, const oop* reference) : _parent(parent),
|
||||
_reference(reference) {}
|
||||
Edge::Edge(const Edge* parent, UnifiedOopRef reference) : _parent(parent),
|
||||
_reference(reference) {}
|
||||
|
||||
const oop Edge::pointee() const {
|
||||
return UnifiedOop::dereference(_reference);
|
||||
return _reference.dereference();
|
||||
}
|
||||
|
||||
const oop Edge::reference_owner() const {
|
||||
return is_root() ? (oop)NULL : UnifiedOop::dereference(_parent->reference());
|
||||
return is_root() ? (oop)NULL : _parent->reference().dereference();
|
||||
}
|
||||
|
||||
static const Klass* resolve_klass(const oop obj) {
|
||||
|
@ -25,18 +25,18 @@
|
||||
#ifndef SHARE_JFR_LEAKPROFILER_CHAINS_EDGE_HPP
|
||||
#define SHARE_JFR_LEAKPROFILER_CHAINS_EDGE_HPP
|
||||
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "oops/oopsHierarchy.hpp"
|
||||
|
||||
class Edge {
|
||||
protected:
|
||||
const Edge* _parent;
|
||||
const oop* _reference;
|
||||
UnifiedOopRef _reference;
|
||||
public:
|
||||
Edge();
|
||||
Edge(const Edge* parent, const oop* reference);
|
||||
Edge(const Edge* parent, UnifiedOopRef reference);
|
||||
|
||||
const oop* reference() const {
|
||||
UnifiedOopRef reference() const {
|
||||
return _reference;
|
||||
}
|
||||
const Edge* parent() const {
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "jfr/leakprofiler/chains/edgeQueue.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
|
||||
#include "jfr/recorder/storage/jfrVirtualMemory.hpp"
|
||||
|
||||
EdgeQueue::EdgeQueue(size_t reservation_size_bytes, size_t commit_block_size_bytes) :
|
||||
@ -45,8 +46,8 @@ EdgeQueue::~EdgeQueue() {
|
||||
delete _vmm;
|
||||
}
|
||||
|
||||
void EdgeQueue::add(const Edge* parent, const oop* ref) {
|
||||
assert(ref != NULL, "Null objects not allowed in EdgeQueue");
|
||||
void EdgeQueue::add(const Edge* parent, UnifiedOopRef ref) {
|
||||
assert(!ref.is_null(), "Null objects not allowed in EdgeQueue");
|
||||
assert(!is_full(), "EdgeQueue is full. Check is_full before adding another Edge");
|
||||
assert(!_vmm->is_full(), "invariant");
|
||||
void* const allocation = _vmm->new_datum();
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "jfr/leakprofiler/chains/edge.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.hpp"
|
||||
|
||||
class JfrVirtualMemory;
|
||||
|
||||
@ -43,7 +44,7 @@ class EdgeQueue : public CHeapObj<mtTracing> {
|
||||
|
||||
bool initialize();
|
||||
|
||||
void add(const Edge* parent, const oop* ref);
|
||||
void add(const Edge* parent, UnifiedOopRef ref);
|
||||
const Edge* remove() const;
|
||||
const Edge* element_at(size_t index) const;
|
||||
|
||||
|
@ -25,21 +25,15 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "jfr/leakprofiler/chains/edgeStore.hpp"
|
||||
#include "jfr/leakprofiler/chains/edgeUtils.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
|
||||
StoredEdge::StoredEdge() : Edge() {}
|
||||
StoredEdge::StoredEdge(const Edge* parent, const oop* reference) : Edge(parent, reference), _gc_root_id(0), _skip_length(0) {}
|
||||
StoredEdge::StoredEdge(const Edge* parent, UnifiedOopRef reference) : Edge(parent, reference), _gc_root_id(0), _skip_length(0) {}
|
||||
|
||||
StoredEdge::StoredEdge(const Edge& edge) : Edge(edge), _gc_root_id(0), _skip_length(0) {}
|
||||
|
||||
StoredEdge::StoredEdge(const StoredEdge& edge) : Edge(edge), _gc_root_id(edge._gc_root_id), _skip_length(edge._skip_length) {}
|
||||
|
||||
void StoredEdge::operator=(const StoredEdge& edge) {
|
||||
Edge::operator=(edge);
|
||||
_gc_root_id = edge._gc_root_id;
|
||||
_skip_length = edge._skip_length;
|
||||
}
|
||||
|
||||
traceid EdgeStore::_edge_id_counter = 0;
|
||||
|
||||
EdgeStore::EdgeStore() : _edges(NULL) {
|
||||
@ -73,28 +67,28 @@ void EdgeStore::on_unlink(EdgeEntry* entry) {
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
bool EdgeStore::contains(const oop* reference) const {
|
||||
bool EdgeStore::contains(UnifiedOopRef reference) const {
|
||||
return get(reference) != NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
StoredEdge* EdgeStore::get(const oop* reference) const {
|
||||
assert(reference != NULL, "invariant");
|
||||
EdgeEntry* const entry = _edges->lookup_only((uintptr_t)reference);
|
||||
StoredEdge* EdgeStore::get(UnifiedOopRef reference) const {
|
||||
assert(!reference.is_null(), "invariant");
|
||||
EdgeEntry* const entry = _edges->lookup_only(reference.addr<uintptr_t>());
|
||||
return entry != NULL ? entry->literal_addr() : NULL;
|
||||
}
|
||||
|
||||
StoredEdge* EdgeStore::put(const oop* reference) {
|
||||
assert(reference != NULL, "invariant");
|
||||
StoredEdge* EdgeStore::put(UnifiedOopRef reference) {
|
||||
assert(!reference.is_null(), "invariant");
|
||||
const StoredEdge e(NULL, reference);
|
||||
assert(NULL == _edges->lookup_only((uintptr_t)reference), "invariant");
|
||||
EdgeEntry& entry = _edges->put((uintptr_t)reference, e);
|
||||
assert(NULL == _edges->lookup_only(reference.addr<uintptr_t>()), "invariant");
|
||||
EdgeEntry& entry = _edges->put(reference.addr<uintptr_t>(), e);
|
||||
return entry.literal_addr();
|
||||
}
|
||||
|
||||
traceid EdgeStore::get_id(const Edge* edge) const {
|
||||
assert(edge != NULL, "invariant");
|
||||
EdgeEntry* const entry = _edges->lookup_only((uintptr_t)edge->reference());
|
||||
EdgeEntry* const entry = _edges->lookup_only(edge->reference().addr<uintptr_t>());
|
||||
assert(entry != NULL, "invariant");
|
||||
return entry->id();
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define SHARE_JFR_LEAKPROFILER_CHAINS_EDGESTORE_HPP
|
||||
|
||||
#include "jfr/leakprofiler/chains/edge.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.hpp"
|
||||
#include "jfr/utilities/jfrHashtable.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
@ -38,10 +39,9 @@ class StoredEdge : public Edge {
|
||||
|
||||
public:
|
||||
StoredEdge();
|
||||
StoredEdge(const Edge* parent, const oop* reference);
|
||||
StoredEdge(const Edge* parent, UnifiedOopRef reference);
|
||||
StoredEdge(const Edge& edge);
|
||||
StoredEdge(const StoredEdge& edge);
|
||||
void operator=(const StoredEdge& edge);
|
||||
|
||||
traceid gc_root_id() const { return _gc_root_id; }
|
||||
void set_gc_root_id(traceid root_id) const { _gc_root_id = root_id; }
|
||||
@ -78,8 +78,8 @@ class EdgeStore : public CHeapObj<mtTracing> {
|
||||
bool on_equals(uintptr_t hash, const EdgeEntry* entry);
|
||||
void on_unlink(EdgeEntry* entry);
|
||||
|
||||
StoredEdge* get(const oop* reference) const;
|
||||
StoredEdge* put(const oop* reference);
|
||||
StoredEdge* get(UnifiedOopRef reference) const;
|
||||
StoredEdge* put(UnifiedOopRef reference);
|
||||
traceid gc_root_id(const Edge* edge) const;
|
||||
|
||||
bool put_edges(StoredEdge** previous, const Edge** current, size_t length);
|
||||
@ -94,7 +94,7 @@ class EdgeStore : public CHeapObj<mtTracing> {
|
||||
template <typename T>
|
||||
void iterate(T& functor) const { _edges->iterate_value<T>(functor); }
|
||||
|
||||
DEBUG_ONLY(bool contains(const oop* reference) const;)
|
||||
DEBUG_ONLY(bool contains(UnifiedOopRef reference) const;)
|
||||
|
||||
public:
|
||||
EdgeStore();
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "jfr/leakprofiler/chains/edge.hpp"
|
||||
#include "jfr/leakprofiler/chains/edgeStore.hpp"
|
||||
#include "jfr/leakprofiler/chains/edgeUtils.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
|
||||
#include "oops/fieldStreams.inline.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/objArrayOop.inline.hpp"
|
||||
@ -42,12 +42,11 @@ static int field_offset(const StoredEdge& edge) {
|
||||
assert(!edge.is_root(), "invariant");
|
||||
const oop ref_owner = edge.reference_owner();
|
||||
assert(ref_owner != NULL, "invariant");
|
||||
const oop* reference = UnifiedOop::decode(edge.reference());
|
||||
assert(reference != NULL, "invariant");
|
||||
assert(!UnifiedOop::is_narrow(reference), "invariant");
|
||||
UnifiedOopRef reference = edge.reference();
|
||||
assert(!reference.is_null(), "invariant");
|
||||
assert(!ref_owner->is_array(), "invariant");
|
||||
assert(ref_owner->is_instance(), "invariant");
|
||||
const int offset = (int)pointer_delta(reference, ref_owner, sizeof(char));
|
||||
const int offset = (int)(reference.addr<uintptr_t>() - cast_from_oop<uintptr_t>(ref_owner));
|
||||
assert(offset < (ref_owner->size() * HeapWordSize), "invariant");
|
||||
return offset;
|
||||
}
|
||||
@ -103,12 +102,11 @@ static int array_offset(const Edge& edge) {
|
||||
assert(!edge.is_root(), "invariant");
|
||||
const oop ref_owner = edge.reference_owner();
|
||||
assert(ref_owner != NULL, "invariant");
|
||||
const oop* reference = UnifiedOop::decode(edge.reference());
|
||||
assert(reference != NULL, "invariant");
|
||||
assert(!UnifiedOop::is_narrow(reference), "invariant");
|
||||
UnifiedOopRef reference = edge.reference();
|
||||
assert(!reference.is_null(), "invariant");
|
||||
assert(ref_owner->is_array(), "invariant");
|
||||
const objArrayOop ref_owner_array = static_cast<const objArrayOop>(ref_owner);
|
||||
const int offset = (int)pointer_delta(reference, ref_owner_array->base(), heapOopSize);
|
||||
const int offset = (int)pointer_delta(reference.addr<HeapWord*>(), ref_owner_array->base(), heapOopSize);
|
||||
assert(offset >= 0 && offset < ref_owner_array->length(), "invariant");
|
||||
return offset;
|
||||
}
|
||||
@ -122,7 +120,7 @@ int EdgeUtils::array_size(const Edge& edge) {
|
||||
const oop ref_owner = edge.reference_owner();
|
||||
assert(ref_owner != NULL, "invariant");
|
||||
assert(ref_owner->is_objArray(), "invariant");
|
||||
return ((objArrayOop)(ref_owner))->length();
|
||||
return ((objArrayOop)ref_owner)->length();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "jfr/leakprofiler/chains/dfsClosure.hpp"
|
||||
#include "jfr/leakprofiler/chains/edgeQueue.hpp"
|
||||
#include "jfr/leakprofiler/chains/rootSetClosure.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOop.hpp"
|
||||
#include "jfr/leakprofiler/utilities/unifiedOopRef.inline.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
@ -49,20 +49,9 @@ RootSetClosure<Delegate>::RootSetClosure(Delegate* delegate) : _delegate(delegat
|
||||
template <typename Delegate>
|
||||
void RootSetClosure<Delegate>::do_oop(oop* ref) {
|
||||
assert(ref != NULL, "invariant");
|
||||
// We discard unaligned root references because
|
||||
// our reference tagging scheme will use
|
||||
// the lowest bit in a represented reference
|
||||
// to indicate the reference is narrow.
|
||||
// It is mainly roots delivered via nmethods::do_oops()
|
||||
// that come in unaligned. It should be ok to duck these
|
||||
// since they are supposedly weak.
|
||||
if (!is_aligned(ref, HeapWordSize)) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(is_aligned(ref, HeapWordSize), "invariant");
|
||||
if (*ref != NULL) {
|
||||
_delegate->do_root(ref);
|
||||
_delegate->do_root(UnifiedOopRef::encode_in_native(ref));
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,9 +59,8 @@ template <typename Delegate>
|
||||
void RootSetClosure<Delegate>::do_oop(narrowOop* ref) {
|
||||
assert(ref != NULL, "invariant");
|
||||
assert(is_aligned(ref, sizeof(narrowOop)), "invariant");
|
||||
const oop pointee = RawAccess<>::oop_load(ref);
|
||||
if (pointee != NULL) {
|
||||
_delegate->do_root(UnifiedOop::encode(ref));
|
||||
if (*ref != 0) {
|
||||
_delegate->do_root(UnifiedOopRef::encode_in_native(ref));
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,8 +71,8 @@ void RootSetClosure<Delegate>::process() {
|
||||
RootSetClosureMarkScope mark_scope;
|
||||
CLDToOopClosure cldt_closure(this, ClassLoaderData::_claim_none);
|
||||
ClassLoaderDataGraph::always_strong_cld_do(&cldt_closure);
|
||||
CodeBlobToOopClosure blobs(this, false);
|
||||
Threads::oops_do(this, &blobs);
|
||||
// We don't follow code blob oops, because they have misaligned oops.
|
||||
Threads::oops_do(this, NULL);
|
||||
ObjectSynchronizer::oops_do(this);
|
||||
Universe::oops_do(this);
|
||||
JNIHandles::oops_do(this);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user