mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
Compare commits
No commits in common. "master" and "jdk-27+4" have entirely different histories.
1
.github/workflows/build-alpine-linux.yml
vendored
1
.github/workflows/build-alpine-linux.yml
vendored
@ -97,7 +97,6 @@ jobs:
|
||||
--with-zlib=system
|
||||
--with-jmod-compress=zip-1
|
||||
--with-external-symbols-in-bundles=none
|
||||
--with-native-debug-symbols-level=1
|
||||
${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || (
|
||||
echo "Dumping config.log:" &&
|
||||
cat config.log &&
|
||||
|
||||
1
.github/workflows/build-cross-compile.yml
vendored
1
.github/workflows/build-cross-compile.yml
vendored
@ -180,7 +180,6 @@ jobs:
|
||||
--with-sysroot=sysroot
|
||||
--with-jmod-compress=zip-1
|
||||
--with-external-symbols-in-bundles=none
|
||||
--with-native-debug-symbols-level=1
|
||||
CC=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-gcc-${{ inputs.gcc-major-version }}
|
||||
CXX=${{ matrix.gnu-arch }}-linux-gnu${{ matrix.gnu-abi}}-g++-${{ inputs.gcc-major-version }}
|
||||
${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || (
|
||||
|
||||
1
.github/workflows/build-linux.yml
vendored
1
.github/workflows/build-linux.yml
vendored
@ -144,7 +144,6 @@ jobs:
|
||||
--with-zlib=system
|
||||
--with-jmod-compress=zip-1
|
||||
--with-external-symbols-in-bundles=none
|
||||
--with-native-debug-symbols-level=1
|
||||
${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || (
|
||||
echo "Dumping config.log:" &&
|
||||
cat config.log &&
|
||||
|
||||
1
.github/workflows/build-macos.yml
vendored
1
.github/workflows/build-macos.yml
vendored
@ -111,7 +111,6 @@ jobs:
|
||||
--with-zlib=system
|
||||
--with-jmod-compress=zip-1
|
||||
--with-external-symbols-in-bundles=none
|
||||
--with-native-debug-symbols-level=1
|
||||
${{ inputs.extra-conf-options }} ${{ inputs.configure-arguments }} || (
|
||||
echo "Dumping config.log:" &&
|
||||
cat config.log &&
|
||||
|
||||
@ -72,7 +72,6 @@ id="toc-notes-for-specific-tests">Notes for Specific Tests</a>
|
||||
<li><a href="#non-us-locale" id="toc-non-us-locale">Non-US
|
||||
locale</a></li>
|
||||
<li><a href="#pkcs11-tests" id="toc-pkcs11-tests">PKCS11 Tests</a></li>
|
||||
<li><a href="#sctp-tests" id="toc-sctp-tests">SCTP Tests</a></li>
|
||||
<li><a href="#testing-ahead-of-time-optimizations"
|
||||
id="toc-testing-ahead-of-time-optimizations">Testing Ahead-of-time
|
||||
Optimizations</a></li>
|
||||
@ -622,21 +621,6 @@ element of the appropriate <code>@Artifact</code> class. (See
|
||||
JTREG="JAVA_OPTIONS=-Djdk.test.lib.artifacts.nsslib-linux_aarch64=/path/to/NSS-libs"</code></pre>
|
||||
<p>For more notes about the PKCS11 tests, please refer to
|
||||
test/jdk/sun/security/pkcs11/README.</p>
|
||||
<h3 id="sctp-tests">SCTP Tests</h3>
|
||||
<p>The SCTP tests require the SCTP runtime library, which is often not
|
||||
installed by default in popular Linux distributions. Without this
|
||||
library, the SCTP tests will be skipped. If you want to enable the SCTP
|
||||
tests, you should install the SCTP library before running the tests.</p>
|
||||
<p>For distributions using the .deb packaging format and the apt tool
|
||||
(such as Debian, Ubuntu, etc.), try this:</p>
|
||||
<pre><code>sudo apt install libsctp1
|
||||
sudo modprobe sctp
|
||||
lsmod | grep sctp</code></pre>
|
||||
<p>For distributions using the .rpm packaging format and the dnf tool
|
||||
(such as Fedora, Red Hat, etc.), try this:</p>
|
||||
<pre><code>sudo dnf install -y lksctp-tools
|
||||
sudo modprobe sctp
|
||||
lsmod | grep sctp</code></pre>
|
||||
<h3 id="testing-ahead-of-time-optimizations">Testing Ahead-of-time
|
||||
Optimizations</h3>
|
||||
<p>One way to improve test coverage of ahead-of-time (AOT) optimizations
|
||||
|
||||
@ -640,32 +640,6 @@ $ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" \
|
||||
For more notes about the PKCS11 tests, please refer to
|
||||
test/jdk/sun/security/pkcs11/README.
|
||||
|
||||
|
||||
### SCTP Tests
|
||||
|
||||
The SCTP tests require the SCTP runtime library, which is often not installed
|
||||
by default in popular Linux distributions. Without this library, the SCTP tests
|
||||
will be skipped. If you want to enable the SCTP tests, you should install the
|
||||
SCTP library before running the tests.
|
||||
|
||||
For distributions using the .deb packaging format and the apt tool
|
||||
(such as Debian, Ubuntu, etc.), try this:
|
||||
|
||||
```
|
||||
sudo apt install libsctp1
|
||||
sudo modprobe sctp
|
||||
lsmod | grep sctp
|
||||
```
|
||||
|
||||
For distributions using the .rpm packaging format and the dnf tool
|
||||
(such as Fedora, Red Hat, etc.), try this:
|
||||
|
||||
```
|
||||
sudo dnf install -y lksctp-tools
|
||||
sudo modprobe sctp
|
||||
lsmod | grep sctp
|
||||
```
|
||||
|
||||
### Testing Ahead-of-time Optimizations
|
||||
|
||||
One way to improve test coverage of ahead-of-time (AOT) optimizations in
|
||||
|
||||
@ -69,19 +69,6 @@ AC_DEFUN([FLAGS_SETUP_DEBUG_SYMBOLS],
|
||||
# Debug prefix mapping if supported by compiler
|
||||
DEBUG_PREFIX_CFLAGS=
|
||||
|
||||
UTIL_ARG_WITH(NAME: native-debug-symbols-level, TYPE: literal,
|
||||
DEFAULT: [auto], VALID_VALUES: [auto 1 2 3],
|
||||
CHECK_AVAILABLE: [
|
||||
if test x$TOOLCHAIN_TYPE = xmicrosoft; then
|
||||
AVAILABLE=false
|
||||
fi
|
||||
],
|
||||
DESC: [set the native debug symbol level (GCC and Clang only)],
|
||||
DEFAULT_DESC: [toolchain default],
|
||||
IF_AUTO: [
|
||||
RESULT=""
|
||||
])
|
||||
|
||||
# Debug symbols
|
||||
if test "x$TOOLCHAIN_TYPE" = xgcc; then
|
||||
if test "x$ALLOW_ABSOLUTE_PATHS_IN_OUTPUT" = "xfalse"; then
|
||||
@ -106,9 +93,8 @@ AC_DEFUN([FLAGS_SETUP_DEBUG_SYMBOLS],
|
||||
)
|
||||
fi
|
||||
|
||||
# Debug info level should follow the debug format to be effective.
|
||||
CFLAGS_DEBUG_SYMBOLS="-gdwarf-4 -g${NATIVE_DEBUG_SYMBOLS_LEVEL}"
|
||||
ASFLAGS_DEBUG_SYMBOLS="-g${NATIVE_DEBUG_SYMBOLS_LEVEL}"
|
||||
CFLAGS_DEBUG_SYMBOLS="-g -gdwarf-4"
|
||||
ASFLAGS_DEBUG_SYMBOLS="-g"
|
||||
elif test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
if test "x$ALLOW_ABSOLUTE_PATHS_IN_OUTPUT" = "xfalse"; then
|
||||
# Check if compiler supports -fdebug-prefix-map. If so, use that to make
|
||||
@ -127,9 +113,8 @@ AC_DEFUN([FLAGS_SETUP_DEBUG_SYMBOLS],
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [${GDWARF_FLAGS}],
|
||||
IF_FALSE: [GDWARF_FLAGS=""])
|
||||
|
||||
# Debug info level should follow the debug format to be effective.
|
||||
CFLAGS_DEBUG_SYMBOLS="${GDWARF_FLAGS} -g${NATIVE_DEBUG_SYMBOLS_LEVEL}"
|
||||
ASFLAGS_DEBUG_SYMBOLS="-g${NATIVE_DEBUG_SYMBOLS_LEVEL}"
|
||||
CFLAGS_DEBUG_SYMBOLS="-g ${GDWARF_FLAGS}"
|
||||
ASFLAGS_DEBUG_SYMBOLS="-g"
|
||||
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||
CFLAGS_DEBUG_SYMBOLS="-Z7"
|
||||
fi
|
||||
|
||||
@ -114,7 +114,7 @@ EscapeDollar = $(subst $$,\$$,$(subst \$$,$$,$(strip $1)))
|
||||
|
||||
################################################################################
|
||||
# This macro works just like EscapeDollar above, but for #.
|
||||
EscapeHash = $(subst $(HASH),\$(HASH),$(subst \$(HASH),$(HASH),$(strip $1)))
|
||||
EscapeHash = $(subst \#,\\\#,$(subst \\\#,\#,$(strip $1)))
|
||||
|
||||
################################################################################
|
||||
# This macro translates $ into $$ to protect the string from make itself.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2016, 2025, 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
|
||||
@ -61,8 +61,7 @@ $(eval $(call SetupJdkLibrary, BUILD_GTEST_LIBGTEST, \
|
||||
INCLUDE_FILES := gtest-all.cc gmock-all.cc, \
|
||||
DISABLED_WARNINGS_gcc := format-nonliteral maybe-uninitialized undef \
|
||||
unused-result zero-as-null-pointer-constant, \
|
||||
DISABLED_WARNINGS_clang := format-nonliteral undef unused-result \
|
||||
zero-as-null-pointer-constant, \
|
||||
DISABLED_WARNINGS_clang := format-nonliteral undef unused-result, \
|
||||
DISABLED_WARNINGS_microsoft := 4530, \
|
||||
DEFAULT_CFLAGS := false, \
|
||||
CFLAGS := $(JVM_CFLAGS) \
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -49,15 +49,13 @@ import static com.sun.source.doctree.DocTree.Kind.*;
|
||||
* The tags can be used as follows:
|
||||
*
|
||||
* <pre>
|
||||
* @jls chapter.section description
|
||||
* @jls preview-feature-chapter.section description
|
||||
* @jls section-number description
|
||||
* </pre>
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* <pre>
|
||||
* @jls 3.4 Line Terminators
|
||||
* @jls primitive-types-in-patterns-instanceof-switch-5.7.1 Exact Testing Conversions
|
||||
* </pre>
|
||||
*
|
||||
* will produce the following HTML, depending on the file containing
|
||||
@ -66,24 +64,10 @@ import static com.sun.source.doctree.DocTree.Kind.*;
|
||||
* <pre>{@code
|
||||
* <dt>See <i>Java Language Specification</i>:
|
||||
* <dd><a href="../../specs/jls/jls-3.html#jls-3.4">3.4 Line terminators</a>
|
||||
* <dd><a href="../../specs/primitive-types-in-patterns-instanceof-switch-jls.html#jls-5.7.1">
|
||||
* 5.7.1 Exact Testing Conversions</a><sup class="preview-mark">
|
||||
* <a href="../../specs/jls/jls-1.html#jls-1.5.1">PREVIEW</a></sup>
|
||||
* }</pre>
|
||||
*
|
||||
* In inline tags (note you need manual JLS/JVMS prefix):
|
||||
* <pre>
|
||||
* JLS {@jls 3.4}
|
||||
* </pre>
|
||||
*
|
||||
* produces (note the section sign and no trailing dot):
|
||||
* <pre>
|
||||
* JLS <a href="../../specs/jls/jls-3.html#jls-3.4">§3.4</a>
|
||||
* </pre>
|
||||
*
|
||||
* Copies of JLS, JVMS, and preview JLS and JVMS changes are expected to have
|
||||
* been placed in the {@code specs} folder. These documents are not included
|
||||
* in open-source repositories.
|
||||
* Copies of JLS and JVMS are expected to have been placed in the {@code specs}
|
||||
* folder. These documents are not included in open-source repositories.
|
||||
*/
|
||||
public class JSpec implements Taglet {
|
||||
|
||||
@ -103,9 +87,9 @@ public class JSpec implements Taglet {
|
||||
}
|
||||
}
|
||||
|
||||
private final String tagName;
|
||||
private final String specTitle;
|
||||
private final String idPrefix;
|
||||
private String tagName;
|
||||
private String specTitle;
|
||||
private String idPrefix;
|
||||
|
||||
JSpec(String tagName, String specTitle, String idPrefix) {
|
||||
this.tagName = tagName;
|
||||
@ -114,7 +98,7 @@ public class JSpec implements Taglet {
|
||||
}
|
||||
|
||||
// Note: Matches special cases like @jvms 6.5.checkcast
|
||||
private static final Pattern TAG_PATTERN = Pattern.compile("(?s)(.+ )?(?<preview>([a-z0-9]+-)+)?(?<chapter>[1-9][0-9]*)(?<section>[0-9a-z_.]*)( .*)?$");
|
||||
private static final Pattern TAG_PATTERN = Pattern.compile("(?s)(.+ )?(?<chapter>[1-9][0-9]*)(?<section>[0-9a-z_.]*)( .*)?$");
|
||||
|
||||
/**
|
||||
* Returns the set of locations in which the tag may be used.
|
||||
@ -173,50 +157,19 @@ public class JSpec implements Taglet {
|
||||
.trim();
|
||||
Matcher m = TAG_PATTERN.matcher(tagText);
|
||||
if (m.find()) {
|
||||
// preview-feature-4.6 is preview-feature-, 4, .6
|
||||
String preview = m.group("preview"); // null if no preview feature
|
||||
String chapter = m.group("chapter");
|
||||
String section = m.group("section");
|
||||
String rootParent = currentPath().replaceAll("[^/]+", "..");
|
||||
|
||||
String url = preview == null ?
|
||||
String.format("%1$s/specs/%2$s/%2$s-%3$s.html#%2$s-%3$s%4$s",
|
||||
rootParent, idPrefix, chapter, section) :
|
||||
String.format("%1$s/specs/%5$s%2$s.html#%2$s-%3$s%4$s",
|
||||
rootParent, idPrefix, chapter, section, preview);
|
||||
|
||||
var literal = expand(contents).trim();
|
||||
var prefix = (preview == null ? "" : preview) + chapter + section;
|
||||
if (literal.startsWith(prefix)) {
|
||||
var hasFullTitle = literal.length() > prefix.length();
|
||||
if (hasFullTitle) {
|
||||
// Drop the preview identifier
|
||||
literal = chapter + section + literal.substring(prefix.length());
|
||||
} else {
|
||||
// No section sign if the tag refers to a chapter, like {@jvms 4}
|
||||
String sectionSign = section.isEmpty() ? "" : "§";
|
||||
// Change whole text to "§chapter.x" in inline tags.
|
||||
literal = sectionSign + chapter + section;
|
||||
}
|
||||
}
|
||||
String url = String.format("%1$s/specs/%2$s/%2$s-%3$s.html#%2$s-%3$s%4$s",
|
||||
rootParent, idPrefix, chapter, section);
|
||||
|
||||
sb.append("<a href=\"")
|
||||
.append(url)
|
||||
.append("\">")
|
||||
.append(literal)
|
||||
.append(expand(contents))
|
||||
.append("</a>");
|
||||
|
||||
if (preview != null) {
|
||||
// Add PREVIEW superscript that links to JLS/JVMS 1.5.1
|
||||
// "Restrictions on the Use of Preview Features"
|
||||
// Similar to how APIs link to the Preview info box warning
|
||||
var sectionLink = String.format("%1$s/specs/%2$s/%2$s-%3$s.html#%2$s-%3$s%4$s",
|
||||
rootParent, idPrefix, "1", ".5.1");
|
||||
sb.append("<sup class=\"preview-mark\"><a href=\"")
|
||||
.append(sectionLink)
|
||||
.append("\">PREVIEW</a></sup>");
|
||||
}
|
||||
|
||||
if (tag.getKind() == DocTree.Kind.UNKNOWN_BLOCK_TAG) {
|
||||
sb.append("<br>");
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ public class ClassGenerator {
|
||||
diagnosticFlags.isEmpty() ?
|
||||
StubKind.DIAGNOSTIC_FLAGS_EMPTY.format() :
|
||||
StubKind.DIAGNOSTIC_FLAGS_NON_EMPTY.format(diagnosticFlags),
|
||||
StubKind.LINT_CATEGORY.format(toLintFieldName(lintCategory)),
|
||||
StubKind.LINT_CATEGORY.format("\"" + lintCategory + "\""),
|
||||
"\"" + keyParts[0] + "\"",
|
||||
"\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
|
||||
javadoc);
|
||||
@ -314,7 +314,7 @@ public class ClassGenerator {
|
||||
diagnosticFlags.isEmpty() ?
|
||||
StubKind.DIAGNOSTIC_FLAGS_EMPTY.format() :
|
||||
StubKind.DIAGNOSTIC_FLAGS_NON_EMPTY.format(diagnosticFlags),
|
||||
StubKind.LINT_CATEGORY.format(toLintFieldName(lintCategory)),
|
||||
StubKind.LINT_CATEGORY.format("\"" + lintCategory + "\""),
|
||||
"\"" + keyParts[0] + "\"",
|
||||
"\"" + Stream.of(keyParts).skip(2).collect(Collectors.joining(".")) + "\"",
|
||||
argNames.stream().collect(Collectors.joining(", ")));
|
||||
@ -329,11 +329,6 @@ public class ClassGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
String toLintFieldName(String lintCategory) {
|
||||
return lintCategory.toUpperCase()
|
||||
.replaceAll("-", "_");
|
||||
}
|
||||
|
||||
/**
|
||||
* Form the name of a factory method/field given a resource key.
|
||||
*/
|
||||
|
||||
@ -87,7 +87,7 @@ suppress.warnings=\
|
||||
@SuppressWarnings("rawtypes")\n
|
||||
|
||||
lint.category=\
|
||||
LintCategory.{0}
|
||||
LintCategory.get({0}).get()
|
||||
|
||||
diagnostic.flags.empty=\
|
||||
EnumSet.noneOf(DiagnosticFlag.class)
|
||||
|
||||
@ -31,14 +31,13 @@ include LibCommon.gmk
|
||||
## Build libjaas
|
||||
################################################################################
|
||||
|
||||
ifeq ($(call isTargetOs, windows), true)
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIBJAAS, \
|
||||
NAME := jaas, \
|
||||
OPTIMIZATION := LOW, \
|
||||
EXTRA_HEADER_DIRS := java.base:libjava, \
|
||||
LIBS_windows := advapi32.lib mpr.lib netapi32.lib user32.lib, \
|
||||
))
|
||||
$(eval $(call SetupJdkLibrary, BUILD_LIBJAAS, \
|
||||
NAME := jaas, \
|
||||
OPTIMIZATION := LOW, \
|
||||
EXTRA_HEADER_DIRS := java.base:libjava, \
|
||||
LIBS_windows := advapi32.lib mpr.lib netapi32.lib user32.lib, \
|
||||
))
|
||||
|
||||
TARGETS += $(BUILD_LIBJAAS)
|
||||
|
||||
TARGETS += $(BUILD_LIBJAAS)
|
||||
endif
|
||||
################################################################################
|
||||
|
||||
@ -1218,11 +1218,43 @@ void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
|
||||
__ bind(*op->stub()->continuation());
|
||||
}
|
||||
|
||||
void LIR_Assembler::type_profile_helper(Register mdo, ciMethodData *md,
|
||||
ciProfileData *data, Register recv) {
|
||||
void LIR_Assembler::type_profile_helper(Register mdo,
|
||||
ciMethodData *md, ciProfileData *data,
|
||||
Register recv, Label* update_done) {
|
||||
|
||||
int mdp_offset = md->byte_offset_of_slot(data, in_ByteSize(0));
|
||||
__ profile_receiver_type(recv, mdo, mdp_offset);
|
||||
// Given a profile data offset, generate an Address which points to
|
||||
// the corresponding slot in mdo->data().
|
||||
// Clobbers rscratch2.
|
||||
auto slot_at = [=](ByteSize offset) -> Address {
|
||||
return __ form_address(rscratch2, mdo,
|
||||
md->byte_offset_of_slot(data, offset),
|
||||
LogBytesPerWord);
|
||||
};
|
||||
|
||||
for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) {
|
||||
Label next_test;
|
||||
// See if the receiver is receiver[n].
|
||||
__ ldr(rscratch1, slot_at(ReceiverTypeData::receiver_offset(i)));
|
||||
__ cmp(recv, rscratch1);
|
||||
__ br(Assembler::NE, next_test);
|
||||
__ addptr(slot_at(ReceiverTypeData::receiver_count_offset(i)),
|
||||
DataLayout::counter_increment);
|
||||
__ b(*update_done);
|
||||
__ bind(next_test);
|
||||
}
|
||||
|
||||
// Didn't find receiver; find next empty slot and fill it in
|
||||
for (uint i = 0; i < ReceiverTypeData::row_limit(); i++) {
|
||||
Label next_test;
|
||||
Address recv_addr(slot_at(ReceiverTypeData::receiver_offset(i)));
|
||||
__ ldr(rscratch1, recv_addr);
|
||||
__ cbnz(rscratch1, next_test);
|
||||
__ str(recv, recv_addr);
|
||||
__ mov(rscratch1, DataLayout::counter_increment);
|
||||
__ str(rscratch1, slot_at(ReceiverTypeData::receiver_count_offset(i)));
|
||||
__ b(*update_done);
|
||||
__ bind(next_test);
|
||||
}
|
||||
}
|
||||
|
||||
void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
|
||||
@ -1284,9 +1316,14 @@ void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, L
|
||||
__ b(*obj_is_null);
|
||||
__ bind(not_null);
|
||||
|
||||
Label update_done;
|
||||
Register recv = k_RInfo;
|
||||
__ load_klass(recv, obj);
|
||||
type_profile_helper(mdo, md, data, recv);
|
||||
type_profile_helper(mdo, md, data, recv, &update_done);
|
||||
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
|
||||
__ addptr(counter_addr, DataLayout::counter_increment);
|
||||
|
||||
__ bind(update_done);
|
||||
} else {
|
||||
__ cbz(obj, *obj_is_null);
|
||||
}
|
||||
@ -1393,9 +1430,13 @@ void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
|
||||
__ b(done);
|
||||
__ bind(not_null);
|
||||
|
||||
Label update_done;
|
||||
Register recv = k_RInfo;
|
||||
__ load_klass(recv, value);
|
||||
type_profile_helper(mdo, md, data, recv);
|
||||
type_profile_helper(mdo, md, data, recv, &update_done);
|
||||
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
|
||||
__ addptr(counter_addr, DataLayout::counter_increment);
|
||||
__ bind(update_done);
|
||||
} else {
|
||||
__ cbz(value, done);
|
||||
}
|
||||
@ -2499,9 +2540,13 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
|
||||
if (C1OptimizeVirtualCallProfiling && known_klass != nullptr) {
|
||||
// We know the type that will be seen at this call site; we can
|
||||
// statically update the MethodData* rather than needing to do
|
||||
// dynamic tests on the receiver type.
|
||||
// dynamic tests on the receiver type
|
||||
|
||||
// NOTE: we should probably put a lock around this search to
|
||||
// avoid collisions by concurrent compilations
|
||||
ciVirtualCallData* vc_data = (ciVirtualCallData*) data;
|
||||
for (uint i = 0; i < VirtualCallData::row_limit(); i++) {
|
||||
uint i;
|
||||
for (i = 0; i < VirtualCallData::row_limit(); i++) {
|
||||
ciKlass* receiver = vc_data->receiver(i);
|
||||
if (known_klass->equals(receiver)) {
|
||||
Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
|
||||
@ -2509,13 +2554,36 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Receiver type is not found in profile data.
|
||||
// Fall back to runtime helper to handle the rest at runtime.
|
||||
__ mov_metadata(recv, known_klass->constant_encoding());
|
||||
|
||||
// Receiver type not found in profile data; select an empty slot
|
||||
|
||||
// Note that this is less efficient than it should be because it
|
||||
// always does a write to the receiver part of the
|
||||
// VirtualCallData rather than just the first time
|
||||
for (i = 0; i < VirtualCallData::row_limit(); i++) {
|
||||
ciKlass* receiver = vc_data->receiver(i);
|
||||
if (receiver == nullptr) {
|
||||
__ mov_metadata(rscratch1, known_klass->constant_encoding());
|
||||
Address recv_addr =
|
||||
__ form_address(rscratch2, mdo,
|
||||
md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)),
|
||||
LogBytesPerWord);
|
||||
__ str(rscratch1, recv_addr);
|
||||
Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
|
||||
__ addptr(data_addr, DataLayout::counter_increment);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
__ load_klass(recv, recv);
|
||||
Label update_done;
|
||||
type_profile_helper(mdo, md, data, recv, &update_done);
|
||||
// Receiver did not match any saved receiver and there is no empty row for it.
|
||||
// Increment total counter to indicate polymorphic case.
|
||||
__ addptr(counter_addr, DataLayout::counter_increment);
|
||||
|
||||
__ bind(update_done);
|
||||
}
|
||||
type_profile_helper(mdo, md, data, recv);
|
||||
} else {
|
||||
// Static call
|
||||
__ addptr(counter_addr, DataLayout::counter_increment);
|
||||
|
||||
@ -50,8 +50,9 @@ friend class ArrayCopyStub;
|
||||
Address stack_slot_address(int index, uint shift, Register tmp, int adjust = 0);
|
||||
|
||||
// Record the type of the receiver in ReceiverTypeData
|
||||
void type_profile_helper(Register mdo, ciMethodData *md,
|
||||
ciProfileData *data, Register recv);
|
||||
void type_profile_helper(Register mdo,
|
||||
ciMethodData *md, ciProfileData *data,
|
||||
Register recv, Label* update_done);
|
||||
void add_debug_info_for_branch(address adr, CodeEmitInfo* info);
|
||||
|
||||
void casw(Register addr, Register newval, Register cmpval);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -23,13 +23,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include <stdlib.h> // do not reorder
|
||||
#include <stdint.h> // do not reorder
|
||||
|
||||
#include "immediate_aarch64.hpp"
|
||||
#include "metaprogramming/primitiveConversions.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// there are at most 2^13 possible logical immediate encodings
|
||||
// however, some combinations of immr and imms are invalid
|
||||
static const unsigned LI_TABLE_SIZE = (1 << 13);
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -23,10 +22,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CPU_AARCH64_IMMEDIATE_AARCH64_HPP
|
||||
#define CPU_AARCH64_IMMEDIATE_AARCH64_HPP
|
||||
#ifndef _IMMEDIATE_H
|
||||
#define _IMMEDIATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* functions to map backwards and forwards between logical or floating
|
||||
@ -52,4 +51,4 @@ uint32_t encoding_for_logical_immediate(uint64_t immediate);
|
||||
uint64_t fp_immediate_for_encoding(uint32_t imm8, int is_dp);
|
||||
uint32_t encoding_for_fp_immediate(float immediate);
|
||||
|
||||
#endif // CPU_AARCH64_IMMEDIATE_AARCH64_HPP
|
||||
#endif // _IMMEDIATE_H
|
||||
|
||||
@ -240,14 +240,15 @@ void InterpreterMacroAssembler::load_resolved_klass_at_offset(
|
||||
// Rsub_klass: subklass
|
||||
//
|
||||
// Kills:
|
||||
// r2
|
||||
// r2, r5
|
||||
void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
|
||||
Label& ok_is_subtype) {
|
||||
assert(Rsub_klass != r0, "r0 holds superklass");
|
||||
assert(Rsub_klass != r2, "r2 holds 2ndary super array length");
|
||||
assert(Rsub_klass != r5, "r5 holds 2ndary super array scan ptr");
|
||||
|
||||
// Profile the not-null value's klass.
|
||||
profile_typecheck(r2, Rsub_klass); // blows r2
|
||||
profile_typecheck(r2, Rsub_klass, r5); // blows r2, reloads r5
|
||||
|
||||
// Do the check.
|
||||
check_klass_subtype(Rsub_klass, r0, r2, ok_is_subtype); // blows r2
|
||||
@ -990,6 +991,7 @@ void InterpreterMacroAssembler::profile_final_call(Register mdp) {
|
||||
|
||||
void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
||||
Register mdp,
|
||||
Register reg2,
|
||||
bool receiver_can_be_null) {
|
||||
if (ProfileInterpreter) {
|
||||
Label profile_continue;
|
||||
@ -1007,7 +1009,7 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
||||
}
|
||||
|
||||
// Record the receiver type.
|
||||
profile_receiver_type(receiver, mdp, 0);
|
||||
record_klass_in_profile(receiver, mdp, reg2);
|
||||
bind(skip_receiver_profile);
|
||||
|
||||
// The method data pointer needs to be updated to reflect the new target.
|
||||
@ -1016,6 +1018,131 @@ void InterpreterMacroAssembler::profile_virtual_call(Register receiver,
|
||||
}
|
||||
}
|
||||
|
||||
// This routine creates a state machine for updating the multi-row
|
||||
// type profile at a virtual call site (or other type-sensitive bytecode).
|
||||
// The machine visits each row (of receiver/count) until the receiver type
|
||||
// is found, or until it runs out of rows. At the same time, it remembers
|
||||
// the location of the first empty row. (An empty row records null for its
|
||||
// receiver, and can be allocated for a newly-observed receiver type.)
|
||||
// Because there are two degrees of freedom in the state, a simple linear
|
||||
// search will not work; it must be a decision tree. Hence this helper
|
||||
// function is recursive, to generate the required tree structured code.
|
||||
// It's the interpreter, so we are trading off code space for speed.
|
||||
// See below for example code.
|
||||
void InterpreterMacroAssembler::record_klass_in_profile_helper(
|
||||
Register receiver, Register mdp,
|
||||
Register reg2, int start_row,
|
||||
Label& done) {
|
||||
if (TypeProfileWidth == 0) {
|
||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
||||
} else {
|
||||
record_item_in_profile_helper(receiver, mdp, reg2, 0, done, TypeProfileWidth,
|
||||
&VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset);
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::record_item_in_profile_helper(Register item, Register mdp,
|
||||
Register reg2, int start_row, Label& done, int total_rows,
|
||||
OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn) {
|
||||
int last_row = total_rows - 1;
|
||||
assert(start_row <= last_row, "must be work left to do");
|
||||
// Test this row for both the item and for null.
|
||||
// Take any of three different outcomes:
|
||||
// 1. found item => increment count and goto done
|
||||
// 2. found null => keep looking for case 1, maybe allocate this cell
|
||||
// 3. found something else => keep looking for cases 1 and 2
|
||||
// Case 3 is handled by a recursive call.
|
||||
for (int row = start_row; row <= last_row; row++) {
|
||||
Label next_test;
|
||||
bool test_for_null_also = (row == start_row);
|
||||
|
||||
// See if the item is item[n].
|
||||
int item_offset = in_bytes(item_offset_fn(row));
|
||||
test_mdp_data_at(mdp, item_offset, item,
|
||||
(test_for_null_also ? reg2 : noreg),
|
||||
next_test);
|
||||
// (Reg2 now contains the item from the CallData.)
|
||||
|
||||
// The item is item[n]. Increment count[n].
|
||||
int count_offset = in_bytes(item_count_offset_fn(row));
|
||||
increment_mdp_data_at(mdp, count_offset);
|
||||
b(done);
|
||||
bind(next_test);
|
||||
|
||||
if (test_for_null_also) {
|
||||
Label found_null;
|
||||
// Failed the equality check on item[n]... Test for null.
|
||||
if (start_row == last_row) {
|
||||
// The only thing left to do is handle the null case.
|
||||
cbz(reg2, found_null);
|
||||
// Item did not match any saved item and there is no empty row for it.
|
||||
// Increment total counter to indicate polymorphic case.
|
||||
increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
|
||||
b(done);
|
||||
bind(found_null);
|
||||
break;
|
||||
}
|
||||
// Since null is rare, make it be the branch-taken case.
|
||||
cbz(reg2, found_null);
|
||||
|
||||
// Put all the "Case 3" tests here.
|
||||
record_item_in_profile_helper(item, mdp, reg2, start_row + 1, done, total_rows,
|
||||
item_offset_fn, item_count_offset_fn);
|
||||
|
||||
// Found a null. Keep searching for a matching item,
|
||||
// but remember that this is an empty (unused) slot.
|
||||
bind(found_null);
|
||||
}
|
||||
}
|
||||
|
||||
// In the fall-through case, we found no matching item, but we
|
||||
// observed the item[start_row] is null.
|
||||
|
||||
// Fill in the item field and increment the count.
|
||||
int item_offset = in_bytes(item_offset_fn(start_row));
|
||||
set_mdp_data_at(mdp, item_offset, item);
|
||||
int count_offset = in_bytes(item_count_offset_fn(start_row));
|
||||
mov(reg2, DataLayout::counter_increment);
|
||||
set_mdp_data_at(mdp, count_offset, reg2);
|
||||
if (start_row > 0) {
|
||||
b(done);
|
||||
}
|
||||
}
|
||||
|
||||
// Example state machine code for three profile rows:
|
||||
// // main copy of decision tree, rooted at row[1]
|
||||
// if (row[0].rec == rec) { row[0].incr(); goto done; }
|
||||
// if (row[0].rec != nullptr) {
|
||||
// // inner copy of decision tree, rooted at row[1]
|
||||
// if (row[1].rec == rec) { row[1].incr(); goto done; }
|
||||
// if (row[1].rec != nullptr) {
|
||||
// // degenerate decision tree, rooted at row[2]
|
||||
// if (row[2].rec == rec) { row[2].incr(); goto done; }
|
||||
// if (row[2].rec != nullptr) { count.incr(); goto done; } // overflow
|
||||
// row[2].init(rec); goto done;
|
||||
// } else {
|
||||
// // remember row[1] is empty
|
||||
// if (row[2].rec == rec) { row[2].incr(); goto done; }
|
||||
// row[1].init(rec); goto done;
|
||||
// }
|
||||
// } else {
|
||||
// // remember row[0] is empty
|
||||
// if (row[1].rec == rec) { row[1].incr(); goto done; }
|
||||
// if (row[2].rec == rec) { row[2].incr(); goto done; }
|
||||
// row[0].init(rec); goto done;
|
||||
// }
|
||||
// done:
|
||||
|
||||
void InterpreterMacroAssembler::record_klass_in_profile(Register receiver,
|
||||
Register mdp, Register reg2) {
|
||||
assert(ProfileInterpreter, "must be profiling");
|
||||
Label done;
|
||||
|
||||
record_klass_in_profile_helper(receiver, mdp, reg2, 0, done);
|
||||
|
||||
bind (done);
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_ret(Register return_bci,
|
||||
Register mdp) {
|
||||
if (ProfileInterpreter) {
|
||||
@ -1073,7 +1200,7 @@ void InterpreterMacroAssembler::profile_null_seen(Register mdp) {
|
||||
}
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass) {
|
||||
void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass, Register reg2) {
|
||||
if (ProfileInterpreter) {
|
||||
Label profile_continue;
|
||||
|
||||
@ -1086,7 +1213,7 @@ void InterpreterMacroAssembler::profile_typecheck(Register mdp, Register klass)
|
||||
mdp_delta = in_bytes(VirtualCallData::virtual_call_data_size());
|
||||
|
||||
// Record the object type.
|
||||
profile_receiver_type(klass, mdp, 0);
|
||||
record_klass_in_profile(klass, mdp, reg2);
|
||||
}
|
||||
update_mdp_by_constant(mdp, mdp_delta);
|
||||
|
||||
|
||||
@ -273,6 +273,15 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
Register test_value_out,
|
||||
Label& not_equal_continue);
|
||||
|
||||
void record_klass_in_profile(Register receiver, Register mdp,
|
||||
Register reg2);
|
||||
void record_klass_in_profile_helper(Register receiver, Register mdp,
|
||||
Register reg2, int start_row,
|
||||
Label& done);
|
||||
void record_item_in_profile_helper(Register item, Register mdp,
|
||||
Register reg2, int start_row, Label& done, int total_rows,
|
||||
OffsetFunction item_offset_fn, OffsetFunction item_count_offset_fn);
|
||||
|
||||
void update_mdp_by_offset(Register mdp_in, int offset_of_offset);
|
||||
void update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp);
|
||||
void update_mdp_by_constant(Register mdp_in, int constant);
|
||||
@ -286,10 +295,11 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void profile_call(Register mdp);
|
||||
void profile_final_call(Register mdp);
|
||||
void profile_virtual_call(Register receiver, Register mdp,
|
||||
Register scratch2,
|
||||
bool receiver_can_be_null = false);
|
||||
void profile_ret(Register return_bci, Register mdp);
|
||||
void profile_null_seen(Register mdp);
|
||||
void profile_typecheck(Register mdp, Register klass);
|
||||
void profile_typecheck(Register mdp, Register klass, Register scratch);
|
||||
void profile_typecheck_failed(Register mdp);
|
||||
void profile_switch_default(Register mdp);
|
||||
void profile_switch_case(Register index_in_scratch, Register mdp,
|
||||
|
||||
@ -2118,161 +2118,6 @@ Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the receiver type profile update given the "recv" klass.
|
||||
//
|
||||
// Normally updates the ReceiverData (RD) that starts at "mdp" + "mdp_offset".
|
||||
// If there are no matching or claimable receiver entries in RD, updates
|
||||
// the polymorphic counter.
|
||||
//
|
||||
// This code expected to run by either the interpreter or JIT-ed code, without
|
||||
// extra synchronization. For safety, receiver cells are claimed atomically, which
|
||||
// avoids grossly misrepresenting the profiles under concurrent updates. For speed,
|
||||
// counter updates are not atomic.
|
||||
//
|
||||
void MacroAssembler::profile_receiver_type(Register recv, Register mdp, int mdp_offset) {
|
||||
assert_different_registers(recv, mdp, rscratch1, rscratch2);
|
||||
|
||||
int base_receiver_offset = in_bytes(ReceiverTypeData::receiver_offset(0));
|
||||
int end_receiver_offset = in_bytes(ReceiverTypeData::receiver_offset(ReceiverTypeData::row_limit()));
|
||||
int poly_count_offset = in_bytes(CounterData::count_offset());
|
||||
int receiver_step = in_bytes(ReceiverTypeData::receiver_offset(1)) - base_receiver_offset;
|
||||
int receiver_to_count_step = in_bytes(ReceiverTypeData::receiver_count_offset(0)) - base_receiver_offset;
|
||||
|
||||
// Adjust for MDP offsets.
|
||||
base_receiver_offset += mdp_offset;
|
||||
end_receiver_offset += mdp_offset;
|
||||
poly_count_offset += mdp_offset;
|
||||
|
||||
#ifdef ASSERT
|
||||
// We are about to walk the MDO slots without asking for offsets.
|
||||
// Check that our math hits all the right spots.
|
||||
for (uint c = 0; c < ReceiverTypeData::row_limit(); c++) {
|
||||
int real_recv_offset = mdp_offset + in_bytes(ReceiverTypeData::receiver_offset(c));
|
||||
int real_count_offset = mdp_offset + in_bytes(ReceiverTypeData::receiver_count_offset(c));
|
||||
int offset = base_receiver_offset + receiver_step*c;
|
||||
int count_offset = offset + receiver_to_count_step;
|
||||
assert(offset == real_recv_offset, "receiver slot math");
|
||||
assert(count_offset == real_count_offset, "receiver count math");
|
||||
}
|
||||
int real_poly_count_offset = mdp_offset + in_bytes(CounterData::count_offset());
|
||||
assert(poly_count_offset == real_poly_count_offset, "poly counter math");
|
||||
#endif
|
||||
|
||||
// Corner case: no profile table. Increment poly counter and exit.
|
||||
if (ReceiverTypeData::row_limit() == 0) {
|
||||
increment(Address(mdp, poly_count_offset), DataLayout::counter_increment);
|
||||
return;
|
||||
}
|
||||
|
||||
Register offset = rscratch2;
|
||||
|
||||
Label L_loop_search_receiver, L_loop_search_empty;
|
||||
Label L_restart, L_found_recv, L_found_empty, L_polymorphic, L_count_update;
|
||||
|
||||
// The code here recognizes three major cases:
|
||||
// A. Fastest: receiver found in the table
|
||||
// B. Fast: no receiver in the table, and the table is full
|
||||
// C. Slow: no receiver in the table, free slots in the table
|
||||
//
|
||||
// The case A performance is most important, as perfectly-behaved code would end up
|
||||
// there, especially with larger TypeProfileWidth. The case B performance is
|
||||
// important as well, this is where bulk of code would land for normally megamorphic
|
||||
// cases. The case C performance is not essential, its job is to deal with installation
|
||||
// races, we optimize for code density instead. Case C needs to make sure that receiver
|
||||
// rows are only claimed once. This makes sure we never overwrite a row for another
|
||||
// receiver and never duplicate the receivers in the list, making profile type-accurate.
|
||||
//
|
||||
// It is very tempting to handle these cases in a single loop, and claim the first slot
|
||||
// without checking the rest of the table. But, profiling code should tolerate free slots
|
||||
// in the table, as class unloading can clear them. After such cleanup, the receiver
|
||||
// we need might be _after_ the free slot. Therefore, we need to let at least full scan
|
||||
// to complete, before trying to install new slots. Splitting the code in several tight
|
||||
// loops also helpfully optimizes for cases A and B.
|
||||
//
|
||||
// This code is effectively:
|
||||
//
|
||||
// restart:
|
||||
// // Fastest: receiver is already installed
|
||||
// for (i = 0; i < receiver_count(); i++) {
|
||||
// if (receiver(i) == recv) goto found_recv(i);
|
||||
// }
|
||||
//
|
||||
// // Fast: no receiver, but profile is full
|
||||
// for (i = 0; i < receiver_count(); i++) {
|
||||
// if (receiver(i) == null) goto found_null(i);
|
||||
// }
|
||||
// goto polymorphic
|
||||
//
|
||||
// // Slow: try to install receiver
|
||||
// found_null(i):
|
||||
// CAS(&receiver(i), null, recv);
|
||||
// goto restart
|
||||
//
|
||||
// polymorphic:
|
||||
// count++;
|
||||
// return
|
||||
//
|
||||
// found_recv(i):
|
||||
// *receiver_count(i)++
|
||||
//
|
||||
|
||||
bind(L_restart);
|
||||
|
||||
// Fastest: receiver is already installed
|
||||
mov(offset, base_receiver_offset);
|
||||
bind(L_loop_search_receiver);
|
||||
ldr(rscratch1, Address(mdp, offset));
|
||||
cmp(rscratch1, recv);
|
||||
br(Assembler::EQ, L_found_recv);
|
||||
add(offset, offset, receiver_step);
|
||||
sub(rscratch1, offset, end_receiver_offset);
|
||||
cbnz(rscratch1, L_loop_search_receiver);
|
||||
|
||||
// Fast: no receiver, but profile is full
|
||||
mov(offset, base_receiver_offset);
|
||||
bind(L_loop_search_empty);
|
||||
ldr(rscratch1, Address(mdp, offset));
|
||||
cbz(rscratch1, L_found_empty);
|
||||
add(offset, offset, receiver_step);
|
||||
sub(rscratch1, offset, end_receiver_offset);
|
||||
cbnz(rscratch1, L_loop_search_empty);
|
||||
b(L_polymorphic);
|
||||
|
||||
// Slow: try to install receiver
|
||||
bind(L_found_empty);
|
||||
|
||||
// Atomically swing receiver slot: null -> recv.
|
||||
//
|
||||
// The update uses CAS, which clobbers rscratch1. Therefore, rscratch2
|
||||
// is used to hold the destination address. This is safe because the
|
||||
// offset is no longer needed after the address is computed.
|
||||
|
||||
lea(rscratch2, Address(mdp, offset));
|
||||
cmpxchg(/*addr*/ rscratch2, /*expected*/ zr, /*new*/ recv, Assembler::xword,
|
||||
/*acquire*/ false, /*release*/ false, /*weak*/ true, noreg);
|
||||
|
||||
// CAS success means the slot now has the receiver we want. CAS failure means
|
||||
// something had claimed the slot concurrently: it can be the same receiver we want,
|
||||
// or something else. Since this is a slow path, we can optimize for code density,
|
||||
// and just restart the search from the beginning.
|
||||
b(L_restart);
|
||||
|
||||
// Counter updates:
|
||||
|
||||
// Increment polymorphic counter instead of receiver slot.
|
||||
bind(L_polymorphic);
|
||||
mov(offset, poly_count_offset);
|
||||
b(L_count_update);
|
||||
|
||||
// Found a receiver, convert its slot offset to corresponding count offset.
|
||||
bind(L_found_recv);
|
||||
add(offset, offset, receiver_to_count_step);
|
||||
|
||||
bind(L_count_update);
|
||||
increment(Address(mdp, offset), DataLayout::counter_increment);
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::call_VM_leaf_base(address entry_point,
|
||||
int number_of_arguments,
|
||||
Label *retaddr) {
|
||||
@ -5761,11 +5606,12 @@ void MacroAssembler::adrp(Register reg1, const Address &dest, uint64_t &byte_off
|
||||
}
|
||||
|
||||
void MacroAssembler::load_byte_map_base(Register reg) {
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
CardTable::CardValue* byte_map_base =
|
||||
((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
|
||||
|
||||
// Strictly speaking the card table base isn't an address at all, and it might
|
||||
// Strictly speaking the byte_map_base isn't an address at all, and it might
|
||||
// even be negative. It is thus materialised as a constant.
|
||||
mov(reg, (uint64_t)ctbs->card_table_base_const());
|
||||
mov(reg, (uint64_t)byte_map_base);
|
||||
}
|
||||
|
||||
void MacroAssembler::build_frame(int framesize) {
|
||||
@ -5936,9 +5782,6 @@ address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
|
||||
// return false;
|
||||
bind(A_IS_NOT_NULL);
|
||||
ldrw(cnt1, Address(a1, length_offset));
|
||||
ldrw(tmp5, Address(a2, length_offset));
|
||||
cmp(cnt1, tmp5);
|
||||
br(NE, DONE); // If lengths differ, return false
|
||||
// Increase loop counter by diff between base- and actual start-offset.
|
||||
addw(cnt1, cnt1, extra_length);
|
||||
lea(a1, Address(a1, start_offset));
|
||||
@ -6005,9 +5848,6 @@ address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
|
||||
cbz(a1, DONE);
|
||||
ldrw(cnt1, Address(a1, length_offset));
|
||||
cbz(a2, DONE);
|
||||
ldrw(tmp5, Address(a2, length_offset));
|
||||
cmp(cnt1, tmp5);
|
||||
br(NE, DONE); // If lengths differ, return false
|
||||
// Increase loop counter by diff between base- and actual start-offset.
|
||||
addw(cnt1, cnt1, extra_length);
|
||||
|
||||
@ -6419,10 +6259,14 @@ void MacroAssembler::fill_words(Register base, Register cnt, Register value)
|
||||
|
||||
// Intrinsic for
|
||||
//
|
||||
// - sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray
|
||||
// return the number of characters copied.
|
||||
// - java/lang/StringUTF16.compress
|
||||
// return index of non-latin1 character if copy fails, otherwise 'len'.
|
||||
// - sun.nio.cs.ISO_8859_1.Encoder#encodeISOArray0(byte[] sa, int sp, byte[] da, int dp, int len)
|
||||
// Encodes char[] to byte[] in ISO-8859-1
|
||||
//
|
||||
// - java.lang.StringCoding#encodeISOArray0(byte[] sa, int sp, byte[] da, int dp, int len)
|
||||
// Encodes byte[] (containing UTF-16) to byte[] in ISO-8859-1
|
||||
//
|
||||
// - java.lang.StringCoding#encodeAsciiArray0(char[] sa, int sp, byte[] da, int dp, int len)
|
||||
// Encodes char[] to byte[] in ASCII
|
||||
//
|
||||
// This version always returns the number of characters copied, and does not
|
||||
// clobber the 'len' register. A successful copy will complete with the post-
|
||||
|
||||
@ -1122,8 +1122,6 @@ public:
|
||||
|
||||
Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
|
||||
|
||||
void profile_receiver_type(Register recv, Register mdp, int mdp_offset);
|
||||
|
||||
void verify_sve_vector_length(Register tmp = rscratch1);
|
||||
void reinitialize_ptrue() {
|
||||
if (UseSVE > 0) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2021, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -722,20 +722,22 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr;
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
Label L_skip_barrier;
|
||||
if (VM_Version::supports_fast_class_init_checks()) {
|
||||
Label L_skip_barrier;
|
||||
|
||||
// Bypass the barrier for non-static methods
|
||||
__ ldrh(rscratch1, Address(rmethod, Method::access_flags_offset()));
|
||||
__ andsw(zr, rscratch1, JVM_ACC_STATIC);
|
||||
__ br(Assembler::EQ, L_skip_barrier); // non-static
|
||||
{ // Bypass the barrier for non-static methods
|
||||
__ ldrh(rscratch1, Address(rmethod, Method::access_flags_offset()));
|
||||
__ andsw(zr, rscratch1, JVM_ACC_STATIC);
|
||||
__ br(Assembler::EQ, L_skip_barrier); // non-static
|
||||
}
|
||||
|
||||
__ load_method_holder(rscratch2, rmethod);
|
||||
__ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
|
||||
__ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
|
||||
__ load_method_holder(rscratch2, rmethod);
|
||||
__ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
|
||||
__ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
|
||||
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
}
|
||||
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->c2i_entry_barrier(masm);
|
||||
@ -1506,8 +1508,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
// SVC, HVC, or SMC. Make it a NOP.
|
||||
__ nop();
|
||||
|
||||
if (method->needs_clinit_barrier()) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
|
||||
Label L_skip_barrier;
|
||||
__ mov_metadata(rscratch2, method->method_holder()); // InstanceKlass*
|
||||
__ clinit_barrier(rscratch2, rscratch1, &L_skip_barrier);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -2290,8 +2290,7 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
|
||||
__ subs(zr, temp, (int) code); // have we resolved this bytecode?
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
if (bytecode() == Bytecodes::_invokestatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
|
||||
__ br(Assembler::NE, L_clinit_barrier_slow);
|
||||
__ ldr(temp, Address(Rcache, in_bytes(ResolvedMethodEntry::method_offset())));
|
||||
__ load_method_holder(temp, temp);
|
||||
@ -2341,8 +2340,8 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
__ subs(zr, temp, (int) code); // have we resolved this bytecode?
|
||||
|
||||
// Class initialization barrier for static fields
|
||||
if (bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() &&
|
||||
(bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic)) {
|
||||
const Register field_holder = temp;
|
||||
|
||||
__ br(Assembler::NE, L_clinit_barrier_slow);
|
||||
@ -3370,7 +3369,7 @@ void TemplateTable::invokevirtual_helper(Register index,
|
||||
__ load_klass(r0, recv);
|
||||
|
||||
// profile this call
|
||||
__ profile_virtual_call(r0, rlocals);
|
||||
__ profile_virtual_call(r0, rlocals, r3);
|
||||
|
||||
// get target Method & entry point
|
||||
__ lookup_virtual_method(r0, index, method);
|
||||
@ -3500,7 +3499,7 @@ void TemplateTable::invokeinterface(int byte_no) {
|
||||
/*return_method=*/false);
|
||||
|
||||
// profile this call
|
||||
__ profile_virtual_call(r3, r13);
|
||||
__ profile_virtual_call(r3, r13, r19);
|
||||
|
||||
// Get declaring interface class from method, and itable index
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, 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
|
||||
@ -356,10 +356,10 @@ frame frame::sender_for_interpreter_frame(RegisterMap* map) const {
|
||||
bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
|
||||
assert(is_interpreted_frame(), "Not an interpreted frame");
|
||||
// These are reasonable sanity checks
|
||||
if (fp() == nullptr || (intptr_t(fp()) & (wordSize-1)) != 0) {
|
||||
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (sp() == nullptr || (intptr_t(sp()) & (wordSize-1)) != 0) {
|
||||
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (fp() + interpreter_frame_initial_sp_offset < sp()) {
|
||||
|
||||
@ -67,7 +67,9 @@ void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet d
|
||||
void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
|
||||
Register addr, Register count, Register tmp) {
|
||||
BLOCK_COMMENT("CardTablePostBarrier");
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
BarrierSet* bs = BarrierSet::barrier_set();
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
|
||||
CardTable* ct = ctbs->card_table();
|
||||
|
||||
Label L_cardtable_loop, L_done;
|
||||
|
||||
@ -81,7 +83,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
|
||||
__ sub(count, count, addr); // nb of cards
|
||||
|
||||
// warning: Rthread has not been preserved
|
||||
__ mov_address(tmp, (address)ctbs->card_table_base_const());
|
||||
__ mov_address(tmp, (address) ct->byte_map_base());
|
||||
__ add(addr,tmp, addr);
|
||||
|
||||
Register zero = __ zero_register(tmp);
|
||||
@ -120,7 +122,8 @@ void CardTableBarrierSetAssembler::store_check_part1(MacroAssembler* masm, Regis
|
||||
assert(bs->kind() == BarrierSet::CardTableBarrierSet,
|
||||
"Wrong barrier set kind");
|
||||
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
|
||||
CardTable* ct = ctbs->card_table();
|
||||
|
||||
// Load card table base address.
|
||||
|
||||
@ -137,7 +140,7 @@ void CardTableBarrierSetAssembler::store_check_part1(MacroAssembler* masm, Regis
|
||||
Possible cause is a cache miss (card table base address resides in a
|
||||
rarely accessed area of thread descriptor).
|
||||
*/
|
||||
__ mov_address(card_table_base, (address)ctbs->card_table_base_const());
|
||||
__ mov_address(card_table_base, (address)ct->byte_map_base());
|
||||
}
|
||||
|
||||
// The 2nd part of the store check.
|
||||
@ -167,8 +170,8 @@ void CardTableBarrierSetAssembler::store_check_part2(MacroAssembler* masm, Regis
|
||||
|
||||
void CardTableBarrierSetAssembler::set_card(MacroAssembler* masm, Register card_table_base, Address card_table_addr, Register tmp) {
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
|
||||
|
||||
if ((((uintptr_t)ctbs->card_table_base_const() & 0xff) == 0)) {
|
||||
CardTable* ct = ctbs->card_table();
|
||||
if ((((uintptr_t)ct->byte_map_base() & 0xff) == 0)) {
|
||||
// Card table is aligned so the lowest byte of the table address base is zero.
|
||||
// This works only if the code is not saved for later use, possibly
|
||||
// in a context where the base would no longer be aligned.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, 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
|
||||
@ -172,7 +172,7 @@ void NativeMovConstReg::set_data(intptr_t x, address pc) {
|
||||
|
||||
address addr = oop_addr != nullptr ? (address)oop_addr : (address)metadata_addr;
|
||||
|
||||
if (pc == nullptr) {
|
||||
if(pc == 0) {
|
||||
offset = addr - instruction_address() - 8;
|
||||
} else {
|
||||
offset = addr - pc - 8;
|
||||
@ -228,7 +228,7 @@ void NativeMovConstReg::set_data(intptr_t x, address pc) {
|
||||
|
||||
void NativeMovConstReg::set_pc_relative_offset(address addr, address pc) {
|
||||
int offset;
|
||||
if (pc == nullptr) {
|
||||
if (pc == 0) {
|
||||
offset = addr - instruction_address() - 8;
|
||||
} else {
|
||||
offset = addr - pc - 8;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, 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
|
||||
@ -371,7 +371,7 @@ class NativeMovConstReg: public NativeInstruction {
|
||||
public:
|
||||
|
||||
intptr_t data() const;
|
||||
void set_data(intptr_t x, address pc = nullptr);
|
||||
void set_data(intptr_t x, address pc = 0);
|
||||
bool is_pc_relative() {
|
||||
return !is_movw();
|
||||
}
|
||||
|
||||
@ -103,7 +103,8 @@ void CardTableBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Registe
|
||||
|
||||
void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr,
|
||||
Register count, Register preserve) {
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
|
||||
CardTable* ct = ctbs->card_table();
|
||||
assert_different_registers(addr, count, R0);
|
||||
|
||||
Label Lskip_loop, Lstore_loop;
|
||||
@ -116,7 +117,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
|
||||
__ srdi(addr, addr, CardTable::card_shift());
|
||||
__ srdi(count, count, CardTable::card_shift());
|
||||
__ subf(count, addr, count);
|
||||
__ add_const_optimized(addr, addr, (address)ctbs->card_table_base_const(), R0);
|
||||
__ add_const_optimized(addr, addr, (address)ct->byte_map_base(), R0);
|
||||
__ addi(count, count, 1);
|
||||
__ li(R0, 0);
|
||||
__ mtctr(count);
|
||||
@ -139,8 +140,8 @@ void CardTableBarrierSetAssembler::card_table_write(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
void CardTableBarrierSetAssembler::card_write_barrier_post(MacroAssembler* masm, Register store_addr, Register tmp) {
|
||||
CardTableBarrierSet* bs = CardTableBarrierSet::barrier_set();
|
||||
card_table_write(masm, bs->card_table_base_const(), tmp, store_addr);
|
||||
CardTableBarrierSet* bs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
|
||||
card_table_write(masm, bs->card_table()->byte_map_base(), tmp, store_addr);
|
||||
}
|
||||
|
||||
void CardTableBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
|
||||
@ -771,6 +771,9 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler *masm, Register b
|
||||
void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
|
||||
Register addr, Register count, Register preserve) {
|
||||
assert(ShenandoahCardBarrier, "Should have been checked by caller");
|
||||
|
||||
ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
|
||||
CardTable* ct = bs->card_table();
|
||||
assert_different_registers(addr, count, R0);
|
||||
|
||||
Label L_skip_loop, L_store_loop;
|
||||
|
||||
@ -1109,11 +1109,11 @@ void InterpreterMacroAssembler::verify_method_data_pointer() {
|
||||
lhz(R11_scratch1, in_bytes(DataLayout::bci_offset()), R28_mdx);
|
||||
ld(R12_scratch2, in_bytes(Method::const_offset()), R19_method);
|
||||
addi(R11_scratch1, R11_scratch1, in_bytes(ConstMethod::codes_offset()));
|
||||
add(R11_scratch1, R11_scratch1, R12_scratch2);
|
||||
add(R11_scratch1, R12_scratch2, R12_scratch2);
|
||||
cmpd(CR0, R11_scratch1, R14_bcp);
|
||||
beq(CR0, verify_continue);
|
||||
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), R19_method, R14_bcp, R28_mdx);
|
||||
call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp ), R19_method, R14_bcp, R28_mdx);
|
||||
|
||||
bind(verify_continue);
|
||||
#endif
|
||||
|
||||
@ -4535,7 +4535,7 @@ void MacroAssembler::push_cont_fastpath() {
|
||||
Label done;
|
||||
ld_ptr(R0, JavaThread::cont_fastpath_offset(), R16_thread);
|
||||
cmpld(CR0, R1_SP, R0);
|
||||
ble(CR0, done); // if (SP <= _cont_fastpath) goto done;
|
||||
ble(CR0, done);
|
||||
st_ptr(R1_SP, JavaThread::cont_fastpath_offset(), R16_thread);
|
||||
bind(done);
|
||||
}
|
||||
@ -4546,7 +4546,7 @@ void MacroAssembler::pop_cont_fastpath() {
|
||||
Label done;
|
||||
ld_ptr(R0, JavaThread::cont_fastpath_offset(), R16_thread);
|
||||
cmpld(CR0, R1_SP, R0);
|
||||
blt(CR0, done); // if (SP < _cont_fastpath) goto done;
|
||||
ble(CR0, done);
|
||||
li(R0, 0);
|
||||
st_ptr(R0, JavaThread::cont_fastpath_offset(), R16_thread);
|
||||
bind(done);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -1237,24 +1237,26 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr;
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
Label L_skip_barrier;
|
||||
if (VM_Version::supports_fast_class_init_checks()) {
|
||||
Label L_skip_barrier;
|
||||
|
||||
// Bypass the barrier for non-static methods
|
||||
__ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method);
|
||||
__ andi_(R0, R0, JVM_ACC_STATIC);
|
||||
__ beq(CR0, L_skip_barrier); // non-static
|
||||
{ // Bypass the barrier for non-static methods
|
||||
__ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method);
|
||||
__ andi_(R0, R0, JVM_ACC_STATIC);
|
||||
__ beq(CR0, L_skip_barrier); // non-static
|
||||
}
|
||||
|
||||
Register klass = R11_scratch1;
|
||||
__ load_method_holder(klass, R19_method);
|
||||
__ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
|
||||
Register klass = R11_scratch1;
|
||||
__ load_method_holder(klass, R19_method);
|
||||
__ clinit_barrier(klass, R16_thread, &L_skip_barrier /*L_fast_path*/);
|
||||
|
||||
__ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
|
||||
__ mtctr(klass);
|
||||
__ bctr();
|
||||
__ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub(), R0);
|
||||
__ mtctr(klass);
|
||||
__ bctr();
|
||||
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
}
|
||||
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->c2i_entry_barrier(masm, /* tmp register*/ ic_klass, /* tmp register*/ receiver_klass, /* tmp register*/ code);
|
||||
@ -2208,8 +2210,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
// --------------------------------------------------------------------------
|
||||
vep_start_pc = (intptr_t)__ pc();
|
||||
|
||||
if (method->needs_clinit_barrier()) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
|
||||
Label L_skip_barrier;
|
||||
Register klass = r_temp_1;
|
||||
// Notify OOP recorder (don't need the relocation)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -2199,8 +2199,7 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no, Register Rca
|
||||
__ isync(); // Order load wrt. succeeding loads.
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
if (bytecode() == Bytecodes::_invokestatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
|
||||
const Register method = Rscratch;
|
||||
const Register klass = Rscratch;
|
||||
|
||||
@ -2245,8 +2244,8 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no, Register Rcac
|
||||
__ isync(); // Order load wrt. succeeding loads.
|
||||
|
||||
// Class initialization barrier for static fields
|
||||
if (bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() &&
|
||||
(bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic)) {
|
||||
const Register field_holder = R4_ARG2;
|
||||
|
||||
// InterpreterRuntime::resolve_get_put sets field_holder and finally release-stores put_code.
|
||||
|
||||
@ -2813,10 +2813,14 @@ void C2_MacroAssembler::char_array_compress_v(Register src, Register dst, Regist
|
||||
|
||||
// Intrinsic for
|
||||
//
|
||||
// - sun/nio/cs/ISO_8859_1$Encoder.implEncodeISOArray
|
||||
// return the number of characters copied.
|
||||
// - java/lang/StringUTF16.compress
|
||||
// return index of non-latin1 character if copy fails, otherwise 'len'.
|
||||
// - sun.nio.cs.ISO_8859_1.Encoder#encodeISOArray0(byte[] sa, int sp, byte[] da, int dp, int len)
|
||||
// Encodes char[] to byte[] in ISO-8859-1
|
||||
//
|
||||
// - java.lang.StringCoding#encodeISOArray0(byte[] sa, int sp, byte[] da, int dp, int len)
|
||||
// Encodes byte[] (containing UTF-16) to byte[] in ISO-8859-1
|
||||
//
|
||||
// - java.lang.StringCoding#encodeAsciiArray0(char[] sa, int sp, byte[] da, int dp, int len)
|
||||
// Encodes char[] to byte[] in ASCII
|
||||
//
|
||||
// This version always returns the number of characters copied. A successful
|
||||
// copy will complete with the post-condition: 'res' == 'len', while an
|
||||
|
||||
@ -5110,8 +5110,9 @@ void MacroAssembler::get_thread(Register thread) {
|
||||
}
|
||||
|
||||
void MacroAssembler::load_byte_map_base(Register reg) {
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
mv(reg, (uint64_t)ctbs->card_table_base_const());
|
||||
CardTable::CardValue* byte_map_base =
|
||||
((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
|
||||
mv(reg, (uint64_t)byte_map_base);
|
||||
}
|
||||
|
||||
void MacroAssembler::build_frame(int framesize) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -213,7 +213,7 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm) {
|
||||
// Is vector's size (in bytes) bigger than a size saved by default?
|
||||
// riscv does not ovlerlay the floating-point registers on vector registers like aarch64.
|
||||
bool SharedRuntime::is_wide_vector(int size) {
|
||||
return UseRVV && size > 0;
|
||||
return UseRVV;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -637,20 +637,22 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr;
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
Label L_skip_barrier;
|
||||
if (VM_Version::supports_fast_class_init_checks()) {
|
||||
Label L_skip_barrier;
|
||||
|
||||
// Bypass the barrier for non-static methods
|
||||
__ load_unsigned_short(t0, Address(xmethod, Method::access_flags_offset()));
|
||||
__ test_bit(t1, t0, exact_log2(JVM_ACC_STATIC));
|
||||
__ beqz(t1, L_skip_barrier); // non-static
|
||||
{ // Bypass the barrier for non-static methods
|
||||
__ load_unsigned_short(t0, Address(xmethod, Method::access_flags_offset()));
|
||||
__ test_bit(t1, t0, exact_log2(JVM_ACC_STATIC));
|
||||
__ beqz(t1, L_skip_barrier); // non-static
|
||||
}
|
||||
|
||||
__ load_method_holder(t1, xmethod);
|
||||
__ clinit_barrier(t1, t0, &L_skip_barrier);
|
||||
__ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
|
||||
__ load_method_holder(t1, xmethod);
|
||||
__ clinit_barrier(t1, t0, &L_skip_barrier);
|
||||
__ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
|
||||
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
}
|
||||
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->c2i_entry_barrier(masm);
|
||||
@ -1441,8 +1443,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
__ nop(); // 4 bytes
|
||||
}
|
||||
|
||||
if (method->needs_clinit_barrier()) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
|
||||
Label L_skip_barrier;
|
||||
__ mov_metadata(t1, method->method_holder()); // InstanceKlass*
|
||||
__ clinit_barrier(t1, t0, &L_skip_barrier);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2020, 2023, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -2192,8 +2192,7 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
|
||||
__ mv(t0, (int) code);
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
if (bytecode() == Bytecodes::_invokestatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
|
||||
__ bne(temp, t0, L_clinit_barrier_slow); // have we resolved this bytecode?
|
||||
__ ld(temp, Address(Rcache, in_bytes(ResolvedMethodEntry::method_offset())));
|
||||
__ load_method_holder(temp, temp);
|
||||
@ -2244,8 +2243,8 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
__ mv(t0, (int) code); // have we resolved this bytecode?
|
||||
|
||||
// Class initialization barrier for static fields
|
||||
if (bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() &&
|
||||
(bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic)) {
|
||||
const Register field_holder = temp;
|
||||
|
||||
__ bne(temp, t0, L_clinit_barrier_slow);
|
||||
|
||||
@ -167,6 +167,11 @@ void VM_Version::common_initialize() {
|
||||
(unaligned_scalar.value() == MISALIGNED_SCALAR_FAST));
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(AlignVector)) {
|
||||
FLAG_SET_DEFAULT(AlignVector,
|
||||
unaligned_vector.value() != MISALIGNED_VECTOR_FAST);
|
||||
}
|
||||
|
||||
#ifdef __riscv_ztso
|
||||
// Hotspot is compiled with TSO support, it will only run on hardware which
|
||||
// supports Ztso
|
||||
@ -237,11 +242,6 @@ void VM_Version::c2_initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
if (FLAG_IS_DEFAULT(AlignVector)) {
|
||||
FLAG_SET_DEFAULT(AlignVector,
|
||||
unaligned_vector.value() != MISALIGNED_VECTOR_FAST);
|
||||
}
|
||||
|
||||
// NOTE: Make sure codes dependent on UseRVV are put after MaxVectorSize initialize,
|
||||
// as there are extra checks inside it which could disable UseRVV
|
||||
// in some situations.
|
||||
|
||||
@ -83,7 +83,8 @@ void CardTableBarrierSetAssembler::resolve_jobject(MacroAssembler* masm, Registe
|
||||
|
||||
void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count,
|
||||
bool do_return) {
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
|
||||
CardTable* ct = ctbs->card_table();
|
||||
|
||||
NearLabel doXC, done;
|
||||
assert_different_registers(Z_R0, Z_R1, addr, count);
|
||||
@ -104,7 +105,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
|
||||
__ add2reg_with_index(count, -BytesPerHeapOop, count, addr);
|
||||
|
||||
// Get base address of card table.
|
||||
__ load_const_optimized(Z_R1, (address)ctbs->card_table_base_const());
|
||||
__ load_const_optimized(Z_R1, (address)ct->byte_map_base());
|
||||
|
||||
// count = (count>>shift) - (addr>>shift)
|
||||
__ z_srlg(addr, addr, CardTable::card_shift());
|
||||
@ -178,12 +179,13 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
|
||||
void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register store_addr, Register tmp) {
|
||||
// Does a store check for the oop in register obj. The content of
|
||||
// register obj is destroyed afterwards.
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(BarrierSet::barrier_set());
|
||||
CardTable* ct = ctbs->card_table();
|
||||
|
||||
assert_different_registers(store_addr, tmp);
|
||||
|
||||
__ z_srlg(store_addr, store_addr, CardTable::card_shift());
|
||||
__ load_absolute_address(tmp, (address)ctbs->card_table_base_const());
|
||||
__ load_absolute_address(tmp, (address)ct->byte_map_base());
|
||||
__ z_agr(store_addr, tmp);
|
||||
__ z_mvi(0, store_addr, CardTable::dirty_card_val());
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2024 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -1567,8 +1567,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
//---------------------------------------------------------------------
|
||||
wrapper_VEPStart = __ offset();
|
||||
|
||||
if (method->needs_clinit_barrier()) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
|
||||
Label L_skip_barrier;
|
||||
Register klass = Z_R1_scratch;
|
||||
// Notify OOP recorder (don't need the relocation)
|
||||
@ -2379,22 +2378,24 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr;
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
Label L_skip_barrier;
|
||||
if (VM_Version::supports_fast_class_init_checks()) {
|
||||
Label L_skip_barrier;
|
||||
|
||||
// Bypass the barrier for non-static methods
|
||||
__ testbit_ushort(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT);
|
||||
__ z_bfalse(L_skip_barrier); // non-static
|
||||
{ // Bypass the barrier for non-static methods
|
||||
__ testbit_ushort(Address(Z_method, Method::access_flags_offset()), JVM_ACC_STATIC_BIT);
|
||||
__ z_bfalse(L_skip_barrier); // non-static
|
||||
}
|
||||
|
||||
Register klass = Z_R11;
|
||||
__ load_method_holder(klass, Z_method);
|
||||
__ clinit_barrier(klass, Z_thread, &L_skip_barrier /*L_fast_path*/);
|
||||
Register klass = Z_R11;
|
||||
__ load_method_holder(klass, Z_method);
|
||||
__ clinit_barrier(klass, Z_thread, &L_skip_barrier /*L_fast_path*/);
|
||||
|
||||
__ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub());
|
||||
__ z_br(klass);
|
||||
__ load_const_optimized(klass, SharedRuntime::get_handle_wrong_method_stub());
|
||||
__ z_br(klass);
|
||||
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
}
|
||||
|
||||
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
|
||||
return;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2024 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -2377,8 +2377,7 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
|
||||
__ z_cli(Address(Rcache, bc_offset), code);
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
if (bytecode() == Bytecodes::_invokestatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
|
||||
const Register method = Z_R1_scratch;
|
||||
const Register klass = Z_R1_scratch;
|
||||
__ z_brne(L_clinit_barrier_slow);
|
||||
@ -2428,8 +2427,8 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
__ z_cli(Address(cache, code_offset), code);
|
||||
|
||||
// Class initialization barrier for static fields
|
||||
if (bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() &&
|
||||
(bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic)) {
|
||||
const Register field_holder = index;
|
||||
|
||||
__ z_brne(L_clinit_barrier_slow);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2026, Intel Corporation. All rights reserved.
|
||||
* Copyright (c) 2024, 2025, Intel Corporation. All rights reserved.
|
||||
*
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -1330,12 +1330,10 @@ static void big_case_loop_helper(bool sizeKnown, int size, Label &noMatch, Label
|
||||
// Clarification: The BYTE_K compare above compares haystack[(n-32):(n-1)]. We need to
|
||||
// compare haystack[(k-1):(k-1+31)]. Subtracting either index gives shift value of
|
||||
// (k + 31 - n): x = (k-1+31)-(n-1) = k-1+31-n+1 = k+31-n.
|
||||
// When isU is set, similarly, shift is from haystack[(n-32):(n-1)] to [(k-2):(k-2+31)]
|
||||
|
||||
if (sizeKnown) {
|
||||
__ movl(temp2, (isU ? 30 : 31) + size);
|
||||
__ movl(temp2, 31 + size);
|
||||
} else {
|
||||
__ movl(temp2, isU ? 30 : 31);
|
||||
__ movl(temp2, 31);
|
||||
__ addl(temp2, needleLen);
|
||||
}
|
||||
__ subl(temp2, hsLength);
|
||||
|
||||
@ -95,7 +95,11 @@ void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet d
|
||||
|
||||
void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
|
||||
Register addr, Register count, Register tmp) {
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
BarrierSet *bs = BarrierSet::barrier_set();
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
|
||||
CardTable* ct = ctbs->card_table();
|
||||
intptr_t disp = (intptr_t) ct->byte_map_base();
|
||||
SHENANDOAHGC_ONLY(assert(!UseShenandoahGC, "Shenandoah byte_map_base is not constant.");)
|
||||
|
||||
Label L_loop, L_done;
|
||||
const Register end = count;
|
||||
@ -111,7 +115,7 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
|
||||
__ shrptr(end, CardTable::card_shift());
|
||||
__ subptr(end, addr); // end --> cards count
|
||||
|
||||
__ mov64(tmp, (intptr_t)ctbs->card_table_base_const());
|
||||
__ mov64(tmp, disp);
|
||||
__ addptr(addr, tmp);
|
||||
__ BIND(L_loop);
|
||||
__ movb(Address(addr, count, Address::times_1), 0);
|
||||
@ -124,7 +128,10 @@ __ BIND(L_done);
|
||||
void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Address dst) {
|
||||
// Does a store check for the oop in register obj. The content of
|
||||
// register obj is destroyed afterwards.
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
BarrierSet* bs = BarrierSet::barrier_set();
|
||||
|
||||
CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs);
|
||||
CardTable* ct = ctbs->card_table();
|
||||
|
||||
__ shrptr(obj, CardTable::card_shift());
|
||||
|
||||
@ -135,7 +142,7 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob
|
||||
// So this essentially converts an address to a displacement and it will
|
||||
// never need to be relocated. On 64bit however the value may be too
|
||||
// large for a 32bit displacement.
|
||||
intptr_t byte_map_base = (intptr_t)ctbs->card_table_base_const();
|
||||
intptr_t byte_map_base = (intptr_t)ct->byte_map_base();
|
||||
if (__ is_simm32(byte_map_base)) {
|
||||
card_addr = Address(noreg, obj, Address::times_1, byte_map_base);
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, 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
|
||||
@ -6086,7 +6086,7 @@ void MacroAssembler::generate_fill(BasicType t, bool aligned,
|
||||
vpbroadcastd(xtmp, xtmp, Assembler::AVX_512bit);
|
||||
|
||||
subptr(count, 16 << shift);
|
||||
jcc(Assembler::less, L_check_fill_32_bytes);
|
||||
jccb(Assembler::less, L_check_fill_32_bytes);
|
||||
align(16);
|
||||
|
||||
BIND(L_fill_64_bytes_loop_avx3);
|
||||
@ -6251,32 +6251,46 @@ void MacroAssembler::evpbroadcast(BasicType type, XMMRegister dst, Register src,
|
||||
}
|
||||
}
|
||||
|
||||
// encode char[] to byte[] in ISO_8859_1 or ASCII
|
||||
//@IntrinsicCandidate
|
||||
//private static int implEncodeISOArray(byte[] sa, int sp,
|
||||
//byte[] da, int dp, int len) {
|
||||
// int i = 0;
|
||||
// for (; i < len; i++) {
|
||||
// char c = StringUTF16.getChar(sa, sp++);
|
||||
// if (c > '\u00FF')
|
||||
// break;
|
||||
// da[dp++] = (byte)c;
|
||||
// }
|
||||
// return i;
|
||||
//}
|
||||
//
|
||||
//@IntrinsicCandidate
|
||||
//private static int implEncodeAsciiArray(char[] sa, int sp,
|
||||
// byte[] da, int dp, int len) {
|
||||
// int i = 0;
|
||||
// for (; i < len; i++) {
|
||||
// char c = sa[sp++];
|
||||
// if (c >= '\u0080')
|
||||
// break;
|
||||
// da[dp++] = (byte)c;
|
||||
// }
|
||||
// return i;
|
||||
//}
|
||||
// Encode given char[]/byte[] to byte[] in ISO_8859_1 or ASCII
|
||||
//
|
||||
// @IntrinsicCandidate
|
||||
// int sun.nio.cs.ISO_8859_1.Encoder#encodeISOArray0(
|
||||
// char[] sa, int sp, byte[] da, int dp, int len) {
|
||||
// int i = 0;
|
||||
// for (; i < len; i++) {
|
||||
// char c = sa[sp++];
|
||||
// if (c > '\u00FF')
|
||||
// break;
|
||||
// da[dp++] = (byte) c;
|
||||
// }
|
||||
// return i;
|
||||
// }
|
||||
//
|
||||
// @IntrinsicCandidate
|
||||
// int java.lang.StringCoding.encodeISOArray0(
|
||||
// byte[] sa, int sp, byte[] da, int dp, int len) {
|
||||
// int i = 0;
|
||||
// for (; i < len; i++) {
|
||||
// char c = StringUTF16.getChar(sa, sp++);
|
||||
// if (c > '\u00FF')
|
||||
// break;
|
||||
// da[dp++] = (byte) c;
|
||||
// }
|
||||
// return i;
|
||||
// }
|
||||
//
|
||||
// @IntrinsicCandidate
|
||||
// int java.lang.StringCoding.encodeAsciiArray0(
|
||||
// char[] sa, int sp, byte[] da, int dp, int len) {
|
||||
// int i = 0;
|
||||
// for (; i < len; i++) {
|
||||
// char c = sa[sp++];
|
||||
// if (c >= '\u0080')
|
||||
// break;
|
||||
// da[dp++] = (byte) c;
|
||||
// }
|
||||
// return i;
|
||||
// }
|
||||
void MacroAssembler::encode_iso_array(Register src, Register dst, Register len,
|
||||
XMMRegister tmp1Reg, XMMRegister tmp2Reg,
|
||||
XMMRegister tmp3Reg, XMMRegister tmp4Reg,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,10 +32,14 @@ const KRegister::KRegisterImpl all_KRegisterImpls [KRegister::number_
|
||||
|
||||
const char * Register::RegisterImpl::name() const {
|
||||
static const char *const names[number_of_registers] = {
|
||||
#ifdef _LP64
|
||||
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
|
||||
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
|
||||
#else
|
||||
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
|
||||
#endif // _LP64
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "noreg";
|
||||
}
|
||||
@ -50,9 +54,11 @@ const char* FloatRegister::FloatRegisterImpl::name() const {
|
||||
const char* XMMRegister::XMMRegisterImpl::name() const {
|
||||
static const char *const names[number_of_registers] = {
|
||||
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
|
||||
#ifdef _LP64
|
||||
,"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
|
||||
,"xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23"
|
||||
,"xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31"
|
||||
#endif // _LP64
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "xnoreg";
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,7 +34,7 @@
|
||||
class VMRegImpl;
|
||||
typedef VMRegImpl* VMReg;
|
||||
|
||||
// The implementation of integer registers for the x64 architectures.
|
||||
// The implementation of integer registers for the x86/x64 architectures.
|
||||
class Register {
|
||||
private:
|
||||
int _encoding;
|
||||
@ -44,9 +44,11 @@ private:
|
||||
public:
|
||||
inline friend constexpr Register as_Register(int encoding);
|
||||
|
||||
static const int number_of_registers = 32;
|
||||
static const int number_of_byte_registers = 32;
|
||||
static const int max_slots_per_register = 2;
|
||||
enum {
|
||||
number_of_registers = LP64_ONLY( 32 ) NOT_LP64( 8 ),
|
||||
number_of_byte_registers = LP64_ONLY( 32 ) NOT_LP64( 4 ),
|
||||
max_slots_per_register = LP64_ONLY( 2 ) NOT_LP64( 1 )
|
||||
};
|
||||
|
||||
class RegisterImpl: public AbstractRegisterImpl {
|
||||
friend class Register;
|
||||
@ -77,9 +79,11 @@ public:
|
||||
|
||||
// Actually available GP registers for use, depending on actual CPU capabilities and flags.
|
||||
static int available_gp_registers() {
|
||||
#ifdef _LP64
|
||||
if (!UseAPX) {
|
||||
return number_of_registers / 2;
|
||||
}
|
||||
#endif // _LP64
|
||||
return number_of_registers;
|
||||
}
|
||||
};
|
||||
@ -112,8 +116,9 @@ constexpr Register rsp = as_Register(4);
|
||||
constexpr Register rbp = as_Register(5);
|
||||
constexpr Register rsi = as_Register(6);
|
||||
constexpr Register rdi = as_Register(7);
|
||||
constexpr Register r8 = as_Register(8);
|
||||
constexpr Register r9 = as_Register(9);
|
||||
#ifdef _LP64
|
||||
constexpr Register r8 = as_Register( 8);
|
||||
constexpr Register r9 = as_Register( 9);
|
||||
constexpr Register r10 = as_Register(10);
|
||||
constexpr Register r11 = as_Register(11);
|
||||
constexpr Register r12 = as_Register(12);
|
||||
@ -136,6 +141,7 @@ constexpr Register r28 = as_Register(28);
|
||||
constexpr Register r29 = as_Register(29);
|
||||
constexpr Register r30 = as_Register(30);
|
||||
constexpr Register r31 = as_Register(31);
|
||||
#endif // _LP64
|
||||
|
||||
|
||||
// The implementation of x87 floating point registers for the ia32 architecture.
|
||||
@ -148,8 +154,10 @@ private:
|
||||
public:
|
||||
inline friend constexpr FloatRegister as_FloatRegister(int encoding);
|
||||
|
||||
static const int number_of_registers = 8;
|
||||
static const int max_slots_per_register = 2;
|
||||
enum {
|
||||
number_of_registers = 8,
|
||||
max_slots_per_register = 2
|
||||
};
|
||||
|
||||
class FloatRegisterImpl: public AbstractRegisterImpl {
|
||||
friend class FloatRegister;
|
||||
@ -209,8 +217,10 @@ private:
|
||||
public:
|
||||
inline friend constexpr XMMRegister as_XMMRegister(int encoding);
|
||||
|
||||
static const int number_of_registers = 32;
|
||||
static const int max_slots_per_register = 16; // 512-bit
|
||||
enum {
|
||||
number_of_registers = LP64_ONLY( 32 ) NOT_LP64( 8 ),
|
||||
max_slots_per_register = LP64_ONLY( 16 ) NOT_LP64( 16 ) // 512-bit
|
||||
};
|
||||
|
||||
class XMMRegisterImpl: public AbstractRegisterImpl {
|
||||
friend class XMMRegister;
|
||||
@ -240,9 +250,11 @@ public:
|
||||
|
||||
// Actually available XMM registers for use, depending on actual CPU capabilities and flags.
|
||||
static int available_xmm_registers() {
|
||||
#ifdef _LP64
|
||||
if (UseAVX < 3) {
|
||||
return number_of_registers / 2;
|
||||
}
|
||||
#endif // _LP64
|
||||
return number_of_registers;
|
||||
}
|
||||
};
|
||||
@ -275,6 +287,7 @@ constexpr XMMRegister xmm4 = as_XMMRegister( 4);
|
||||
constexpr XMMRegister xmm5 = as_XMMRegister( 5);
|
||||
constexpr XMMRegister xmm6 = as_XMMRegister( 6);
|
||||
constexpr XMMRegister xmm7 = as_XMMRegister( 7);
|
||||
#ifdef _LP64
|
||||
constexpr XMMRegister xmm8 = as_XMMRegister( 8);
|
||||
constexpr XMMRegister xmm9 = as_XMMRegister( 9);
|
||||
constexpr XMMRegister xmm10 = as_XMMRegister(10);
|
||||
@ -299,6 +312,7 @@ constexpr XMMRegister xmm28 = as_XMMRegister(28);
|
||||
constexpr XMMRegister xmm29 = as_XMMRegister(29);
|
||||
constexpr XMMRegister xmm30 = as_XMMRegister(30);
|
||||
constexpr XMMRegister xmm31 = as_XMMRegister(31);
|
||||
#endif // _LP64
|
||||
|
||||
|
||||
// The implementation of AVX-512 opmask registers.
|
||||
@ -380,17 +394,25 @@ constexpr KRegister k7 = as_KRegister(7);
|
||||
// Define a class that exports it.
|
||||
class ConcreteRegisterImpl : public AbstractRegisterImpl {
|
||||
public:
|
||||
static const int max_gpr = Register::number_of_registers * Register::max_slots_per_register;
|
||||
static const int max_fpr = max_gpr + FloatRegister::number_of_registers * FloatRegister::max_slots_per_register;
|
||||
static const int max_xmm = max_fpr + XMMRegister::number_of_registers * XMMRegister::max_slots_per_register;
|
||||
static const int max_kpr = max_xmm + KRegister::number_of_registers * KRegister::max_slots_per_register;
|
||||
enum {
|
||||
max_gpr = Register::number_of_registers * Register::max_slots_per_register,
|
||||
max_fpr = max_gpr + FloatRegister::number_of_registers * FloatRegister::max_slots_per_register,
|
||||
max_xmm = max_fpr + XMMRegister::number_of_registers * XMMRegister::max_slots_per_register,
|
||||
max_kpr = max_xmm + KRegister::number_of_registers * KRegister::max_slots_per_register,
|
||||
|
||||
// A big enough number for C2: all the registers plus flags
|
||||
// This number must be large enough to cover REG_COUNT (defined by c2) registers.
|
||||
// There is no requirement that any ordering here matches any ordering c2 gives
|
||||
// it's optoregs.
|
||||
static const int number_of_registers = max_kpr + // gpr/fpr/xmm/kpr
|
||||
1; // eflags
|
||||
|
||||
// x86_32.ad defines additional dummy FILL0-FILL7 registers, in order to tally
|
||||
// REG_COUNT (computed by ADLC based on the number of reg_defs seen in .ad files)
|
||||
// with ConcreteRegisterImpl::number_of_registers additional count of 8 is being
|
||||
// added for 32 bit jvm.
|
||||
number_of_registers = max_kpr + // gpr/fpr/xmm/kpr
|
||||
NOT_LP64( 8 + ) // FILL0-FILL7 in x86_32.ad
|
||||
1 // eflags
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2025, 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
|
||||
@ -1043,24 +1043,26 @@ void SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm,
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = nullptr;
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
Label L_skip_barrier;
|
||||
Register method = rbx;
|
||||
if (VM_Version::supports_fast_class_init_checks()) {
|
||||
Label L_skip_barrier;
|
||||
Register method = rbx;
|
||||
|
||||
// Bypass the barrier for non-static methods
|
||||
Register flags = rscratch1;
|
||||
__ load_unsigned_short(flags, Address(method, Method::access_flags_offset()));
|
||||
__ testl(flags, JVM_ACC_STATIC);
|
||||
__ jcc(Assembler::zero, L_skip_barrier); // non-static
|
||||
{ // Bypass the barrier for non-static methods
|
||||
Register flags = rscratch1;
|
||||
__ load_unsigned_short(flags, Address(method, Method::access_flags_offset()));
|
||||
__ testl(flags, JVM_ACC_STATIC);
|
||||
__ jcc(Assembler::zero, L_skip_barrier); // non-static
|
||||
}
|
||||
|
||||
Register klass = rscratch1;
|
||||
__ load_method_holder(klass, method);
|
||||
__ clinit_barrier(klass, &L_skip_barrier /*L_fast_path*/);
|
||||
Register klass = rscratch1;
|
||||
__ load_method_holder(klass, method);
|
||||
__ clinit_barrier(klass, &L_skip_barrier /*L_fast_path*/);
|
||||
|
||||
__ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
|
||||
__ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path
|
||||
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
__ bind(L_skip_barrier);
|
||||
entry_address[AdapterBlob::C2I_No_Clinit_Check] = __ pc();
|
||||
}
|
||||
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->c2i_entry_barrier(masm);
|
||||
@ -1902,8 +1904,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||
|
||||
int vep_offset = ((intptr_t)__ pc()) - start;
|
||||
|
||||
if (method->needs_clinit_barrier()) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
|
||||
Label L_skip_barrier;
|
||||
Register klass = r10;
|
||||
__ mov_metadata(klass, method->method_holder()); // InstanceKlass*
|
||||
@ -3601,3 +3602,4 @@ RuntimeStub* SharedRuntime::generate_jfr_return_lease() {
|
||||
}
|
||||
|
||||
#endif // INCLUDE_JFR
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 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
|
||||
@ -64,39 +64,6 @@ static address kyberAvx512ConstsAddr(int offset) {
|
||||
|
||||
const Register scratch = r10;
|
||||
|
||||
ATTRIBUTE_ALIGNED(64) static const uint8_t kyberAvx512_12To16Dup[] = {
|
||||
// 0 - 63
|
||||
0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15, 16,
|
||||
16, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 28, 28, 29, 30,
|
||||
31, 31, 32, 33, 34, 34, 35, 36, 37, 37, 38, 39, 40, 40, 41, 42, 43, 43, 44,
|
||||
45, 46, 46, 47
|
||||
};
|
||||
|
||||
static address kyberAvx512_12To16DupAddr() {
|
||||
return (address) kyberAvx512_12To16Dup;
|
||||
}
|
||||
|
||||
ATTRIBUTE_ALIGNED(64) static const uint16_t kyberAvx512_12To16Shift[] = {
|
||||
// 0 - 31
|
||||
0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0,
|
||||
4, 0, 4, 0, 4, 0, 4
|
||||
};
|
||||
|
||||
static address kyberAvx512_12To16ShiftAddr() {
|
||||
return (address) kyberAvx512_12To16Shift;
|
||||
}
|
||||
|
||||
ATTRIBUTE_ALIGNED(64) static const uint64_t kyberAvx512_12To16And[] = {
|
||||
// 0 - 7
|
||||
0x0FFF0FFF0FFF0FFF, 0x0FFF0FFF0FFF0FFF, 0x0FFF0FFF0FFF0FFF,
|
||||
0x0FFF0FFF0FFF0FFF, 0x0FFF0FFF0FFF0FFF, 0x0FFF0FFF0FFF0FFF,
|
||||
0x0FFF0FFF0FFF0FFF, 0x0FFF0FFF0FFF0FFF
|
||||
};
|
||||
|
||||
static address kyberAvx512_12To16AndAddr() {
|
||||
return (address) kyberAvx512_12To16And;
|
||||
}
|
||||
|
||||
ATTRIBUTE_ALIGNED(64) static const uint16_t kyberAvx512NttPerms[] = {
|
||||
// 0
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
@ -855,65 +822,10 @@ address generate_kyber12To16_avx512(StubGenerator *stubgen,
|
||||
|
||||
const Register perms = r11;
|
||||
|
||||
Label Loop, VBMILoop;
|
||||
Label Loop;
|
||||
|
||||
__ addptr(condensed, condensedOffs);
|
||||
|
||||
if (VM_Version::supports_avx512_vbmi()) {
|
||||
// mask load for the first 48 bytes of each vector
|
||||
__ mov64(rax, 0x0000FFFFFFFFFFFF);
|
||||
__ kmovql(k1, rax);
|
||||
|
||||
__ lea(perms, ExternalAddress(kyberAvx512_12To16DupAddr()));
|
||||
__ evmovdqub(xmm20, Address(perms), Assembler::AVX_512bit);
|
||||
|
||||
__ lea(perms, ExternalAddress(kyberAvx512_12To16ShiftAddr()));
|
||||
__ evmovdquw(xmm21, Address(perms), Assembler::AVX_512bit);
|
||||
|
||||
__ lea(perms, ExternalAddress(kyberAvx512_12To16AndAddr()));
|
||||
__ evmovdquq(xmm22, Address(perms), Assembler::AVX_512bit);
|
||||
|
||||
__ align(OptoLoopAlignment);
|
||||
__ BIND(VBMILoop);
|
||||
|
||||
__ evmovdqub(xmm0, k1, Address(condensed, 0), false,
|
||||
Assembler::AVX_512bit);
|
||||
__ evmovdqub(xmm1, k1, Address(condensed, 48), false,
|
||||
Assembler::AVX_512bit);
|
||||
__ evmovdqub(xmm2, k1, Address(condensed, 96), false,
|
||||
Assembler::AVX_512bit);
|
||||
__ evmovdqub(xmm3, k1, Address(condensed, 144), false,
|
||||
Assembler::AVX_512bit);
|
||||
|
||||
__ evpermb(xmm4, k0, xmm20, xmm0, false, Assembler::AVX_512bit);
|
||||
__ evpermb(xmm5, k0, xmm20, xmm1, false, Assembler::AVX_512bit);
|
||||
__ evpermb(xmm6, k0, xmm20, xmm2, false, Assembler::AVX_512bit);
|
||||
__ evpermb(xmm7, k0, xmm20, xmm3, false, Assembler::AVX_512bit);
|
||||
|
||||
__ evpsrlvw(xmm4, xmm4, xmm21, Assembler::AVX_512bit);
|
||||
__ evpsrlvw(xmm5, xmm5, xmm21, Assembler::AVX_512bit);
|
||||
__ evpsrlvw(xmm6, xmm6, xmm21, Assembler::AVX_512bit);
|
||||
__ evpsrlvw(xmm7, xmm7, xmm21, Assembler::AVX_512bit);
|
||||
|
||||
__ evpandq(xmm0, xmm22, xmm4, Assembler::AVX_512bit);
|
||||
__ evpandq(xmm1, xmm22, xmm5, Assembler::AVX_512bit);
|
||||
__ evpandq(xmm2, xmm22, xmm6, Assembler::AVX_512bit);
|
||||
__ evpandq(xmm3, xmm22, xmm7, Assembler::AVX_512bit);
|
||||
|
||||
store4regs(parsed, 0, xmm0_3, _masm);
|
||||
|
||||
__ addptr(condensed, 192);
|
||||
__ addptr(parsed, 256);
|
||||
__ subl(parsedLength, 128);
|
||||
__ jcc(Assembler::greater, VBMILoop);
|
||||
|
||||
__ leave(); // required for proper stackwalking of RuntimeStub frame
|
||||
__ mov64(rax, 0); // return 0
|
||||
__ ret(0);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
__ lea(perms, ExternalAddress(kyberAvx512_12To16PermsAddr()));
|
||||
|
||||
load4regs(xmm24_27, perms, 0, _masm);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, 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
|
||||
@ -2216,8 +2216,7 @@ void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
|
||||
__ cmpl(temp, code); // have we resolved this bytecode?
|
||||
|
||||
// Class initialization barrier for static methods
|
||||
if (bytecode() == Bytecodes::_invokestatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
|
||||
const Register method = temp;
|
||||
const Register klass = temp;
|
||||
|
||||
@ -2265,8 +2264,8 @@ void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
|
||||
__ cmpl(temp, code); // have we resolved this bytecode?
|
||||
|
||||
// Class initialization barrier for static fields
|
||||
if (bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic) {
|
||||
assert(VM_Version::supports_fast_class_init_checks(), "sanity");
|
||||
if (VM_Version::supports_fast_class_init_checks() &&
|
||||
(bytecode() == Bytecodes::_getstatic || bytecode() == Bytecodes::_putstatic)) {
|
||||
const Register field_holder = temp;
|
||||
|
||||
__ jcc(Assembler::notEqual, L_clinit_barrier_slow);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, 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
|
||||
@ -921,9 +921,8 @@ void VM_Version::get_processor_features() {
|
||||
|
||||
// Check if processor has Intel Ecore
|
||||
if (FLAG_IS_DEFAULT(EnableX86ECoreOpts) && is_intel() && is_intel_server_family() &&
|
||||
(supports_hybrid() ||
|
||||
_model == 0xAF /* Xeon 6 E-cores (Sierra Forest) */ ||
|
||||
_model == 0xDD /* Xeon 6+ E-cores (Clearwater Forest) */ )) {
|
||||
(_model == 0x97 || _model == 0xAA || _model == 0xAC || _model == 0xAF ||
|
||||
_model == 0xCC || _model == 0xDD)) {
|
||||
FLAG_SET_DEFAULT(EnableX86ECoreOpts, true);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,7 +32,9 @@ void VMRegImpl::set_regName() {
|
||||
int i;
|
||||
for (i = 0; i < ConcreteRegisterImpl::max_gpr ; ) {
|
||||
regName[i++] = reg->name();
|
||||
#ifdef AMD64
|
||||
regName[i++] = reg->name();
|
||||
#endif // AMD64
|
||||
reg = reg->successor();
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2024, 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
|
||||
@ -52,8 +52,14 @@ inline bool is_KRegister() {
|
||||
}
|
||||
|
||||
inline Register as_Register() {
|
||||
assert(is_Register(), "must be");
|
||||
|
||||
assert( is_Register(), "must be");
|
||||
// Yuk
|
||||
#ifdef AMD64
|
||||
return ::as_Register(value() >> 1);
|
||||
#else
|
||||
return ::as_Register(value());
|
||||
#endif // AMD64
|
||||
}
|
||||
|
||||
inline FloatRegister as_FloatRegister() {
|
||||
@ -76,6 +82,9 @@ inline KRegister as_KRegister() {
|
||||
|
||||
inline bool is_concrete() {
|
||||
assert(is_reg(), "must be");
|
||||
#ifndef AMD64
|
||||
if (is_Register()) return true;
|
||||
#endif // AMD64
|
||||
// Do not use is_XMMRegister() here as it depends on the UseAVX setting.
|
||||
if (value() >= ConcreteRegisterImpl::max_fpr && value() < ConcreteRegisterImpl::max_xmm) {
|
||||
int base = value() - ConcreteRegisterImpl::max_fpr;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,7 @@
|
||||
#define CPU_X86_VMREG_X86_INLINE_HPP
|
||||
|
||||
inline VMReg Register::RegisterImpl::as_VMReg() const {
|
||||
return VMRegImpl::as_VMReg(encoding() << 1);
|
||||
return VMRegImpl::as_VMReg(encoding() LP64_ONLY( << 1 ));
|
||||
}
|
||||
|
||||
inline VMReg FloatRegister::FloatRegisterImpl::as_VMReg() const {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
// Copyright (c) 2011, 2025, 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
|
||||
@ -2633,19 +2633,17 @@ bool Matcher::supports_vector_calling_convention(void) {
|
||||
return EnableVectorSupport;
|
||||
}
|
||||
|
||||
static bool is_ndd_demotable_opr1(const MachNode* mdef) {
|
||||
return ((mdef->flags() & Node::PD::Flag_ndd_demotable_opr1) != 0);
|
||||
}
|
||||
|
||||
static bool is_ndd_demotable_opr2(const MachNode* mdef) {
|
||||
return ((mdef->flags() & Node::PD::Flag_ndd_demotable_opr2) != 0);
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
static bool is_ndd_demotable(const MachNode* mdef) {
|
||||
return (is_ndd_demotable_opr1(mdef) || is_ndd_demotable_opr2(mdef));
|
||||
return ((mdef->flags() & Node::PD::Flag_ndd_demotable) != 0);
|
||||
}
|
||||
|
||||
static bool is_ndd_demotable_commutative(const MachNode* mdef) {
|
||||
return ((mdef->flags() & Node::PD::Flag_ndd_demotable_commutative) != 0);
|
||||
}
|
||||
|
||||
static bool is_demotion_candidate(const MachNode* mdef) {
|
||||
return (is_ndd_demotable(mdef) || is_ndd_demotable_commutative(mdef));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Matcher::is_register_biasing_candidate(const MachNode* mdef,
|
||||
int oper_index) {
|
||||
@ -2655,8 +2653,8 @@ bool Matcher::is_register_biasing_candidate(const MachNode* mdef,
|
||||
|
||||
if (mdef->num_opnds() <= oper_index || mdef->operand_index(oper_index) < 0 ||
|
||||
mdef->in(mdef->operand_index(oper_index)) == nullptr) {
|
||||
assert(oper_index != 1 || !is_ndd_demotable_opr1(mdef), "%s", mdef->Name());
|
||||
assert(oper_index != 2 || !is_ndd_demotable_opr2(mdef), "%s", mdef->Name());
|
||||
assert(oper_index != 1 || !is_demotion_candidate(mdef), "%s", mdef->Name());
|
||||
assert(oper_index != 2 || !is_ndd_demotable_commutative(mdef), "%s", mdef->Name());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2664,13 +2662,14 @@ bool Matcher::is_register_biasing_candidate(const MachNode* mdef,
|
||||
// address computation. Biasing def towards any address component will not
|
||||
// result in NDD demotion by assembler.
|
||||
if (mdef->operand_num_edges(oper_index) != 1) {
|
||||
assert(!is_ndd_demotable(mdef), "%s", mdef->Name());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Demotion candidate must be register mask compatible with definition.
|
||||
const RegMask& oper_mask = mdef->in_RegMask(mdef->operand_index(oper_index));
|
||||
if (!oper_mask.overlap(mdef->out_RegMask())) {
|
||||
assert(!is_ndd_demotable(mdef), "%s", mdef->Name());
|
||||
assert(!is_demotion_candidate(mdef), "%s", mdef->Name());
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2682,12 +2681,12 @@ bool Matcher::is_register_biasing_candidate(const MachNode* mdef,
|
||||
// EVEX prefix with shorter REX/REX2 encoding. Demotion candidates
|
||||
// are decorated with a special flag by instruction selector.
|
||||
case 1:
|
||||
return is_ndd_demotable_opr1(mdef);
|
||||
return is_demotion_candidate(mdef);
|
||||
|
||||
// Definition operand of commutative operation can be biased towards second
|
||||
// operand.
|
||||
case 2:
|
||||
return is_ndd_demotable_opr2(mdef);
|
||||
return is_ndd_demotable_commutative(mdef);
|
||||
|
||||
// Current scheme only selects up to two biasing candidates
|
||||
default:
|
||||
@ -2889,9 +2888,9 @@ public:
|
||||
Flag_clears_zero_flag = Node::_last_flag << 9,
|
||||
Flag_clears_overflow_flag = Node::_last_flag << 10,
|
||||
Flag_clears_sign_flag = Node::_last_flag << 11,
|
||||
Flag_ndd_demotable_opr1 = Node::_last_flag << 12,
|
||||
Flag_ndd_demotable_opr2 = Node::_last_flag << 13,
|
||||
_last_flag = Flag_ndd_demotable_opr2
|
||||
Flag_ndd_demotable = Node::_last_flag << 12,
|
||||
Flag_ndd_demotable_commutative = Node::_last_flag << 13,
|
||||
_last_flag = Flag_ndd_demotable_commutative
|
||||
};
|
||||
};
|
||||
|
||||
@ -9873,7 +9872,7 @@ instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AddI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -9901,7 +9900,7 @@ instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AddI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -9944,7 +9943,7 @@ instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AddI src1 (LoadI src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "eaddl $dst, $src1, $src2\t# int ndd" %}
|
||||
@ -10001,7 +10000,7 @@ instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr)
|
||||
predicate(UseAPX && UseIncDec);
|
||||
match(Set dst (AddI src val));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eincl $dst, $src\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -10056,7 +10055,7 @@ instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr)
|
||||
predicate(UseAPX && UseIncDec);
|
||||
match(Set dst (AddI src val));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "edecl $dst, $src\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -10163,7 +10162,7 @@ instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AddL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -10191,7 +10190,7 @@ instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AddL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -10234,7 +10233,7 @@ instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AddL src1 (LoadL src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "eaddq $dst, $src1, $src2\t# long ndd" %}
|
||||
@ -10290,7 +10289,7 @@ instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr)
|
||||
predicate(UseAPX && UseIncDec);
|
||||
match(Set dst (AddL src val));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eincq $dst, $src\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -10345,7 +10344,7 @@ instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr)
|
||||
predicate(UseAPX && UseIncDec);
|
||||
match(Set dst (AddL src val));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "edecq $dst, $src\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -11060,7 +11059,7 @@ instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (SubI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -11074,7 +11073,7 @@ instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (SubI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -11117,7 +11116,7 @@ instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (SubI src1 (LoadI src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "esubl $dst, $src1, $src2\t# int ndd" %}
|
||||
@ -11175,7 +11174,7 @@ instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (SubL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -11189,7 +11188,7 @@ instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (SubL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -11232,7 +11231,7 @@ instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (SubL src1 (LoadL src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "esubq $dst, $src1, $src2\t# long ndd" %}
|
||||
@ -11304,7 +11303,7 @@ instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (SubI zero src));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "enegl $dst, $src\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -11332,7 +11331,7 @@ instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (NegI src));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "enegl $dst, $src\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -11373,7 +11372,7 @@ instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (SubL zero src));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "enegq $dst, $src\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -11401,7 +11400,7 @@ instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (NegL src));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "enegq $dst, $src\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -11446,7 +11445,7 @@ instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (MulI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "eimull $dst, $src1, $src2\t# int ndd" %}
|
||||
@ -11488,7 +11487,7 @@ instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (MulI src1 (LoadI src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
ins_cost(350);
|
||||
format %{ "eimull $dst, $src1, $src2\t# int ndd" %}
|
||||
@ -11540,7 +11539,7 @@ instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (MulL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(300);
|
||||
format %{ "eimulq $dst, $src1, $src2\t# long ndd" %}
|
||||
@ -11582,7 +11581,7 @@ instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (MulL src1 (LoadL src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(350);
|
||||
format %{ "eimulq $dst, $src1, $src2 \t# long" %}
|
||||
@ -11857,7 +11856,7 @@ instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (LShiftI src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esall $dst, $src, $shift\t# int(ndd)" %}
|
||||
ins_encode %{
|
||||
@ -11886,7 +11885,7 @@ instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (LShiftI src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esall $dst, $src, $shift\t# int (ndd)" %}
|
||||
ins_encode %{
|
||||
@ -11993,7 +11992,7 @@ instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (RShiftI src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esarl $dst, $src, $shift\t# int (ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12100,7 +12099,7 @@ instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (URShiftI src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12208,7 +12207,7 @@ instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (LShiftL src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esalq $dst, $src, $shift\t# long (ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12237,7 +12236,7 @@ instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (LShiftL src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esalq $dst, $src, $shift\t# long (ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12344,7 +12343,7 @@ instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (RShiftL src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "esarq $dst, $src, $shift\t# long (ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12451,7 +12450,7 @@ instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (URShiftL src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12623,7 +12622,7 @@ instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr)
|
||||
predicate(UseAPX && n->bottom_type()->basic_type() == T_INT);
|
||||
match(Set dst (RotateLeft src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12688,7 +12687,7 @@ instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr)
|
||||
predicate(UseAPX && n->bottom_type()->basic_type() == T_INT);
|
||||
match(Set dst (RotateRight src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12755,7 +12754,7 @@ instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr)
|
||||
predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG);
|
||||
match(Set dst (RotateLeft src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12820,7 +12819,7 @@ instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr)
|
||||
predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG);
|
||||
match(Set dst (RotateRight src shift));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %}
|
||||
ins_encode %{
|
||||
@ -12898,7 +12897,7 @@ instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AndI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -12991,7 +12990,7 @@ instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AndI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -13035,7 +13034,7 @@ instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AndI src1 (LoadI src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "eandl $dst, $src1, $src2\t# int ndd" %}
|
||||
@ -13235,7 +13234,7 @@ instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (OrI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -13264,7 +13263,7 @@ instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (OrI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -13278,7 +13277,7 @@ instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (OrI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eorl $dst, $src2, $src1\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -13322,7 +13321,7 @@ instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (OrI src1 (LoadI src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "eorl $dst, $src1, $src2\t# int ndd" %}
|
||||
@ -13398,7 +13397,7 @@ instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (XorI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -13424,7 +13423,7 @@ instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm)
|
||||
%{
|
||||
match(Set dst (XorI src imm));
|
||||
predicate(UseAPX);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "enotl $dst, $src" %}
|
||||
ins_encode %{
|
||||
@ -13455,7 +13454,7 @@ instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr)
|
||||
predicate(UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1);
|
||||
match(Set dst (XorI src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
||||
ins_encode %{
|
||||
@ -13501,7 +13500,7 @@ instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (XorI src1 (LoadI src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "exorl $dst, $src1, $src2\t# int ndd" %}
|
||||
@ -13580,7 +13579,7 @@ instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AndL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -13636,7 +13635,7 @@ instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AndL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -13680,7 +13679,7 @@ instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (AndL src1 (LoadL src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "eandq $dst, $src1, $src2\t# long ndd" %}
|
||||
@ -13883,7 +13882,7 @@ instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (OrL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -13938,7 +13937,7 @@ instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (OrL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -13952,7 +13951,7 @@ instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (OrL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "eorq $dst, $src2, $src1\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -13997,7 +13996,7 @@ instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (OrL src1 (LoadL src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "eorq $dst, $src1, $src2\t# long ndd" %}
|
||||
@ -14076,7 +14075,7 @@ instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (XorL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -14102,7 +14101,7 @@ instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm)
|
||||
%{
|
||||
predicate(UseAPX);
|
||||
match(Set dst (XorL src imm));
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "enotq $dst, $src" %}
|
||||
ins_encode %{
|
||||
@ -14133,7 +14132,7 @@ instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr)
|
||||
predicate(UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L);
|
||||
match(Set dst (XorL src1 src2));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable);
|
||||
|
||||
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
||||
ins_encode %{
|
||||
@ -14179,7 +14178,7 @@ instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr
|
||||
predicate(UseAPX);
|
||||
match(Set dst (XorL src1 (LoadL src2)));
|
||||
effect(KILL cr);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_opr1, PD::Flag_ndd_demotable_opr2);
|
||||
flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag, PD::Flag_ndd_demotable_commutative);
|
||||
|
||||
ins_cost(150);
|
||||
format %{ "exorq $dst, $src1, $src2\t# long ndd" %}
|
||||
@ -16634,7 +16633,7 @@ instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (MinI src1 src2));
|
||||
effect(DEF dst, USE src1, USE src2);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
ins_cost(200);
|
||||
expand %{
|
||||
@ -16686,7 +16685,7 @@ instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2)
|
||||
predicate(UseAPX);
|
||||
match(Set dst (MaxI src1 src2));
|
||||
effect(DEF dst, USE src1, USE src2);
|
||||
flag(PD::Flag_ndd_demotable_opr1);
|
||||
flag(PD::Flag_ndd_demotable);
|
||||
|
||||
ins_cost(200);
|
||||
expand %{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2019 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -23,15 +23,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "libodm_aix.hpp"
|
||||
#include "misc_aix.hpp"
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/permitForbiddenFunctions.hpp"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
|
||||
dynamicOdm::dynamicOdm() {
|
||||
const char* libodmname = "/usr/lib/libodm.a(shr_64.o)";
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2024 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2022, IBM Corp.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -32,9 +32,8 @@
|
||||
#ifndef OS_AIX_LIBPERFSTAT_AIX_HPP
|
||||
#define OS_AIX_LIBPERFSTAT_AIX_HPP
|
||||
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// These are excerpts from the AIX 7.1 libperfstat.h -
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -258,18 +258,10 @@ bool os::free_memory(physical_memory_size_type& value) {
|
||||
return Aix::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Machine::free_memory(physical_memory_size_type& value) {
|
||||
return Aix::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::available_memory(physical_memory_size_type& value) {
|
||||
return Aix::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Machine::available_memory(physical_memory_size_type& value) {
|
||||
return Aix::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Aix::available_memory(physical_memory_size_type& value) {
|
||||
os::Aix::meminfo_t mi;
|
||||
if (os::Aix::get_meminfo(&mi)) {
|
||||
@ -281,10 +273,6 @@ bool os::Aix::available_memory(physical_memory_size_type& value) {
|
||||
}
|
||||
|
||||
bool os::total_swap_space(physical_memory_size_type& value) {
|
||||
return Machine::total_swap_space(value);
|
||||
}
|
||||
|
||||
bool os::Machine::total_swap_space(physical_memory_size_type& value) {
|
||||
perfstat_memory_total_t memory_info;
|
||||
if (libperfstat::perfstat_memory_total(nullptr, &memory_info, sizeof(perfstat_memory_total_t), 1) == -1) {
|
||||
return false;
|
||||
@ -294,10 +282,6 @@ bool os::Machine::total_swap_space(physical_memory_size_type& value) {
|
||||
}
|
||||
|
||||
bool os::free_swap_space(physical_memory_size_type& value) {
|
||||
return Machine::free_swap_space(value);
|
||||
}
|
||||
|
||||
bool os::Machine::free_swap_space(physical_memory_size_type& value) {
|
||||
perfstat_memory_total_t memory_info;
|
||||
if (libperfstat::perfstat_memory_total(nullptr, &memory_info, sizeof(perfstat_memory_total_t), 1) == -1) {
|
||||
return false;
|
||||
@ -310,10 +294,6 @@ physical_memory_size_type os::physical_memory() {
|
||||
return Aix::physical_memory();
|
||||
}
|
||||
|
||||
physical_memory_size_type os::Machine::physical_memory() {
|
||||
return Aix::physical_memory();
|
||||
}
|
||||
|
||||
size_t os::rss() { return (size_t)0; }
|
||||
|
||||
// Cpu architecture string
|
||||
@ -2284,10 +2264,6 @@ int os::active_processor_count() {
|
||||
return ActiveProcessorCount;
|
||||
}
|
||||
|
||||
return Machine::active_processor_count();
|
||||
}
|
||||
|
||||
int os::Machine::active_processor_count() {
|
||||
int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
|
||||
assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
|
||||
return online_cpus;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2022, 2024, IBM Corp.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -23,7 +23,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "jvm.h"
|
||||
#include "libperfstat_aix.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
@ -47,6 +46,7 @@
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -25,7 +25,6 @@
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "nmt/memMapPrinter.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
@ -35,6 +34,7 @@
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <libproc.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -132,7 +132,7 @@ public:
|
||||
static const char* tagToStr(uint32_t user_tag) {
|
||||
switch (user_tag) {
|
||||
case 0:
|
||||
return nullptr;
|
||||
return 0;
|
||||
X1(MALLOC, malloc);
|
||||
X1(MALLOC_SMALL, malloc_small);
|
||||
X1(MALLOC_LARGE, malloc_large);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, 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
|
||||
@ -137,18 +137,10 @@ bool os::available_memory(physical_memory_size_type& value) {
|
||||
return Bsd::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Machine::available_memory(physical_memory_size_type& value) {
|
||||
return Bsd::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::free_memory(physical_memory_size_type& value) {
|
||||
return Bsd::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Machine::free_memory(physical_memory_size_type& value) {
|
||||
return Bsd::available_memory(value);
|
||||
}
|
||||
|
||||
// Available here means free. Note that this number is of no much use. As an estimate
|
||||
// for future memory pressure it is far too conservative, since MacOS will use a lot
|
||||
// of unused memory for caches, and return it willingly in case of needs.
|
||||
@ -189,10 +181,6 @@ void os::Bsd::print_uptime_info(outputStream* st) {
|
||||
}
|
||||
|
||||
bool os::total_swap_space(physical_memory_size_type& value) {
|
||||
return Machine::total_swap_space(value);
|
||||
}
|
||||
|
||||
bool os::Machine::total_swap_space(physical_memory_size_type& value) {
|
||||
#if defined(__APPLE__)
|
||||
struct xsw_usage vmusage;
|
||||
size_t size = sizeof(vmusage);
|
||||
@ -207,10 +195,6 @@ bool os::Machine::total_swap_space(physical_memory_size_type& value) {
|
||||
}
|
||||
|
||||
bool os::free_swap_space(physical_memory_size_type& value) {
|
||||
return Machine::free_swap_space(value);
|
||||
}
|
||||
|
||||
bool os::Machine::free_swap_space(physical_memory_size_type& value) {
|
||||
#if defined(__APPLE__)
|
||||
struct xsw_usage vmusage;
|
||||
size_t size = sizeof(vmusage);
|
||||
@ -228,10 +212,6 @@ physical_memory_size_type os::physical_memory() {
|
||||
return Bsd::physical_memory();
|
||||
}
|
||||
|
||||
physical_memory_size_type os::Machine::physical_memory() {
|
||||
return Bsd::physical_memory();
|
||||
}
|
||||
|
||||
size_t os::rss() {
|
||||
size_t rss = 0;
|
||||
#ifdef __APPLE__
|
||||
@ -628,7 +608,7 @@ static void *thread_native_entry(Thread *thread) {
|
||||
log_info(os, thread)("Thread finished (tid: %zu, pthread id: %zu).",
|
||||
os::current_thread_id(), (uintx) pthread_self());
|
||||
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool os::create_thread(Thread* thread, ThreadType thr_type,
|
||||
@ -1420,7 +1400,7 @@ int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *pa
|
||||
#elif defined(__APPLE__)
|
||||
for (uint32_t i = 1; i < _dyld_image_count(); i++) {
|
||||
// Value for top_address is returned as 0 since we don't have any information about module size
|
||||
if (callback(_dyld_get_image_name(i), (address)_dyld_get_image_header(i), nullptr, param)) {
|
||||
if (callback(_dyld_get_image_name(i), (address)_dyld_get_image_header(i), (address)0, param)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -2209,10 +2189,6 @@ int os::active_processor_count() {
|
||||
return ActiveProcessorCount;
|
||||
}
|
||||
|
||||
return Machine::active_processor_count();
|
||||
}
|
||||
|
||||
int os::Machine::active_processor_count() {
|
||||
return _processor_count;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2025, 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
|
||||
@ -631,20 +631,22 @@ void CgroupSubsystemFactory::cleanup(CgroupInfo* cg_infos) {
|
||||
* return:
|
||||
* true if there were no errors. false otherwise.
|
||||
*/
|
||||
bool CgroupSubsystem::active_processor_count(double& value) {
|
||||
bool CgroupSubsystem::active_processor_count(int& value) {
|
||||
int cpu_count;
|
||||
int result = -1;
|
||||
|
||||
// We use a cache with a timeout to avoid performing expensive
|
||||
// computations in the event this function is called frequently.
|
||||
// [See 8227006].
|
||||
CachingCgroupController<CgroupCpuController, double>* contrl = cpu_controller();
|
||||
CachedMetric<double>* cpu_limit = contrl->metrics_cache();
|
||||
CachingCgroupController<CgroupCpuController>* contrl = cpu_controller();
|
||||
CachedMetric* cpu_limit = contrl->metrics_cache();
|
||||
if (!cpu_limit->should_check_metric()) {
|
||||
value = cpu_limit->value();
|
||||
log_trace(os, container)("CgroupSubsystem::active_processor_count (cached): %.2f", value);
|
||||
value = (int)cpu_limit->value();
|
||||
log_trace(os, container)("CgroupSubsystem::active_processor_count (cached): %d", value);
|
||||
return true;
|
||||
}
|
||||
|
||||
int cpu_count = os::Linux::active_processor_count();
|
||||
double result = -1;
|
||||
cpu_count = os::Linux::active_processor_count();
|
||||
if (!CgroupUtil::processor_count(contrl->controller(), cpu_count, result)) {
|
||||
return false;
|
||||
}
|
||||
@ -669,8 +671,8 @@ bool CgroupSubsystem::active_processor_count(double& value) {
|
||||
*/
|
||||
bool CgroupSubsystem::memory_limit_in_bytes(physical_memory_size_type upper_bound,
|
||||
physical_memory_size_type& value) {
|
||||
CachingCgroupController<CgroupMemoryController, physical_memory_size_type>* contrl = memory_controller();
|
||||
CachedMetric<physical_memory_size_type>* memory_limit = contrl->metrics_cache();
|
||||
CachingCgroupController<CgroupMemoryController>* contrl = memory_controller();
|
||||
CachedMetric* memory_limit = contrl->metrics_cache();
|
||||
if (!memory_limit->should_check_metric()) {
|
||||
value = memory_limit->value();
|
||||
return true;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2025, 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
|
||||
@ -181,21 +181,20 @@ class CgroupController: public CHeapObj<mtInternal> {
|
||||
static bool limit_from_str(char* limit_str, physical_memory_size_type& value);
|
||||
};
|
||||
|
||||
template <typename MetricType>
|
||||
class CachedMetric : public CHeapObj<mtInternal>{
|
||||
private:
|
||||
volatile MetricType _metric;
|
||||
volatile physical_memory_size_type _metric;
|
||||
volatile jlong _next_check_counter;
|
||||
public:
|
||||
CachedMetric() {
|
||||
_metric = static_cast<MetricType>(value_unlimited);
|
||||
_metric = value_unlimited;
|
||||
_next_check_counter = min_jlong;
|
||||
}
|
||||
bool should_check_metric() {
|
||||
return os::elapsed_counter() > _next_check_counter;
|
||||
}
|
||||
MetricType value() { return _metric; }
|
||||
void set_value(MetricType value, jlong timeout) {
|
||||
physical_memory_size_type value() { return _metric; }
|
||||
void set_value(physical_memory_size_type value, jlong timeout) {
|
||||
_metric = value;
|
||||
// Metric is unlikely to change, but we want to remain
|
||||
// responsive to configuration changes. A very short grace time
|
||||
@ -206,19 +205,19 @@ class CachedMetric : public CHeapObj<mtInternal>{
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, typename MetricType>
|
||||
template <class T>
|
||||
class CachingCgroupController : public CHeapObj<mtInternal> {
|
||||
private:
|
||||
T* _controller;
|
||||
CachedMetric<MetricType>* _metrics_cache;
|
||||
CachedMetric* _metrics_cache;
|
||||
|
||||
public:
|
||||
CachingCgroupController(T* cont) {
|
||||
_controller = cont;
|
||||
_metrics_cache = new CachedMetric<MetricType>();
|
||||
_metrics_cache = new CachedMetric();
|
||||
}
|
||||
|
||||
CachedMetric<MetricType>* metrics_cache() { return _metrics_cache; }
|
||||
CachedMetric* metrics_cache() { return _metrics_cache; }
|
||||
T* controller() { return _controller; }
|
||||
};
|
||||
|
||||
@ -278,7 +277,7 @@ class CgroupMemoryController: public CHeapObj<mtInternal> {
|
||||
class CgroupSubsystem: public CHeapObj<mtInternal> {
|
||||
public:
|
||||
bool memory_limit_in_bytes(physical_memory_size_type upper_bound, physical_memory_size_type& value);
|
||||
bool active_processor_count(double& value);
|
||||
bool active_processor_count(int& value);
|
||||
|
||||
virtual bool pids_max(uint64_t& value) = 0;
|
||||
virtual bool pids_current(uint64_t& value) = 0;
|
||||
@ -287,8 +286,8 @@ class CgroupSubsystem: public CHeapObj<mtInternal> {
|
||||
virtual char * cpu_cpuset_cpus() = 0;
|
||||
virtual char * cpu_cpuset_memory_nodes() = 0;
|
||||
virtual const char * container_type() = 0;
|
||||
virtual CachingCgroupController<CgroupMemoryController, physical_memory_size_type>* memory_controller() = 0;
|
||||
virtual CachingCgroupController<CgroupCpuController, double>* cpu_controller() = 0;
|
||||
virtual CachingCgroupController<CgroupMemoryController>* memory_controller() = 0;
|
||||
virtual CachingCgroupController<CgroupCpuController>* cpu_controller() = 0;
|
||||
virtual CgroupCpuacctController* cpuacct_controller() = 0;
|
||||
|
||||
bool cpu_quota(int& value);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2025, Red Hat, Inc.
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,8 +25,9 @@
|
||||
#include "cgroupUtil_linux.hpp"
|
||||
#include "os_linux.hpp"
|
||||
|
||||
bool CgroupUtil::processor_count(CgroupCpuController* cpu_ctrl, int upper_bound, double& value) {
|
||||
bool CgroupUtil::processor_count(CgroupCpuController* cpu_ctrl, int upper_bound, int& value) {
|
||||
assert(upper_bound > 0, "upper bound of cpus must be positive");
|
||||
int limit_count = upper_bound;
|
||||
int quota = -1;
|
||||
int period = -1;
|
||||
if (!cpu_ctrl->cpu_quota(quota)) {
|
||||
@ -37,15 +37,20 @@ bool CgroupUtil::processor_count(CgroupCpuController* cpu_ctrl, int upper_bound,
|
||||
return false;
|
||||
}
|
||||
int quota_count = 0;
|
||||
double result = upper_bound;
|
||||
int result = upper_bound;
|
||||
|
||||
if (quota > 0 && period > 0) { // Use quotas
|
||||
double cpu_quota = static_cast<double>(quota) / period;
|
||||
log_trace(os, container)("CPU Quota based on quota/period: %.2f", cpu_quota);
|
||||
result = MIN2(result, cpu_quota);
|
||||
if (quota > -1 && period > 0) {
|
||||
quota_count = ceilf((float)quota / (float)period);
|
||||
log_trace(os, container)("CPU Quota count based on quota/period: %d", quota_count);
|
||||
}
|
||||
|
||||
log_trace(os, container)("OSContainer::active_processor_count: %.2f", result);
|
||||
// Use quotas
|
||||
if (quota_count != 0) {
|
||||
limit_count = quota_count;
|
||||
}
|
||||
|
||||
result = MIN2(upper_bound, limit_count);
|
||||
log_trace(os, container)("OSContainer::active_processor_count: %d", result);
|
||||
value = result;
|
||||
return true;
|
||||
}
|
||||
@ -68,11 +73,11 @@ physical_memory_size_type CgroupUtil::get_updated_mem_limit(CgroupMemoryControll
|
||||
|
||||
// Get an updated cpu limit. The return value is strictly less than or equal to the
|
||||
// passed in 'lowest' value.
|
||||
double CgroupUtil::get_updated_cpu_limit(CgroupCpuController* cpu,
|
||||
int CgroupUtil::get_updated_cpu_limit(CgroupCpuController* cpu,
|
||||
int lowest,
|
||||
int upper_bound) {
|
||||
assert(lowest > 0 && lowest <= upper_bound, "invariant");
|
||||
double cpu_limit_val = -1;
|
||||
int cpu_limit_val = -1;
|
||||
if (CgroupUtil::processor_count(cpu, upper_bound, cpu_limit_val) && cpu_limit_val != upper_bound) {
|
||||
assert(cpu_limit_val <= upper_bound, "invariant");
|
||||
if (lowest > cpu_limit_val) {
|
||||
@ -167,7 +172,7 @@ void CgroupUtil::adjust_controller(CgroupCpuController* cpu) {
|
||||
assert(cg_path[0] == '/', "cgroup path must start with '/'");
|
||||
int host_cpus = os::Linux::active_processor_count();
|
||||
int lowest_limit = host_cpus;
|
||||
double cpus = get_updated_cpu_limit(cpu, lowest_limit, host_cpus);
|
||||
int cpus = get_updated_cpu_limit(cpu, lowest_limit, host_cpus);
|
||||
int orig_limit = lowest_limit != host_cpus ? lowest_limit : host_cpus;
|
||||
char* limit_cg_path = nullptr;
|
||||
while ((last_slash = strrchr(cg_path, '/')) != cg_path) {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Red Hat, Inc.
|
||||
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,7 +31,7 @@
|
||||
class CgroupUtil: AllStatic {
|
||||
|
||||
public:
|
||||
static bool processor_count(CgroupCpuController* cpu, int upper_bound, double& value);
|
||||
static bool processor_count(CgroupCpuController* cpu, int upper_bound, int& value);
|
||||
// Given a memory controller, adjust its path to a point in the hierarchy
|
||||
// that represents the closest memory limit.
|
||||
static void adjust_controller(CgroupMemoryController* m);
|
||||
@ -43,7 +42,9 @@ class CgroupUtil: AllStatic {
|
||||
static physical_memory_size_type get_updated_mem_limit(CgroupMemoryController* m,
|
||||
physical_memory_size_type lowest,
|
||||
physical_memory_size_type upper_bound);
|
||||
static double get_updated_cpu_limit(CgroupCpuController* c, int lowest, int upper_bound);
|
||||
static int get_updated_cpu_limit(CgroupCpuController* c,
|
||||
int lowest,
|
||||
int upper_bound);
|
||||
};
|
||||
|
||||
#endif // CGROUP_UTIL_LINUX_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2025, 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
|
||||
@ -328,8 +328,8 @@ CgroupV1Subsystem::CgroupV1Subsystem(CgroupV1Controller* cpuset,
|
||||
_pids(pids) {
|
||||
CgroupUtil::adjust_controller(memory);
|
||||
CgroupUtil::adjust_controller(cpu);
|
||||
_memory = new CachingCgroupController<CgroupMemoryController, physical_memory_size_type>(memory);
|
||||
_cpu = new CachingCgroupController<CgroupCpuController, double>(cpu);
|
||||
_memory = new CachingCgroupController<CgroupMemoryController>(memory);
|
||||
_cpu = new CachingCgroupController<CgroupCpuController>(cpu);
|
||||
}
|
||||
|
||||
bool CgroupV1Subsystem::is_containerized() {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2025, 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
|
||||
@ -214,15 +214,15 @@ class CgroupV1Subsystem: public CgroupSubsystem {
|
||||
const char * container_type() override {
|
||||
return "cgroupv1";
|
||||
}
|
||||
CachingCgroupController<CgroupMemoryController, physical_memory_size_type>* memory_controller() override { return _memory; }
|
||||
CachingCgroupController<CgroupCpuController, double>* cpu_controller() override { return _cpu; }
|
||||
CachingCgroupController<CgroupMemoryController>* memory_controller() override { return _memory; }
|
||||
CachingCgroupController<CgroupCpuController>* cpu_controller() override { return _cpu; }
|
||||
CgroupCpuacctController* cpuacct_controller() override { return _cpuacct; }
|
||||
|
||||
private:
|
||||
/* controllers */
|
||||
CachingCgroupController<CgroupMemoryController, physical_memory_size_type>* _memory = nullptr;
|
||||
CachingCgroupController<CgroupMemoryController>* _memory = nullptr;
|
||||
CgroupV1Controller* _cpuset = nullptr;
|
||||
CachingCgroupController<CgroupCpuController, double>* _cpu = nullptr;
|
||||
CachingCgroupController<CgroupCpuController>* _cpu = nullptr;
|
||||
CgroupV1CpuacctController* _cpuacct = nullptr;
|
||||
CgroupV1Controller* _pids = nullptr;
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2025, Red Hat Inc.
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 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
|
||||
@ -156,8 +156,8 @@ CgroupV2Subsystem::CgroupV2Subsystem(CgroupV2MemoryController * memory,
|
||||
_unified(unified) {
|
||||
CgroupUtil::adjust_controller(memory);
|
||||
CgroupUtil::adjust_controller(cpu);
|
||||
_memory = new CachingCgroupController<CgroupMemoryController, physical_memory_size_type>(memory);
|
||||
_cpu = new CachingCgroupController<CgroupCpuController, double>(cpu);
|
||||
_memory = new CachingCgroupController<CgroupMemoryController>(memory);
|
||||
_cpu = new CachingCgroupController<CgroupCpuController>(cpu);
|
||||
_cpuacct = cpuacct;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2024, Red Hat Inc.
|
||||
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2025, 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
|
||||
@ -152,8 +152,8 @@ class CgroupV2Subsystem: public CgroupSubsystem {
|
||||
/* One unified controller */
|
||||
CgroupV2Controller _unified;
|
||||
/* Caching wrappers for cpu/memory metrics */
|
||||
CachingCgroupController<CgroupMemoryController, physical_memory_size_type>* _memory = nullptr;
|
||||
CachingCgroupController<CgroupCpuController, double>* _cpu = nullptr;
|
||||
CachingCgroupController<CgroupMemoryController>* _memory = nullptr;
|
||||
CachingCgroupController<CgroupCpuController>* _cpu = nullptr;
|
||||
|
||||
CgroupCpuacctController* _cpuacct = nullptr;
|
||||
|
||||
@ -175,8 +175,8 @@ class CgroupV2Subsystem: public CgroupSubsystem {
|
||||
const char * container_type() override {
|
||||
return "cgroupv2";
|
||||
}
|
||||
CachingCgroupController<CgroupMemoryController, physical_memory_size_type>* memory_controller() override { return _memory; }
|
||||
CachingCgroupController<CgroupCpuController, double>* cpu_controller() override { return _cpu; }
|
||||
CachingCgroupController<CgroupMemoryController>* memory_controller() override { return _memory; }
|
||||
CachingCgroupController<CgroupCpuController>* cpu_controller() override { return _cpu; }
|
||||
CgroupCpuacctController* cpuacct_controller() override { return _cpuacct; };
|
||||
};
|
||||
|
||||
|
||||
@ -66,6 +66,9 @@
|
||||
#endif
|
||||
|
||||
// open(2) flags
|
||||
#ifndef O_CLOEXEC
|
||||
#define O_CLOEXEC 02000000
|
||||
#endif
|
||||
#ifndef O_TMPFILE
|
||||
#define O_TMPFILE (020000000 | O_DIRECTORY)
|
||||
#endif
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2025, 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
|
||||
@ -86,8 +86,8 @@ void OSContainer::init() {
|
||||
// 2.) On a physical Linux system with a limit enforced by other means (like systemd slice)
|
||||
physical_memory_size_type mem_limit_val = value_unlimited;
|
||||
(void)memory_limit_in_bytes(mem_limit_val); // discard error and use default
|
||||
double host_cpus = os::Linux::active_processor_count();
|
||||
double cpus = host_cpus;
|
||||
int host_cpus = os::Linux::active_processor_count();
|
||||
int cpus = host_cpus;
|
||||
(void)active_processor_count(cpus); // discard error and use default
|
||||
any_mem_cpu_limit_present = mem_limit_val != value_unlimited || host_cpus != cpus;
|
||||
if (any_mem_cpu_limit_present) {
|
||||
@ -127,7 +127,8 @@ bool OSContainer::available_memory_in_bytes(physical_memory_size_type& value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OSContainer::available_swap_in_bytes(physical_memory_size_type& value) {
|
||||
bool OSContainer::available_swap_in_bytes(physical_memory_size_type host_free_swap,
|
||||
physical_memory_size_type& value) {
|
||||
physical_memory_size_type mem_limit = 0;
|
||||
physical_memory_size_type mem_swap_limit = 0;
|
||||
if (memory_limit_in_bytes(mem_limit) &&
|
||||
@ -178,7 +179,8 @@ bool OSContainer::available_swap_in_bytes(physical_memory_size_type& value) {
|
||||
assert(num < 25, "buffer too small");
|
||||
mem_limit_buf[num] = '\0';
|
||||
log_trace(os,container)("OSContainer::available_swap_in_bytes: container_swap_limit=%s"
|
||||
" container_mem_limit=%s", mem_swap_buf, mem_limit_buf);
|
||||
" container_mem_limit=%s, host_free_swap: " PHYS_MEM_TYPE_FORMAT,
|
||||
mem_swap_buf, mem_limit_buf, host_free_swap);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -250,7 +252,7 @@ char * OSContainer::cpu_cpuset_memory_nodes() {
|
||||
return cgroup_subsystem->cpu_cpuset_memory_nodes();
|
||||
}
|
||||
|
||||
bool OSContainer::active_processor_count(double& value) {
|
||||
bool OSContainer::active_processor_count(int& value) {
|
||||
assert(cgroup_subsystem != nullptr, "cgroup subsystem not available");
|
||||
return cgroup_subsystem->active_processor_count(value);
|
||||
}
|
||||
@ -289,13 +291,11 @@ template<typename T> struct metric_fmt;
|
||||
template<> struct metric_fmt<unsigned long long int> { static constexpr const char* fmt = "%llu"; };
|
||||
template<> struct metric_fmt<unsigned long int> { static constexpr const char* fmt = "%lu"; };
|
||||
template<> struct metric_fmt<int> { static constexpr const char* fmt = "%d"; };
|
||||
template<> struct metric_fmt<double> { static constexpr const char* fmt = "%.2f"; };
|
||||
template<> struct metric_fmt<const char*> { static constexpr const char* fmt = "%s"; };
|
||||
|
||||
template void OSContainer::print_container_metric<unsigned long long int>(outputStream*, const char*, unsigned long long int, const char*);
|
||||
template void OSContainer::print_container_metric<unsigned long int>(outputStream*, const char*, unsigned long int, const char*);
|
||||
template void OSContainer::print_container_metric<int>(outputStream*, const char*, int, const char*);
|
||||
template void OSContainer::print_container_metric<double>(outputStream*, const char*, double, const char*);
|
||||
template void OSContainer::print_container_metric<const char*>(outputStream*, const char*, const char*, const char*);
|
||||
|
||||
template <typename T>
|
||||
@ -304,13 +304,12 @@ void OSContainer::print_container_metric(outputStream* st, const char* metrics,
|
||||
constexpr int longest_value = max_length - 11; // Max length - shortest "metric: " string ("cpu_quota: ")
|
||||
char value_str[longest_value + 1] = {};
|
||||
os::snprintf_checked(value_str, longest_value, metric_fmt<T>::fmt, value);
|
||||
|
||||
const int pad_width = max_length - static_cast<int>(strlen(metrics)) - 2; // -2 for the ": "
|
||||
const char* unit_prefix = unit[0] != '\0' ? " " : "";
|
||||
|
||||
char line[128] = {};
|
||||
os::snprintf_checked(line, sizeof(line), "%s: %*s%s%s", metrics, pad_width, value_str, unit_prefix, unit);
|
||||
st->print_cr("%s", line);
|
||||
st->print("%s: %*s", metrics, max_length - static_cast<int>(strlen(metrics)) - 2, value_str); // -2 for the ": "
|
||||
if (unit[0] != '\0') {
|
||||
st->print_cr(" %s", unit);
|
||||
} else {
|
||||
st->print_cr("");
|
||||
}
|
||||
}
|
||||
|
||||
void OSContainer::print_container_helper(outputStream* st, MetricResult& res, const char* metrics) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2025, 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
|
||||
@ -72,7 +72,8 @@ class OSContainer: AllStatic {
|
||||
static const char * container_type();
|
||||
|
||||
static bool available_memory_in_bytes(physical_memory_size_type& value);
|
||||
static bool available_swap_in_bytes(physical_memory_size_type& value);
|
||||
static bool available_swap_in_bytes(physical_memory_size_type host_free_swap,
|
||||
physical_memory_size_type& value);
|
||||
static bool memory_limit_in_bytes(physical_memory_size_type& value);
|
||||
static bool memory_and_swap_limit_in_bytes(physical_memory_size_type& value);
|
||||
static bool memory_and_swap_usage_in_bytes(physical_memory_size_type& value);
|
||||
@ -83,7 +84,7 @@ class OSContainer: AllStatic {
|
||||
static bool rss_usage_in_bytes(physical_memory_size_type& value);
|
||||
static bool cache_usage_in_bytes(physical_memory_size_type& value);
|
||||
|
||||
static bool active_processor_count(double& value);
|
||||
static bool active_processor_count(int& value);
|
||||
|
||||
static char * cpu_cpuset_cpus();
|
||||
static char * cpu_cpuset_memory_nodes();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2024 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -27,7 +27,6 @@
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "hugepages.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
@ -97,6 +96,7 @@
|
||||
# include <signal.h>
|
||||
# include <stdint.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/ipc.h>
|
||||
@ -211,58 +211,15 @@ static bool suppress_primordial_thread_resolution = false;
|
||||
|
||||
// utility functions
|
||||
|
||||
bool os::is_containerized() {
|
||||
return OSContainer::is_containerized();
|
||||
}
|
||||
|
||||
bool os::Container::memory_limit(physical_memory_size_type& value) {
|
||||
physical_memory_size_type result = 0;
|
||||
if (OSContainer::memory_limit_in_bytes(result) && result != value_unlimited) {
|
||||
value = result;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool os::Container::memory_soft_limit(physical_memory_size_type& value) {
|
||||
physical_memory_size_type result = 0;
|
||||
if (OSContainer::memory_soft_limit_in_bytes(result) && result != 0 && result != value_unlimited) {
|
||||
value = result;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool os::Container::memory_throttle_limit(physical_memory_size_type& value) {
|
||||
physical_memory_size_type result = 0;
|
||||
if (OSContainer::memory_throttle_limit_in_bytes(result) && result != value_unlimited) {
|
||||
value = result;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool os::Container::used_memory(physical_memory_size_type& value) {
|
||||
return OSContainer::memory_usage_in_bytes(value);
|
||||
}
|
||||
|
||||
bool os::available_memory(physical_memory_size_type& value) {
|
||||
if (is_containerized() && Container::available_memory(value)) {
|
||||
if (OSContainer::is_containerized() && OSContainer::available_memory_in_bytes(value)) {
|
||||
log_trace(os)("available container memory: " PHYS_MEM_TYPE_FORMAT, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return Machine::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Machine::available_memory(physical_memory_size_type& value) {
|
||||
return Linux::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Container::available_memory(physical_memory_size_type& value) {
|
||||
return OSContainer::available_memory_in_bytes(value);
|
||||
}
|
||||
|
||||
bool os::Linux::available_memory(physical_memory_size_type& value) {
|
||||
physical_memory_size_type avail_mem = 0;
|
||||
|
||||
@ -294,15 +251,11 @@ bool os::Linux::available_memory(physical_memory_size_type& value) {
|
||||
}
|
||||
|
||||
bool os::free_memory(physical_memory_size_type& value) {
|
||||
if (is_containerized() && Container::available_memory(value)) {
|
||||
if (OSContainer::is_containerized() && OSContainer::available_memory_in_bytes(value)) {
|
||||
log_trace(os)("free container memory: " PHYS_MEM_TYPE_FORMAT, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return Machine::free_memory(value);
|
||||
}
|
||||
|
||||
bool os::Machine::free_memory(physical_memory_size_type& value) {
|
||||
return Linux::free_memory(value);
|
||||
}
|
||||
|
||||
@ -321,28 +274,19 @@ bool os::Linux::free_memory(physical_memory_size_type& value) {
|
||||
}
|
||||
|
||||
bool os::total_swap_space(physical_memory_size_type& value) {
|
||||
if (is_containerized() && Container::total_swap_space(value)) {
|
||||
return true;
|
||||
} // fallback to the host swap space if the container value fails
|
||||
return Machine::total_swap_space(value);
|
||||
}
|
||||
|
||||
bool os::Machine::total_swap_space(physical_memory_size_type& value) {
|
||||
return Linux::host_swap(value);
|
||||
}
|
||||
|
||||
bool os::Container::total_swap_space(physical_memory_size_type& value) {
|
||||
physical_memory_size_type mem_swap_limit = value_unlimited;
|
||||
physical_memory_size_type memory_limit = value_unlimited;
|
||||
if (OSContainer::memory_and_swap_limit_in_bytes(mem_swap_limit) &&
|
||||
OSContainer::memory_limit_in_bytes(memory_limit)) {
|
||||
if (memory_limit != value_unlimited && mem_swap_limit != value_unlimited &&
|
||||
mem_swap_limit >= memory_limit /* ensure swap is >= 0 */) {
|
||||
value = mem_swap_limit - memory_limit;
|
||||
return true;
|
||||
if (OSContainer::is_containerized()) {
|
||||
physical_memory_size_type mem_swap_limit = value_unlimited;
|
||||
physical_memory_size_type memory_limit = value_unlimited;
|
||||
if (OSContainer::memory_and_swap_limit_in_bytes(mem_swap_limit) &&
|
||||
OSContainer::memory_limit_in_bytes(memory_limit)) {
|
||||
if (memory_limit != value_unlimited && mem_swap_limit != value_unlimited &&
|
||||
mem_swap_limit >= memory_limit /* ensure swap is >= 0 */) {
|
||||
value = mem_swap_limit - memory_limit;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} // fallback to the host swap space if the container returned unlimited
|
||||
return Linux::host_swap(value);
|
||||
}
|
||||
|
||||
static bool host_free_swap_f(physical_memory_size_type& value) {
|
||||
@ -365,45 +309,32 @@ bool os::free_swap_space(physical_memory_size_type& value) {
|
||||
return false;
|
||||
}
|
||||
physical_memory_size_type host_free_swap_val = MIN2(total_swap_space, host_free_swap);
|
||||
if (is_containerized()) {
|
||||
if (Container::free_swap_space(value)) {
|
||||
if (OSContainer::is_containerized()) {
|
||||
if (OSContainer::available_swap_in_bytes(host_free_swap_val, value)) {
|
||||
return true;
|
||||
}
|
||||
// Fall through to use host value
|
||||
log_trace(os,container)("os::free_swap_space: containerized value unavailable"
|
||||
" returning host value: " PHYS_MEM_TYPE_FORMAT, host_free_swap_val);
|
||||
}
|
||||
|
||||
value = host_free_swap_val;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool os::Machine::free_swap_space(physical_memory_size_type& value) {
|
||||
return host_free_swap_f(value);
|
||||
}
|
||||
|
||||
bool os::Container::free_swap_space(physical_memory_size_type& value) {
|
||||
return OSContainer::available_swap_in_bytes(value);
|
||||
}
|
||||
|
||||
physical_memory_size_type os::physical_memory() {
|
||||
if (is_containerized()) {
|
||||
if (OSContainer::is_containerized()) {
|
||||
physical_memory_size_type mem_limit = value_unlimited;
|
||||
if (Container::memory_limit(mem_limit) && mem_limit != value_unlimited) {
|
||||
if (OSContainer::memory_limit_in_bytes(mem_limit) && mem_limit != value_unlimited) {
|
||||
log_trace(os)("total container memory: " PHYS_MEM_TYPE_FORMAT, mem_limit);
|
||||
return mem_limit;
|
||||
}
|
||||
}
|
||||
|
||||
physical_memory_size_type phys_mem = Machine::physical_memory();
|
||||
physical_memory_size_type phys_mem = Linux::physical_memory();
|
||||
log_trace(os)("total system memory: " PHYS_MEM_TYPE_FORMAT, phys_mem);
|
||||
return phys_mem;
|
||||
}
|
||||
|
||||
physical_memory_size_type os::Machine::physical_memory() {
|
||||
return Linux::physical_memory();
|
||||
}
|
||||
|
||||
// Returns the resident set size (RSS) of the process.
|
||||
// Falls back to using VmRSS from /proc/self/status if /proc/self/smaps_rollup is unavailable.
|
||||
// Note: On kernels with memory cgroups or shared memory, VmRSS may underreport RSS.
|
||||
@ -2508,21 +2439,20 @@ bool os::Linux::print_container_info(outputStream* st) {
|
||||
OSContainer::print_container_metric(st, "cpu_memory_nodes", p != nullptr ? p : "not supported");
|
||||
free(p);
|
||||
|
||||
double cpus = -1;
|
||||
bool supported = OSContainer::active_processor_count(cpus);
|
||||
int i = -1;
|
||||
bool supported = OSContainer::active_processor_count(i);
|
||||
if (supported) {
|
||||
assert(cpus > 0, "must be");
|
||||
assert(i > 0, "must be");
|
||||
if (ActiveProcessorCount > 0) {
|
||||
OSContainer::print_container_metric(st, "active_processor_count", ActiveProcessorCount, "(from -XX:ActiveProcessorCount)");
|
||||
} else {
|
||||
OSContainer::print_container_metric(st, "active_processor_count", cpus);
|
||||
OSContainer::print_container_metric(st, "active_processor_count", i);
|
||||
}
|
||||
} else {
|
||||
OSContainer::print_container_metric(st, "active_processor_count", "not supported");
|
||||
}
|
||||
|
||||
|
||||
int i = -1;
|
||||
supported = OSContainer::cpu_quota(i);
|
||||
if (supported && i > 0) {
|
||||
OSContainer::print_container_metric(st, "cpu_quota", i);
|
||||
@ -4807,26 +4737,15 @@ int os::active_processor_count() {
|
||||
return ActiveProcessorCount;
|
||||
}
|
||||
|
||||
if (is_containerized()) {
|
||||
double cpu_quota;
|
||||
if (Container::processor_count(cpu_quota)) {
|
||||
int active_cpus = ceilf(cpu_quota); // Round fractional CPU quota up.
|
||||
assert(active_cpus <= Machine::active_processor_count(), "must be");
|
||||
log_trace(os)("active_processor_count: determined by OSContainer: %d",
|
||||
active_cpus);
|
||||
return active_cpus;
|
||||
}
|
||||
int active_cpus = -1;
|
||||
if (OSContainer::is_containerized() && OSContainer::active_processor_count(active_cpus)) {
|
||||
log_trace(os)("active_processor_count: determined by OSContainer: %d",
|
||||
active_cpus);
|
||||
} else {
|
||||
active_cpus = os::Linux::active_processor_count();
|
||||
}
|
||||
|
||||
return Machine::active_processor_count();
|
||||
}
|
||||
|
||||
int os::Machine::active_processor_count() {
|
||||
return os::Linux::active_processor_count();
|
||||
}
|
||||
|
||||
bool os::Container::processor_count(double& value) {
|
||||
return OSContainer::active_processor_count(value);
|
||||
return active_cpus;
|
||||
}
|
||||
|
||||
static bool should_warn_invalid_processor_id() {
|
||||
@ -4959,18 +4878,36 @@ int os::open(const char *path, int oflag, int mode) {
|
||||
// All file descriptors that are opened in the Java process and not
|
||||
// specifically destined for a subprocess should have the close-on-exec
|
||||
// flag set. If we don't set it, then careless 3rd party native code
|
||||
// might fork and exec without closing all appropriate file descriptors.
|
||||
// might fork and exec without closing all appropriate file descriptors,
|
||||
// and this in turn might:
|
||||
//
|
||||
// - cause end-of-file to fail to be detected on some file
|
||||
// descriptors, resulting in mysterious hangs, or
|
||||
//
|
||||
// - might cause an fopen in the subprocess to fail on a system
|
||||
// suffering from bug 1085341.
|
||||
//
|
||||
// (Yes, the default setting of the close-on-exec flag is a Unix
|
||||
// design flaw)
|
||||
//
|
||||
// See:
|
||||
// 1085341: 32-bit stdio routines should support file descriptors >255
|
||||
// 4843136: (process) pipe file descriptor from Runtime.exec not being closed
|
||||
// 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
|
||||
//
|
||||
// Modern Linux kernels (after 2.6.23 2007) support O_CLOEXEC with open().
|
||||
// O_CLOEXEC is preferable to using FD_CLOEXEC on an open file descriptor
|
||||
// because it saves a system call and removes a small window where the flag
|
||||
// is unset. On ancient Linux kernels the O_CLOEXEC flag will be ignored
|
||||
// and we fall back to using FD_CLOEXEC (see below).
|
||||
#ifdef O_CLOEXEC
|
||||
oflag |= O_CLOEXEC;
|
||||
#endif
|
||||
|
||||
int fd = ::open(path, oflag, mode);
|
||||
// No further checking is needed if open() returned an error or
|
||||
// access mode is not read only.
|
||||
if (fd == -1 || (oflag & O_ACCMODE) != O_RDONLY) {
|
||||
return fd;
|
||||
}
|
||||
if (fd == -1) return -1;
|
||||
|
||||
// If the open succeeded and is read only, the file might be a directory
|
||||
// which the JVM doesn't allow to be read.
|
||||
//If the open succeeded, the file might still be a directory
|
||||
{
|
||||
struct stat buf;
|
||||
int ret = ::fstat(fd, &buf);
|
||||
@ -4988,6 +4925,21 @@ int os::open(const char *path, int oflag, int mode) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FD_CLOEXEC
|
||||
// Validate that the use of the O_CLOEXEC flag on open above worked.
|
||||
// With recent kernels, we will perform this check exactly once.
|
||||
static sig_atomic_t O_CLOEXEC_is_known_to_work = 0;
|
||||
if (!O_CLOEXEC_is_known_to_work) {
|
||||
int flags = ::fcntl(fd, F_GETFD);
|
||||
if (flags != -1) {
|
||||
if ((flags & FD_CLOEXEC) != 0)
|
||||
O_CLOEXEC_is_known_to_work = 1;
|
||||
else
|
||||
::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -22,7 +22,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "jvm.h"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "os_linux.inline.hpp"
|
||||
@ -41,6 +40,7 @@
|
||||
#include <pthread.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,12 +36,15 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
// POSIX puts _exit in <unistd.h>.
|
||||
FORBID_IMPORTED_NORETURN_C_FUNCTION(void _exit(int), /* not noexcept */, "use os::exit")
|
||||
|
||||
// If needed, add os::strndup and use that instead.
|
||||
FORBID_C_FUNCTION(char* strndup(const char*, size_t), noexcept, "don't use");
|
||||
|
||||
// These are unimplementable for Windows, and they aren't useful for a
|
||||
// POSIX implementation of NMT either.
|
||||
// https://stackoverflow.com/questions/62962839/stdaligned-alloc-missing-from-visual-studio-2019
|
||||
FORBID_C_FUNCTION(int posix_memalign(void**, size_t, size_t), noexcept, "don't use");
|
||||
FORBID_C_FUNCTION(void* aligned_alloc(size_t, size_t), noexcept, "don't use");
|
||||
|
||||
// realpath with a null second argument mallocs a string for the result.
|
||||
// With a non-null second argument, there is a risk of buffer overrun.
|
||||
PRAGMA_DIAG_PUSH
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,7 +23,6 @@
|
||||
*/
|
||||
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "jvmtifiles/jvmti.h"
|
||||
@ -458,10 +457,12 @@ char* os::map_memory_to_file(char* base, size_t size, int fd) {
|
||||
warning("Failed mmap to file. (%s)", os::strerror(errno));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The requested address should be the same as the returned address when using MAP_FIXED
|
||||
// as per POSIX.
|
||||
assert(base == nullptr || addr == base, "base should equal addr when using MAP_FIXED");
|
||||
if (base != nullptr && addr != base) {
|
||||
if (!os::release_memory(addr, size)) {
|
||||
warning("Could not release memory on unsuccessful file mapping");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -112,10 +112,6 @@ static void save_memory_to_file(char* addr, size_t size) {
|
||||
result = ::close(fd);
|
||||
if (result == OS_ERR) {
|
||||
warning("Could not close %s: %s\n", destfile, os::strerror(errno));
|
||||
} else {
|
||||
if (!successful_write) {
|
||||
remove(destfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
FREE_C_HEAP_ARRAY(char, destfile);
|
||||
@ -950,10 +946,9 @@ static int create_sharedmem_file(const char* dirname, const char* filename, size
|
||||
if (result == -1 ) break;
|
||||
if (!os::write(fd, &zero_int, 1)) {
|
||||
if (errno == ENOSPC) {
|
||||
warning("Insufficient space for shared memory file: %s/%s\n", dirname, filename);
|
||||
warning("Insufficient space for shared memory file:\n %s\nTry using the -Djava.io.tmpdir= option to select an alternate temp location.\n", filename);
|
||||
}
|
||||
result = OS_ERR;
|
||||
remove(filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,20 +25,15 @@
|
||||
#ifndef OS_POSIX_PERMITFORBIDDENFUNCTIONS_POSIX_HPP
|
||||
#define OS_POSIX_PERMITFORBIDDENFUNCTIONS_POSIX_HPP
|
||||
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "utilities/compilerWarnings.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
// Provide wrappers for some functions otherwise forbidden from use in HotSpot.
|
||||
// See forbiddenFunctions.hpp for details.
|
||||
|
||||
namespace permit_forbidden_function {
|
||||
BEGIN_ALLOW_FORBIDDEN_FUNCTIONS
|
||||
|
||||
[[noreturn]] inline void _exit(int status) { ::_exit(status); }
|
||||
|
||||
// Used by the POSIX implementation of os::realpath.
|
||||
inline char* realpath(const char* path, char* resolved_path) {
|
||||
return ::realpath(path, resolved_path);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2025, 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
|
||||
@ -951,32 +951,6 @@ struct enum_sigcode_desc_t {
|
||||
const char* s_desc;
|
||||
};
|
||||
|
||||
#if defined(LINUX)
|
||||
// Additional kernel si_code definitions that are only exported by
|
||||
// more recent glibc distributions, so we have to hard-code the values.
|
||||
#ifndef BUS_MCEERR_AR // glibc 2.17
|
||||
#define BUS_MCEERR_AR 4
|
||||
#define BUS_MCEERR_AO 5
|
||||
#endif
|
||||
|
||||
#ifndef SEGV_PKUERR // glibc 2.27
|
||||
#define SEGV_PKUERR 4
|
||||
#endif
|
||||
|
||||
#ifndef SYS_SECCOMP // glibc 2.28
|
||||
#define SYS_SECCOMP 1
|
||||
#endif
|
||||
|
||||
#ifndef TRAP_BRANCH // glibc 2.30
|
||||
#define TRAP_BRANCH 3
|
||||
#endif
|
||||
|
||||
#ifndef TRAP_HWBKPT // not glibc version specific - gdb related
|
||||
#define TRAP_HWBKPT 4
|
||||
#endif
|
||||
|
||||
#endif // LINUX
|
||||
|
||||
static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t* out) {
|
||||
|
||||
const struct {
|
||||
@ -1002,7 +976,6 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
|
||||
{ SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for mapped object." },
|
||||
#if defined(LINUX)
|
||||
{ SIGSEGV, SEGV_BNDERR, "SEGV_BNDERR", "Failed address bound checks." },
|
||||
{ SIGSEGV, SEGV_PKUERR, "SEGV_PKUERR", "Protection key checking failure." },
|
||||
#endif
|
||||
#if defined(AIX)
|
||||
// no explanation found what keyerr would be
|
||||
@ -1011,18 +984,8 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
|
||||
{ SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." },
|
||||
{ SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." },
|
||||
{ SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." },
|
||||
#if defined(LINUX)
|
||||
{ SIGBUS, BUS_MCEERR_AR,"BUS_MCEERR_AR","Hardware memory error consumed on a machine check: action required." },
|
||||
{ SIGBUS, BUS_MCEERR_AO,"BUS_MCEERR_AO","Hardware memory error detected in process but not consumed: action optional." },
|
||||
|
||||
{ SIGSYS, SYS_SECCOMP, "SYS_SECCOMP", "Secure computing (seccomp) filter failure." },
|
||||
#endif
|
||||
{ SIGTRAP, TRAP_BRKPT, "TRAP_BRKPT", "Process breakpoint." },
|
||||
{ SIGTRAP, TRAP_TRACE, "TRAP_TRACE", "Process trace trap." },
|
||||
#if defined(LINUX)
|
||||
{ SIGTRAP, TRAP_BRANCH, "TRAP_BRANCH", "Process taken branch trap." },
|
||||
{ SIGTRAP, TRAP_HWBKPT, "TRAP_HWBKPT", "Hardware breakpoint/watchpoint." },
|
||||
#endif
|
||||
{ SIGCHLD, CLD_EXITED, "CLD_EXITED", "Child has exited." },
|
||||
{ SIGCHLD, CLD_KILLED, "CLD_KILLED", "Child has terminated abnormally and did not create a core file." },
|
||||
{ SIGCHLD, CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally and created a core file." },
|
||||
@ -1030,7 +993,6 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t
|
||||
{ SIGCHLD, CLD_STOPPED, "CLD_STOPPED", "Child has stopped." },
|
||||
{ SIGCHLD, CLD_CONTINUED,"CLD_CONTINUED","Stopped child has continued." },
|
||||
#ifdef SIGPOLL
|
||||
{ SIGPOLL, POLL_IN, "POLL_IN", "Data input available." },
|
||||
{ SIGPOLL, POLL_OUT, "POLL_OUT", "Output buffers available." },
|
||||
{ SIGPOLL, POLL_MSG, "POLL_MSG", "Input message available." },
|
||||
{ SIGPOLL, POLL_ERR, "POLL_ERR", "I/O error." },
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,7 +30,6 @@
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "jvmtifiles/jvmti.h"
|
||||
@ -839,18 +838,10 @@ bool os::available_memory(physical_memory_size_type& value) {
|
||||
return win32::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Machine::available_memory(physical_memory_size_type& value) {
|
||||
return win32::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::free_memory(physical_memory_size_type& value) {
|
||||
return win32::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::Machine::free_memory(physical_memory_size_type& value) {
|
||||
return win32::available_memory(value);
|
||||
}
|
||||
|
||||
bool os::win32::available_memory(physical_memory_size_type& value) {
|
||||
// Use GlobalMemoryStatusEx() because GlobalMemoryStatus() may return incorrect
|
||||
// value if total memory is larger than 4GB
|
||||
@ -866,11 +857,7 @@ bool os::win32::available_memory(physical_memory_size_type& value) {
|
||||
}
|
||||
}
|
||||
|
||||
bool os::total_swap_space(physical_memory_size_type& value) {
|
||||
return Machine::total_swap_space(value);
|
||||
}
|
||||
|
||||
bool os::Machine::total_swap_space(physical_memory_size_type& value) {
|
||||
bool os::total_swap_space(physical_memory_size_type& value) {
|
||||
MEMORYSTATUSEX ms;
|
||||
ms.dwLength = sizeof(ms);
|
||||
BOOL res = GlobalMemoryStatusEx(&ms);
|
||||
@ -884,10 +871,6 @@ bool os::Machine::total_swap_space(physical_memory_size_type& value) {
|
||||
}
|
||||
|
||||
bool os::free_swap_space(physical_memory_size_type& value) {
|
||||
return Machine::free_swap_space(value);
|
||||
}
|
||||
|
||||
bool os::Machine::free_swap_space(physical_memory_size_type& value) {
|
||||
MEMORYSTATUSEX ms;
|
||||
ms.dwLength = sizeof(ms);
|
||||
BOOL res = GlobalMemoryStatusEx(&ms);
|
||||
@ -904,10 +887,6 @@ physical_memory_size_type os::physical_memory() {
|
||||
return win32::physical_memory();
|
||||
}
|
||||
|
||||
physical_memory_size_type os::Machine::physical_memory() {
|
||||
return win32::physical_memory();
|
||||
}
|
||||
|
||||
size_t os::rss() {
|
||||
size_t rss = 0;
|
||||
PROCESS_MEMORY_COUNTERS_EX pmex;
|
||||
@ -931,10 +910,6 @@ int os::active_processor_count() {
|
||||
return ActiveProcessorCount;
|
||||
}
|
||||
|
||||
return Machine::active_processor_count();
|
||||
}
|
||||
|
||||
int os::Machine::active_processor_count() {
|
||||
bool schedules_all_processor_groups = win32::is_windows_11_or_greater() || win32::is_windows_server_2022_or_greater();
|
||||
if (UseAllWindowsProcessorGroups && !schedules_all_processor_groups && !win32::processor_group_warning_displayed()) {
|
||||
win32::set_processor_group_warning_displayed(true);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,6 @@
|
||||
#ifndef OS_WINDOWS_PERMITFORBIDDENFUNCTIONS_WINDOWS_HPP
|
||||
#define OS_WINDOWS_PERMITFORBIDDENFUNCTIONS_WINDOWS_HPP
|
||||
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "utilities/compilerWarnings.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
@ -35,8 +34,6 @@
|
||||
namespace permit_forbidden_function {
|
||||
BEGIN_ALLOW_FORBIDDEN_FUNCTIONS
|
||||
|
||||
[[noreturn]] inline void _exit(int status) { ::_exit(status); }
|
||||
|
||||
// Used by the Windows implementation of os::realpath.
|
||||
inline char* _fullpath(char* absPath, const char* relPath, size_t maxLength) {
|
||||
return ::_fullpath(absPath, relPath, maxLength);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,7 +24,6 @@
|
||||
|
||||
#include "cds/aotMetaspace.hpp"
|
||||
#include "cds/cdsConfig.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/javaThread.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -412,8 +412,12 @@ run_stub:
|
||||
}
|
||||
|
||||
void os::Aix::init_thread_fpu_state(void) {
|
||||
#if !defined(USE_XLC_BUILTINS)
|
||||
// Disable FP exceptions.
|
||||
__asm__ __volatile__ ("mtfsfi 6,0");
|
||||
#else
|
||||
__mtfsfi(6, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2026 SAP SE. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,24 +26,33 @@
|
||||
#ifndef OS_CPU_AIX_PPC_PREFETCH_AIX_PPC_INLINE_HPP
|
||||
#define OS_CPU_AIX_PPC_PREFETCH_AIX_PPC_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
|
||||
inline void Prefetch::read(const void *loc, intx interval) {
|
||||
#if !defined(USE_XLC_BUILTINS)
|
||||
__asm__ __volatile__ (
|
||||
" dcbt 0, %0 \n"
|
||||
:
|
||||
: /*%0*/"r" ( ((address)loc) +((long)interval) )
|
||||
//:
|
||||
);
|
||||
#else
|
||||
__dcbt(((address)loc) +((long)interval));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void Prefetch::write(void *loc, intx interval) {
|
||||
#if !defined(USE_XLC_BUILTINS)
|
||||
__asm__ __volatile__ (
|
||||
" dcbtst 0, %0 \n"
|
||||
:
|
||||
: /*%0*/"r" ( ((address)loc) +((long)interval) )
|
||||
//:
|
||||
);
|
||||
#else
|
||||
__dcbtst( ((address)loc) +((long)interval) );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // OS_CPU_AIX_PPC_PREFETCH_AIX_PPC_INLINE_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -29,7 +29,6 @@
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "logging/log.hpp"
|
||||
@ -64,6 +63,7 @@
|
||||
# include <signal.h>
|
||||
# include <errno.h>
|
||||
# include <dlfcn.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/resource.h>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -27,7 +27,8 @@
|
||||
#ifndef OS_CPU_BSD_AARCH64_PREFETCH_BSD_AARCH64_INLINE_HPP
|
||||
#define OS_CPU_BSD_AARCH64_PREFETCH_BSD_AARCH64_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
|
||||
inline void Prefetch::read (const void *loc, intx interval) {
|
||||
if (interval >= 0)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,6 @@
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "logging/log.hpp"
|
||||
@ -59,6 +58,7 @@
|
||||
# include <signal.h>
|
||||
# include <errno.h>
|
||||
# include <dlfcn.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/resource.h>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,8 @@
|
||||
#ifndef OS_CPU_BSD_X86_PREFETCH_BSD_X86_INLINE_HPP
|
||||
#define OS_CPU_BSD_X86_PREFETCH_BSD_X86_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
|
||||
inline void Prefetch::read (const void *loc, intx interval) {
|
||||
__asm__ ("prefetcht0 (%0,%1,1)" : : "r" (loc), "r" (interval));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2007, 2008 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -26,7 +26,7 @@
|
||||
#ifndef OS_CPU_BSD_ZERO_PREFETCH_BSD_ZERO_INLINE_HPP
|
||||
#define OS_CPU_BSD_ZERO_PREFETCH_BSD_ZERO_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
inline void Prefetch::read(const void* loc, intx interval) {
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -28,7 +28,6 @@
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "code/nativeInst.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
@ -60,6 +59,7 @@
|
||||
# include <signal.h>
|
||||
# include <errno.h>
|
||||
# include <dlfcn.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/resource.h>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -26,7 +26,8 @@
|
||||
#ifndef OS_CPU_LINUX_AARCH64_PREFETCH_LINUX_AARCH64_INLINE_HPP
|
||||
#define OS_CPU_LINUX_AARCH64_PREFETCH_LINUX_AARCH64_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
|
||||
inline void Prefetch::read (const void *loc, intx interval) {
|
||||
if (interval >= 0)
|
||||
|
||||
@ -43,8 +43,7 @@ void JavaThread::cache_global_variables() {
|
||||
BarrierSet* bs = BarrierSet::barrier_set();
|
||||
|
||||
if (bs->is_a(BarrierSet::CardTableBarrierSet)) {
|
||||
CardTableBarrierSet* ctbs = CardTableBarrierSet::barrier_set();
|
||||
_card_table_base = (address)ctbs->card_table_base_const();
|
||||
_card_table_base = (address) (barrier_set_cast<CardTableBarrierSet>(bs)->card_table()->byte_map_base());
|
||||
} else {
|
||||
_card_table_base = nullptr;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,6 @@
|
||||
#include "asm/assembler.inline.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
@ -58,6 +57,7 @@
|
||||
# include <signal.h>
|
||||
# include <errno.h>
|
||||
# include <dlfcn.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/resource.h>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,7 @@
|
||||
#ifndef OS_CPU_LINUX_ARM_PREFETCH_LINUX_ARM_INLINE_HPP
|
||||
#define OS_CPU_LINUX_ARM_PREFETCH_LINUX_ARM_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
inline void Prefetch::read (const void *loc, intx interval) {
|
||||
#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_5TE__)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -28,7 +28,6 @@
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
@ -63,6 +62,7 @@
|
||||
# include <signal.h>
|
||||
# include <errno.h>
|
||||
# include <dlfcn.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/resource.h>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2013 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -26,7 +26,8 @@
|
||||
#ifndef OS_CPU_LINUX_PPC_PREFETCH_LINUX_PPC_INLINE_HPP
|
||||
#define OS_CPU_LINUX_PPC_PREFETCH_LINUX_PPC_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
|
||||
inline void Prefetch::read(const void *loc, intx interval) {
|
||||
__asm__ __volatile__ (
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -28,7 +28,6 @@
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/nativeInst.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
@ -62,6 +61,7 @@
|
||||
# include <pthread.h>
|
||||
# include <signal.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <sys/mman.h>
|
||||
# include <sys/resource.h>
|
||||
# include <sys/socket.h>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -26,7 +26,7 @@
|
||||
#ifndef OS_CPU_LINUX_RISCV_VM_PREFETCH_LINUX_RISCV_INLINE_HPP
|
||||
#define OS_CPU_LINUX_RISCV_VM_PREFETCH_LINUX_RISCV_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
inline void Prefetch::read (const void *loc, intx interval) {
|
||||
if (interval >= 0 && UseZicbop) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2024 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -30,7 +30,6 @@
|
||||
#include "code/nativeInst.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "compiler/disassembler.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
@ -63,6 +62,7 @@
|
||||
# include <signal.h>
|
||||
# include <errno.h>
|
||||
# include <dlfcn.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/resource.h>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -26,7 +26,7 @@
|
||||
#ifndef OS_CPU_LINUX_S390_PREFETCH_LINUX_S390_INLINE_HPP
|
||||
#define OS_CPU_LINUX_S390_PREFETCH_LINUX_S390_INLINE_HPP
|
||||
|
||||
// Included in runtime/prefetch.inline.hpp
|
||||
#include "runtime/prefetch.hpp"
|
||||
|
||||
inline void Prefetch::read(const void* loc, intx interval) {
|
||||
// No prefetch instructions on z/Architecture -> implement trivially.
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,6 @@
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/vtableStubs.hpp"
|
||||
#include "cppstdlib/cstdlib.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "jvm.h"
|
||||
#include "logging/log.hpp"
|
||||
@ -60,6 +59,7 @@
|
||||
# include <signal.h>
|
||||
# include <errno.h>
|
||||
# include <dlfcn.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/resource.h>
|
||||
|
||||
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